1#!/bin/env escript 2 3-mode(compile). 4 5-record(f, {c,f,t,a,os,w,p}). 6 7 8main([]) -> 9 {ok, A280} = file:consult("wx_28_api.dump"), 10 {ok, A300} = file:consult("wx_30_api.dump"), 11 A28 = [#f{c=C,f=F,t=T,a=A,os=Os,w=W,p=P} || {C,F,T,A,Os,W,P} <- A280], 12 A30 = [#f{c=C,f=F,t=T,a=A,os=Os,w=W,p=P} || {C,F,T,A,Os,W,P} <- A300], 13 Diff = A28 -- A30, 14 Problems = diff(Diff, A30, []), 15 {Remain,Incomp} = write(Problems, 0, 0), 16 io:format("~n Remaining Problems: ~p~n",[Remain]), 17 io:format(" Known incompatibles: ~p~n",[Incomp]), 18 ok. 19 20diff([A|R], A30, Acc) -> 21 Potential = find(A, A30), 22 case is_ok(A, Potential, A30) of 23 true -> diff(R, A30, Acc); 24 {opt_differ, _} = Diff -> 25 diff(R, A30, [{A, Diff}|Acc]); 26 false -> 27 diff(R, A30, [{A,Potential}|Acc]) 28 end; 29diff([], _, Acc) -> 30 Acc. 31 32find(#f{c=C,f=Search}, New) -> 33 Parents = parents(C,New), 34 lists:append(find([C|Parents], Search, New)). 35 36find([C|R], M, New) -> 37 [[F || #f{c=C2,f=M2} = F <- New, C =:= C2, M =:= M2] | find(R, M, New)]; 38find([], _, _) -> 39 []. 40 41parents(C, All) -> 42 case lists:keyfind(C, #f.c, All) of 43 #f{p=P} when P =/= root; P =/= object -> 44 [P|parents(P,All)]; 45 _ -> 46 [] 47 end. 48 49is_ok(A,Bs,All) -> 50 is_ok(A,Bs,All,false). 51 52is_ok(#f{f=destroy}, _, _, _) -> 53 %% Ignore destroy 54 true; 55is_ok(#f{f='\'Destroy\''}, _, _, _) -> 56 %% Ignore destroy 57 true; 58is_ok(#f{f=M,t=T,a=As,os=O}, [#f{f=M,t=T,a=As,os=O}|_], _, _) -> 59 true; 60is_ok(#f{f=M,t=T,a=As,os=O,w=Info}=A, [#f{f=M,t=T,a=As,os=O2}|R], All, Acc) -> 61 %% Only opts 62 case O -- O2 of 63 [] when Info == erl_no_opt -> is_ok(A, R, All, Acc); 64 [] -> true; 65 _ when Info == taylormade -> true; 66 _Changed -> is_ok(A, R, All, {opt_differ, O2 -- O}) 67 end; 68is_ok(#f{f=M,t=T,a=As,os=O}=A, [#f{f=M,t=T,a=Bs,os=O}|R], All, Acc) -> 69 %% Only args check if merged 70 check_args(As,Bs,All) orelse is_ok(A,R,All,Acc); 71is_ok(#f{f=M,t=T,a=As,os=O}=A, [#f{f=M,t=_T2, a=As,os=O}|R], All, Acc) -> 72 case T of %% Was cast now returns something 73 ok -> 74 %% io:format("Return type diff: ~p => ~p~n",[A, _T2]), 75 true; 76 _ -> 77 is_ok(A,R,All,Acc) 78 end; 79is_ok(A, [_|R], All, Acc) -> 80 is_ok(A, R, All, Acc); 81is_ok(_, [], _All, Acc) -> 82 Acc. 83 84check_args([A|As], [A|Bs], All) -> 85 check_args(As,Bs, All); 86check_args([A|As], [B|Bs], All) when is_list(A), is_list(B) -> 87 lists:all(fun(M) -> lists:member(M, B) end, B) andalso check_args(As,Bs,All); 88check_args([A|As], [B|Bs], All) when is_list(B) -> 89 lists:member(A, B) andalso check_args(As,Bs,All); 90check_args([], [], _) -> 91 true; 92check_args([A|As], [B|Bs], All) when is_atom(A) -> 93 Parents = parents(A,All), 94 %% io:format("A ~p is ~p? ~p ~p~n", [A, B, Parents, lists:member(B, Parents)]), 95 lists:member(B, Parents) andalso check_args(As,Bs, All); 96check_args(_, _, _) -> 97 false. 98 99%% Known API changes 100write([{#f{c=wxGLCanvas},_}|Rest0], P, K) -> 101 io:format("wxGLCanvas API is incompatible~n",[]), 102 Rest = [F || {#f{c=Mod},_} = F <- Rest0, Mod =/= wxGLCanvas], 103 write(Rest, P, K+1); 104write([{#f{f=clientDC, a=[], os=[]},_}|Rest], P, K) -> 105 io:format("wxClientDC default creators have been removed~n",[]), 106 write(Rest, P, K+1); 107write([{#f{f=paintDC, a=[], os=[]},_}|Rest], P, K) -> 108 io:format("wxPaintDC default creators have been removed~n",[]), 109 write(Rest, P, K+1); 110write([{#f{f=windowDC, a=[], os=[]},_}|Rest], P, K) -> 111 io:format("wxWindowDC default creators have been removed~n",[]), 112 write(Rest, P, K+1); 113write([{#f{c=wxBitmapButton,f=setBitmapSelected},_}|Rest0], P, K) -> 114 io:format("wxBitmapButton:[g|s]etBitmapSelected have been removed~n",[]), 115 [{#f{f=getBitmapSelected},_}|Rest] = Rest0, 116 write(Rest, P, K+1); 117write([{#f{c=wxCalendarDateAttr,f=calendarDateAttr},_}|Rest0], P, K) -> 118 io:format("wxCalendarDateAttr:new(ColText [,OptList]) have been removed~n",[]), 119 [{#f{f=calendarDateAttr},_}|Rest] = Rest0, 120 write(Rest, P, K+1); 121write([{#f{c=wxColourData,f=colourData},_}|Rest], P, K) -> 122 write(Rest, P, K+1); 123write([{#f{c=wxColourPickerCtrl,f=setColour, t=bool},_}|Rest], P, K) -> 124 %% Changed type from bool to void 125 write(Rest, P, K+1); 126write([{#f{c=wxCursor, f=cursor, a=[binary|_]},_}|Rest], P, K) -> 127 %% Removed in 2.9 128 write(Rest, P, K); 129write([{#f{c=wxDC,f=computeScaleAndOrigin},_}|Rest], P, K) -> 130 %% Implementation detail? 131 write(Rest, P, K+1); 132write([{#f{c=wxDC,f=setClippingRegion, a=[_,wxRegion]},_}|Rest], P, K) -> 133 %% Implementation detail? 134 write(Rest, P, K+1); 135write([{#f{c=wxFindReplaceData,f=findReplaceData, a=[_]},_}|Rest], P, K) -> 136 %% Changed with default value 137 write(Rest, P, K+1); 138write([{#f{c=wxGraphicsRenderer,f=GradBrush},_}|Rest], P, K) 139 when GradBrush =:= createRadialGradientBrush; GradBrush =:= createLinearGradientBrush -> 140 io:format("wxGraphicsRenderer:create*GradientBrush(..) uses GradientStops now~n",[]), 141 write(Rest, P, K+1); 142write([{#f{c=wxGraphicsRenderer,f=createPen},_}|Rest], P, K) -> 143 io:format("wxGraphicsRenderer:createPen(..) have been removed~n",[]), 144 write(Rest, P, K+1); 145 146%% wxGrid API have been reworked 147write([{#f{c=wxGrid,f=canDragRowSize},_}|Rest], P, K) -> 148 io:format("wxGrid API have many changes~n",[]), 149 write(Rest, P, K+1); 150write([{#f{c=wxGrid,f=canDragColSize},_}|Rest], P, K) -> write(Rest, P, K); 151write([{#f{c=wxGrid,f=getViewWidth},_}|Rest], P, K) -> write(Rest, P, K); 152write([{#f{c=wxGrid,f=grid, a=[wxWindow,int,int]},_}|Rest], P, K) -> write(Rest, P, K); 153write([{#f{c=wxGrid,f=setCellAlignment},_}|Rest], P, K) -> write(Rest, P, K); 154write([{#f{c=wxGrid,f=setCellBackgroundColour, a=[_,{int,int,int,int}|_]},_}|Rest], P, K) -> write(Rest, P, K); 155write([{#f{c=wxGrid,f=setCellTextColour, a=[_,{int,int,int,int}|_]},_}|Rest], P, K) -> write(Rest, P, K); 156write([{#f{c=wxGrid,f=setCellValue, a=[_,list|_]},_}|Rest], P, K) -> write(Rest, P, K); 157write([{#f{c=wxGridCellEditor,f=paintBackground},_}|Rest], P, K) -> write(Rest, P, K); 158write([{#f{c=wxGridCellEditor,f=beginEdit},_}|Rest], P, K) -> write(Rest, P, K); 159write([{#f{c=wxGridCellEditor,f=endEdit},_}|Rest], P, K) -> write(Rest, P, K); 160 161write([{#f{c=wxIcon,f=icon, a=[wx]},_}|Rest], P, K) -> 162 write(Rest, P, K+1); 163write([{#f{c=wxIconBundle,f=icon, a=[wx]},_}|Rest], P, K) -> 164 %% Removed strange 165 write(Rest, P, K+1); 166write([{#f{c=wxIconizeEvent,f=iconized},_}|Rest], P, K) -> 167 %% Changed to isIconized 168 write(Rest, P, K+1); 169write([{#f{c=wxIdleEvent,f=canSend},_}|Rest], P, K) -> 170 %% removed 171 write(Rest, P, K+1); 172write([{#f{c=wxListCtrl,f=setItem, t=int},_}|Rest], P, K) -> 173 io:format("wxListCtrl:setItem/4 changed return value~n",[]), 174 write(Rest, P, K+1); 175write([{#f{c=wxListCtrl,f=sortItems},_}|Rest], P, K) -> 176 write(Rest, P, K); 177write([{#f{c=wxMDIClientWindow,f=mDIClientWindow},_}|Rest], P, K) -> 178 write(Rest, P, K); 179write([{#f{c=wxMenu,f=prepend,a=[_,_,_,_,bool]},_}|Rest], P, K) -> 180 write(Rest, P, K); 181write([{#f{c=wxMenu,f=insert,a=[_,_,_,_,_,bool]},_}|Rest], P, K) -> 182 write(Rest, P, K); 183write([{#f{c=wxMenu,f=append,a=[_,_,_,_,bool]},_}|Rest], P, K) -> 184 io:format("wxMenu append/insert/prepend have changed return value and lost IsCheckable argument~n",[]), 185 write(Rest, P, K+1); 186write([{#f{c=wxMultiChoiceDialog,f=multiChoiceDialog,a=[]},_}|Rest], P, K) -> 187 write(Rest, P, K+1); 188write([{#f{c=wxNotebookEvent},_}|Rest0], P, K) -> 189 io:format("wxNotebookEvent have been replaced by the wxBookctrlEvent~n",[]), 190 Rest = [F || {#f{c=Mod},_} = F <- Rest0, Mod =/= wxNotebookEvent], 191 write(Rest, P, K+1); 192write([{#f{c=wxPageSetupDialogData,f=setPaperSize},_}|Rest], P, K) -> 193 write(Rest, P, K+1); 194write([{#f{c=wxPanel,f=panel},_}|Rest], P, K) -> 195 write(Rest, P, K+1); 196write([{#f{c=wxPostScriptDC,f=Resolution},_}|Rest], P, K) 197 when Resolution =:= setResolution; Resolution =:= getResolution -> 198 %% Deprecated in 2.9 199 write(Rest, P, K+1); 200write([{#f{c=wxPrinter,f=createAbortWindow},_}|Rest], P, K) -> 201 write(Rest, P, K+1); 202write([{#f{c=wxRegion,f=subtract},_}|Rest], P, K) -> 203 write(Rest, P, K+1); 204write([{#f{c=wxShowEvent,f=getShow},_}|Rest], P, K) -> 205 %% Deprecated in 2.9 206 write(Rest, P, K+1); 207write([{#f{c=wxSingleChoiceDialog,f=singleChoiceDialog, a=[]},_}|Rest], P, K) -> 208 write(Rest, P, K+1); 209write([{#f{c=wxSizer,f=recalcSizes},_}|Rest], P, K) -> 210 io:format("Removed wxSizer:recalcSizer() was an wxWidgets internal function now deprected~n", []), 211 write(Rest, P, K+1); 212write([{#f{c=wxSizerItem,f=setWindow},_}|Rest], P, K) -> 213 io:format("Removed depr wxSizerItem:setWindow() use assignWindow~n", []), 214 write(Rest, P, K+1); 215write([{#f{c=wxSizerItem,f=setSpacer},_}|Rest], P, K) -> 216 io:format("Removed depr wxSizerItem:setSpacer() use assignSpacer~n", []), 217 write(Rest, P, K+1); 218write([{#f{c=wxSizerItem,f=setSizer},_}|Rest], P, K) -> 219 io:format("Removed depr wxSizerItem:setSizer() use assignSizer~n", []), 220 write(Rest, P, K+1); 221write([{#f{c=wxSizerItem, f=sizerItem},_}|Rest0], P, K) -> 222 io:format("wxSizerItem:new() Some args have become options ~n",[]), 223 Rest = [F || {#f{c=Mod, f=M},_} = F <- Rest0, Mod =/= wxSizerItem orelse M =/= sizerItem], 224 write(Rest, P, K+1); 225write([{#f{c=wxSplashScreen,f=splashScreen, a=[]},_}|Rest], P, K) -> 226 write(Rest, P, K+1); 227write([{#f{c=wxSplitterWindow,f=setSashSize},_}|Rest], P, K) -> 228 %% Deprecated No-op 229 write(Rest, P, K+1); 230write([{#f{c=wxStyledTextCtrl,f=addStyledText},_}|Rest], P, K) -> 231 %% Unusable API couldn't have been used 232 write(Rest, P, K); 233write([{#f{c=wxStyledTextCtrl,f=getStyledText},_}|Rest], P, K) -> 234 %% Unusable API couldn't have been used 235 write(Rest, P, K); 236write([{#f{c=wxStyledTextCtrl,f=getCaretSticky},_}|Rest], P, K) -> 237 write(Rest, P, K); %% Changed from bool => int 238write([{#f{c=wxStyledTextCtrl,f=setCaretSticky},_}|Rest], P, K) -> 239 write(Rest, P, K); %% Changed from bool => int 240write([{#f{c=wxStyledTextCtrl,f=getIndentationGuides},_}|Rest], P, K) -> 241 write(Rest, P, K); %% Changed from bool => int 242write([{#f{c=wxStyledTextCtrl,f=setIndentationGuides},_}|Rest], P, K) -> 243 write(Rest, P, K); %% Changed from bool => int 244write([{#f{c=wxStyledTextCtrl,f=startStyling},_}|Rest], P, K) -> 245 write(Rest, P, K); %% Remove mask arg? 246write([{#f{c=wxStyledTextCtrl,f=usePopUp},_}|Rest], P, K) -> 247 io:format("wxStyledTextCtrl some functions have changed args from boolean to int~n"), 248 write(Rest, P, K+1); 249write([{#f{c=wxToolBar,f=insertTool},_}|Rest], P, K) -> 250 write(Rest, P, K); 251write([{#f{c=wxToolBar,f=addTool},_}|Rest0], P, K) -> 252 io:format("wxToolBar add/insertTool without label have been deprecated~n",[]), 253 Rest = [F || {#f{c=Mod, f=M},_} = F <- Rest0, Mod =/= wxToolBar orelse M =/= addTool], 254 write(Rest, P, K+1); 255write([{#f{c=wxWindow,f=makeModal},_}|Rest], P, K) -> 256 io:format("wxWindow:makeModal(..) have been deprecated~n",[]), 257 write(Rest, P, K+1); 258write([{#f{c=wxWindow,f=setVirtualSizeHints},_}|Rest0], P, K) -> 259 io:format("wxWindow:setVirtualSizeHints(..) have been deprecated~n",[]), 260 Rest = [F || {#f{c=Mod, f=M},_} = F <- Rest0, Mod =/= wxWindow orelse M =/= setVirtualSizeHints], 261 write(Rest, P, K+1); 262write([{#f{c=wx_misc,f=genericFindWindowAtPoint},_}|Rest], P, K) -> 263 write(Rest, P, K+1); 264write([{#f{c=wx_misc,f=shutdown},_}|Rest], P, K) -> 265 write(Rest, P, K+1); 266 267 268%% Options 269write([{#f{c=wxDisplay, f=display},{opt_differ,_}}|Rest], P, K) -> 270 io:format("wxDisplay::wxDisplay opts incompatible~n",[]), 271 write(Rest, P, K+1); 272write([{#f{c=wxFlexGridSizer, f=flexGridSizer},{opt_differ,_}}|Rest], P, K) -> 273 io:format("wxFlexGridSizer::wxFlexGridSizer opts incompatible~n",[]), 274 write(Rest, P, K+1); 275write([{#f{c=wxGridSizer, f=gridSizer},{opt_differ,_}}|Rest], P, K) -> 276 io:format("wxGridSizer::wxGridSizer opts incompatible~n",[]), 277 write(Rest, P, K+1); 278write([{#f{c=wxHtmlWindow, f=setFonts},{opt_differ,_}}|Rest], P, K) -> 279 %% Bug in old api?? 280 write(Rest, P, K); 281write([{#f{c=wxImage, f=convertToGreyscale},{opt_differ,_}}|Rest], P, K) -> 282 io:format("wxImage::convertToGreyscale opts incompatible~n",[]), 283 write(Rest, P, K+1); 284 285%% Unknown 286 287write([{A, {opt_differ, Opts}}|Rest], P, K) -> 288 io:format("28: ~0p ",[A]), 289 io:format(" Changed Opts: ~p~n",[Opts]), 290 write(Rest, P+1, K); 291write([{A,Ps}|Rest], P, K) -> 292 io:format("28: ~0p~n",[A]), 293 [io:format(" 30: ~0p~n",[B]) || B <- Ps], 294 io:nl(), 295 write(Rest, P+1, K); 296%% write([_|Rest], P, K) -> 297%% write(Rest, P+1, K); 298write([], P, K) -> 299 {P,K}. 300 301