aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåkan Mattsson <[email protected]>2010-03-15 15:08:17 +0100
committerBjörn Gustavsson <[email protected]>2010-03-23 10:12:41 +0100
commit5e454b3d8ea3bf14db3afd44c34964de21770ecb (patch)
tree187307ac4d58873e5ca68004777ebca018e7e7ef
parenta3202b05d648732b7d2afe3ad952782e5376a18d (diff)
downloadotp-5e454b3d8ea3bf14db3afd44c34964de21770ecb.tar.gz
otp-5e454b3d8ea3bf14db3afd44c34964de21770ecb.tar.bz2
otp-5e454b3d8ea3bf14db3afd44c34964de21770ecb.zip
Add app and appup files to the wx application
-rw-r--r--lib/wx/src/Makefile26
-rw-r--r--lib/wx/src/wx.app.src37
-rw-r--r--lib/wx/src/wx.appup.src22
-rw-r--r--lib/wx/src/wxe_master.erl1
-rw-r--r--lib/wx/test/Makefile4
-rw-r--r--lib/wx/test/wx_app_SUITE.erl277
6 files changed, 364 insertions, 3 deletions
diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile
index 6c636bb51f..161ef82c57 100644
--- a/lib/wx/src/Makefile
+++ b/lib/wx/src/Makefile
@@ -44,6 +44,8 @@ GEN_FILES = $(wildcard gen/wx*.erl) \
gen/glu.erl \
gen/gl.erl
+GEN_MODS = $(GEN_FILES:gen/%.erl= %,\n )
+
GEN_HRL = \
$(EGEN)/gl_debug.hrl \
$(EGEN)/wxe_debug.hrl \
@@ -56,15 +58,25 @@ EXT_HRL = $(ERLINC)/wx.hrl \
TARGET_FILES = $(ErlMods:%=$(EBIN)/%.beam) $(GEN_FILES:gen/%.erl=$(EBIN)/%.beam)
HEADER_FILES = $(HRL_FILES) $(GEN_HRL) $(EXT_HRL)
+APP_FILE = wx.app
+APP_SRC = $(APP_FILE).src
+APP_TARGET = $(EBIN)/$(APP_FILE)
+
+APPUP_FILE = wx.appup
+APPUP_SRC = $(APPUP_FILE).src
+APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
+
# Targets
-debug opt: $(TARGET_FILES)
+debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
clean:
rm -f $(TARGET_FILES)
+ rm -f $(APP_TARGET) $(APPUP_TARGET)
rm -f *~
complete_clean:
rm -f $(TARGET_FILES)
+ rm -f $(APP_TARGET) $(APPUP_TARGET)
rm -f $(GEN_FILES)
rm -f $(GenHrl)
rm -f *~
@@ -75,6 +87,17 @@ docs:
archive: opt
(cd ../..; zip -0 wx/$(ARCHIVE) wx wx/ebin wx/ebin/*)
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+$(APP_TARGET): $(APP_SRC) ../vsn.mk Makefile
+ sed -e 's;%GEN_MODS%;$(GEN_MODS);' $< > [email protected]
+ sed -e 's;%VSN%;$(VSN);' [email protected] > $@
+
+$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk Makefile
+ sed -e 's;%VSN%;$(VSN);' $< > $@
# Rules
$(EBIN)/%.beam: $(ESRC)/%.erl $(HEADER_FILES)
@@ -97,6 +120,7 @@ release_spec: opt
$(INSTALL_DATA) $(EXT_HRL) $(RELSYSDIR)/include
$(INSTALL_DIR) $(RELSYSDIR)/ebin
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin
# $(INSTALL_DATA) ../$(ARCHIVE) $(RELEASE_PATH)/lib
release_docs_spec:
diff --git a/lib/wx/src/wx.app.src b/lib/wx/src/wx.app.src
new file mode 100644
index 0000000000..e13982b0c1
--- /dev/null
+++ b/lib/wx/src/wx.app.src
@@ -0,0 +1,37 @@
+%% This is an -*- erlang -*- file.
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+{application, wx,
+ [{description, "Yet another graphics system"},
+ {vsn, "%VSN%"},
+ {modules,
+ [
+ %% Generated modules
+ %GEN_MODS%
+ %% Handcrafted modules
+ wx,
+ wx_object,
+ wxe_master,
+ wxe_server,
+ wxe_util
+ ]},
+ {registered, []},
+ {applications, [stdlib, kernel]},
+ {env, []}
+ ]}.
diff --git a/lib/wx/src/wx.appup.src b/lib/wx/src/wx.appup.src
new file mode 100644
index 0000000000..c02edd2afb
--- /dev/null
+++ b/lib/wx/src/wx.appup.src
@@ -0,0 +1,22 @@
+%% This is an -*- erlang -*- file.
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+
+{"%VSN%",
+ [ ]
+}.
diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl
index 70872775fb..8810763210 100644
--- a/lib/wx/src/wxe_master.erl
+++ b/lib/wx/src/wxe_master.erl
@@ -33,7 +33,6 @@
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
--compile(export_all).
-record(state, {cb_port, %% Callback port and to erlang messages goes via it.
users, %% List of wx servers, needed ??
diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile
index 65d7d56650..0a1a43731d 100644
--- a/lib/wx/test/Makefile
+++ b/lib/wx/test/Makefile
@@ -28,7 +28,9 @@ APPDIR = $(shell dirname $(PWD))
ERL_COMPILE_FLAGS = -pa $(APPDIR)/ebin
Mods = wxt wx_test_lib \
- wx_basic_SUITE wx_event_SUITE \
+ wx_app_SUITE \
+ wx_basic_SUITE \
+ wx_event_SUITE \
wx_class_SUITE \
wx_xtra_SUITE \
wx_opengl_SUITE
diff --git a/lib/wx/test/wx_app_SUITE.erl b/lib/wx/test/wx_app_SUITE.erl
new file mode 100644
index 0000000000..8fff324913
--- /dev/null
+++ b/lib/wx/test/wx_app_SUITE.erl
@@ -0,0 +1,277 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%%----------------------------------------------------------------------
+%% Purpose: Verify the application specifics of the Wx application
+%%----------------------------------------------------------------------
+-module(wx_app_SUITE).
+
+-compile(export_all).
+
+-include("wx_test_lib.hrl").
+
+
+t() -> wx_test_lib:t(?MODULE).
+t(Case) -> wx_test_lib:t({?MODULE, Case}).
+
+%% Test server callbacks
+init_per_testcase(Case, Config0) ->
+ Config1 = wx_test_lib:init_per_testcase(Case, Config0),
+ case is_app(wx) of
+ {ok, AppFile} ->
+ %% io:format("AppFile: ~n~p~n", [AppFile]),
+ [{app_file, AppFile} | Config1];
+ {error, Reason} ->
+ fail(Reason)
+ end.
+
+end_per_testcase(Func,Config) ->
+ wx_test_lib:end_per_testcase(Func, Config).
+
+fin_per_testcase(Case, Config) ->
+ wx_test_lib:end_per_testcase(Case, Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+all() ->
+ all(suite).
+
+all(suite) ->
+ [
+ fields,
+ modules,
+ exportall,
+ app_depend,
+ undef_funcs
+ ].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+is_app(App) ->
+ LibDir = code:lib_dir(App),
+ File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
+ case file:consult(File) of
+ {ok, [{application, App, AppFile}]} ->
+ {ok, AppFile};
+ Error ->
+ {error, {invalid_format, Error}}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fields(suite) ->
+ [];
+fields(doc) ->
+ [];
+fields(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Fields = [vsn, description, modules, registered, applications],
+ case check_fields(Fields, AppFile, []) of
+ [] ->
+ ok;
+ Missing ->
+ fail({missing_fields, Missing})
+ end.
+
+check_fields([], _AppFile, Missing) ->
+ Missing;
+check_fields([Field|Fields], AppFile, Missing) ->
+ check_fields(Fields, AppFile, check_field(Field, AppFile, Missing)).
+
+check_field(Name, AppFile, Missing) ->
+ io:format("checking field: ~p~n", [Name]),
+ case lists:keymember(Name, 1, AppFile) of
+ true ->
+ Missing;
+ false ->
+ [Name|Missing]
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+modules(suite) ->
+ [];
+modules(doc) ->
+ [];
+modules(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ EbinList = get_ebin_mods(wx),
+ case missing_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Missing ->
+ throw({error, {missing_modules, Missing}})
+ end,
+ case extra_modules(Mods, EbinList, []) of
+ [] ->
+ ok;
+ Extra ->
+ throw({error, {extra_modules, Extra}})
+ end,
+ {ok, Mods}.
+
+get_ebin_mods(App) ->
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ {ok, Files0} = file:list_dir(EbinDir),
+ Files1 = [lists:reverse(File) || File <- Files0],
+ [list_to_atom(lists:reverse(Name)) || [$m,$a,$e,$b,$.|Name] <- Files1].
+
+missing_modules([], _Ebins, Missing) ->
+ Missing;
+missing_modules([Mod|Mods], Ebins, Missing) ->
+ case lists:member(Mod, Ebins) of
+ true ->
+ missing_modules(Mods, Ebins, Missing);
+ false ->
+ io:format("missing module: ~p~n", [Mod]),
+ missing_modules(Mods, Ebins, [Mod|Missing])
+ end.
+
+
+extra_modules(_Mods, [], Extra) ->
+ Extra;
+extra_modules(Mods, [Mod|Ebins], Extra) ->
+ case lists:member(Mod, Mods) of
+ true ->
+ extra_modules(Mods, Ebins, Extra);
+ false ->
+ io:format("supefluous module: ~p~n", [Mod]),
+ extra_modules(Mods, Ebins, [Mod|Extra])
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+exportall(suite) ->
+ [];
+exportall(doc) ->
+ [];
+exportall(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ check_export_all(Mods).
+
+
+check_export_all([]) ->
+ ok;
+check_export_all([Mod|Mods]) ->
+ case (catch apply(Mod, module_info, [compile])) of
+ {'EXIT', {undef, _}} ->
+ check_export_all(Mods);
+ O ->
+ case lists:keysearch(options, 1, O) of
+ false ->
+ check_export_all(Mods);
+ {value, {options, List}} ->
+ case lists:member(export_all, List) of
+ true ->
+ throw({error, {export_all, Mod}});
+ false ->
+ check_export_all(Mods)
+ end
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+app_depend(suite) ->
+ [];
+app_depend(doc) ->
+ [];
+app_depend(Config) when is_list(Config) ->
+ AppFile = key1search(app_file, Config),
+ Apps = key1search(applications, AppFile),
+ check_apps(Apps).
+
+check_apps([]) ->
+ ok;
+check_apps([App|Apps]) ->
+ case is_app(App) of
+ {ok, _} ->
+ check_apps(Apps);
+ Error ->
+ throw({error, {missing_app, {App, Error}}})
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+undef_funcs(suite) ->
+ [];
+undef_funcs(doc) ->
+ [];
+undef_funcs(Config) when is_list(Config) ->
+ catch test_server:timetrap(timer:minutes(10)),
+ App = wx,
+ AppFile = key1search(app_file, Config),
+ Mods = key1search(modules, AppFile),
+ Root = code:root_dir(),
+ LibDir = code:lib_dir(App),
+ EbinDir = filename:join([LibDir,"ebin"]),
+ XRefTestName = undef_funcs_make_name(App, xref_test_name),
+ {ok, XRef} = xref:start(XRefTestName),
+ ok = xref:set_default(XRef,
+ [{verbose,false},{warnings,false}]),
+ XRefName = undef_funcs_make_name(App, xref_name),
+ {ok, XRefName} = xref:add_release(XRef, Root, {name,XRefName}),
+ {ok, App} = xref:replace_application(XRef, App, EbinDir),
+ {ok, Undefs} = xref:analyze(XRef, undefined_function_calls),
+ xref:stop(XRef),
+ analyze_undefined_function_calls(Undefs, Mods, []).
+
+analyze_undefined_function_calls([], _, []) ->
+ ok;
+analyze_undefined_function_calls([], _, AppUndefs) ->
+ exit({suite_failed, {undefined_function_calls, AppUndefs}});
+analyze_undefined_function_calls([{{Mod, _F, _A}, _C} = AppUndef|Undefs],
+ AppModules, AppUndefs) ->
+ %% Check that this module is ours
+ case lists:member(Mod,AppModules) of
+ true ->
+ {Calling,Called} = AppUndef,
+ {Mod1,Func1,Ar1} = Calling,
+ {Mod2,Func2,Ar2} = Called,
+ io:format("undefined function call: "
+ "~n ~w:~w/~w calls ~w:~w/~w~n",
+ [Mod1,Func1,Ar1,Mod2,Func2,Ar2]),
+ analyze_undefined_function_calls(Undefs, AppModules,
+ [AppUndef|AppUndefs]);
+ false ->
+ io:format("dropping ~p~n", [Mod]),
+ analyze_undefined_function_calls(Undefs, AppModules, AppUndefs)
+ end.
+
+%% This function is used simply to avoid cut-and-paste errors later...
+undef_funcs_make_name(App, PostFix) ->
+ list_to_atom(atom_to_list(App) ++ "_" ++ atom_to_list(PostFix)).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+fail(Reason) ->
+ exit({suite_failed, Reason}).
+
+key1search(Key, L) ->
+ case lists:keysearch(Key, 1, L) of
+ false ->
+ fail({not_found, Key, L});
+ {value, {Key, Value}} ->
+ Value
+ end.