diff options
author | Niclas Eklund <[email protected]> | 2010-09-02 16:15:32 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-09-09 10:47:56 +0200 |
commit | 27a5daae33616e662a36ed514c31618d51ad66e3 (patch) | |
tree | da22058ccf804c5de127339ea13dce3e0931f44e | |
parent | 8e9b11172194ff2920bf572ccbe87a070fe54ec4 (diff) | |
download | otp-27a5daae33616e662a36ed514c31618d51ad66e3.tar.gz otp-27a5daae33616e662a36ed514c31618d51ad66e3.tar.bz2 otp-27a5daae33616e662a36ed514c31618d51ad66e3.zip |
Add test suite for ic
120 files changed, 21860 insertions, 0 deletions
diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile new file mode 100644 index 0000000000..1142159d19 --- /dev/null +++ b/lib/ic/test/Makefile @@ -0,0 +1,277 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1998-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% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(IC_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/ic_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = ic.spec ic.spec.vxworks + + +IDL_FILES = + +COMPILER_TEST_FILES = \ + ic_SUITE_data/Corba.idl \ + ic_SUITE_data/Coss.idl \ + ic_SUITE_data/attr.idl \ + ic_SUITE_data/c_err1.idl \ + ic_SUITE_data/c_err2.idl \ + ic_SUITE_data/c_err3.idl \ + ic_SUITE_data/c_norm.idl \ + ic_SUITE_data/enum.idl \ + ic_SUITE_data/forward.idl \ + ic_SUITE_data/include.idl \ + ic_SUITE_data/include2.idl \ + ic_SUITE_data/include3.idl \ + ic_SUITE_data/inherit.idl \ + ic_SUITE_data/inherit_err.idl \ + ic_SUITE_data/inherit_warn.idl \ + ic_SUITE_data/mult_ids.idl \ + ic_SUITE_data/nasty.idl \ + ic_SUITE_data/one.idl \ + ic_SUITE_data/one_out.idl \ + ic_SUITE_data/one_raises.idl \ + ic_SUITE_data/one_followed.idl \ + ic_SUITE_data/one_void.idl \ + ic_SUITE_data/raises_reg.idl \ + ic_SUITE_data/struct.idl \ + ic_SUITE_data/syntax1.idl \ + ic_SUITE_data/syntax2.idl \ + ic_SUITE_data/syntax3.idl \ + ic_SUITE_data/syntax4.idl \ + ic_SUITE_data/syntax5.idl \ + ic_SUITE_data/syntax6.idl \ + ic_SUITE_data/type.idl \ + ic_SUITE_data/typeid.idl \ + ic_SUITE_data/u_case_mult.idl \ + ic_SUITE_data/u_mult.idl \ + ic_SUITE_data/u_norm.idl \ + ic_SUITE_data/u_type.idl \ + ic_SUITE_data/u_default.idl \ + ic_SUITE_data/undef_id.idl + + +COMPILER_TEST_FILES2 = \ + ic_register_SUITE_data/reg_m8.idl \ + ic_register_SUITE_data/reg_m9.idl \ + ic_register_SUITE_data/reg_m10.idl \ + ic_register_SUITE_data/reg_m11.idl \ + ic_register_SUITE_data/reg_m12.idl + + +COMPILER_TEST_FILES3 = \ + ic_pragma_SUITE_data/reg_m0.idl \ + ic_pragma_SUITE_data/reg_m1.idl \ + ic_pragma_SUITE_data/reg_m2.idl \ + ic_pragma_SUITE_data/reg_m3.idl \ + ic_pragma_SUITE_data/reg_m4.idl \ + ic_pragma_SUITE_data/reg_m5.idl \ + ic_pragma_SUITE_data/reg_m6.idl \ + ic_pragma_SUITE_data/reg_m7.idl \ + ic_pragma_SUITE_data/uggly.idl + + +COMPILER_TEST_FILES4 = \ + ic_be_SUITE_data/plain.idl + + +PREPROCESSOR_TEST_FILES = \ + ic_pp_SUITE_data/arg.idl \ + ic_pp_SUITE_data/cascade.idl \ + ic_pp_SUITE_data/comment.idl \ + ic_pp_SUITE_data/concat.idl \ + ic_pp_SUITE_data/define.idl \ + ic_pp_SUITE_data/if.idl \ + ic_pp_SUITE_data/if_zero.idl \ + ic_pp_SUITE_data/improp_nest_constr.idl \ + ic_pp_SUITE_data/inc.idl \ + ic_pp_SUITE_data/line.idl \ + ic_pp_SUITE_data/misc.idl \ + ic_pp_SUITE_data/nopara.idl \ + ic_pp_SUITE_data/predef.idl \ + ic_pp_SUITE_data/predef_time.idl \ + ic_pp_SUITE_data/self_ref.idl \ + ic_pp_SUITE_data/separate.idl \ + ic_pp_SUITE_data/swallow_sc.idl \ + ic_pp_SUITE_data/unintended_grp.idl + +C_CLIENT_ERL_SERVER_TEST_FILES = \ + c_client_erl_server_SUITE_data/Makefile.src \ + c_client_erl_server_SUITE_data/c_erl_test.idl \ + c_client_erl_server_SUITE_data/c_client.c \ + c_client_erl_server_SUITE_data/m_i_impl.erl + +C_CLIENT_ERL_SERVER_PROTO_TEST_FILES = \ + c_client_erl_server_proto_SUITE_data/Makefile.src \ + c_client_erl_server_proto_SUITE_data/c_erl_test.idl \ + c_client_erl_server_proto_SUITE_data/c_client.c \ + c_client_erl_server_proto_SUITE_data/my.c \ + c_client_erl_server_proto_SUITE_data/m_i_impl.erl + +C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES = \ + c_client_erl_server_proto_tmo_SUITE_data/Makefile.src \ + c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl \ + c_client_erl_server_proto_tmo_SUITE_data/c_client.c \ + c_client_erl_server_proto_tmo_SUITE_data/my.c \ + c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl + +ERL_CLIENT_C_SERVER_TEST_FILES = \ + erl_client_c_server_SUITE_data/Makefile.src \ + erl_client_c_server_SUITE_data/erl_c_test.idl \ + erl_client_c_server_SUITE_data/erl_client.erl \ + erl_client_c_server_SUITE_data/c_server.c \ + erl_client_c_server_SUITE_data/callbacks.c + +ERL_CLIENT_C_SERVER_PROTO_TEST_FILES = \ + erl_client_c_server_proto_SUITE_data/Makefile.src \ + erl_client_c_server_proto_SUITE_data/erl_c_test.idl \ + erl_client_c_server_proto_SUITE_data/erl_client.erl \ + erl_client_c_server_proto_SUITE_data/c_server.c \ + erl_client_c_server_proto_SUITE_data/callbacks.c + +JAVA_CLIENT_ERL_SERVER_TEST_FILES = \ + java_client_erl_server_SUITE_data/Makefile.src \ + java_client_erl_server_SUITE_data/java_erl_test.idl \ + java_client_erl_server_SUITE_data/JavaClient.java \ + java_client_erl_server_SUITE_data/m_i_impl.erl + +MODULES = \ + ic_SUITE \ + ic_register_SUITE \ + ic_pragma_SUITE \ + ic_pp_SUITE \ + ic_be_SUITE \ + c_client_erl_server_SUITE \ + c_client_erl_server_proto_SUITE \ + c_client_erl_server_proto_tmo_SUITE \ + erl_client_c_server_SUITE \ + erl_client_c_server_proto_SUITE \ + java_client_erl_server_SUITE + +GEN_MODULES = + +ERL_FILES = $(MODULES:%=%.erl) + +HRL_FILES = + +GEN_HRL_FILES = + + +GEN_FILES = \ + $(GEN_HRL_FILES:%=$(IDLOUTDIR)/%) \ + $(GEN_MODULES=:%=$(IDLOUTDIR)/%.erl) + +GEN_TARGET_FILES = $(GEN_MODULES:%=$(IDLOUTDIR)/%.$(EMULATOR)) + +SUITE_TARGET_FILES = $(MODULES:%=%.$(EMULATOR)) + +TARGET_FILES = \ + $(GEN_TARGET_FILES) \ + $(SUITE_TARGET_FILES) + +# ---------------------------------------------------- +# PROGRAMS +# ---------------------------------------------------- + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_LOCAL_FLAGS += -pa $(ERL_TOP)/lib/orber/ebin -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_LOCAL_FLAGS) \ + -pa $(ERL_TOP)/lib/test_server/ebin \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -I$(ERL_TOP)/lib/orber \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +tests debug opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) $(RELSYSDIR)/ic_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_register_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_pragma_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_pp_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/ic_be_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data + $(INSTALL_DIR) $(RELSYSDIR)/java_client_erl_server_SUITE_data + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(ERL_FILES) \ + $(RELSYSDIR) + $(INSTALL_DATA) $(COMPILER_TEST_FILES) $(RELSYSDIR)/ic_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES2) \ + $(RELSYSDIR)/ic_register_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES3) \ + $(RELSYSDIR)/ic_pragma_SUITE_data + $(INSTALL_DATA) $(COMPILER_TEST_FILES4) \ + $(RELSYSDIR)/ic_be_SUITE_data + $(INSTALL_DATA) $(PREPROCESSOR_TEST_FILES) \ + $(RELSYSDIR)/ic_pp_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data + $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES) \ + $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data + $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_TEST_FILES) \ + $(RELSYSDIR)/erl_client_c_server_SUITE_data + $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_PROTO_TEST_FILES) \ + $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(JAVA_CLIENT_ERL_SERVER_TEST_FILES) \ + $(RELSYSDIR)/java_client_erl_server_SUITE_data diff --git a/lib/ic/test/c_client_erl_server_SUITE.erl b/lib/ic/test/c_client_erl_server_SUITE.erl new file mode 100644 index 0000000000..40c1395d10 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. 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 : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + + +-module(c_client_erl_server_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..6516e699bd --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/Makefile.src @@ -0,0 +1,145 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2001-2009. 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% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c new file mode 100644 index 0000000000..e4f9cfdece --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_client.c @@ -0,0 +1,1760 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2001-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% + * + */ +/* C-client for test of IC. + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..ccb8f54508 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/c_erl_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2001-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% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..dffbbb059c --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. 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% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..cfcaa793a5 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2001-2009. 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% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_SUITE.erl new file mode 100644 index 0000000000..58309a2221 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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 : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + +-module(c_client_erl_server_proto_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + %% [NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src new file mode 100644 index 0000000000..3dcd1d9387 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/Makefile.src @@ -0,0 +1,146 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2003-2009. 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% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c my.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \ + "+{user_protocol,my}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c new file mode 100644 index 0000000000..f352b91fd5 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_client.c @@ -0,0 +1,1763 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2003-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% + * + */ +/* C-client for test of IC. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..6d229c3ac1 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/c_erl_test.idl @@ -0,0 +1,173 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2003-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% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..09358b7cf9 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. 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% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..9f231de856 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. 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% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c new file mode 100644 index 0000000000..f8a3b28cc2 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_SUITE_data/my.c @@ -0,0 +1,50 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. 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% + * + */ + +#include "ic.h" +#include "m_i.h" + +int my_prepare_notification_encoding(CORBA_Environment *env) +{ + return oe_prepare_notification_encoding(env); +} + +int my_send_notification(CORBA_Environment *env) +{ + return oe_send_notification(env); +} + +int my_prepare_request_encoding(CORBA_Environment *env) +{ + return oe_prepare_request_encoding(env); +} + +int my_send_request_and_receive_reply(CORBA_Environment *env) +{ + return oe_send_request_and_receive_reply(env); +} + +int my_prepare_reply_decoding(CORBA_Environment *env) +{ + return oe_prepare_reply_decoding(env); +} + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl new file mode 100644 index 0000000000..595c5bf483 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE.erl @@ -0,0 +1,315 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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 : Test suite for c-client/erl-server +%%---------------------------------------------------------------------- + +-module(c_client_erl_server_proto_tmo_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, + all/1, void_test/1, long_test/1, long_long_test/1, + unsigned_short_test/1, unsigned_long_test/1, + unsigned_long_long_test/1, double_test/1, char_test/1, + wchar_test/1, octet_test/1, bool_test/1, struct_test/1, + struct2_test/1, seq1_test/1, seq2_test/1, seq3_test/1, + seq4_test/1, seq5_test/1, array1_test/1, array2_test/1, + enum_test/1, string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, term_test/1, + typedef_test/1, inline_sequence_test/1, term_sequence_test/1, + term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(ERLANG_SERVER_NAME, idl_erlang_server). +-define(C_CLIENT_NODE_NAME, c_client_idl_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with a C-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, long_long_test, unsigned_short_test, + unsigned_long_test, unsigned_long_long_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +long_long_test(doc) -> ""; +long_long_test(suite) -> []; +long_long_test(Config) -> + do_test(long_long_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +unsigned_long_long_test(doc) -> ""; +unsigned_long_long_test(suite) -> []; +unsigned_long_long_test(Config) -> + do_test(unsigned_long_long_test, Config). + +unsigned_long_test(doc) -> ""; +unsigned_long_test(suite) -> []; +unsigned_long_test(Config) -> + do_test(unsigned_long_test, Config). + +unsigned_short_test(doc) -> ""; +unsigned_short_test(suite) -> []; +unsigned_short_test(Config) -> + do_test(unsigned_short_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +%% It is here that all tests really are done. +%% + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + %% Start the server + {ok, _Pid} = m_i:oe_create_link([], {local, ?ERLANG_SERVER_NAME}), + Node = atom_to_list(node()), + %% [NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + %% Start C-client node as a port program. + Cmd = filename:join([DataDir, "c_client"]) ++ + " -this-node-name " ++ atom_to_list(?C_CLIENT_NODE_NAME) ++ + " -peer-node " ++ Node ++ + " -peer-process-name " ++ atom_to_list(?ERLANG_SERVER_NAME) ++ + " -cookie " ++ Cookie ++ + " -test-case " ++ atom_to_list(Case), + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + Res = wait_for_completion(Port), + %% Kill off node if there was timeout + case Res of + {error, timeout} -> + catch rpc:cast(?C_CLIENT_NODE_NAME, erlang, halt, [1]); + _ -> + ok + end, + process_flag(trap_exit, false), + catch m_i:stop(?ERLANG_SERVER_NAME), + ok = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src new file mode 100644 index 0000000000..62672e0b95 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/Makefile.src @@ -0,0 +1,146 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-2009. 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% +# +# +# Makefile.src for c_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I@erl_include@ \ + -I@ic_include_path@ -I@erl_interface_include@ + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m.h \ + m_i.h \ + oe_c_erl_test.h + +# Generated C files +GEN_C_FILES = \ + m.c \ + m_i.c \ + oe_c_erl_test.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_c_erl_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_c_erl_test.erl + +C_FILES = $(GEN_C_FILES) c_client.c my.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_client@exe@ + +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_client}" \ + "+{user_protocol,my}" "+{c_timeout,{5000,5000}}" c_erl_test.idl + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): c_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" c_erl_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c new file mode 100644 index 0000000000..b2c5b0c836 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_client.c @@ -0,0 +1,1763 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-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% + * + */ +/* C-client for test of IC. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +#include <time.h> +#include <sys/times.h> +#else +#include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ei.h" +#include "erl_interface.h" +#include "m_i.h" + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 + +#define INBUFSZ 10 +#define OUTBUFSZ 0 + +#define MAXTRIES 5 + +#define CHECK_EXCEPTION(x) \ + if ((x)->_major != CORBA_NO_EXCEPTION) { \ + fprintf(stderr,"\n\nException: %s\n\n", \ + (char *)CORBA_exception_value((x))); \ + CORBA_exception_free((x)); \ + return -1; \ + } \ + +/* XXX Should free things here too! */ +#define RETURN_IF_OK(x) \ + if ((x)) {\ + fprintf(stdout, "ok\n");\ + return 0;\ + }\ + +#define cmp_str(x,y) (!strcmp((x),(y))) +#define cmp_wstr(x,y) (!ic_wstrcmp((x),(y))) + +typedef CORBA_Environment IC_Env; + +typedef int (*TestFunc)(IC_Env *); +typedef struct { + char *name; + TestFunc func; +} TestCase; + +static char longtext[] = +"Introduction The IC application is an IDL compiler implemented in Erlang." +" The IDL compiler generates client stubs and server skeletons." +" Several back-ends are supported, and they fall into three main groups." +" For more details on IC compiler options consult the ic(3) manual page." +" Argument passing cases 1 Caller allocates all necessary storage," +" except that which may be encapsulated and managed within the parameter itself." +" 2 The caller allocates a pointer and passes it by reference to the callee." +" The callee sets the pointer to point to a valid instance of the parameter's type." +" The caller is responsible for releasing the returned storage." +" Following completion of a request, the caller is not allowed to modify any values" +" in the returned storage. To do so the caller must first copy the returned instance" +" into a new instance, then modify the new instance. 3 The caller allocates a" +" pointer to an array slice which has all the same dimensions of the original" +" array except the first, and passes it by reference to the callee. The callee sets" +" the pointer to point to a valid instance of the array. The caller is responsible for" +" releasing the returned storage. Following completion of a request, the caller is not" +" allowed to modify any values in the returned storage. To do so the caller must first" +" copy the returned instance into a new instance, then modify the new instance." +" Generated Files Two files will be generated for each scope. One set of files will be" +" generated for each module and each interface scope. An extra set is generated for" +" those definitions at top level scope. One of the files is a header file(.h), and the" +" other file is a C source code file (.c). In addition to these files a number of C" +" source files will be generated for type encodings, they are named according to the " +"following template: oe_code_<type>.c."; +static char this_node[NODENAMESZ + 1]; +static char *progname; + +/* Test function prototypes */ + +static int void_test(IC_Env *env); +static int long_test(IC_Env *env); +static int long_long_test(IC_Env *env); +static int unsigned_short_test(IC_Env *env); +static int unsigned_long_test(IC_Env *env); +static int unsigned_long_long_test(IC_Env *env); +static int double_test(IC_Env *env); +static int char_test(IC_Env *env); +static int wchar_test(IC_Env *env); +static int octet_test(IC_Env *env); +static int bool_test(IC_Env *env); +static int struct_test(IC_Env *env); +static int struct2_test(IC_Env *env); +static int seq1_test(IC_Env *env); +static int seq2_test(IC_Env *env); +static int seq3_test(IC_Env *env); +static int seq4_test(IC_Env *env); +static int seq5_test(IC_Env *env); +static int array1_test(IC_Env *env); +static int array2_test(IC_Env *env); +static int enum_test(IC_Env *env); +static int string1_test(IC_Env *env); +static int string2_test(IC_Env *env); +static int string3_test(IC_Env *env); +static int string4_test(IC_Env *env); +static int pid_test(IC_Env *env); +static int port_test(IC_Env *env); +static int ref_test(IC_Env *env); +static int term_test(IC_Env *env); +static int typedef_test(IC_Env *env); +static int inline_sequence_test(IC_Env *env); +static int term_sequence_test(IC_Env *env); +static int term_struct_test(IC_Env *env); +static int wstring1_test(IC_Env *env); + +static TestCase test_cases[] = { + {"void_test", void_test}, + {"long_test", long_test}, + {"long_long_test", long_long_test}, + {"unsigned_short_test", unsigned_short_test}, + {"unsigned_long_test", unsigned_long_test}, + {"unsigned_long_long_test", unsigned_long_long_test}, + {"double_test", double_test}, + {"char_test", char_test}, + {"wchar_test", wchar_test}, + {"octet_test", octet_test}, + {"bool_test", bool_test}, + {"struct_test", struct_test}, + {"struct2_test", struct2_test}, + {"seq1_test", seq1_test}, + {"seq2_test", seq2_test}, + {"seq3_test", seq3_test}, + {"seq4_test", seq4_test}, + {"seq5_test", seq5_test}, + {"array1_test", array1_test}, + {"array2_test", array2_test}, + {"enum_test", enum_test}, + {"string1_test", string1_test}, + {"string2_test", string2_test}, + {"string3_test", string3_test}, + {"string4_test", string4_test}, + {"pid_test", pid_test}, + {"port_test", port_test}, + {"ref_test", ref_test}, + {"term_test", term_test}, + {"typedef_test", typedef_test}, + {"inline_sequence_test", inline_sequence_test}, + {"term_sequence_test", term_sequence_test}, + {"term_struct_test", term_struct_test}, + {"wstring1_test", wstring1_test}, + {"", NULL} +}; + +/* Other prototypes */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2); +static int cmp_a(m_a *a1, m_a *a2); +static int cmp_bseq(m_bseq *b1, m_bseq *b2); +static int cmp_b(m_b *b1, m_b *b2); +static int cmp_lseq(m_lseq *b1, m_lseq *b2); +static int cmp_etseq(m_etseq *b1, m_etseq *b2); +static int cmp_et(m_et* b1, m_et *b2); +static int cmp_es(m_es *b1, m_es *b2); +static int cmp_arr1(m_arr1 b1, m_arr1 b2); +static int cmp_dd(m_dd b1, m_dd b2); +static int cmp_strRec(m_strRec *b1, m_strRec *b2); +static int cmp_sseq(m_sseq *b1, m_sseq *b2); +static int cmp_pid(erlang_pid *p1, erlang_pid *p2); +static int cmp_port(erlang_port *p1, erlang_port *p2); +static int cmp_ref(erlang_ref *p1, erlang_ref *p2); +static int cmp_s(m_s *b1, m_s *b2); +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2); +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2); +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2); +static int cmp_arr3(m_arr3 b1, m_arr3 b2); + +static void print_aseq(m_aseq *a); +static void print_a(m_a *a); +static void print_bseq(m_bseq *b); +static void print_lseq(m_lseq *b); +static void print_b(m_b *b); +static void print_etseq(m_etseq *b); +static void print_et(m_et* b); +static void print_es(m_es *b); +static void print_arr1(long a[500]); +static void print_dd(long a[2][3]); +static void print_strRec(m_strRec* sr); +static void print_sseq(m_sseq *b); +static void print_pid(erlang_pid *p); +static void print_port(erlang_port *p); +static void print_ref(erlang_ref *p); +static void print_term(ETERM *t); +static void print_s(m_s *p); +static void print_ssstr3(m_ssstr3 *b1); +static void print_ssarr3(m_ssarr3 *b1); +static void print_sarr3(m_sarr3 *b1); +static void print_arr3(m_arr3 b1); +static void print_wstr(CORBA_wchar *ws); + +static void free_etseq_buf(m_etseq *b); +static void free_et(m_et* b); + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + + + +/* main */ + +#ifdef VXWORKS +int client(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + erlang_pid pid; + MyTimeval start, stop; + int i, fd, ires, tres; + IC_Env *env; + int tries = 0; + char *this_node_name = NULL; + char *peer_node = NULL; + char *peer_process_name = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + TestFunc test_func = NULL; + TestCase *test_case; + char *test_case_name = NULL; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (cmp_str(argv[i], "-help")) { + usage(); + done(0); + } else if (cmp_str(argv[i], "-this-node-name")) { + i++; + this_node_name = argv[i]; + } else if (cmp_str(argv[i], "-peer-node")) { + i++; + peer_node = argv[i]; + } else if (cmp_str(argv[i], "-peer-process-name")) { + i++; + peer_process_name = argv[i]; + } else if (cmp_str(argv[i], "-cookie")) { + i++; + cookie = argv[i]; + } else if (cmp_str(argv[i], "-test-case")) { + i++; + test_case_name = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || test_case_name == NULL + || peer_process_name == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + test_case = test_cases; + while (test_case->func) { + if (cmp_str(test_case->name, test_case_name)) { + test_func = test_case->func; + break; + } + test_case++; + } + if (test_func == NULL) { + fprintf(stderr, "Error: illegal test case: \"%s\"\n", test_case_name); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + fprintf(stderr, "c_client: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_client: peer node: \"%s\"\n", peer_node); + fprintf(stderr, "c_client: test case: \"%s\"\n", test_case_name); + + fprintf(stderr, "c_client: starting\n"); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + + /* connect to erlang node */ + + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + + fprintf(stderr, "c_client: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_client: erl_connect(): %d\n", fd); + + if (fd >= 0) + break; + fprintf(stderr, "c_client: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_client: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + strcpy(env->_regname, peer_process_name); + env->_to_pid = NULL; + env->_from_pid = &pid; + + strcpy(pid.node, this_node); + pid.num = fd; + pid.serial = 0; + pid.creation = 0; + + my_gettimeofday(&start); + tres = test_func(env); /* Call test case */ + my_gettimeofday(&stop); + showtime(&start, &stop); + erl_close_connection(fd); + + printf("c_client: env->_inbuf before : %d\n", INBUFSZ); + printf("c_client: env->_outbuf before : %d\n", OUTBUFSZ); + printf("c_client: env->_inbuf after : %d\n", env->_inbufsz); + printf("c_client: env->_outbuf after : %d\n", env->_outbufsz); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + done(tres); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -peer-process-name <name> " + "-cookie <cookie> -test-case <test case name>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -peer-process-name idltest " + "-cookie oa678er -test-case octet_test\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + + +/* TESTS */ + +static int void_test(IC_Env *env) +{ + fprintf(stdout, "\n======== m_i_void test ======\n\n"); + m_i_void_test(NULL,env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(1); +} + +static int long_test(IC_Env *env) +{ + long l = 4711, lo, lr; + + fprintf(stdout, "\n======== m_i_long test ======\n\n"); + lr = m_i_long_test(NULL, l, &lo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(l == lo && l == lr); + if (l != lo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", l, lo); + if (l != lr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", l, lr); + return -1; +} + +static int long_long_test(IC_Env *env) +{ + CORBA_long_long ll = 4711, llo, llr; + + fprintf(stdout, "\n======== m_i_longlong test ======\n\n"); + llr = m_i_longlong_test(NULL, ll, &llo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ll == llo && ll == llr); + if (ll != llo) + fprintf(stdout, " out parameter error, sent: %ld, got: %ld\n", + ll, llo); + if (ll != llr) + fprintf(stdout, " result error, sent: %ld, got: %ld\n", ll, llr); + return -1; +} + +static int unsigned_short_test(IC_Env *env) +{ + unsigned short x, y = 2, z; + + fprintf(stdout, "\n======== m_i_ushort test ======\n\n"); + x = m_i_ushort_test(NULL, y, &z, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(y == z && y == x); + if (y != z) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", y, z); + if (y != x) + fprintf(stdout, " result error, sent: %d, got: %d\n", y, x); + return -1; +} + + +static int unsigned_long_test(IC_Env *env) +{ + unsigned long ul = 5050, ulo, ulr; + + fprintf(stdout, "\n======== m_i_ulong test ======\n\n"); + ulr = m_i_ulong_test(NULL, ul, &ulo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ul == ulo && ul == ulr); + if (ul != ulo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ul, ulo); + if (ul != ulr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", ul, ulr); + return -1; +} + +/* + * Note: CORBA_unsigned_long_long is in fact a plain long. + */ +static int unsigned_long_long_test(IC_Env *env) +{ + CORBA_unsigned_long_long ull = 5050, ullo, ullr; + + fprintf(stdout, "\n======== m_i_ulonglong test ======\n\n"); + ullr = m_i_ulonglong_test(NULL, ull, &ullo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ull == ullo && ull == ullr); + if (ull != ullo) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + ull, ullo); + if (ull != ullr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + ull, ullr); + return -1; +} + +static int double_test(IC_Env *env) +{ + double d = 12.1212, db, dr; + + fprintf(stdout, "\n======== m_i_double test ======\n\n"); + dr = m_i_double_test(NULL, d, &db, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(d == db && d == dr); + if (d != db) + fprintf(stdout, " out parameter error, sent: %f, got: %f\n", d, db); + if (d != dr) + fprintf(stdout, " result error, sent: %f, got: %f\n", d, dr); + return -1; +} + +static int char_test(IC_Env *env) +{ + char c = 'g', co, cr; + + /* char test */ + fprintf(stdout, "\n======== m_i_char test ======\n\n"); + cr = m_i_char_test(NULL, c, &co, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(c == co && c == cr); + if (c !=co) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", c, co); + if (c != cr) + fprintf(stdout, " result error, sent: %c, got: %c\n", c, cr); + return -1; +} + +static int wchar_test(IC_Env *env) +{ + CORBA_wchar wc = 103, wco, wcr; + + fprintf(stdout, "\n======== m_i_wchar test ======\n\n"); + wcr = m_i_wchar_test(NULL, wc, &wco, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(wc == wco && wc == wcr); + if (wc != wco) + fprintf(stdout, " out parameter error, sent: %lu, got: %lu\n", + wc, wco); + if (wc != wcr) + fprintf(stdout, " result error, sent: %lu, got: %lu\n", + wc, wcr); + return -1; +} + +static int octet_test(IC_Env *env) +{ + char o ='r', oo, or; + + fprintf(stdout, "\n======== m_i_octet test ======\n\n"); + or = m_i_octet_test(NULL, o, &oo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(o == oo && o == or); + if (o != oo) + fprintf(stdout, " out parameter error, sent: %c, got: %c\n", o, oo); + if (o != or) + fprintf(stdout, " result error, sent: %c, got: %c\n", o, or); + return -1; +} + +static int bool_test(IC_Env *env) +{ + unsigned char i = 0, io, ir; + + fprintf(stdout, "\n======== m_i_bool test ======\n\n"); + ir = m_i_bool_test(NULL, i, &io, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(i == io && i == ir); + if (i != io) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", i, io); + if (i != ir) + fprintf(stdout, " result error, sent: %d, got: %d\n", i, ir); + return -1; +} + +static int struct_test(IC_Env *env) +{ + m_b b = {4711, 'a'}, bo, br; + + fprintf(stdout, "\n======== m_i_struct test ======\n\n"); + br = m_i_struct_test(NULL, &b, &bo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_b(&b, &bo) && cmp_b(&b, &br)); + if (!cmp_b(&b, &bo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&bo); + fprintf(stdout, "\n"); + } + if (!cmp_b(&b, &br)) { + fprintf(stdout, " result error, sent:\n"); + print_b(&b); + fprintf(stdout, " got:\n"); + print_b(&br); + fprintf(stdout, "\n"); + } + return -1; +} + +static int struct2_test(IC_Env *env) +{ + m_es esi = {m_peach, 5050}, eso, esr; + + fprintf(stdout, "\n======== m_i_struct2 test ======\n\n"); + esr = m_i_struct2_test(NULL, &esi, &eso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_es(&esi, &eso) && cmp_es(&esi, &esr)); + if (!cmp_es(&esi, &eso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&eso); + fprintf(stdout, "\n"); + } + if (!cmp_es(&esi, &esr)) { + fprintf(stdout, " result error, sent:\n"); + print_es(&esi); + fprintf(stdout, " got:\n"); + print_es(&esr); + fprintf(stdout, "\n"); + } + return -1; +} + + +static int seq1_test(IC_Env *env) +{ + m_bseq bs, *bso, *bsr; + + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + bs._length = 3; + bs._buffer = ba; + + fprintf(stdout, "\n======== m_i_seq1 test ======\n\n"); + bsr = m_i_seq1_test(NULL, &bs, &bso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_bseq(&bs, bso) && cmp_bseq(&bs, bsr)); + if (!cmp_bseq(&bs, bso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bso); + fprintf(stdout, "\n"); + } + if (!cmp_bseq(&bs, bsr)) { + fprintf(stdout, " result error, sent:\n"); + print_bseq(&bs); + fprintf(stdout, " got:\n"); + print_bseq(bsr); + fprintf(stdout, "\n"); + } + CORBA_free(bso); + CORBA_free(bsr); + return -1; +} + +static int seq2_test(IC_Env *env) +{ + m_b ba[3] = {{4711, 'a'}, {4712, 'b'}, {4713, 'c'}}; + m_a a; + m_a aa[2]; + m_aseq as, *aso, *asr; + + a.l = 9999; + a.y._length = 3; + a.y._buffer = ba; + a.d = 66.89898989; + + aa[0] = a; + aa[1] = a; + as._length = 2; + as._buffer = aa; + + fprintf(stdout, "\n======== m_i_seq2 test ======\n\n"); + asr = m_i_seq2_test(NULL, &as, &aso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_aseq(&as, aso) && cmp_aseq(&as, asr)); + if (!cmp_aseq(&as, aso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(aso); + fprintf(stdout, "\n"); + } + if (!cmp_aseq(&as, asr)) { + fprintf(stdout, " result error, sent:\n"); + print_aseq(&as); + fprintf(stdout, " got:\n"); + print_aseq(asr); + fprintf(stdout, "\n"); + } + CORBA_free(aso); + CORBA_free(asr); + return -1; +} + +static int seq3_test(IC_Env *env) +{ + m_lseq lsi, *lso, *lsr; + long al[500]; + int i=0; + + for (i = 0; i < 500; i++) + al[i]=i; + lsi._length = 500; + lsi._buffer = al; + + fprintf(stdout, "\n======== m_i_seq3 test ======\n\n"); + lsr = m_i_seq3_test(NULL, &lsi, &lso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_lseq(&lsi, lso) && cmp_lseq(&lsi, lsr)); + if (!cmp_lseq(&lsi, lso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lso); + fprintf(stdout, "\n"); + } + if (!cmp_lseq(&lsi, lsr)) { + fprintf(stdout, " result error, sent:\n"); + print_lseq(&lsi); + fprintf(stdout, " got:\n"); + print_lseq(lsr); + fprintf(stdout, "\n"); + } + CORBA_free(lso); + CORBA_free(lsr); + return -1; +} + +static int seq4_test(IC_Env *env) +{ + char *stra0[3] = {"a", "long", "time"}; + char *stra1[3] = {"ago", "there", "was"}; + char *stra2[3] = {"a", "buggy", "compiler"}; + m_sstr3 str3s[3] = {{3, 3, stra0}, {3, 3, stra1}, {3, 3, stra2}}; + m_ssstr3 str3ssi = {3, 3, str3s}; + m_ssstr3 *str3sso, *str3ssr; + + fprintf(stdout, "\n======== m_i_seq4 test ======\n\n"); + str3ssr = m_i_seq4_test(NULL, &str3ssi, &str3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssstr3(&str3ssi, str3sso) && + cmp_ssstr3(&str3ssi, str3ssr)); + if (!cmp_ssstr3(&str3ssi, str3sso)){ + fprintf(stdout, " out parameter error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssstr3(&str3ssi, str3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssstr3(&str3ssi); + fprintf(stdout, " got:\n"); + print_ssstr3(str3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(str3sso); + CORBA_free(str3ssr); + return -1; +} + +static int seq5_test(IC_Env *env) +{ + m_arr3 arr3a[3] = { + {4711, 18931947, 3}, + {4711, 18931947, 3}, + {4711, 18931947, 3}}; + m_sarr3 arr3sa[3] = {{3, 3, arr3a}, {3, 3, arr3a}, {3, 3, arr3a}}; + m_ssarr3 arr3ssi = {3, 3, arr3sa}; + m_ssarr3 *arr3sso; + m_ssarr3 *arr3ssr; + + fprintf(stdout, "\n======== m_i_seq5 test ======\n\n"); + arr3ssr = m_i_seq5_test(NULL, &arr3ssi, &arr3sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ssarr3(&arr3ssi, arr3sso) && + cmp_ssarr3(&arr3ssi, arr3ssr)); + if (!cmp_ssarr3(&arr3ssi, arr3sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3sso); + fprintf(stdout, "\n"); + } + if (!cmp_ssarr3(&arr3ssi, arr3ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_ssarr3(&arr3ssi); + fprintf(stdout, " got:\n"); + print_ssarr3(arr3ssr); + fprintf(stdout, "\n"); + } + CORBA_free(arr3sso); + CORBA_free(arr3ssr); + return -1; +} + +static int array1_test(IC_Env *env) +{ + int i; + long al[500]; + m_arr1 alo; + m_arr1_slice* alr; + + for (i = 0; i < 500; i++) + al[i]=i; + + fprintf(stdout, "\n======== m_i_array1 test ======\n\n"); + alr = m_i_array1_test(NULL, al, alo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_arr1(al, alo) && cmp_arr1(al, alr)); + if (!cmp_arr1(al, alo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alo); + fprintf(stdout, "\n"); + } + if (!cmp_arr1(al,alr)) { + fprintf(stdout, " result error, sent:\n"); + print_arr1(al); + fprintf(stdout, " got:\n"); + print_arr1(alr); + fprintf(stdout, "\n"); + } + free(alo); + free(alr); + return -1; +} + +static int array2_test(IC_Env *env) +{ + long dl[2][3] = {{11, 2, 7}, {22, 8 ,13}}; + m_dd dlo; + m_dd_slice* dlr; + + fprintf(stdout, "\n======== m_i_array2 test ======\n\n"); + dlr = m_i_array2_test(NULL, dl, dlo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_dd(dl,dlo) && cmp_dd(dl,dlr)); + if (!cmp_dd(dl,dlo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlo); + fprintf(stdout, "\n"); + } + if (!cmp_dd(dl,dlr)) { + fprintf(stdout, " result error, sent:\n"); + print_dd(dl); + fprintf(stdout, " got:\n"); + print_dd(dlr); + fprintf(stdout, "\n"); + } + free(*dlr); + return -1; +} + +static int enum_test(IC_Env *env) +{ + m_fruit ei = m_banana, eo, er; + + fprintf(stdout, "\n======== m_i_enum test ======\n\n"); + er = m_i_enum_test(NULL, ei, &eo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(ei == eo && ei == er); + if (ei != eo) + fprintf(stdout, " out parameter error, sent: %d, got: %d\n", ei, eo); + if (ei != er) + fprintf(stdout, " result error, sent: %d, got: %d\n", ei, er); + return -1; +} + +static int string1_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string1 test ======\n\n"); + sr = m_i_string1_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, sr)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string2_test(IC_Env *env) +{ + char* sa[3] = {"hello", "foo", "bar"}; + m_sseq ssi = {3, 3, sa}; + m_sseq *sso, *ssr; + + fprintf(stdout, "\n======== m_i_string2 test ======\n\n"); + ssr = m_i_string2_test(NULL, &ssi, &sso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_sseq(&ssi, sso) && cmp_sseq(&ssi, sso)); + if (!cmp_sseq(&ssi, sso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(sso); + } + if (!cmp_sseq(&ssi, ssr)) { + fprintf(stdout, " result error, sent:\n"); + print_sseq(&ssi); + fprintf(stdout, "got:\n"); + print_sseq(ssr); + } + CORBA_free(sso); + CORBA_free(ssr); + return -1; +} + +static int string3_test(IC_Env *env) +{ + char* si = longtext; + char* so; + char* sr; + + fprintf(stdout, "\n======== m_i_string3 test ======\n\n"); + sr = m_i_string3_test(NULL, si, &so, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_str(si, so) && cmp_str(si, so)); + if (!cmp_str(si, so)) + fprintf(stdout, " out parameter error, sent: %s, got: %s\n", si, so); + if (!cmp_str(si, sr)) + fprintf(stdout, " result error, sent: %s, got: %s\n", si, sr); + CORBA_free(so); + CORBA_free(sr); + return -1; +} + +static int string4_test(IC_Env *env) +{ + char as1[100] = "a string", as2[200] = "help", as3[200] = "hello there"; + m_strRec stri = { 1, /* dd */ + as1, /* str4 */ + {{'a', 'k'}, {'z', 'g'}, {'n', 'q'}}, /* str7 */ + {3, 3, "buf"}, /* str5 */ + as2, /* str6 */ + {'m', 'f', 'o'}, /* str8 */ + as3, /* str9 */ + {3, 3, "stu"} /* str10 */ + }; + m_strRec *stro, *strr; + + fprintf(stdout, "\n======== m_i_string4 test ======\n\n"); + strr = m_i_string4_test(NULL, &stri, &stro, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_strRec(&stri,stro) && cmp_strRec(&stri,strr)); + if (!cmp_strRec(&stri,stro)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(stro); + fprintf(stdout, "\n"); + } + if (!cmp_strRec(&stri,strr)) { + fprintf(stdout, " result error, sent:\n"); + print_strRec(&stri); + fprintf(stdout, " got:\n"); + print_strRec(strr); + fprintf(stdout, "\n"); + } + CORBA_free(stro); + CORBA_free(strr); + return -1; +} + + +static int pid_test(IC_Env *env) +{ + erlang_pid pid = {"", 7, 0, 0}, pido, pidr; + + strcpy(pid.node, this_node), /* this currently running node */ + fprintf(stdout, "\n======== m_i_pid test ======\n\n"); + pidr = m_i_pid_test(NULL, &pid, &pido, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_pid(&pid, &pido) && cmp_pid(&pid, &pidr)); + if (!cmp_pid(&pid, &pido)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pido); + } + if (!cmp_pid(&pid, &pidr)) { + fprintf(stdout, " result error, sent:\n"); + print_pid(&pid); + fprintf(stdout, "got:\n"); + print_pid(&pidr); + } + return -1; +} + +static int port_test(IC_Env *env) +{ + erlang_port porti = {"node", 5, 1}, porto, portr; + + fprintf(stdout, "\n======== m_i_port test ======\n\n"); + portr = m_i_port_test(NULL, &porti, &porto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_port(&porti, &porto) && cmp_port(&porti, &portr)); + if (!cmp_port(&porti, &porto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&porto); + } + if (!cmp_port(&porti, &portr)) { + fprintf(stdout, " result error, sent:\n"); + print_port(&porti); + fprintf(stdout, "got:\n"); + print_port(&portr); + } + return -1; +} + +static int ref_test(IC_Env *env) +{ + erlang_ref refi = { "node1", 3, {1, 2, 3}, 1}, + refo, refr; + + fprintf(stdout, "\n======== m_i_ref test ======\n\n"); + refr = m_i_ref_test(NULL, &refi, &refo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_ref(&refi, &refo) && cmp_ref(&refi, &refr)); + if (!cmp_ref(&refi, &refo)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refo); + } + if (!cmp_ref(&refi, &refr)) { + fprintf(stdout, " result error, sent:\n"); + print_ref(&refi); + fprintf(stdout, "got:\n"); + print_ref(&refr); + } + return -1; +} + +static int term_test(IC_Env *env) +{ + ETERM *ti, *to, *tr; + + ti = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + + fprintf(stdout, "\n======== m_i_term test ======\n\n"); + tr = m_i_term_test(NULL, ti, &to, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(ti, to) && erl_match(ti, tr)); + if (!erl_match(ti, to)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(to); + } + if (!erl_match(ti, tr)) { + fprintf(stdout, " result error, sent:\n"); + print_term(ti); + fprintf(stdout, "got:\n"); + print_term(tr); + } + erl_free_term(ti); + erl_free_term(to); + erl_free_term(tr); + return -1; +} + +static int typedef_test(IC_Env *env) +{ + m_banan mbi, mbo; /* erlang_port */ + m_apa mai; /* ETERM* */ + m_apa mao = NULL; + long tl; + + strcpy(mbi.node,"node"); + mbi.id = 15; + mbi.creation = 1; + + fprintf(stdout, "\n======== m_i_typedef test ======\n\n"); + mai = erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"); + tl = m_i_typedef_test(NULL, mai, &mbi, &mao, &mbo, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(erl_match(mai, mao) && cmp_port(&mbi, &mbo) && tl == 4711); + if (!erl_match(mai, mao)) { + fprintf(stdout, " out parameter error (term), sent:\n"); + print_term(mai); + fprintf(stdout, "got:\n"); + print_term(mao); + } + if (!cmp_port(&mbi, &mbo)) { + fprintf(stdout, " out parameter error (port), sent:\n"); + print_port(&mbi); + fprintf(stdout, "got:\n"); + print_port(&mbo); + } + if (tl != 4711) { + fprintf(stdout, " result error, sent: 4711, got %ld\n", tl); + } + erl_free_term(mai); + erl_free_term(mao); + return -1; +} + +static int inline_sequence_test(IC_Env *env) +{ + int i; + long al[500]; + m_s isi = {4711, {500, 10, al}}, + *iso, *isr; + + for (i = 0; i < 500; i++) + al[i]=i; + fprintf(stdout, "\n======== m_i_inline_sequence test ======\n\n"); + isr = m_i_inline_sequence_test(NULL, &isi, &iso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_s(&isi, iso) && cmp_s(&isi, isr)); + if (!cmp_s(&isi, iso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(iso); + } + if (!cmp_s(&isi, isr)) { + fprintf(stdout, " result error, sent:\n"); + print_s(&isi); + fprintf(stdout, "got:\n"); + print_s(isr); + } + CORBA_free(iso); + CORBA_free(isr); + return -1; +} + +static int term_sequence_test(IC_Env *env) +{ + ETERM* et_array[4] = { + erl_format("[{apa, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{banan, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{apelsin, 1, 23}, \"string\", {1.23, 45}]"), + erl_format("[{mango, 1, 23}, \"string\", {1.23, 45}]")}; + m_etseq etsi = {4, 4, et_array}, *etso, *etsr; + + fprintf(stdout, "\n======== m_i_term_sequence test ======\n\n"); + etsr = m_i_term_sequence_test(NULL, &etsi, &etso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_etseq(&etsi, etso) && cmp_etseq(&etsi, etsr)); + if (!cmp_etseq(&etsi, etso)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etso); + } + if (!cmp_etseq(&etsi, etsr)) { + fprintf(stdout, " result error, sent:\n"); + print_etseq(&etsi); + fprintf(stdout, "got:\n"); + print_etseq(etsr); + } + free_etseq_buf(&etsi); + free_etseq_buf(etso); + free_etseq_buf(etsr); + CORBA_free(etso); + CORBA_free(etsr); + return -1; +} + +static int term_struct_test(IC_Env *env) +{ + m_et eti = { erl_format("[{hej, 1, 23}, \"string\", {1.23, 45}]"), + 121212 }; + m_et eto, etr; + + fprintf(stdout, "\n======== m_i_term_struct test ======\n\n"); + etr = m_i_term_struct_test(NULL, &eti, &eto, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_et(&eti, &eto) && cmp_et(&eti, &etr)); + if (!cmp_et(&eti, &eto)) { + fprintf(stdout, " out parameter error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&eto); + } + if (!cmp_et(&eti, &etr)) { + fprintf(stdout, " result error, sent:\n"); + print_et(&eti); + fprintf(stdout, "got:\n"); + print_et(&etr); + } + free_et(&eti); + free_et(&eto); + free_et(&etr); + return -1; +} + +static int wstring1_test(IC_Env *env) +{ + CORBA_wchar wsi[] = {100, 101, 102, 103, 104, 0}, *wso, *wsr; + + fprintf(stdout, "\n======== m_i_wstring1 test ======\n\n"); + wsr = m_i_wstring1_test(NULL, wsi, &wso, env); + CHECK_EXCEPTION(env); + RETURN_IF_OK(cmp_wstr(wsi, wso) && cmp_wstr(wsi, wsr)); + if (!cmp_wstr(wsi, wso)) { + fprintf(stdout, " out parameter error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wso); + } + if (!cmp_wstr(wsi, wsr)) { + fprintf(stdout, " result error, sent: \n"); + print_wstr(wsi); + fprintf(stdout, "got:\n"); + print_wstr(wsr); + } + CORBA_free(wso); + CORBA_free(wsr); + return -1; +} + +/* Compare functions */ +static int cmp_aseq(m_aseq *a1, m_aseq *a2) +{ + int i; + + if (a1->_length != a2->_length) + return 0; + for (i = 0; i < a1->_length; i++) + if (cmp_a(&(a1->_buffer[i]), &(a2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_a(m_a *a1, m_a *a2) +{ + return a1->l == a2->l && + a1->d == a2->d && + cmp_bseq(&a1->y, &a2->y); +} + +static int cmp_bseq(m_bseq *b1, m_bseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (cmp_b(&(b1->_buffer[i]), &(b2->_buffer[i])) == 0) + return 0; + return 1; +} + +static int cmp_b(m_b *b1, m_b *b2) +{ + return b1->l == b2->l && b1->c == b2->c; +} + +static int cmp_lseq(m_lseq *b1, m_lseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (b1->_buffer[i] != b2->_buffer[i]) + return 0; + return 1; +} + +static int cmp_etseq(m_etseq *b1, m_etseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!erl_match(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + +static int cmp_et(m_et* b1, m_et *b2) +{ + return erl_match(b1->e, b2->e) && b1->l == b2->l; +} + +static int cmp_es(m_es *b1, m_es *b2) +{ + return b1->f == b2->f && b1->l == b2->l; +} + +static int cmp_arr1(m_arr1 b1, m_arr1 b2) +{ + int i; + + for (i = 0; i < 500; i++) + if (b1[i] != b2[i]) + return 0; + return 1; +} + +static int cmp_dd(m_dd b1, m_dd b2) +{ + + int i, j; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1[i][j] != b2[i][j]) + return 0; + return 1; +} + + + +static int cmp_strRec(m_strRec *b1, m_strRec *b2) +{ + int i, j; + + if (b1->bb != b2->bb) + return 0; + if (!cmp_str(b1->str4,b2->str4)) + return 0; + if (b1->str5._length != b2->str5._length) + return 0; + for (j = 0; j < b1->str5._length; j++) + if (b1->str5._buffer[j] != b2->str5._buffer[j]) + return 0; + if (!cmp_str(b1->str6,b2->str6)) + return 0; + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + if (b1->str7[i][j] != b2->str7[i][j]) + return 0; + for (j = 0; j < 3; j++) + if (b1->str8[j] != b2->str8[j]) + return 0; + if (!cmp_str(b1->str9,b2->str9)) + return 0; + if (b1->str10._length != b2->str10._length) + return 0; + for (j = 0; j < b1->str10._length; j++) + if (b1->str10._buffer[j] != b2->str10._buffer[j]) + return 0; + return 1; +} + + +static int cmp_sseq(m_sseq *b1, m_sseq *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) + if (!cmp_str(b1->_buffer[i], b2->_buffer[i])) + return 0; + return 1; +} + + +static int cmp_pid(erlang_pid *p1, erlang_pid *p2) +{ + return cmp_str(p1->node,p2-> node) && + p1->num == p2->num && + p1->serial == p2->serial && + p1->creation == p2->creation; +} + +static int cmp_port(erlang_port *p1, erlang_port *p2) +{ + return cmp_str(p1->node,p2-> node) && p1->id == p2->id; +} + +static int cmp_ref(erlang_ref *p1, erlang_ref *p2) +{ + return cmp_str(p1->node, p2->node) && + p1->len == p2->len && + (p1->len < 1 || p1->n[0] == p2->n[0]) && + (p1->len < 2 || p1->n[1] == p2->n[1]) && + (p1->len < 3 || p1->n[2] == p2->n[2]); +} + +static int cmp_s(m_s *b1, m_s *b2) +{ + int i; + + if (b1->l != b2->l) + return 0; + if (b1->sl._length != b2->sl._length) + return 0; + for (i = 0; i < b1->sl._length; i++) + if (b1->sl._buffer[i] != b2->sl._buffer[i]) + return 0; + return 1; +} + + +static int cmp_ssstr3(m_ssstr3 *b1, m_ssstr3 *b2) +{ + int i,j; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (b1->_buffer[i]._length != b2->_buffer[i]._length) + return 0; + for (j = 0; j < b1->_buffer[i]._length; j++) + if (!cmp_str(b1->_buffer[i]._buffer[j], + b2->_buffer[i]._buffer[j])) + return 0; + } + return 1; +} + + + +static int cmp_ssarr3(m_ssarr3 *b1, m_ssarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_sarr3(&b1->_buffer[i], &b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_sarr3(m_sarr3 *b1, m_sarr3 *b2) +{ + int i; + + if (b1->_length != b2->_length) + return 0; + for (i = 0; i < b1->_length; i++) { + if (!cmp_arr3(b1->_buffer[i], b2->_buffer[i])) + return 0; + } + return 1; +} + +static int cmp_arr3(m_arr3 b1, m_arr3 b2) +{ + int i; + + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) { + if (b1[i] != b2[i]) + return 0; + } + return 1; +} + +/* Print functions */ +static void print_aseq(m_aseq *a) +{ + int i; + fprintf(stdout, "\nm_aseq size: %ld --------\n", a->_length); + for (i = 0; i < a->_length; i++) + print_a(&(a->_buffer[i])); +} + +static void print_a(m_a *a) +{ + fprintf(stdout, "\nm_a --------\n l: %ld\n d:%f\n", a->l, a->d); + print_bseq(&a->y); +} + +static void print_bseq(m_bseq *b) +{ + int i; + + fprintf(stdout, "\nm_bseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + print_b(&(b->_buffer[i])); +} + +static void print_lseq(m_lseq *b) +{ + int i; + + fprintf(stdout, "\nm_lseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "[%d]: %ld\n", i, b->_buffer[i]); +} + +static void print_b(m_b *b) +{ + fprintf(stdout, "\nm_b --------\n l: %ld\n c: %c\n", b->l, b->c); +} + + +static void print_etseq(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) { + fprintf(stdout, "[%d]:\n", i); + erl_print_term(stdout, b->_buffer[i]); + } +} + + +static void print_et(m_et* b) +{ + fprintf(stdout, "\net struct --------\n"); + erl_print_term(stdout, b->e); + fprintf(stdout, "long: %ld\n", b->l); + fprintf(stdout, "\n--------\n"); +} + +static void print_es(m_es *b) +{ + fprintf(stdout, "\nm_es --------\n f: %d\n l: %ld\n", b->f, b->l); +} + + +static void print_arr1(long a[10]) +{ + int i; + + for (i = 0; i < 10; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, a[i]); +} + +static void print_dd(long a[2][3]) +{ + int i, j; + + fprintf(stdout, "\nlong dd[2][3] --------\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "\n[%d][%d]: %ld\n", i, j, a[i][j]); +} + + +static void print_strRec(m_strRec* sr) +{ + int i, j; + + fprintf(stdout, "\nboolean bb : %d\n",sr->bb); + fprintf(stdout, "string str4 : %s\n",sr->str4); + fprintf(stdout, "str7[2][3] :\n"); + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) + fprintf(stdout, "str7[%d][%d]: %ld\n", i, j, sr->str7[i][j]); + fprintf(stdout, "str5._length : %ld\n",sr->str5._length); + for (j = 0; j < sr->str5._length; j++) + fprintf(stdout, "str5._buffer[%d]: %c\n", j, sr->str5._buffer[j]); + fprintf(stdout, "string str6 : %s\n",sr->str6); + fprintf(stdout, "str8 :\n"); + for (j = 0; j < 3; j++) + fprintf(stdout, "str8[%d]: %c\n", j, sr->str8[j]); + fprintf(stdout, "string str9 : %s\n",sr->str9); + fprintf(stdout, "str10._length : %ld\n",sr->str10._length); + for (j = 0; j < sr->str10._length; j++) + fprintf(stdout, "str10._buffer[%d]: %c\n", j, sr->str10._buffer[j]); +} + +static void print_sseq(m_sseq *b) +{ + int i; + + fprintf(stdout, "\nm_sseq size: %ld --------\n",b->_length); + for (i = 0; i < b->_length; i++) + fprintf(stdout, "%s\n", b->_buffer[i]); + +} + + +static void print_pid(erlang_pid *p) +{ + fprintf(stdout, "\nerlang_pid --------\n node: %s\n num: %d\n " + "serial: %d\n creation: %d\n", + p->node, p->num, p->serial, p->creation); +} + +static void print_port(erlang_port *p) +{ + fprintf(stdout, "\nerlang_port --------\n node: %s\n id: %d\n " + "creation: %d\n", p->node, p->id, p->creation); +} + +static void print_ref(erlang_ref *p) +{ + fprintf(stdout, "\nerlang_ref --------\n node: %s\n len: %d\n " + "n[0]: %d\n n[1]: %d\n n[2]: %d\n creation: %d\n", + p->node, p->len, p->n[0], p->n[1], p->n[2], p->creation); +} + +static void print_term(ETERM *t) +{ + fprintf(stdout, "\nETERM --------\n"); + erl_print_term(stdout, t); + fprintf(stdout, "\n--------\n"); +} + +static void print_s(m_s *p) +{ + int i; + + fprintf(stdout, "\n%ld\n", p->l); + for (i = 0; i < p->sl._length; i++) + fprintf(stdout, "\n[%d]: %ld\n", i, p->sl._buffer[i]); +} + + +static void print_ssstr3(m_ssstr3 *b1) +{ + int i,j; + + fprintf(stdout, "\nSSSTR3 --------\n"); + fprintf(stdout,"b1->_length = %ld\n",b1->_length); + for (i = 0; i < b1->_length; i++) { + fprintf(stdout,"\nb1->_buffer[%d]._length %ld\n", + i, b1->_buffer[i]._length); + for (j = 0; j < b1->_buffer[i]._length; j++) + fprintf(stdout,"b1->_buffer[%d]._buffer[%d] = %s\n", + i, j, b1->_buffer[i]._buffer[j]); + } + fprintf(stdout, "\n--------\n"); +} + +static void print_wstr(CORBA_wchar *ws) +{ + int i = 0; + + fprintf(stdout, "\nwstr --------\n"); + while (ws[i]) { + fprintf(stdout, "[%d]: %ld\n", i, ws[i]); + i++; + } + fprintf(stdout, "\n--------\n"); +} + + +static void print_ssarr3(m_ssarr3 *b1) +{ + int i; + + fprintf(stdout, "\nssarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_sarr3(&b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_sarr3(m_sarr3 *b1) +{ + int i; + + fprintf(stdout, "\nsarr3 --------\n"); + fprintf(stdout,"length: %ld\n",b1->_length); + fprintf(stdout, "buffer:\n"); + for (i = 0; i < b1->_length; i++) + print_arr3(b1->_buffer[i]); + fprintf(stdout, "\n--------\n"); +} + +static void print_arr3(m_arr3 b1) +{ + int i; + + fprintf(stdout, "\narr3 --------\n"); + for (i = 0; i < sizeof(m_arr3)/sizeof(CORBA_long); i++) + fprintf(stdout, "%ld ", b1[i]); + fprintf(stdout, "\n--------\n"); +} + +static void free_etseq_buf(m_etseq *b) +{ + int i; + + for (i = 0; i < b->_length; i++) + erl_free_term(b->_buffer[i]); +} + +static void free_et(m_et* b) +{ + erl_free_term(b->e); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl new file mode 100644 index 0000000000..e687cec114 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/c_erl_test.idl @@ -0,0 +1,173 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2004-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% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl new file mode 100644 index 0000000000..2e624ec5c0 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/erl_server.erl @@ -0,0 +1,28 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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% +%% +%% +-module(erl_server). + +-export([run/0, stop/0]). + +run() -> + m_i:oe_create(). + +stop() -> + gen_server:cast(cidl_test, stop). diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..0c96fb9edf --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/m_i_impl.erl @@ -0,0 +1,161 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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% +%% +%% +-module(m_i_impl). +-include("m.hrl"). + +-export([init/1, terminate/2, void_test/1, long_test/2, ushort_test/2, + longlong_test/2, ulong_test/2, ulonglong_test/2, + double_test/2, char_test/2, wchar_test/2, octet_test/2, + bool_test/2, struct_test/2, struct2_test/2, seq1_test/2, + seq2_test/2, seq3_test/2, seq4_test/2, seq5_test/2, + array1_test/2, array2_test/2, enum_test/2, string1_test/2, + string2_test/2, string3_test/2, string4_test/2, pid_test/2, + port_test/2, ref_test/2, term_test/2, typedef_test/3, + inline_sequence_test/2, '_set_l'/2, '_get_l'/1, + term_struct_test/2, term_sequence_test/2, wstring1_test/2]). + +-define(PRINTDEBUG(Case), + io:format("erl_server: case: ~p~n" + "erl_server: location: ~p~n", [Case, [?FILE, ?LINE]])). +-define(PRINTDEBUG2(Case, Msg), + io:format("erl_server: case: ~p~n" + "erl_server: Msg: ~p~n" + "erl_server: location: ~p~n", [Case, Msg, [?FILE, ?LINE]])). + +init(Env) -> + {ok, []}. + +terminate(F, R) -> + ok. + +'_get_l'(State) -> + ?PRINTDEBUG("_get_l"), + {reply, State, State}. +void_test(State) -> + ?PRINTDEBUG("void_test"), + {reply, ok, State}. + +'_set_l'(State, V) -> + ?PRINTDEBUG2("_set_l", V), + {reply, ok, V}. +ushort_test(State, V) -> + ?PRINTDEBUG2("ushort_test", V), + {reply, {V, V}, State}. +long_test(State, V) -> + ?PRINTDEBUG2("long_test", V), + {reply, {V, V}, State}. +longlong_test(State, V) -> + ?PRINTDEBUG2("longlong_test", V), + {reply, {V, V}, State}. +ulong_test(State, V) -> + ?PRINTDEBUG2("ulong_test", V), + {reply, {V, V}, State}. +ulonglong_test(State, V) -> + ?PRINTDEBUG2("ulonglong_test", V), + {reply, {V, V}, State}. +double_test(State, V) -> + ?PRINTDEBUG2("double_test", V), + {reply, {V, V}, State}. +char_test(State, V) -> + ?PRINTDEBUG2("char_test", V), + {reply, {V, V}, State}. +wchar_test(State, V) -> + ?PRINTDEBUG2("wchar_test", V), + {reply, {V, V}, State}. +octet_test(State, V) -> + ?PRINTDEBUG2("octet_test", V), + {reply, {V, V}, State}. +bool_test(State, V) -> + ?PRINTDEBUG2("bool_test", V), + {reply, {V, V}, State}. + +struct_test(State, V) -> + ?PRINTDEBUG2("struct_test", V), + {reply, {V, V}, State}. +struct2_test(State, V) -> + ?PRINTDEBUG2("struct2_test", V), + {reply, {V, V}, State}. +seq1_test(State, V) -> + ?PRINTDEBUG2("seq1_test", V), + {reply, {V, V}, State}. +seq2_test(State, V) -> + ?PRINTDEBUG2("seq2_test", V), + {reply, {V, V}, State}. +seq3_test(State, V) -> + ?PRINTDEBUG2("seq3_test", V), + {reply, {V, V}, State}. +seq4_test(State, V) -> + ?PRINTDEBUG2("seq4_test", V), + {reply, {V, V}, State}. +seq5_test(State, V) -> + ?PRINTDEBUG2("seq5_test", V), + {reply, {V, V}, State}. +array1_test(State, V) -> + ?PRINTDEBUG2("array1_test", V), + {reply, {V, V}, State}. +array2_test(State, V) -> + ?PRINTDEBUG2("array2_test", V), + {reply, {V, V}, State}. +enum_test(State, V) -> + ?PRINTDEBUG2("enum_test", V), + {reply, {V, V}, State}. +string1_test(State, V) -> + ?PRINTDEBUG2("string1_test", V), + {reply, {V, V}, State}. +string2_test(State, V) -> + ?PRINTDEBUG2("string2_test", V), + {reply, {V, V}, State}. +string3_test(State, V) -> + ?PRINTDEBUG2("string3_test", V), + {reply, {V, V}, State}. +string4_test(State, V) -> + ?PRINTDEBUG2("string4_test", V), + {reply, {V, V}, State}. +pid_test(State, V) -> + ?PRINTDEBUG2("pid_test", V), + {reply, {V, V}, State}. +port_test(State, V) -> + ?PRINTDEBUG2("port_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +ref_test(State, V) -> + ?PRINTDEBUG2("ref_test", binary_to_list(term_to_binary(V))), + {reply, {V, V}, State}. +term_test(State, V) -> + ?PRINTDEBUG2("term_test", V), + {reply, {V, V}, State}. +typedef_test(State, A, B) -> + ?PRINTDEBUG2("typedef_test", [A,B]), + {reply, {4711, A, B}, State}. +inline_sequence_test(State, V) -> + ?PRINTDEBUG2("inline_sequence_test", V), + {reply, {V, V}, State}. +term_sequence_test(State, V) -> + ?PRINTDEBUG2("term_sequence_test", V), + {reply, {V, V}, State}. +term_struct_test(State, V) -> + ?PRINTDEBUG2("term_struct_test", V), + {reply, {V, V}, State}. +wstring1_test(State, V) -> + ?PRINTDEBUG2("wstring1_test", V), + {reply, {V, V}, State}. + + + + diff --git a/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c new file mode 100644 index 0000000000..4e0be3fec1 --- /dev/null +++ b/lib/ic/test/c_client_erl_server_proto_tmo_SUITE_data/my.c @@ -0,0 +1,51 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. 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% + * + */ +#include "ic.h" +#include "m_i.h" + +int my_prepare_notification_encoding(CORBA_Environment *env) +{ + return oe_prepare_notification_encoding(env); +} + +int my_send_notification_tmo(CORBA_Environment *env, unsigned int send_ms) +{ + return oe_send_notification_tmo(env, send_ms); +} + +int my_prepare_request_encoding(CORBA_Environment *env) +{ + return oe_prepare_request_encoding(env); +} + +int my_send_request_and_receive_reply_tmo(CORBA_Environment *env, + unsigned int send_ms, + unsigned int recv_ms) +{ + return oe_send_request_and_receive_reply_tmo(env, send_ms, recv_ms); +} + +int my_prepare_reply_decoding(CORBA_Environment *env) +{ + return oe_prepare_reply_decoding(env); +} + + + diff --git a/lib/ic/test/erl_client_c_server_SUITE.erl b/lib/ic/test/erl_client_c_server_SUITE.erl new file mode 100644 index 0000000000..c5f5b6a218 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE.erl @@ -0,0 +1,350 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-2009. 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 : Test suite for erl-client/c-server +%%---------------------------------------------------------------------- + + +-module(erl_client_c_server_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1, + long_test/1, longlong_test/1, ushort_test/1, ulong_test/1, + ulonglong_test/1, double_test/1, char_test/1, wchar_test/1, + octet_test/1, bool_test/1, struct_test/1, struct2_test/1, + seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1, + seq5_test/1, array1_test/1, array2_test/1, enum_test/1, + string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, + term_test/1, typedef_test/1, inline_sequence_test/1, + term_sequence_test/1, term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(CALL_TIMEOUT, 5000). + +-define(C_SERVER_NODE_NAME, idl_c_server_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with an Erlang client and a C server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, longlong_test, ushort_test, + ulong_test, ulonglong_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +longlong_test(doc) -> ""; +longlong_test(suite) -> []; +longlong_test(Config) -> + do_test(longlong_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +ulonglong_test(doc) -> ""; +ulonglong_test(suite) -> []; +ulonglong_test(Config) -> + do_test(ulonglong_test, Config). + +ulong_test(doc) -> ""; +ulong_test(suite) -> []; +ulong_test(Config) -> + do_test(ulong_test, Config). + +ushort_test(doc) -> ""; +ushort_test(suite) -> []; +ushort_test(Config) -> + do_test(ushort_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + Node = atom_to_list(node()), + [_NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME), + %% Start C-server node as a port program. We wait for the node + %% to connect to us. + Cmd = filename:join([DataDir, "c_server"]) ++ + " -this-node-name " ++ ServerNodeName ++ + " -peer-node " ++ Node ++ + " -cookie " ++ Cookie, + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName), + Res = case wait_for_hidden_node(ServerNode) of + ok -> + %% Need a port for port_test and typedef_test + put(port_test_port, Port), + R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)), + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + R; + {error, timeout} -> + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + {error, timeout} + end, + process_flag(trap_exit, false), + true = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + +wait_for_hidden_node(Node) -> + Times = ?DEFAULT_TIMEOUT div 100, + wait_for_hidden_node(Node, Times, 100). + +wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 -> + io:format("Waiting for hidden node: ~p~n", [Node]), + case lists:member(Node, erlang:nodes(hidden)) of + true -> + ok; + false -> + delay(WaitTime), + wait_for_hidden_node(Node, Times - 1, WaitTime) + end; +wait_for_hidden_node(_Node, _, _WaitTime) -> + {error, timeout}. + +kill_off_node(Node) -> + catch rpc:cast(Node, erlang, halt, [1]). + +delay(Time) -> + receive + after Time -> + ok + end. + + + + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..cd34d2b247 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/Makefile.src @@ -0,0 +1,150 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2002-2009. 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% +# +# +# Makefile.src for erl_client_c_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \ + -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE) + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m__s.h \ + m_i__s.h \ + oe_erl_c_test__s.h + +# Generated C files +GEN_C_FILES = \ + m__s.c \ + m_i__s.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c \ + oe_erl_c_test__s.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_erl_c_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_erl_c_test.erl + +C_FILES = $(GEN_C_FILES) c_server.c callbacks.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_server@exe@ + +ERL_FILES = $(GEN_ERL_FILES) erl_client.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \ + "+{scoped_op_calls,true}" erl_c_test.idl + +# If we have scoped operation calls for C, we must have that for +# Erlang as well, if we use the m_i.erl file for calling the server. + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \ + "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -W -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c new file mode 100644 index 0000000000..acdeff80fe --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/c_server.c @@ -0,0 +1,299 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2009. 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% + * + */ +/* C-server for test of IC. + * + * The C-node implemented here connects to its peer node, waits for + * one message, evaluates the message, returns an result message, and + * terminates. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +# include <time.h> +# include <sys/times.h> +#else +# include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ic.h" +#include "ei.h" +#include "erl_interface.h" +#include "eicode.h" +#include "m_i__s.h" +#include "m__s.h" + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 +#define INBUFSZ 10 +#define OUTBUFSZ 0 +#define MAXTRIES 5 + +static char *progname; + +/* main */ +#ifdef VXWORKS +int c_server(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + MyTimeval start, stop; + int i, fd, ires, tries; + CORBA_Environment *env; + char *this_node_name = NULL; + char *peer_node = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + char this_node[NODENAMESZ + 1]; + erlang_msg msg; + int status, loop; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-help") == 0) { + usage(); + done(0); + } else if (strcmp(argv[i], "-this-node-name") == 0) { + i++; + this_node_name = argv[i]; + } else if (strcmp(argv[i], "-peer-node") == 0) { + i++; + peer_node = argv[i]; + } else if (strcmp(argv[i], "-cookie") == 0) { + i++; + cookie = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + + fprintf(stderr, "c_server: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + /* connect to peer node */ + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_server: erl_connect(): %d\n", fd); + if (fd >= 0) + break; + fprintf(stderr, "c_server: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_server: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + + status = 1; + loop = 1; + my_gettimeofday(&start); + while (status >= 0 && loop > 0) { + status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, + &msg, &env->_iin); + switch(status) { + case ERL_SEND: + case ERL_REG_SEND: + /* get result */ + m_i__switch(NULL, env); + switch(env->_major) { + case CORBA_NO_EXCEPTION: + break; + case CORBA_SYSTEM_EXCEPTION: + fprintf(stderr, "Request failure, reason : %s\n", + (char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + break; + default: /* Should not happen */ + CORBA_exception_free(env); + break; + } + /* send back result data */ + if (env->_iout > 0) + ei_send_encoded(env->_fd, &env->_caller, env->_outbuf, + env->_iout); + loop = 0; + break; + case ERL_TICK: + break; + default: + if (status < 0) { + fprintf(stderr, "Status negative: %d\n", status); + loop = 0; + } + break; + } + } + my_gettimeofday(&stop); + showtime(&start, &stop); + + erl_close_connection(fd); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + if (status < 0) + done(-status); + else + done(0); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -cookie <cookie>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -cookie oa678er\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + + + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c new file mode 100644 index 0000000000..d6b28b619d --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/callbacks.c @@ -0,0 +1,610 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2002-2009. 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% + * + */ +#include <stdio.h> +#include <stdlib.h> +#ifndef __WIN32__ +# include <unistd.h> +#endif +#include <string.h> +#include <ctype.h> +#include <ic.h> +#include <erl_interface.h> +#include <ei.h> +#include "m_i__s.h" + + + +/* OK */ + +void my_void_test(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + /* printf("void test !\n"); */ +} + +m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + return (m_i_void_test__rs*) (my_void_test); +} + + + +/* OK */ + +void my_long_test(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + + +m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_long_test__rs*) (my_long_test); +} + +/* OK */ + +void my_longlong_test(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + +m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_longlong_test__rs*) (my_longlong_test); +} + +/* OK */ +void my_ulong_test(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulong_test__rs*) (my_ulong_test); +} + +/* OK */ +void my_ulonglong_test(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulonglong_test__rs*) (my_ulonglong_test); +} + +m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj, + unsigned short* a, + unsigned short* b, + unsigned short* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ushort_test__rs*) NULL; +} + + +/* OK */ +void my_double_test(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + /* printf("double test !\n"); */ +} + +m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_double_test__rs*) (my_double_test); +} + +/* OK */ +m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_char_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + + +/* OK */ +m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj, + CORBA_wchar* a, + CORBA_wchar* b, + CORBA_wchar* c, + CORBA_Environment *oe_env) +{ + m_i_wchar_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_octet_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj, + CORBA_boolean* a, + CORBA_boolean* b, + CORBA_boolean* c, + CORBA_Environment *oe_env) +{ + m_i_bool_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +void my_struct_test(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + /* printf("struct test !\n"); */ +} + +m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_struct_test__rs*) (my_struct_test); +} + +/* OK */ +m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj, + m_es* a, + m_es* b, + m_es* c, + CORBA_Environment *oe_env) +{ + m_i_struct2_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +/* XXX Commented out +m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj, + m_simple* a, + m_simple* b, + m_simple* c, + CORBA_Environment *oe_env) +{ + m_i_struct3_test__rs* rs = NULL; + *a = *b; + *c = *b; + return rs; +} +*/ + +/* OK */ +m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj, + m_bseq** a, + m_bseq* b, + m_bseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq1_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj, + m_aseq** a, + m_aseq* b, + m_aseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj, + m_lseq** a, + m_lseq* b, + m_lseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj, + m_ssstr3** a, + m_ssstr3* b, + m_ssstr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq4_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj, + m_ssarr3** a, + m_ssarr3* b, + m_ssarr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq5_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj, + m_arr1 a, + m_arr1 b, + m_arr1 c, + CORBA_Environment *oe_env) +{ + int i; + m_i_array1_test__rs* rs = NULL; + + for (i = 0; i < 500; i++) { + a[i] = b[i]; + c[i] = b[i]; + } + return rs; +} + +/* OK */ +m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj, + m_dd a, + m_dd b, + m_dd c, + CORBA_Environment *oe_env) +{ + int i,j; + m_i_array2_test__rs* rs = NULL; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) { + a[i][j] = b[i][j]; + c[i][j] = b[i][j]; + } + return rs; +} + + +/* OK */ +m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj, + m_fruit* a, + m_fruit* b, + m_fruit* c, + CORBA_Environment *oe_env) +{ + m_i_enum_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj, + m_sseq** a, + m_sseq* b, + m_sseq** c, + CORBA_Environment *oe_env) +{ + m_i_string2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj, + m_strRec** a, + m_strRec* b, + m_strRec** c, + CORBA_Environment *oe_env) +{ + *a = b; + *c = b; + + return (m_i_string4_test__rs*) NULL; +} + +/* OK */ +m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj, + CORBA_wchar ** a, + CORBA_wchar * b, + CORBA_wchar ** c, + CORBA_Environment *oe_env) +{ + int tmp; + m_i_wstring1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + + for(tmp = 0; tmp < 5; tmp++) + fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]); + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj, + erlang_pid* a, + erlang_pid* b, + erlang_pid* c, + CORBA_Environment *oe_env) +{ + m_i_pid_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj, + erlang_port* a, + erlang_port* b, + erlang_port* c, + CORBA_Environment *oe_env) +{ + m_i_port_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + (*a).id = (*b).id; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + (*c).id = (*b).id; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj, + erlang_ref* a, + erlang_ref* b, + erlang_ref* c, + CORBA_Environment *oe_env) +{ + + m_i_ref_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + /*(*a).id = (*b).id;*/ + (*a).len = (*b).len; + (*a).n[0] = (*b).n[0]; + (*a).n[1] = (*b).n[1]; + (*a).n[2] = (*b).n[2]; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + /*(*c).id = (*b).id;*/ + (*c).len = (*b).len; + (*c).n[0] = (*b).n[0]; + (*c).n[1] = (*b).n[1]; + (*c).n[2] = (*b).n[2]; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj, + ETERM** a, + ETERM** b, + ETERM** c, + CORBA_Environment *oe_env) +{ + m_i_term_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj, + long* a, + ETERM** b, + erlang_port* c, + ETERM** d , + erlang_port* e, + CORBA_Environment *oe_env) +{ + m_i_typedef_test__rs* rs = NULL; + + *d = *b; + strcpy((*e).node,(*c).node); + (*e).id = (*c).id; + (*e).creation = 0; + *a = 4711; + return rs; +} + +/* OK */ +m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb( + CORBA_Object oe_obj, + m_s** a, + m_s* b, + m_s** c, + CORBA_Environment *oe_env) +{ + m_i_inline_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_term_sequence_test__rs* m_i_term_sequence_test__cb( + CORBA_Object oe_obj, + m_etseq** a, + m_etseq* b, + m_etseq** c, + CORBA_Environment *oe_env) +{ + m_i_term_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj, + m_et* a, + m_et* b, + m_et* c, + CORBA_Environment *oe_env) +{ + m_i_term_struct_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl new file mode 100644 index 0000000000..963bc69017 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_c_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2002-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% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl new file mode 100644 index 0000000000..79ec28a921 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_SUITE_data/erl_client.erl @@ -0,0 +1,331 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2002-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% +%% +%% +-module(erl_client). + +-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2, + ulong_test/2, ulonglong_test/2, double_test/2, char_test/2, + wchar_test/2, octet_test/2, bool_test/2, struct_test/2, + struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2, + seq4_test/2, seq5_test/2, array1_test/2, array2_test/2, + enum_test/2, string1_test/2, wstring1_test/2, string2_test/2, + string3_test/2, string4_test/2, pid_test/2, port_test/2, + ref_test/2, term_test/2, typedef_test/2, + inline_sequence_test/2, term_sequence_test/2, + term_struct_test/2 + +]). + +-include("m.hrl"). +-include("m_i.hrl"). +-include("oe_erl_c_test.hrl"). + +%%b +void_test(Node, Timeout) -> + Ret = m_i:void_test({olsson, Node}, Timeout), + Ret == void. % XXX Not documented +%%e + +%%b +long_test(Node, Timeout) -> + In = max_long(), + {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +longlong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ushort_test(Node, Timeout) -> + In = max_ushort(), + {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulong_test(Node, Timeout) -> + In = max_ulong(), + {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulonglong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +double_test(Node, Timeout) -> + In = 37768.93, + {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +char_test(Node, Timeout) -> + In = 80, + {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wchar_test(Node, Timeout) -> + In = 4097, + {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +octet_test(Node, Timeout) -> + In = 255, + {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +bool_test(Node, Timeout) -> + In = false, + {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct_test(Node, Timeout) -> + In = #m_b{l = max_long(), c = $a}, + {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct2_test(Node, Timeout) -> + In = #m_es{ f = banana, l = max_long()}, + {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq1_test(Node, Timeout) -> + B1 = #m_b{l = max_long(), c = $a}, + B2 = #m_b{l = min_long(), c = $b}, + In = [B1, B2], + {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq2_test(Node, Timeout) -> + B = #m_b{l = max_long(), c = $a}, + A = #m_a{l = min_long(), y = [B, B], d = 4711.31}, + In = [A, A, A], + {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq3_test(Node, Timeout) -> + In = [max_long(), min_long(), max_long()], + {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq4_test(Node, Timeout) -> + In = [["hello", "all"], ["Erlang", "users", "!"]], + {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq5_test(Node, Timeout) -> + Arr3 = mk_array(3, max_long()), + In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]], + {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array1_test(Node, Timeout) -> + In = mk_array(500, min_long()), + {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array2_test(Node, Timeout) -> + In = mk_array(2, mk_array(3, min_long())), + {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +enum_test(Node, Timeout) -> + In = banana, + {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string1_test(Node, Timeout) -> + In = "Developing Erlang applications is fun!", + {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wstring1_test(Node, Timeout) -> + In = [1047| "eveloping Erlang applications is fun!"], + {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string2_test(Node, Timeout) -> + In = ["Developing Erlang applications ", "is fun!"], + {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string3_test(Node, Timeout) -> + In = "Developing Erlang applications is fun!", + {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string4_test(Node, Timeout) -> + + In = #m_strRec{ + bb = true, + str4 = "Developing Erlang applications " + "is fun!", + str7 = mk_array(3, mk_array(2, max_long())), + str5 = [$a, $b, $c, $d, $e, $f], + str6 = "123456789012", + str8 = {$x, $y, $x}, + str9 = "123456789012", + str10 = [$a, $b, $c, $d, $e, $f] + }, + {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +pid_test(Node, Timeout) -> + In = self(), + {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +port_test(Node, Timeout) -> + In = get(port_test_port), + {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ref_test(Node, Timeout) -> + In = make_ref(), + {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_test(Node, Timeout) -> + In = {[a, b], 17, kalle}, + {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +typedef_test(Node, Timeout) -> + In1 = {nisse, [1, 2], olsson}, + In2 = get(port_test_port), + {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2), + %% XXX Should check that Ret is an integer. + (Out1 == In1) and (Out2 == In2). +%%e + +%%b +inline_sequence_test(Node, Timeout) -> + In = #m_s{l = min_long(), sl = [max_long(), min_long()]}, + {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_sequence_test(Node, Timeout) -> + In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}), + {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_struct_test(Node, Timeout) -> + In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711}, + {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + + +%% Locals + +mk_array(Es) -> + list_to_tuple(Es). + +mk_array(N, E) -> + mk_array(lists:duplicate(N, E)). + +%% max_short() -> +%% power_of_two(15) - 1. +max_long() -> + power_of_two(31) - 1. +max_longlong() -> + power_of_two(63) - 1. +max_ushort() -> + power_of_two(16) - 1. +max_ulong() -> + power_of_two(32) - 1. +max_ulonglong() -> + power_of_two(64) - 1. + +%% min_short() -> +%% -power_of_two(15). +min_long() -> + -power_of_two(31). +%% min_longlong() -> +%% -power_of_two(63). +%% min_ushort() -> +%% 0. +%% min_ulong() -> +%% 0. +%% min_ulonglong() -> +%% 0. + +power_of_two(N) -> + round(math:pow(2, N)). + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE.erl b/lib/ic/test/erl_client_c_server_proto_SUITE.erl new file mode 100644 index 0000000000..d75feb621a --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE.erl @@ -0,0 +1,350 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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 : Test suite for erl-client/c-server +%%---------------------------------------------------------------------- + + +-module(erl_client_c_server_proto_SUITE). +-include("test_server.hrl"). + +-export([init_per_testcase/2, fin_per_testcase/2, all/1, void_test/1, + long_test/1, longlong_test/1, ushort_test/1, ulong_test/1, + ulonglong_test/1, double_test/1, char_test/1, wchar_test/1, + octet_test/1, bool_test/1, struct_test/1, struct2_test/1, + seq1_test/1, seq2_test/1, seq3_test/1, seq4_test/1, + seq5_test/1, array1_test/1, array2_test/1, enum_test/1, + string1_test/1, string2_test/1, string3_test/1, + string4_test/1, pid_test/1, port_test/1, ref_test/1, + term_test/1, typedef_test/1, inline_sequence_test/1, + term_sequence_test/1, term_struct_test/1, wstring1_test/1]). + +-define(DEFAULT_TIMEOUT, 20000). +-define(PORT_TIMEOUT, 15000). +-define(CALL_TIMEOUT, 5000). + +-define(C_SERVER_NODE_NAME, idl_c_server_test). + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i, we have + %% to make sure we are using the right m_i module. + code:purge(m_i), + code:load_file(m_i), + + WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + +all(doc) -> + "Test of IC with an Erlang client and a C server. " + "The communication is via Erlang distribution."; +all(suite) -> + [void_test, long_test, longlong_test, ushort_test, + ulong_test, ulonglong_test, double_test, + char_test, wchar_test, octet_test, bool_test, struct_test, + struct2_test, seq1_test, seq2_test, seq3_test, seq4_test, + seq5_test, array1_test, array2_test, enum_test, string1_test, + string2_test, string3_test, string4_test, pid_test, port_test, + ref_test, term_test, typedef_test, inline_sequence_test, + term_sequence_test, term_struct_test, wstring1_test]. + + +array1_test(doc) -> ""; +array1_test(suite) -> []; +array1_test(Config) -> + do_test(array1_test, Config). + +array2_test(doc) -> ""; +array2_test(suite) -> []; +array2_test(Config) -> + do_test(array2_test, Config). + +bool_test(doc) -> ""; +bool_test(suite) -> []; +bool_test(Config) -> + do_test(bool_test, Config). + +char_test(doc) -> ""; +char_test(suite) -> []; +char_test(Config) -> + do_test(char_test, Config). + +double_test(doc) -> ""; +double_test(suite) -> []; +double_test(Config) -> + do_test(double_test, Config). + +enum_test(doc) -> ""; +enum_test(suite) -> []; +enum_test(Config) -> + do_test(enum_test, Config). + +inline_sequence_test(doc) -> ""; +inline_sequence_test(suite) -> []; +inline_sequence_test(Config) -> + do_test(inline_sequence_test, Config). + +longlong_test(doc) -> ""; +longlong_test(suite) -> []; +longlong_test(Config) -> + do_test(longlong_test, Config). + +long_test(doc) -> ""; +long_test(suite) -> []; +long_test(Config) -> + do_test(long_test, Config). + +octet_test(doc) -> ""; +octet_test(suite) -> []; +octet_test(Config) -> + do_test(octet_test, Config). + +pid_test(doc) -> ""; +pid_test(suite) -> []; +pid_test(Config) -> + do_test(pid_test, Config). + +port_test(doc) -> ""; +port_test(suite) -> []; +port_test(Config) -> + do_test(port_test, Config). + +ref_test(doc) -> ""; +ref_test(suite) -> []; +ref_test(Config) -> + do_test(ref_test, Config). + +seq1_test(doc) -> ""; +seq1_test(suite) -> []; +seq1_test(Config) -> + do_test(seq1_test, Config). + +seq2_test(doc) -> ""; +seq2_test(suite) -> []; +seq2_test(Config) -> + do_test(seq2_test, Config). + +seq3_test(doc) -> ""; +seq3_test(suite) -> []; +seq3_test(Config) -> + do_test(seq3_test, Config). + +seq4_test(doc) -> ""; +seq4_test(suite) -> []; +seq4_test(Config) -> + do_test(seq4_test, Config). + +seq5_test(doc) -> ""; +seq5_test(suite) -> []; +seq5_test(Config) -> + do_test(seq5_test, Config). + +string1_test(doc) -> ""; +string1_test(suite) -> []; +string1_test(Config) -> + do_test(string1_test, Config). + +string2_test(doc) -> ""; +string2_test(suite) -> []; +string2_test(Config) -> + do_test(string2_test, Config). + +string3_test(doc) -> ""; +string3_test(suite) -> []; +string3_test(Config) -> + do_test(string3_test, Config). + +string4_test(doc) -> ""; +string4_test(suite) -> []; +string4_test(Config) -> + do_test(string4_test, Config). + +struct2_test(doc) -> ""; +struct2_test(suite) -> []; +struct2_test(Config) -> + do_test(struct2_test, Config). + +struct_test(doc) -> ""; +struct_test(suite) -> []; +struct_test(Config) -> + do_test(struct_test, Config). + +term_sequence_test(doc) -> ""; +term_sequence_test(suite) -> []; +term_sequence_test(Config) -> + do_test(term_sequence_test, Config). + +term_struct_test(doc) -> ""; +term_struct_test(suite) -> []; +term_struct_test(Config) -> + do_test(term_struct_test, Config). + +term_test(doc) -> ""; +term_test(suite) -> []; +term_test(Config) -> + do_test(term_test, Config). + +typedef_test(doc) -> ""; +typedef_test(suite) -> []; +typedef_test(Config) -> + do_test(typedef_test, Config). + +ulonglong_test(doc) -> ""; +ulonglong_test(suite) -> []; +ulonglong_test(Config) -> + do_test(ulonglong_test, Config). + +ulong_test(doc) -> ""; +ulong_test(suite) -> []; +ulong_test(Config) -> + do_test(ulong_test, Config). + +ushort_test(doc) -> ""; +ushort_test(suite) -> []; +ushort_test(Config) -> + do_test(ushort_test, Config). + +void_test(doc) -> ""; +void_test(suite) -> []; +void_test(Config) -> + do_test(void_test, Config). + +wchar_test(doc) -> ""; +wchar_test(suite) -> []; +wchar_test(Config) -> + do_test(wchar_test, Config). + +wstring1_test(doc) -> ""; +wstring1_test(suite) -> []; +wstring1_test(Config) -> + do_test(wstring1_test, Config). + + +do_test(Case, Config) -> + %% Trap exits + process_flag(trap_exit, true), + Node = atom_to_list(node()), + [_NodeName, HostName] = string:tokens(Node, "@"), + DataDir = ?config(data_dir, Config), + %% io:format("~p: data directory: ~p~n", [?MODULE, DataDir]), + Cookie = atom_to_list(erlang:get_cookie()), + ServerNodeName = atom_to_list(?C_SERVER_NODE_NAME), + %% Start C-server node as a port program. We wait for the node + %% to connect to us. + Cmd = filename:join([DataDir, "c_server"]) ++ + " -this-node-name " ++ ServerNodeName ++ + " -peer-node " ++ Node ++ + " -cookie " ++ Cookie, + Port = open_port({spawn, Cmd}, [exit_status, eof, stderr_to_stdout]), + ServerNode = list_to_atom(ServerNodeName ++ "@" ++ HostName), + Res = case wait_for_hidden_node(ServerNode) of + ok -> + %% Need a port for port_test and typedef_test + put(port_test_port, Port), + R = (catch erl_client:Case(ServerNode, ?CALL_TIMEOUT)), + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + R; + {error, timeout} -> + case wait_for_completion(Port) of + {error, timeout} -> + kill_off_node(ServerNode); + _ -> + ok + end, + {error, timeout} + end, + process_flag(trap_exit, false), + true = Res. + + +%% Wait for eof *and* exit status, but return if exit status indicates +%% an error, or we have been waiting more than PORT_TIMEOUT seconds. +%% +wait_for_completion(Port) -> + wait_for_completion(Port, 0). + +wait_for_completion(Port, N) when N < 2 -> + receive + {Port, {data, Bytes}} -> + %% Relay output + io:format("~s", [Bytes]), + wait_for_completion(Port, N); + {Port, {exit_status, 0}} -> + wait_for_completion(Port, N + 1); + {Port, {exit_status, Status}} -> + {error, Status}; + {Port, eof} -> + wait_for_completion(Port, N + 1); + {'EXIT', Port, Reason} -> + io:format("Port exited with reason: ~w~n", [Reason]), + wait_for_completion(Port, N); + {'EXIT', From, Reason} -> + io:format("Got unexpected exit: ~p~n", [{'EXIT', From, Reason}]), + wait_for_completion(Port, N) + after ?PORT_TIMEOUT -> + {error, timeout} + end; +wait_for_completion(_, _) -> + ok. + +wait_for_hidden_node(Node) -> + Times = ?DEFAULT_TIMEOUT div 100, + wait_for_hidden_node(Node, Times, 100). + +wait_for_hidden_node(Node, Times, WaitTime) when Times > 0 -> + io:format("Waiting for hidden node: ~p~n", [Node]), + case lists:member(Node, erlang:nodes(hidden)) of + true -> + ok; + false -> + delay(WaitTime), + wait_for_hidden_node(Node, Times - 1, WaitTime) + end; +wait_for_hidden_node(_Node, _, _WaitTime) -> + {error, timeout}. + +kill_off_node(Node) -> + catch rpc:cast(Node, erlang, halt, [1]). + +delay(Time) -> + receive + after Time -> + ok + end. + + + + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src new file mode 100644 index 0000000000..b7e7ee77d0 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/Makefile.src @@ -0,0 +1,150 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2004-2009. 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% +# +# +# Makefile.src for erl_client_c_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .c .h .erl .idl @obj@ .@EMULATOR@ + + +# Variables from ts: +# + +ERL_INCLUDE = @erl_include@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_LIB = @ic_libpath@@DS@@ic_lib@ + +ERL_INTERFACE_INCLUDE = @erl_interface_include@ +ERL_INTERFACE_LIB = @erl_interface_libpath@@DS@@erl_interface_lib@ +ERL_INTERFACE_EILIB = @erl_interface_libpath@@DS@@erl_interface_eilib@ +ERL_INTERFACE_THREADLIB = @erl_interface_threadlib@ +ERL_INTERFACE_SOCK_LIBS = @erl_interface_sock_libs@ + +CC = @CC@ +## XXX Should set warning flag with a DEBUG_FLAG +CFLAGS = @CFLAGS@ @DEFS@ -I$(ERL_INCLUDE) \ + -I$(IC_INCLUDE_PATH) -I$(ERL_INTERFACE_INCLUDE) + +LD = @LD@ +LDFLAGS = @CROSSLDFLAGS@ +LIBS = $(IC_LIB) $(ERL_INTERFACE_LIB) $(ERL_INTERFACE_EILIB) \ + $(ERL_INTERFACE_THREADLIB) @LIBS@ $(ERL_INTERFACE_SOCK_LIBS) +ERLC = erlc + +# Generated C header files +GEN_H_FILES = \ + m__s.h \ + m_i__s.h \ + oe_erl_c_test__s.h + +# Generated C files +GEN_C_FILES = \ + m__s.c \ + m_i__s.c \ + oe_code_m_a.c \ + oe_code_m_arr1.c \ + oe_code_m_arr2.c \ + oe_code_m_arr3.c \ + oe_code_m_aseq.c \ + oe_code_m_b.c \ + oe_code_m_bseq.c \ + oe_code_m_dd.c \ + oe_code_m_dyn.c \ + oe_code_m_dyn_sl.c \ + oe_code_m_es.c \ + oe_code_m_et.c \ + oe_code_m_etseq.c \ + oe_code_m_fruit.c \ + oe_code_m_lseq.c \ + oe_code_m_s.c \ + oe_code_m_s_sl.c \ + oe_code_m_sarr3.c \ + oe_code_m_simple.c \ + oe_code_m_ssarr3.c \ + oe_code_m_sseq.c \ + oe_code_m_ssstr3.c \ + oe_code_m_sstr3.c \ + oe_code_m_str1.c \ + oe_code_m_str3.c \ + oe_code_m_strRec.c \ + oe_code_m_strRec_str5.c \ + oe_code_m_strRec_str7.c \ + oe_erl_c_test__s.c + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_erl_c_test.hrl + +GEN_ERL_FILES = \ + m.erl \ + m_arr2.erl \ + m_arr3.erl \ + m_i.erl \ + m_str3.erl \ + oe_erl_c_test.erl + +C_FILES = $(GEN_C_FILES) c_server.c callbacks.c + +OBJS = $(C_FILES:.c=@obj@) + +PGMS = c_server@exe@ + +ERL_FILES = $(GEN_ERL_FILES) erl_client.erl + +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(PGMS) $(EBINS) + +clean: + -rm -f $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + -del /F /Q $(OBJS) $(GEN_C_FILES) $(GEN_H_FILES) $(PGMS) \ + $(EBINS) $(GEN_ERL_FILES) $(GEN_HRL_FILES) + +$(PGMS): $(OBJS) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(GEN_C_FILES) $(GEN_H_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,c_server}" \ + "+{scoped_op_calls,true}" erl_c_test.idl + +# If we have scoped operation calls for C, we must have that for +# Erlang as well, if we use the m_i.erl file for calling the server. + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): erl_c_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" \ + "+{scoped_op_calls,true}" "+{timeout,true}" erl_c_test.idl + +.c@obj@: + $(CC) -c -o $*@obj@ $(CFLAGS) $< + +.erl.@EMULATOR@: + $(ERLC) -W -I $(IC_INCLUDE_PATH) $< + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c new file mode 100644 index 0000000000..329f444112 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/c_server.c @@ -0,0 +1,299 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. 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% + * + */ +/* C-server for test of IC. + * + * The C-node implemented here connects to its peer node, waits for + * one message, evaluates the message, returns an result message, and + * terminates. + * + * TODO: + * + * 1. XXX #includes for VxWorks, Windows + */ + +#include <stdio.h> +#include <stdlib.h> + +#ifndef __WIN32__ +# include <unistd.h> +#endif + +#include <string.h> + +#ifdef __WIN32__ +# include <time.h> +# include <sys/timeb.h> +#elif defined VXWORKS +# include <time.h> +# include <sys/times.h> +#else +# include <sys/time.h> +#endif + +#include <ctype.h> + +#ifdef __WIN32__ +# include <winsock2.h> +# include <windows.h> +#else +# include <sys/types.h> +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +# include <netdb.h> +#endif + +#include "ic.h" +#include "ei.h" +#include "erl_interface.h" +#include "eicode.h" +#include "m_i__s.h" +#include "m__s.h" + +#ifdef __WIN32__ +typedef struct { + long tv_sec; + long tv_usec; +} MyTimeval; +#else +typedef struct timeval MyTimeval; +#endif +static void my_gettimeofday(MyTimeval *tv); +static void showtime(MyTimeval *start, MyTimeval *stop); +static void usage(void); +static void done(int r); + +#define HOSTNAMESZ 256 +#define NODENAMESZ 512 +#define INBUFSZ 10 +#define OUTBUFSZ 0 +#define MAXTRIES 5 + +static char *progname; + +/* main */ +#ifdef VXWORKS +int c_server(int argc, char **argv) +#else +int main(int argc, char **argv) +#endif +{ + struct hostent *hp; + MyTimeval start, stop; + int i, fd, ires, tries; + CORBA_Environment *env; + char *this_node_name = NULL; + char *peer_node = NULL; + char *cookie = NULL; + char host[HOSTNAMESZ + 1]; + char this_node[NODENAMESZ + 1]; + erlang_msg msg; + int status, loop; + +#ifdef __WIN32__ + WORD wVersionRequested; + WSADATA wsaData; + + wVersionRequested = MAKEWORD(2, 0); + + if (WSAStartup(wVersionRequested, &wsaData) != 0) { + fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); + exit(1); + } +#endif + + progname = argv[0]; + host[HOSTNAMESZ] = '\0'; + if (gethostname(host, HOSTNAMESZ) < 0) { + fprintf(stderr, "Can't find own hostname\n"); + done(1); + } + if ((hp = gethostbyname(host)) == 0) { + fprintf(stderr, "Can't get ip address for host %s\n", host); + done(1); + } + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-help") == 0) { + usage(); + done(0); + } else if (strcmp(argv[i], "-this-node-name") == 0) { + i++; + this_node_name = argv[i]; + } else if (strcmp(argv[i], "-peer-node") == 0) { + i++; + peer_node = argv[i]; + } else if (strcmp(argv[i], "-cookie") == 0) { + i++; + cookie = argv[i]; + } else { + fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); + usage(); + done(1); + } + } + + if (this_node_name == NULL || peer_node == NULL || cookie == NULL) { + fprintf(stderr, "Error: missing option\n"); + usage(); + done(1); + } + + /* Behead hostname at first dot */ + for (i=0; host[i] != '\0'; i++) { + if (host[i] == '.') { host[i] = '\0'; break; } + } + sprintf(this_node, "%s@%s", this_node_name, host); + + fprintf(stderr, "c_server: this node: \"%s\"\n", this_node); + fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node); + + /* initialize erl_interface */ + erl_init(NULL, 0); + + for (tries = 0; tries < MAXTRIES; tries++) { + /* connect to peer node */ + ires = erl_connect_xinit(host, this_node_name, this_node, + (struct in_addr *)*hp->h_addr_list, + cookie, 0); + fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires); + + fd = erl_connect(peer_node); + fprintf(stderr, "c_server: erl_connect(): %d\n", fd); + if (fd >= 0) + break; + fprintf(stderr, "c_server: cannot connect, retrying\n"); + } + if (fd < 0) { + fprintf(stderr, "c_server: cannot connect, exiting\n"); + done(1); + } + env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); + env->_fd = fd; + + status = 1; + loop = 1; + my_gettimeofday(&start); + while (status >= 0 && loop > 0) { + status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, + &msg, &env->_iin); + switch(status) { + case ERL_SEND: + case ERL_REG_SEND: + /* get result */ + m_i__switch(NULL, env); + switch(env->_major) { + case CORBA_NO_EXCEPTION: + break; + case CORBA_SYSTEM_EXCEPTION: + fprintf(stderr, "Request failure, reason : %s\n", + (char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + break; + default: /* Should not happen */ + CORBA_exception_free(env); + break; + } + /* send back result data */ + if (env->_iout > 0) + ei_send_encoded(env->_fd, &env->_caller, env->_outbuf, + env->_iout); + loop = 0; + break; + case ERL_TICK: + break; + default: + if (status < 0) { + fprintf(stderr, "Status negative: %d\n", status); + loop = 0; + } + break; + } + } + my_gettimeofday(&stop); + showtime(&start, &stop); + + erl_close_connection(fd); + + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + if (status < 0) + done(-status); + else + done(0); +} + +static void usage() +{ + fprintf(stderr, "Usage: %s [-help] -this-node-name <name> " + "-peer-node <nodename> -cookie <cookie>\n", progname); + fprintf(stderr, "Example:\n %s -this-node-name kalle " + "-peer-node olle@home -cookie oa678er\n", progname); +} + +static void done(int r) +{ +#ifdef __WIN32__ + WSACleanup(); +#endif + exit(r); +} + +static void showtime(MyTimeval *start, MyTimeval *stop) +{ + MyTimeval elapsed; + + elapsed.tv_sec = stop->tv_sec - start->tv_sec; + elapsed.tv_usec = stop->tv_usec - start->tv_usec; + while (elapsed.tv_usec < 0) { + elapsed.tv_sec -= 1; + elapsed.tv_usec += 1000000; + } + fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); +} + + + +static void my_gettimeofday(MyTimeval *tv) +#ifdef __WIN32__ +#define EPOCH_JULIAN_DIFF 11644473600i64 +{ + SYSTEMTIME t; + FILETIME ft; + LONGLONG lft; + + GetSystemTime(&t); + SystemTimeToFileTime(&t, &ft); + memcpy(&lft, &ft, sizeof(lft)); + tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); + tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); +} +#elif defined VXWORKS +{ + int rate = sysClkRateGet(); /* Ticks per second */ + unsigned long ctick = tickGet(); + tv->tv_sec = ctick / rate; /* secs since reboot */ + tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; +} +#else +{ + gettimeofday(tv, NULL); +} +#endif diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c new file mode 100644 index 0000000000..b029bcc63c --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/callbacks.c @@ -0,0 +1,610 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. 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% + * + */ +#include <stdio.h> +#include <stdlib.h> +#ifndef __WIN32__ +# include <unistd.h> +#endif +#include <string.h> +#include <ctype.h> +#include <ic.h> +#include <erl_interface.h> +#include <ei.h> +#include "m_i__s.h" + + + +/* OK */ + +void my_void_test(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + /* printf("void test !\n"); */ +} + +m_i_void_test__rs* m_i_void_test__cb(CORBA_Object oe_obj, + CORBA_Environment *oe_env) +{ + return (m_i_void_test__rs*) (my_void_test); +} + + + +/* OK */ + +void my_long_test(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + + +m_i_long_test__rs* m_i_long_test__cb(CORBA_Object oe_obj, + long* a, + long* b, + long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_long_test__rs*) (my_long_test); +} + +/* OK */ + +void my_longlong_test(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("long test !\n"); */ +} + +m_i_longlong_test__rs* m_i_longlong_test__cb(CORBA_Object oe_obj, + CORBA_long_long* a, + CORBA_long_long* b, + CORBA_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_longlong_test__rs*) (my_longlong_test); +} + +/* OK */ +void my_ulong_test(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulong_test__rs* m_i_ulong_test__cb(CORBA_Object oe_obj, + unsigned long* a, + unsigned long* b, + unsigned long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulong_test__rs*) (my_ulong_test); +} + +/* OK */ +void my_ulonglong_test(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + /* printf("ulong test !\n"); */ +} + +m_i_ulonglong_test__rs* m_i_ulonglong_test__cb(CORBA_Object oe_obj, + CORBA_unsigned_long_long* a, + CORBA_unsigned_long_long* b, + CORBA_unsigned_long_long* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ulonglong_test__rs*) (my_ulonglong_test); +} + +m_i_ushort_test__rs* m_i_ushort_test__cb(CORBA_Object oe_obj, + unsigned short* a, + unsigned short* b, + unsigned short* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_ushort_test__rs*) NULL; +} + + +/* OK */ +void my_double_test(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + /* printf("double test !\n"); */ +} + +m_i_double_test__rs* m_i_double_test__cb(CORBA_Object oe_obj, + double* a, + double* b, + double* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_double_test__rs*) (my_double_test); +} + +/* OK */ +m_i_char_test__rs* m_i_char_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_char_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + + +/* OK */ +m_i_wchar_test__rs* m_i_wchar_test__cb(CORBA_Object oe_obj, + CORBA_wchar* a, + CORBA_wchar* b, + CORBA_wchar* c, + CORBA_Environment *oe_env) +{ + m_i_wchar_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_octet_test__rs* m_i_octet_test__cb(CORBA_Object oe_obj, + char* a, + char* b, + char* c, + CORBA_Environment *oe_env) +{ + m_i_octet_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_bool_test__rs* m_i_bool_test__cb(CORBA_Object oe_obj, + CORBA_boolean* a, + CORBA_boolean* b, + CORBA_boolean* c, + CORBA_Environment *oe_env) +{ + m_i_bool_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +void my_struct_test(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + /* printf("struct test !\n"); */ +} + +m_i_struct_test__rs* m_i_struct_test__cb(CORBA_Object oe_obj, + m_b* a, + m_b* b, + m_b* c, + CORBA_Environment *oe_env) +{ + *a = *b; + *c = *b; + return (m_i_struct_test__rs*) (my_struct_test); +} + +/* OK */ +m_i_struct2_test__rs* m_i_struct2_test__cb(CORBA_Object oe_obj, + m_es* a, + m_es* b, + m_es* c, + CORBA_Environment *oe_env) +{ + m_i_struct2_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +/* XXX Commented out +m_i_struct3_test__rs* m_i_struct3_test__cb(CORBA_Object oe_obj, + m_simple* a, + m_simple* b, + m_simple* c, + CORBA_Environment *oe_env) +{ + m_i_struct3_test__rs* rs = NULL; + *a = *b; + *c = *b; + return rs; +} +*/ + +/* OK */ +m_i_seq1_test__rs* m_i_seq1_test__cb(CORBA_Object oe_obj, + m_bseq** a, + m_bseq* b, + m_bseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq1_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_seq2_test__rs* m_i_seq2_test__cb(CORBA_Object oe_obj, + m_aseq** a, + m_aseq* b, + m_aseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq3_test__rs* m_i_seq3_test__cb(CORBA_Object oe_obj, + m_lseq** a, + m_lseq* b, + m_lseq** c, + CORBA_Environment *oe_env) +{ + m_i_seq3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq4_test__rs* m_i_seq4_test__cb(CORBA_Object oe_obj, + m_ssstr3** a, + m_ssstr3* b, + m_ssstr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq4_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_seq5_test__rs* m_i_seq5_test__cb(CORBA_Object oe_obj, + m_ssarr3** a, + m_ssarr3* b, + m_ssarr3** c, + CORBA_Environment *oe_env) +{ + m_i_seq5_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_array1_test__rs* m_i_array1_test__cb(CORBA_Object oe_obj, + m_arr1 a, + m_arr1 b, + m_arr1 c, + CORBA_Environment *oe_env) +{ + int i; + m_i_array1_test__rs* rs = NULL; + + for (i = 0; i < 500; i++) { + a[i] = b[i]; + c[i] = b[i]; + } + return rs; +} + +/* OK */ +m_i_array2_test__rs* m_i_array2_test__cb(CORBA_Object oe_obj, + m_dd a, + m_dd b, + m_dd c, + CORBA_Environment *oe_env) +{ + int i,j; + m_i_array2_test__rs* rs = NULL; + + for (i = 0; i < 2; i++) + for (j = 0; j < 3; j++) { + a[i][j] = b[i][j]; + c[i][j] = b[i][j]; + } + return rs; +} + + +/* OK */ +m_i_enum_test__rs* m_i_enum_test__cb(CORBA_Object oe_obj, + m_fruit* a, + m_fruit* b, + m_fruit* c, + CORBA_Environment *oe_env) +{ + m_i_enum_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_string1_test__rs* m_i_string1_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string2_test__rs* m_i_string2_test__cb(CORBA_Object oe_obj, + m_sseq** a, + m_sseq* b, + m_sseq** c, + CORBA_Environment *oe_env) +{ + m_i_string2_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_string3_test__rs* m_i_string3_test__cb(CORBA_Object oe_obj, + char ** a, + char * b, + char ** c, + CORBA_Environment *oe_env) +{ + m_i_string3_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +m_i_string4_test__rs* m_i_string4_test__cb(CORBA_Object oe_obj, + m_strRec** a, + m_strRec* b, + m_strRec** c, + CORBA_Environment *oe_env) +{ + *a = b; + *c = b; + + return (m_i_string4_test__rs*) NULL; +} + +/* OK */ +m_i_wstring1_test__rs* m_i_wstring1_test__cb(CORBA_Object oe_obj, + CORBA_wchar ** a, + CORBA_wchar * b, + CORBA_wchar ** c, + CORBA_Environment *oe_env) +{ + int tmp; + m_i_wstring1_test__rs* rs = NULL; + + /*printf("\nString in ------> %s\n\n",b);*/ + + for(tmp = 0; tmp < 5; tmp++) + fprintf(stderr,"\np[%d] = %ld\n", tmp, b[tmp]); + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_pid_test__rs* m_i_pid_test__cb(CORBA_Object oe_obj, + erlang_pid* a, + erlang_pid* b, + erlang_pid* c, + CORBA_Environment *oe_env) +{ + m_i_pid_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +/* OK */ +m_i_port_test__rs* m_i_port_test__cb(CORBA_Object oe_obj, + erlang_port* a, + erlang_port* b, + erlang_port* c, + CORBA_Environment *oe_env) +{ + m_i_port_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + (*a).id = (*b).id; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + (*c).id = (*b).id; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_ref_test__rs* m_i_ref_test__cb(CORBA_Object oe_obj, + erlang_ref* a, + erlang_ref* b, + erlang_ref* c, + CORBA_Environment *oe_env) +{ + + m_i_ref_test__rs* rs = NULL; + + strcpy((*a).node,(*b).node); + /*(*a).id = (*b).id;*/ + (*a).len = (*b).len; + (*a).n[0] = (*b).n[0]; + (*a).n[1] = (*b).n[1]; + (*a).n[2] = (*b).n[2]; + (*a).creation = 0; + + strcpy((*c).node,(*b).node); + /*(*c).id = (*b).id;*/ + (*c).len = (*b).len; + (*c).n[0] = (*b).n[0]; + (*c).n[1] = (*b).n[1]; + (*c).n[2] = (*b).n[2]; + (*c).creation = 0; + return rs; +} + +/* OK */ +m_i_term_test__rs* m_i_term_test__cb(CORBA_Object oe_obj, + ETERM** a, + ETERM** b, + ETERM** c, + CORBA_Environment *oe_env) +{ + m_i_term_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + +m_i_typedef_test__rs* m_i_typedef_test__cb(CORBA_Object oe_obj, + long* a, + ETERM** b, + erlang_port* c, + ETERM** d , + erlang_port* e, + CORBA_Environment *oe_env) +{ + m_i_typedef_test__rs* rs = NULL; + + *d = *b; + strcpy((*e).node,(*c).node); + (*e).id = (*c).id; + (*e).creation = 0; + *a = 4711; + return rs; +} + +/* OK */ +m_i_inline_sequence_test__rs* m_i_inline_sequence_test__cb( + CORBA_Object oe_obj, + m_s** a, + m_s* b, + m_s** c, + CORBA_Environment *oe_env) +{ + m_i_inline_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + +/* OK */ +m_i_term_sequence_test__rs* m_i_term_sequence_test__cb( + CORBA_Object oe_obj, + m_etseq** a, + m_etseq* b, + m_etseq** c, + CORBA_Environment *oe_env) +{ + m_i_term_sequence_test__rs* rs = NULL; + + *a = b; + *c = b; + return rs; +} + + +/* OK */ +m_i_term_struct_test__rs* m_i_term_struct_test__cb(CORBA_Object oe_obj, + m_et* a, + m_et* b, + m_et* c, + CORBA_Environment *oe_env) +{ + m_i_term_struct_test__rs* rs = NULL; + + *a = *b; + *c = *b; + return rs; +} + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl new file mode 100644 index 0000000000..e90d0dd5f0 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_c_test.idl @@ -0,0 +1,174 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2004-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% + +#include "erlang.idl" + + +const short TestConst = 1; + +module m { + + const short TestConst = 2; + + struct b { + long l; + char c; + }; + + struct simple { + long l; + b b_t; + }; + + enum fruit {orange, banana, apple, peach, pear}; + + typedef sequence<long> lseq; + + typedef sequence<b> bseq; + + struct a { + long l; + bseq y; + double d; + }; + + typedef sequence<a> aseq; + + typedef sequence<string> sseq; + typedef string str; + typedef long myLong; + + typedef long arr1[500], dd[2][3]; + + typedef erlang::term apa; + typedef erlang::port banan; + + typedef sequence<erlang::term> etseq; + + struct s { + long l; + sequence<long> sl; + }; + + struct es { + fruit f; + myLong l; + }; + + struct et { + erlang::term e; + long l; + }; + + + typedef sequence<char> str1; + typedef string<12> str2; + typedef char str3[3]; + + typedef sequence<string> sstr3; // sequence of string + typedef sequence<sstr3> ssstr3; // sequence of sequences of strings + + typedef long arr3[3]; // array of long + typedef sequence<arr3> sarr3; // sequence of array + typedef sequence<sarr3> ssarr3; // sequence of sequnces of arrays of strings + + struct strRec{ + boolean bb; + string str4; + long str7[3][2]; + sequence<char> str5; + string<12> str6; + str3 str8; + str2 str9; + str1 str10; + }; + + + struct dyn { + long l; + sequence<long> sl; + }; + typedef dyn arr2[1][2]; + + + interface i { + + const short TestConst = 3; + + //arr2 suck(in arr2 x, out arr2 y ); + + ///////////////////////////////// attribute long l; + + // simple types + void void_test(); + long long_test(in long a, out long a1); + long long longlong_test(in long long a, out long long a1); + unsigned short ushort_test(in unsigned short a, out unsigned short a1); + unsigned long ulong_test(in unsigned long a, out unsigned long a1); + unsigned long long ulonglong_test(in unsigned long long a, out unsigned long long a1); + double double_test(in double a, out double a1); + char char_test(in char a, out char a1); + wchar wchar_test(in wchar a, out wchar a1); + octet octet_test(in octet a, out octet a1); + boolean bool_test(in boolean a, out boolean a1); + + // Seq. and struct tests + b struct_test(in b a, out b a1); + es struct2_test(in es a, out es a1); + //simple struct3_test(in simple x, out simple y); + bseq seq1_test(in bseq a, out bseq a1); + aseq seq2_test(in aseq a, out aseq a1); + lseq seq3_test(in lseq a, out lseq a1); + ssstr3 seq4_test(in ssstr3 a, out ssstr3 a1); + ssarr3 seq5_test(in ssarr3 a, out ssarr3 a1); + + // Array tests + arr1 array1_test(in arr1 a, out arr1 a1); + dd array2_test(in dd a, out dd a1); + + // enum test + fruit enum_test(in fruit a, out fruit a1); + + // string tests + string string1_test(in string a, out string a1); + wstring wstring1_test(in wstring a, out wstring a1); + sseq string2_test(in sseq a, out sseq a1); + str string3_test(in str a, out str a1); + strRec string4_test(in strRec a, out strRec a1); + + // Special erlang types + erlang::pid pid_test(in erlang::pid a, out erlang::pid a1); + erlang::port port_test(in erlang::port a, out erlang::port a1); + erlang::ref ref_test(in erlang::ref a, out erlang::ref a1); + erlang::term term_test(in erlang::term a, out erlang::term a1); + + // typedef test + long typedef_test(in apa a, in banan b, out apa a1, out banan b1); + + // inlined seq. test + s inline_sequence_test(in s a, out s a1); + + // term seq. test + etseq term_sequence_test(in etseq a, out etseq a1); + // term struct test + et term_struct_test(in et a, out et a1); + + }; + +}; diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl new file mode 100644 index 0000000000..b5ee7af199 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/erl_client.erl @@ -0,0 +1,331 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2009. 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% +%% +%% +-module(erl_client). + +-export([void_test/2, long_test/2, longlong_test/2, ushort_test/2, + ulong_test/2, ulonglong_test/2, double_test/2, char_test/2, + wchar_test/2, octet_test/2, bool_test/2, struct_test/2, + struct2_test/2, seq1_test/2, seq2_test/2, seq3_test/2, + seq4_test/2, seq5_test/2, array1_test/2, array2_test/2, + enum_test/2, string1_test/2, wstring1_test/2, string2_test/2, + string3_test/2, string4_test/2, pid_test/2, port_test/2, + ref_test/2, term_test/2, typedef_test/2, + inline_sequence_test/2, term_sequence_test/2, + term_struct_test/2 + +]). + +-include("m.hrl"). +-include("m_i.hrl"). +-include("oe_erl_c_test.hrl"). + +%%b +void_test(Node, Timeout) -> + Ret = m_i:void_test({olsson, Node}, Timeout), + Ret == void. % XXX Not documented +%%e + +%%b +long_test(Node, Timeout) -> + In = max_long(), + {Ret, Out} = m_i:long_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +longlong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:longlong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ushort_test(Node, Timeout) -> + In = max_ushort(), + {Ret, Out} = m_i:ushort_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulong_test(Node, Timeout) -> + In = max_ulong(), + {Ret, Out} = m_i:ulong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ulonglong_test(Node, Timeout) -> + In = 65537, + {Ret, Out} = m_i:ulonglong_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +double_test(Node, Timeout) -> + In = 37768.93, + {Ret, Out} = m_i:double_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +char_test(Node, Timeout) -> + In = 80, + {Ret, Out} = m_i:char_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wchar_test(Node, Timeout) -> + In = 4097, + {Ret, Out} = m_i:wchar_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +octet_test(Node, Timeout) -> + In = 255, + {Ret, Out} = m_i:octet_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +bool_test(Node, Timeout) -> + In = false, + {Ret, Out} = m_i:bool_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct_test(Node, Timeout) -> + In = #m_b{l = max_long(), c = $a}, + {Ret, Out} = m_i:struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +struct2_test(Node, Timeout) -> + In = #m_es{ f = banana, l = max_long()}, + {Ret, Out} = m_i:struct2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq1_test(Node, Timeout) -> + B1 = #m_b{l = max_long(), c = $a}, + B2 = #m_b{l = min_long(), c = $b}, + In = [B1, B2], + {Ret, Out} = m_i:seq1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq2_test(Node, Timeout) -> + B = #m_b{l = max_long(), c = $a}, + A = #m_a{l = min_long(), y = [B, B], d = 4711.31}, + In = [A, A, A], + {Ret, Out} = m_i:seq2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq3_test(Node, Timeout) -> + In = [max_long(), min_long(), max_long()], + {Ret, Out} = m_i:seq3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq4_test(Node, Timeout) -> + In = [["hej", "hopp"], ["ditt", "feta", "nylle"]], + {Ret, Out} = m_i:seq4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +seq5_test(Node, Timeout) -> + Arr3 = mk_array(3, max_long()), + In = [[Arr3, Arr3], [Arr3, Arr3, Arr3]], + {Ret, Out} = m_i:seq5_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array1_test(Node, Timeout) -> + In = mk_array(500, min_long()), + {Ret, Out} = m_i:array1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +array2_test(Node, Timeout) -> + In = mk_array(2, mk_array(3, min_long())), + {Ret, Out} = m_i:array2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +enum_test(Node, Timeout) -> + In = banana, + {Ret, Out} = m_i:enum_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string1_test(Node, Timeout) -> + In = "Die Paula muss beim Tango immer weinen", + {Ret, Out} = m_i:string1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +wstring1_test(Node, Timeout) -> + In = [1047| "ie Paula muss beim Tango immer weinen"], + {Ret, Out} = m_i:wstring1_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string2_test(Node, Timeout) -> + In = ["Lass doch die Blumen,", "Konrad!"], + {Ret, Out} = m_i:string2_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string3_test(Node, Timeout) -> + In = "Seeman, lass uns freuden!", + {Ret, Out} = m_i:string3_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +string4_test(Node, Timeout) -> + + In = #m_strRec{ + bb = true, + str4 = "Paula war zu Hause in ihrem Stadtchen als die beste Tanzerin" + "bekannt", + str7 = mk_array(3, mk_array(2, max_long())), + str5 = [$a, $b, $c, $d, $e, $f], + str6 = "123456789012", + str8 = {$x, $y, $x}, + str9 = "123456789012", + str10 = [$a, $b, $c, $d, $e, $f] + }, + {Ret, Out} = m_i:string4_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +pid_test(Node, Timeout) -> + In = self(), + {Ret, Out} = m_i:pid_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +port_test(Node, Timeout) -> + In = get(port_test_port), + {Ret, Out} = m_i:port_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +ref_test(Node, Timeout) -> + In = make_ref(), + {Ret, Out} = m_i:ref_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_test(Node, Timeout) -> + In = {[a, b], 17, kalle}, + {Ret, Out} = m_i:term_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +typedef_test(Node, Timeout) -> + In1 = {nisse, [1, 2], olsson}, + In2 = get(port_test_port), + {Ret, Out1, Out2} = m_i:typedef_test({olsson, Node}, Timeout, In1, In2), + %% XXX Should check that Ret is an integer. + (Out1 == In1) and (Out2 == In2). +%%e + +%%b +inline_sequence_test(Node, Timeout) -> + In = #m_s{l = min_long(), sl = [max_long(), min_long()]}, + {Ret, Out} = m_i:inline_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_sequence_test(Node, Timeout) -> + In = lists:duplicate(17, {nisse, [1, 2], {kalle, olsson}}), + {Ret, Out} = m_i:term_sequence_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + +%%b +term_struct_test(Node, Timeout) -> + In = #m_et{e = {nisse, ["abcde"], {kalle, olsson}}, l = 4711}, + {Ret, Out} = m_i:term_struct_test({olsson, Node}, Timeout, In), + (Ret == In) and (Out == In). +%%e + + +%% Locals + +mk_array(Es) -> + list_to_tuple(Es). + +mk_array(N, E) -> + mk_array(lists:duplicate(N, E)). + +%% max_short() -> +%% power_of_two(15) - 1. +max_long() -> + power_of_two(31) - 1. +max_longlong() -> + power_of_two(63) - 1. +max_ushort() -> + power_of_two(16) - 1. +max_ulong() -> + power_of_two(32) - 1. +max_ulonglong() -> + power_of_two(64) - 1. + +%% min_short() -> +%% -power_of_two(15). +min_long() -> + -power_of_two(31). +%% min_longlong() -> +%% -power_of_two(63). +%% min_ushort() -> +%% 0. +%% min_ulong() -> +%% 0. +%% min_ulonglong() -> +%% 0. + +power_of_two(N) -> + round(math:pow(2, N)). + diff --git a/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c new file mode 100644 index 0000000000..c0401b2621 --- /dev/null +++ b/lib/ic/test/erl_client_c_server_proto_SUITE_data/my.c @@ -0,0 +1,34 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2004-2009. 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% + * + */ +#include "ic.h" +#include "m_i.h" + +int my_prepare_request_decoding(CORBA_Environment *env) +{ + return oe_prepare_request_decoding(env); +} + +int my_prepare_reply_encoding(CORBA_Environment *env) +{ + return oe_prepare_reply_encoding(env); +} + + + diff --git a/lib/ic/test/ic.spec b/lib/ic/test/ic.spec new file mode 100644 index 0000000000..280c2aba47 --- /dev/null +++ b/lib/ic/test/ic.spec @@ -0,0 +1 @@ +{topcase, {dir, "../ic_test"}}. diff --git a/lib/ic/test/ic.spec.vxworks b/lib/ic/test/ic.spec.vxworks new file mode 100644 index 0000000000..b15260ab70 --- /dev/null +++ b/lib/ic/test/ic.spec.vxworks @@ -0,0 +1,2 @@ +{topcase, {dir, "../ic_test"}}. +{skip,{ic_pp_SUITE,"Uses gcc"}}. diff --git a/lib/ic/test/ic_SUITE.erl b/lib/ic/test/ic_SUITE.erl new file mode 100644 index 0000000000..6682c82f01 --- /dev/null +++ b/lib/ic/test/ic_SUITE.erl @@ -0,0 +1,973 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-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 : Test suite for the IDL compiler +%%%---------------------------------------------------------------------- + +-module(ic_SUITE). +-include("test_server.hrl"). + +-export([all/1]). + + +-include_lib("orber/src/orber_ifr.hrl"). +-include_lib("orber/src/ifr_objects.hrl"). +-include_lib("orber/include/ifr_types.hrl"). + + +%% The type cases +-export([type/1, type_norm/1]). + +%% The syntax case +-export([syntax/1]). +-export([syntax1/1, syntax2/1, syntax3/1, syntax4/1, syntax5/1, syntax6/1]). + +%% The constant cases +-export([const/1]). +-export([const_norm/1, const_bad_tk/1, const_bad_type/1]). +-export([const_bad_comb/1]). + +%% The union cases +-export([union/1]). +-export([union_norm/1, union_type/1, union_mult_err/1, union_case_mult/1]). +-export([union_default/1]). + +%% The enum cases +-export([enum/1]). +-export([enum_norm/1]). + +%% The struct cases +-export([struct/1]). +-export([struct_norm/1]). + +%% The oneway cases +-export([oneway/1]). +-export([oneway_norm/1, oneway_raises/1, oneway_out/1, oneway_void/1, oneway_followed/1]). + +%% The attributes cases +-export([attr/1]). +-export([attr_norm/1]). + +%% The raises registration case +-export([raises_reg/1]). + + +%% The typeID case + +%% general stuff +-export([general/1]). +-export([typeid/1, undef_id/1, dir/1, nasty_names/1, coss/1, mult_ids/1]). +-export([forward/1, include/1, app_test/1]). + +%% inheritance stuff +-export([inherit/1, inherit_norm/1, inherit_warn/1, inherit_err/1]). + +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%% Top of cases + +all(doc) -> + []; +all(suite) -> [app_test, const, union, enum, attr, type, struct, general, inherit, + oneway, syntax, raises_reg]. + + +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ok=test_server:app_test(ic), + ok. + +%%--------------------------------------------------------------------- +%% +%% Test of constant expressions. +%% + +const(suite) -> [const_norm, const_bad_tk, const_bad_type, const_bad_comb]. + + +const_norm(doc) -> + ["Checks normal constant types and values"]; +const_norm(suite) -> []; +const_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(const_norm), + File = filename:join(DataDir, c_norm), + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, const_norm_files()), + ok. + +const_bad_tk(doc) -> + ["Checks when the constant value doesn't match the declared type"]; +const_bad_tk(suite) -> []; +const_bad_tk(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err1), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(18, bad_tk_match, R), + ok. + +const_bad_type(doc) -> + ["Checks operands of ops are of correct type"]; +const_bad_type(suite) -> []; +const_bad_type(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err2), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(4, bad_type, R), + ok. + +const_bad_comb(doc) -> + ["Checks operands of ops are of conflicting types"]; +const_bad_comb(suite) -> []; +const_bad_comb(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, c_err3), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(3, bad_type_combination, R), + ok. + + + +union(suite) -> [union_norm, union_type, union_mult_err, union_case_mult, + union_default]; +union(doc) -> + ["Checks allowed usage of the union as well as the illegal cases"]. + + +union_norm(doc) -> + ["Checks that normal union declarations works."]; +union_norm(suite) -> []; +union_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(union_norm), + File = filename:join(DataDir, u_norm), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, union_norm_files()), + ok. + + +%% Checks OTP-2007 +union_default(doc) -> + ["Checks that default cases are correct in type code."]; +union_default(suite) -> []; +union_default(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(union_default), + File = filename:join(DataDir, u_default), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, union_default_files(), [load]), + TkList = i1:oe_get_interface(), + check_label("op0", 0, TkList), + check_label("op1", 1, TkList), + check_label("op2", 2, TkList), + check_label("op3", -1, TkList), + ok. + +check_label(Id, N, List) -> + case lists:keysearch(Id, 1, List) of + {value, {_, {{_, _, _, _, D, L}, _, _}}} -> + if D /= N -> + test_server:fail({bad_default_num, D, N}); + D /= -1 -> + case lists:nth(D+1, L) of + T when element(1, T) == default -> + ok; + _Que -> + test_server:fail({bad_default_list, D, L}) + end; + true -> + %% D = N = -1, just check that there is no default label + case lists:keysearch(default, 1, L) of + false -> + ok; + _ -> + test_server:fail({bad_default_label, D, L}) + end + end; + _ -> + test_server:fail({'no_such_op!', Id, List}) + end. + +union_type(doc) -> + ["Checks that errors are detected. Check that mismatch between case ", + "value and declared discriminator type is detected."]; +union_type(suite) -> []; +union_type(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_type), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(28, bad_case_type, R), + ok. + + +union_mult_err(doc) -> + ["Check that multiple declared declarators are caught.", + "Also check that if the discriminator is an enum, then the enum name", + "must not be used as a declarator in the union switch (declarator", + "as opposed to label)."]; +union_mult_err(suite) -> []; +union_mult_err(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_mult), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(8, multiply_defined, R), + ok. + +%% Checking mult cases. Now check that other errors are found in the +%% correct order XXXX + + +union_case_mult(doc) -> + ["Check that multiply defined case labels are found and reported."]; +union_case_mult(suite) -> []; +union_case_mult(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, u_case_mult), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(7, multiple_cases, R), + ok. + + +%%-------------------------------------------------------------------- +%% +%% Enum cases +%% + +enum(suite) -> [enum_norm]; +enum(doc) -> + ["Checks allowed usage of the enum as well as the illegal cases"]. + +enum_norm(doc) -> + ["Checks that normal enum declarations works."]; +enum_norm(suite) -> []; +enum_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(enum_norm), + File = filename:join(DataDir, enum), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, enum_norm_files()), + ok. + + +%%-------------------------------------------------------------------- +%% +%% Struct cases +%% + +struct(suite) -> [struct_norm]; +struct(doc) -> + ["Checks allowed usage of the struct as well as the illegal cases"]. + +struct_norm(doc) -> + ["Checks that normal struct declarations works."]; +struct_norm(suite) -> []; +struct_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(struct_norm), + File = filename:join(DataDir, struct), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, struct_norm_files()), + Mod = ridiculous_name_to_avoid_clash_svenne, + TestFile = filename:join(OutDir, Mod), + ?line ok = gen_struct_file(TestFile, Mod), + ?line ok = compile(OutDir, [Mod], [load]), +%% ?line {ok, Mod, []} = compile:file(TestFile, +%% [{i, OutDir}, {outdir, OutDir}, +%% return, load]), + ?line ok = Mod:test(), + ok. + + +%%-------------------------------------------------------------------- +%% +%% General cases +%% + +general(doc) -> + ["Check general things like directories and type identifier", + "detection."]; +general(suite) -> [typeid, undef_id, mult_ids, forward, include, nasty_names]. +%% coss (add sometimes, takes 440 seconds!) + +typeid(doc) -> + ["Check that type id's are generated correctly"]; +typeid(suite) -> []; +typeid(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(typeid), + File = filename:join(DataDir, typeid), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, typeid_files(), [load]), + ?line "IDL:I1:1.0" = 'I1':'typeID'(), + ?line "IDL:M1/I1:1.0" = 'M1_I1':'typeID'(), + ?line "IDL:M2/M1/I1:1.0" = 'M2_M1_I1':'typeID'(), + ?line "IDL:M3/M2/M1/I1:1.0" = 'M3_M2_M1_I1':'typeID'(), + ok. + + +%%% This test case is removed because there's no way to test this from +%%% an automated test suite. +dir(doc) -> + ["Check that relative directories work, absolute is used in", + "all other cases in the suite."]; +%%% xxxxxx +dir(suite) -> []; +dir(Config) when is_list(Config) -> +ok; +dir(Config) -> + DataDir = ?config(data_dir, Config), + + %% Needs a unique directory (any better way?) + OutDir = mk_unique("oe_the_dir"), + + %% More unique names + File = filename:join(DataDir, mk_unique("oe_the_file")), + Const = mk_unique("oe_the_constant"), + Mod = list_to_atom(File), + Func = list_to_atom(Const), + + %% Generate a unique IDL file with a single constant + gen_file(File, Const), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, [load]), + ?line 19955 = Mod:Func(), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, [load]), + ?line 19955 = Mod:Func(), + + ?line ok = ic:gen(File), +%%% ?line ok = compile(".", [load]), + ok. + +undef_id(doc) -> + ["Check that various undefied id's are detected correctly"]; +undef_id(suite) -> []; +undef_id(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, undef_id), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(16, tk_not_found, R), + ok. + +mult_ids(doc) -> + ["Check that multiply defined ids are caught."]; +mult_ids(suite) -> []; +mult_ids(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, mult_ids), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(22, multiply_defined, R), + ok. + + +nasty_names(doc) -> + ["Check that various nasty names can be generated.", + "Try to provoke name clashes and name conflicts with", + "Erlang and IDL"]; +nasty_names(suite) -> []; +nasty_names(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(nasty_names), + File = filename:join(DataDir, nasty), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, nasty_names_files(), [load]), + ok. + +coss(doc) -> + ["Check that the Coss standard specification works."]; +coss(suite) -> []; +coss(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(coss), + File = filename:join(DataDir, 'Coss'), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, [_W1]} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, []), + ok. + +forward(doc) -> + ["Check that forward declaratios work."]; +forward(suite) -> []; +forward(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(forward), + File = filename:join(DataDir, forward), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, forward_files(), [load]), + ok. + +include(doc) -> + ["Check that various undefied id's are detected correctly"]; +include(suite) -> []; +include(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, include), + ?line error = ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir}]), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[{preproc_flags,"-I" ++ DataDir},silent2]), + case lists:map(fun(D) -> + filename:rootname(filename:basename(element(3, D))) + end, + lists:sort(R)) of + ["include", + "include2", + "include2", + "include3"] -> + ok; + RRR -> + test_server:fail({bad_include_file, RRR}) + end, + ok. + + + + +%%-------------------------------------------------------------------- +%% +%% Inhertit cases +%% + +inherit(doc) -> + ["Check the inheritance mechanism."]; +inherit(suite) -> [inherit_norm, inherit_warn, inherit_err]. + +inherit_norm(doc) -> + ["Checks that normal inheritance works."]; +inherit_norm(suite) -> []; +inherit_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(inherit_norm), + File = filename:join(DataDir, inherit), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, _Ws} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, inherit_norm_files(), [load]), + + %% Now check constant values: + ?line 9 = m1_I1:c1(), + + ?line 9 = m1_I2:c1(), + ?line 14 = m1_I2:c2(), + ?line 27 = m1_I2:c3(), + + ?line 50 = m1_I3:c1(), + ?line 14 = m1_I3:c2(), + ?line 27 = m1_I3:c3(), + ?line 91 = m1_I3:c4(), + ?line 100 = m1_I3:c5(), + ok. + +inherit_warn(doc) -> + ["Check that various inheritance shadowing is detected"]; +inherit_warn(suite) -> []; +inherit_warn(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, inherit_warn), + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(7, inherit_name_shadow, R), + ok. + +inherit_err(doc) -> + ["Check that various inheritance errors is detected"]; +inherit_err(suite) -> []; +inherit_err(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, inherit_err), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, _Ws, R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(21, inherit_name_collision, R), + ok. + + +oneway(doc) -> + ["Check the oneway operation mechanism."]; +oneway(suite) -> [oneway_norm, oneway_out, oneway_raises, oneway_void, oneway_followed ]. + +oneway_norm(doc) -> + ["Checks that normal oneway operations works."]; +oneway_norm(suite) -> []; +oneway_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(oneway_norm), + File = filename:join(DataDir, one), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, oneway_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, oneway_norm_files(), [load]), + ok. + +oneway_void(doc) -> + ["Check that non-void oneways are detected."]; +oneway_void(suite) -> []; +oneway_void(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_void), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(2, bad_oneway_type, R), + ok. + +oneway_raises(doc) -> + ["Check that oneways cannot raise exceptions."]; +oneway_raises(suite) -> []; +oneway_raises(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_raises), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(3, oneway_raises, R), + ok. + +oneway_out(doc) -> + ["Check that illegal out parameters are detected"]; +oneway_out(suite) -> []; +oneway_out(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, one_out), + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(2, oneway_outparams, R), + ok. + +oneway_followed(doc) -> + ["Checks that normal oneways, followed by other operations."]; +oneway_followed(suite) -> []; +oneway_followed(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(oneway_followed), + File = filename:join(DataDir, one_followed), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, oneway_followed_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, oneway_followed_files(), [load]), + ok. + +attr(doc) -> + ["Check that attributes work."]; +attr(suite) -> [attr_norm]. + +attr_norm(doc) -> + ["Checks that normal attr operations works."]; +attr_norm(suite) -> []; +attr_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(attr_norm), + File = filename:join(DataDir, attr), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, attr_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, attr_norm_files(), [load]), + ok. + +type(doc) -> + ["Check that typeibutes work."]; +type(suite) -> [type_norm]. + +type_norm(doc) -> + ["Checks all types are handled."]; +type_norm(suite) -> []; +type_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(type_norm), + File = filename:join(DataDir, type), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line ok = compile(OutDir, type_norm_files(), [load]), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, type_norm_files(), [load]), + ok. + + +syntax(doc) -> + ["Check that syntax errors are discovered."]; +syntax(suite) -> [syntax1, syntax2, syntax3, syntax4, syntax5, syntax6]. + +syntax1(suite) -> []; +syntax1(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax1), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax2(suite) -> []; +syntax2(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax2), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax3(suite) -> []; +syntax3(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax3), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax4(suite) -> []; +syntax4(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax4), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax5(suite) -> []; +syntax5(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax5), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + +syntax6(suite) -> []; +syntax6(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, syntax6), + + ?line error = ic:gen(File, stdopts(OutDir)), + ?line {error, [], R} = + ic:gen(File, stdopts(OutDir)++[silent2]), + check_errors(1, parse_error, R), + ok. + + + +%%-------------------------------------------------------------------- +%% +%% Checks RAISES to be registered under IFR operation registration +%% ( OTP-2102 ) +%% + +raises_reg(doc) -> + ["Check that exceptions are really registered to operations."]; +raises_reg(suite) -> []; +raises_reg(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(raises_reg_check), + File = filename:join(DataDir, raises_reg), + + ?line ok = ic:gen(File, stdopts(OutDir)), + ?line {ok, []} = ic:gen(File, stdopts(OutDir)++[silent2]), + ?line ok = compile(OutDir, raises_reg_files(), [load]), + + set_up('oe_raises_reg'), + + io:format("~n##### Starting the test case #####~n"), + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_1:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_1:1.0"), + + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/Exception_2:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:Raises_RegModule/Exception_2:1.0"), + + io:format("Checking for existance of exception : ~s~n",["IDL:Raises_RegModule/XXXXXXXX:1.0"]), + raises_register_check("IDL:Raises_RegModule/R_R/op:1.0","IDL:RaisesModule/XXXXXXXX:1.0"), + + set_down('oe_raises_reg'), + + ok. + +set_up(Register) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + io:format("Running OE_register()~n"), + Register:'oe_register'(). + +set_down(Register) -> + io:format("Running OE_unregister()~n"), + Register:'oe_unregister'(), + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]). + + +raises_register_check(OpId,ExcId) -> + case is_valid_exc(OpId,ExcId) of + true -> + ok; % Because right exception where found, + % the test succeeds for normal cases. + false -> + ok; % Because the exception tested, is not + % registered for that operation. + FailReason -> + test_server:fail({FailReason, OpId, ExcId}) + % Because the test descovered errors in a previous + % stage, or no exceptions where registered att all. + % ( This testcase assumes that operations to be + % checked allways raise excption(s) ) + end. + +is_valid_exc(OpId,ExcId) -> + OE_IFR = orber_ifr:find_repository(), + OpDef = orber_ifr:'Repository_lookup_id'(OE_IFR,OpId), + ExcDefList = orber_ifr:get_exceptions(OpDef), + case ExcDefList of + [] -> + no_exceptions_registered; + _ -> + ExcDef=orber_ifr:lookup_id(OE_IFR,ExcId), + lists:member(ExcDef,ExcDefList) + end. + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +stdopts(OutDir) -> + [{outdir, OutDir},{maxerrs, infinity}]. + +mk_unique(Prefix) -> + {A,B,C} = now(), + Prefix++"_"++integer_to_list(A)++"_"++integer_to_list(B)++"_"++ + integer_to_list(C). + +gen_file(File, Const) -> + {ok, Fd} = file:open(File++".idl", [write]), + io:format(Fd, "interface ~s {~n", [File]), + io:format(Fd, " const long ~s = 19955;~n", [Const]), + io:format(Fd, "};~n", []), + file:close(Fd). + + +%% Compile all files in Dir. Used for checking that valid Erlang has +%% been generated. +%%compile(Dir) -> +%% compile(Dir, []). +%%compile(Dir, Opts) -> +%% {ok, Cwd} = file:get_cwd(), +%% catch do_compile(Dir, Opts), +%% file:set_cwd(Cwd). + +%%do_compile(Dir, Opts) -> +%% ok = file:set_cwd(Dir), +%% up_to_date = ts_make_erl:all(Opts), +%% ok. + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +%% Check that ErrList consists of exactly Num errors of type ErrType +check_errors(Num, ErrType, ErrList) -> + Num = length(ErrList), + lists:foreach(fun(T) -> + case catch element(1, element(4, T)) of + ErrType -> ok; + Else -> + test_server:fail({bad, ErrType, Else}) + end end, ErrList). + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + +%% File must be an atom +gen_struct_file(File, Mod) -> + + ?line {ok, Fd} = file:open(to_list(File)++".erl", [write]), + io:format(Fd, "~n", []), + io:format(Fd, "-module(~p).~n", [Mod]), + io:format(Fd, "-export([test/0]).~n", []), + io:format(Fd, "-include(\"oe_struct.hrl\").~n", []), + io:format(Fd, "test() ->~n", []), + io:format(Fd, " A = #'S1'{a=99, b=$a, s=\"123456789\"},~n", []), + io:format(Fd, " B = #'S2'{a=9, b=#'S2_S3'{a=1, b=9, b1=5, c=$2},~n", []), + io:format(Fd, " c=[#'S1'{a=1}, #'S1'{a=2}],~n", []), + io:format(Fd, +" c2=[#'S1'{a=2}, #'S1'{a=3}, #'S1'{a=2}, #'S1'{a=3}]},~n", []), + io:format(Fd, " C = #'S2_S3'{a=11, b=999, b1=19},~n", []), + io:format(Fd, " D = #s4{a=7},~n", []), + io:format(Fd, " E = {1, #'U1_S5'{a=3}},~n", []), + io:format(Fd, " F = {2, {$b, #'U1_U2_s6'{a=6, b=false}}},~n", []), + io:format(Fd, " ok.~n", []), + file:close(Fd). + + +union_norm_files() -> ['oe_u_norm']. +union_default_files() -> ['oe_u_default', i1]. + +typeid_files() -> ['oe_typeid', 'M3_M2_M1_I1', 'M2_M1_I1', 'M1_I1', 'I1']. + +struct_norm_files() -> ['oe_struct']. +oneway_norm_files() -> ['oe_one', 'I1']. +oneway_followed_files() -> ['oe_one_followed', 'I1']. +nasty_names_files() -> ['oe_nasty', 'I2', 'I1']. + +inherit_norm_files() -> [m1_I3, m1_I2, m1_I1, 'oe_inherit', 'I4', 'I3', + 'I2', 'I1']. + +forward_files() -> [i1, 'oe_forward']. +enum_norm_files() -> ['oe_enum']. +const_norm_files() -> ['oe_c_norm']. +attr_norm_files() -> ['oe_attr', 'I1', 'I2']. +type_norm_files() -> ['oe_type']. + +raises_reg_files() -> ['oe_raises_reg']. + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/Corba.idl b/lib/ic/test/ic_SUITE_data/Corba.idl new file mode 100644 index 0000000000..6b81132500 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/Corba.idl @@ -0,0 +1,1013 @@ +// This file contains OMG IDL from CORBA V2.0, July 1995. +// Includes IDL for CORBA Core +// (Interface Repository, ORB Interface, Basic Object Adapter Interface) +// and CORBA Interoperability (IOP, GIOP, IIOP, and DCE CIOP modules) + +// Complete OMG IDL for Interface Repository starts on pg 6-42, CORBA V2.0 July 1995 +// IRObject interface described on pg 6-9 CORBA V2.0, July 1995 +// Contained interface: pg 6-11 CORBA V2, 7-95 +// Container interface: pg 6-12 thru 6-15 CORBA V2, 7-95 +// IDLType interface: pg 6-15 CORBA V2, 7-95 +// Repository interface: pg 6-16 CORBA V2, 7-95 +// ModuleDef interface: pg 6-17 CORBA V2, 7-95 +// ConstantDef interface: pg 6-18 CORBA V2, 7-95 +// TypeDef interface: pg 6-19 CORBA V2, 7-95 +// StructDef interface: pg 6-19 CORBA V2, 7-95 +// UnionDef interface: pg 6-19 CORBA V2, 7-95 +// EnumDef interface: pg 6-20 CORBA V2, 7-95 +// AliasDef interface: pg 6-21 CORBA V2, 7-95 +// PrimitiveDef interface: pg 6-21 CORBA V2, 7-95 +// StringDef interface: pg 6-22 CORBA V2, 7-95 +// SequenceDef interface: pg 6-22 CORBA V2, 7-95 +// ArrayDef interface: pg 6-23 CORBA V2, 7-95 +// ExceptionDef interface: pg 6-24 CORBA V2, 7-95 +// AttributeDef interface: pg 6-25 CORBA V2, 7-95 +// OperationDef interface: pg 6-26 CORBA V2, 7-95 +// InterfaceDef interface: pg 6-28 CORBA V2, 7-95 +// TypeCode interface (PIDL): pg 6-34 CORBA V2, 7-95 +// ORB interface: pg 6-40 CORBA V2, 7-95 + +#ifndef __CORBA_IDL +#define __CORBA_IDL + +// #pragma prefix "omg.org" +module CORBA { + + interface TypeCode; + typedef string Identifier; + typedef string ScopedName; + typedef string RepositoryId; + + /* + * start of section added by Christian Blum + */ + + typedef enum new_type {NO,USER,SYSTEM_EXCEPTION} exception_type; + + /** + * no definition for this type + */ + interface ImplementationDef + { + }; + + /** + * no definition for this type + */ + //interface Principal + struct Principal + { + string str; + }; + + /** + * no definition for this type + */ + interface Environment + { + + }; + + typedef unsigned long Flags; + typedef unsigned long Status; + + struct NamedValue // PIDL + { + Identifier name; // argument name + any argument; // argument + long len; // length/count of argument value + Flags arg_modes; // argument mode flags + + }; + + typedef sequence<NamedValue> NVList; /* C */ + + interface Request // PIDL + { + + Status add_arg ( + in Identifier name, // argument name + in TypeCode arg_type, // argument datatype + // in void * value, // argument value to be added + in any value_LOOK_AT_SOURCE, // changed by blum + in long len, // length/count of argument value + in Flags arg_flags // argument flags + ); + + Status invoke ( + in Flags invoke_flags // invocation flags + ); + + Status delete (); + Status send ( + in Flags invoke_flags // invocation flags + ); + + Status get_response ( + in Flags response_flags // response flags + ); + + }; + + + interface Context // PIDL + { + + Status set_one_value ( + in Identifier prop_name, // property name to add + in string value // property value to add + ); + + Status set_values ( + in NVList values // property values to be changed + ); + + Status get_values ( + in Identifier start_scope, // search scope + in Flags op_flags, // operation flags + in Identifier prop_name, // name of property(s) to retrieve + out NVList values // requested property(s) + ); + + Status delete_values ( + in Identifier prop_name // name of property(s) to delete + ); + + Status create_child ( + in Identifier ctx_name, // name of context object + out Context child_ctx // newly created context object + ); + + Status delete ( + in Flags del_flags // flags controlling deletion + ); + + }; + + /* + * end of section added by Christian Blum + */ + + + enum DefinitionKind { + dk_none, dk_all, + dk_Attribute, dk_Constant, dk_Exception, dk_Interface, + dk_Module, dk_Operation, dk_Typedef, + dk_Alias, dk_Struct, dk_Union, dk_Enum, + dk_Primitive, dk_String, dk_Sequence, dk_Array, + dk_Repository + }; + + + interface IRObject { + // read interface + readonly attribute DefinitionKind def_kind; + + // write interface + void destroy (); + }; + + + + typedef string VersionSpec; + + interface Contained; + interface Repository; + interface Container; + + interface Contained : IRObject { + // read/write interface + + attribute RepositoryId id; + attribute Identifier name; + attribute VersionSpec version; + + // read interface + + readonly attribute Container defined_in; + readonly attribute ScopedName absolute_name; + readonly attribute Repository containing_repository; + + struct Description { + DefinitionKind kind; + any value; + }; + + Description describe (); + + // write interface + + void move ( + in Container new_container, + in Identifier new_name, + in VersionSpec new_version + ); + }; + + + interface ModuleDef; + interface ConstantDef; + interface IDLType; + interface StructDef; + interface UnionDef; + interface EnumDef; + interface AliasDef; + interface InterfaceDef; + typedef sequence <InterfaceDef> InterfaceDefSeq; + + typedef sequence <Contained> ContainedSeq; + + struct StructMember { + Identifier name; + TypeCode type; + IDLType type_def; + }; + typedef sequence <StructMember> StructMemberSeq; + + struct UnionMember { + Identifier name; + any label; + TypeCode type; + IDLType type_def; + }; + typedef sequence <UnionMember> UnionMemberSeq; + + typedef sequence <Identifier> EnumMemberSeq; + + interface Container : IRObject { + // read interface + + Contained lookup ( in ScopedName search_name); + + ContainedSeq contents ( + in DefinitionKind limit_type, + in boolean exclude_inherited + ); + + ContainedSeq lookup_name ( + in Identifier search_name, + in long levels_to_search, + in DefinitionKind limit_type, + in boolean exclude_inherited + ); + + struct Description { + Contained contained_object; + DefinitionKind kind; + any value; + }; + + typedef sequence<Description> DescriptionSeq; + + DescriptionSeq describe_contents ( + in DefinitionKind limit_type, + in boolean exclude_inherited, + in long max_returned_objs + ); + + // write interface + + ModuleDef create_module ( + in RepositoryId id, + in Identifier name, + in VersionSpec version + ); + + ConstantDef create_constant ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType type, + in any value + ); + + StructDef create_struct ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in StructMemberSeq members + ); + + UnionDef create_union ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType discriminator_type, + in UnionMemberSeq members + ); + + EnumDef create_enum ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in EnumMemberSeq members + ); + + AliasDef create_alias ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType original_type + ); + + InterfaceDef create_interface ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in InterfaceDefSeq base_interfaces + ); + }; + + + + interface IDLType : IRObject { + readonly attribute TypeCode type; + }; + + + + interface PrimitiveDef; + interface StringDef; + interface SequenceDef; + interface ArrayDef; + + enum PrimitiveKind { + pk_null, pk_void, pk_short, pk_long, pk_ushort, pk_ulong, + pk_float, pk_double, pk_boolean, pk_char, pk_octet, + pk_any, pk_TypeCode, pk_Principal, pk_string, pk_objref + }; + + interface Repository : Container { + // read interface + + Contained lookup_id (in RepositoryId search_id); + + PrimitiveDef get_primitive (in PrimitiveKind kind); + + // write interface + + StringDef create_string (in unsigned long bound); + + SequenceDef create_sequence ( + in unsigned long bound, + in IDLType element_type + ); + + ArrayDef create_array ( + in unsigned long length, + in IDLType element_type + ); + }; + + + interface ModuleDef : Container, Contained { + }; + + struct ModuleDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + }; + + + interface ConstantDef : Contained { + readonly attribute TypeCode type; + attribute IDLType type_def; + attribute any value; + }; + + struct ConstantDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + any value; + }; + + + interface TypedefDef : Contained, IDLType { + }; + + struct TypeDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + }; + + + interface StructDef : TypedefDef { + attribute StructMemberSeq members; + }; + + + interface UnionDef : TypedefDef { + readonly attribute TypeCode discriminator_type; + attribute IDLType discriminator_type_def; + attribute UnionMemberSeq members; + }; + + + interface EnumDef : TypedefDef { + attribute EnumMemberSeq members; + }; + + + interface AliasDef : TypedefDef { + attribute IDLType original_type_def; + }; + + + interface PrimitiveDef: IDLType { + readonly attribute PrimitiveKind kind; + }; + + + interface StringDef : IDLType { + attribute unsigned long bound; + }; + + + interface SequenceDef : IDLType { + attribute unsigned long bound; + readonly attribute TypeCode element_type; + attribute IDLType element_type_def; + }; + + interface ArrayDef : IDLType { + attribute unsigned long length; + readonly attribute TypeCode element_type; + attribute IDLType element_type_def; + }; + + + interface ExceptionDef : Contained { + readonly attribute TypeCode type; + attribute StructMemberSeq members; + }; + struct ExceptionDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + }; + + + + enum AttributeMode {ATTR_NORMAL, ATTR_READONLY}; + + interface AttributeDef : Contained { + readonly attribute TypeCode type; + attribute IDLType type_def; + attribute AttributeMode mode; + }; + + struct AttributeDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode type; + AttributeMode mode; + }; + + + + enum OperationMode {OP_NORMAL, OP_ONEWAY}; + + enum ParameterMode {PARAM_IN, PARAM_OUT, PARAM_INOUT}; + struct ParameterDescription { + Identifier name; + TypeCode type; + IDLType type_def; + ParameterMode mode; + }; + typedef sequence <ParameterDescription> ParDescriptionSeq; + + typedef Identifier ContextIdentifier; + typedef sequence <ContextIdentifier> ContextIdSeq; + + typedef sequence <ExceptionDef> ExceptionDefSeq; + typedef sequence <ExceptionDescription> ExcDescriptionSeq; + + interface OperationDef : Contained { + readonly attribute TypeCode result; + attribute IDLType result_def; + attribute ParDescriptionSeq params; + attribute OperationMode mode; + attribute ContextIdSeq contexts; + attribute ExceptionDefSeq exceptions; + }; + + struct OperationDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + TypeCode result; + OperationMode mode; + ContextIdSeq contexts; + ParDescriptionSeq parameters; + ExcDescriptionSeq exceptions; + }; + + + + typedef sequence <RepositoryId> RepositoryIdSeq; + typedef sequence <OperationDescription> OpDescriptionSeq; + typedef sequence <AttributeDescription> AttrDescriptionSeq; + + interface InterfaceDef : Container, Contained, IDLType { + // read/write interface + + attribute InterfaceDefSeq base_interfaces; + + // read interface + + boolean is_a (in RepositoryId interface_id); + + struct FullInterfaceDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + OpDescriptionSeq operations; + AttrDescriptionSeq attributes; + RepositoryIdSeq base_interfaces; + TypeCode type; + }; + + FullInterfaceDescription describe_interface(); + + // write interface + + AttributeDef create_attribute ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType type, + in AttributeMode mode + ); + + OperationDef create_operation ( + in RepositoryId id, + in Identifier name, + in VersionSpec version, + in IDLType result, + in OperationMode mode, + in ParDescriptionSeq params, + in ExceptionDefSeq exceptions, + in ContextIdSeq contexts + ); + }; + + struct InterfaceDescription { + Identifier name; + RepositoryId id; + RepositoryId defined_in; + VersionSpec version; + RepositoryIdSeq base_interfaces; + }; + + + + enum TCKind { + tk_null, tk_void, + tk_short, tk_long, tk_ushort, tk_ulong, + tk_float, tk_double, tk_boolean, tk_char, + tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref, + tk_struct, tk_union, tk_enum, tk_string, + tk_sequence, tk_array, tk_alias, tk_except + }; + + interface TypeCode { // PIDL + exception Bounds {}; + exception BadKind {}; + + // for all TypeCode kinds + boolean equal (in TypeCode tc); + TCKind kind (); + + // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except + RepositoryId id () raises (BadKind); + + // for tk_objref, tk_struct, tk_union, tk_enum, tk_alias, and tk_except + Identifier name () raises (BadKind); + + // for tk_struct, tk_union, tk_enum, and tk_except + unsigned long member_count () raises (BadKind); + Identifier member_name (in unsigned long index) raises (BadKind, Bounds); + + // for tk_struct, tk_union, and tk_except + TypeCode member_type (in unsigned long index) raises (BadKind, Bounds); + + // for tk_union + any member_label (in unsigned long index) raises (BadKind, Bounds); + TypeCode discriminator_type () raises (BadKind); + long default_index () raises (BadKind); + + // for tk_string, tk_sequence, and tk_array + unsigned long length () raises (BadKind); + + // for tk_sequence, tk_array, and tk_alias + TypeCode content_type () raises (BadKind); + + // deprecated interface + long param_count (); + any parameter (in long index) raises (Bounds); + }; + + + /* + * following line added by Christian Blum + */ + interface BOA; + + interface ORB { + // other operations ... + + TypeCode create_struct_tc ( + in RepositoryId id, + in Identifier name, + in StructMemberSeq members + ); + + TypeCode create_union_tc ( + in RepositoryId id, + in Identifier name, + in TypeCode discriminator_type, + in UnionMemberSeq members + ); + + TypeCode create_enum_tc ( + in RepositoryId id, + in Identifier name, + in EnumMemberSeq members + ); + + TypeCode create_alias_tc ( + in RepositoryId id, + in Identifier name, + in TypeCode original_type + ); + + TypeCode create_exception_tc ( + in RepositoryId id, + in Identifier name, + in StructMemberSeq members + ); + + TypeCode create_interface_tc ( + in RepositoryId id, + in Identifier name + ); + + TypeCode create_string_tc ( + in unsigned long bound + ); + + TypeCode create_sequence_tc ( + in unsigned long bound, + in TypeCode element_type + ); + + TypeCode create_recursive_sequence_tc ( + in unsigned long bound, + in unsigned long offset + ); + + TypeCode create_array_tc ( + in unsigned long length, + in TypeCode element_type + ); + + /* + * following line commented out by Christian Blum + */ + // }; + + // The ORB interface (PIDL) is described in Chapter 7, CORBA V2.0 July 1995 + // Object interface (object reference operations): pg 7-3 CORBA V2, 7-95 + // ORB initialization: pg 7-7 CORBA V2, 7-95 + // Object Adapter and Basic Object Adapter initialization: pg 7-8 CORBA V2 7-95 + // Getting initial references: pg 7-10 CORBA V2 7-95 + //PIDL + + /* + * following line commented out by Christian Blum + */ + //interface ORB { + + + string object_to_string (in Object obj); + Object string_to_object (in string str); + + Status create_list ( + in long count, + out NVList new_list + ); + Status create_operation_list ( + in OperationDef oper, + out NVList new_list + ); + Status get_default_context (out Context ctx); + + // Initializing the ORB + typedef string ORBid; + typedef sequence <string> arg_list; + ORB ORB_init (inout arg_list argv, in ORBid orb_identifier); + + // Initializing an object adapter and the Basic Object Adapter + typedef string OAid; + + // Template for OA initialization operations + // <OA> <OA>_init (inout arg_list argv, + // in OAid oa_identifier); + + + + BOA BOA_init (inout arg_list argv, + in OAid boa_identifier); + + + + // Getting initial object references + typedef string ObjectId; + typedef sequence <ObjectId> ObjectIdList; + + exception InvalidName {}; + + ObjectIdList list_initial_services (); + + Object resolve_initial_references (in ObjectId identifier) + raises (InvalidName); + }; + + // had to be changed..., Gerald Brose 1996 + interface ORBject { + + ImplementationDef get_implementation (); + InterfaceDef get_interface (); + boolean is_nil(); + Object duplicate (); + void release (); + boolean is_a (in string logical_type_id); + boolean non_existent(); + boolean is_equivalent (in Object other_object); + unsigned long hash(in unsigned long maximum); + + + Status create_request ( + in Context ctx, + in Identifier operation, + in NVList arg_list, + inout NamedValue result, + out Request request, + in Flags req_flags + ); + }; + + + // Basic Object Adapter interface described in Chapter 8, CORBA V2.0, July 1995 + // interface InterfaceDef; // from Interface Repository // PIDL + // interface ImplementationDef; // from Implementation Repository + // interface Object; // an object reference + // interface Principal; // for the authentication service + typedef sequence <octet, 1024> ReferenceData; + + interface BOA { + Object create ( + in ReferenceData id, + in InterfaceDef intf, + in ImplementationDef impl + ); + void dispose (in Object obj); + ReferenceData get_id (in Object obj); + + void change_implementation (in Object obj, + in ImplementationDef impl + ); + + Principal get_principal (in Object obj, + in Environment ev + ); + + void set_exception (in exception_type major, // NO, USER, + //or SYSTEM_EXCEPTION + in string userid, // exception type id + in any param_LOOK_AT_SOURCE + // in void *param // pointer to associated data + ); + + void impl_is_ready (in ImplementationDef impl); + void deactivate_impl (in ImplementationDef impl); + void obj_is_ready (in Object obj, in ImplementationDef impl); + void deactivate_obj (in Object obj); + }; +}; + +// IOP module described in chap 10 CORBA V2, 7-95 +module IOP{ // IDL + // + // Standard Protocol Profile tag values + // + typedef unsigned long ProfileId; + const ProfileId TAG_INTERNET_IOP = 0; + const ProfileId TAG_MULTIPLE_COMPONENTS = 1; + + struct TaggedProfile { + ProfileId tag; + sequence <octet> profile_data; + }; + + // + // an Interoperable Object Reference is a sequence of + // object-specific protocol profiles, plus a type ID. + // + struct IOR { + string type_id; + sequence <TaggedProfile> profiles; + }; + + // + // Standard way of representing multicomponent profiles. + // This would be encapsulated in a TaggedProfile. + // + typedef unsigned long ComponentId; + struct TaggedComponent { + ComponentId tag; + sequence <octet> component_data; + }; + typedef sequence <TaggedComponent> MultipleComponentProfile; + + + typedef unsigned long ServiceID; + + struct ServiceContext { + ServiceID context_id; + sequence <octet> context_data; + }; + typedef sequence <ServiceContext> ServiceContextList; + + const ServiceID TransactionService = 0; + + + +}; +// GIOP module described in CORBA V2, 7-95 chap 12 +// Complete IDL for GIOP module in CORBA +// V2.0, 7-95 p 10-29 +// GIOP message header: CORBA V2, 7-95 p 12-16 +// GIOP request header: CORBA V2, 7-95 p 12-17 +// GIOP reply header: CORBA V2, 7-95 p 12-19 +// GIOP cancel request and locate request: CORBA V2, 7-95 pp 12-20 -- 12-21 +// GIOP locate reply: CORBA V2, 7-95 p 12-22 +module GIOP { // IDL + enum MsgType { + Request, Reply, CancelRequest, + LocateRequest, LocateReply, + CloseConnection, MessageError + }; + + struct Version { + char major; + char minor; + }; + + struct MessageHeader { + char magic [4]; + Version GIOP_version; + boolean byte_order; + octet message_type; + unsigned long message_size; + }; + + struct RequestHeader { + ::IOP::ServiceContextList service_context; + unsigned long request_id; + boolean response_expected; + sequence <octet> object_key; + string operation; + + /* + * ::CORBA:: added for correct scope + */ + ::CORBA::Principal requesting_principal; + }; + + enum ReplyStatusType { + NO_EXCEPTION, + USER_EXCEPTION, + SYSTEM_EXCEPTION, + LOCATION_FORWARD + }; + + struct ReplyHeader { + ::IOP::ServiceContextList service_context; + unsigned long request_id; + ReplyStatusType reply_status; + }; + + struct CancelRequestHeader { + unsigned long request_id; + }; + + struct LocateRequestHeader { + unsigned long request_id; + sequence <octet> object_key; + }; + + enum LocateStatusType { + UNKNOWN_OBJECT, + OBJECT_HERE, + OBJECT_FORWARD + }; + + struct LocateReplyHeader { + unsigned long request_id; + LocateStatusType locate_status; + }; +}; +// IIOP module described in CORBA V2, 7-95 chap 12 +// Complete IDL for IIOP module: CORBA V2, 7-95 p 12-31 +module IIOP { // IDL + struct Version { + char major; + char minor; + }; + + struct ProfileBody { + Version iiop_version; + string host; + unsigned short port; + sequence <octet> object_key; + }; +}; +// DCE CIOP module described in CORBA V2, 7-95 chap 13 +// IDL for DCE CIOP module: CORBA V2, 7-95 p 13-2 +module DCE_CIOP { + struct InvokeRequestHeader { + boolean byte_order; + ::IOP::ServiceContextList service_context; + sequence <octet> object_key; + string endpoint_id; + string operation; + ::CORBA::Principal principal; + sequence <string> client_context; + + // in and inout parameters follow + }; + enum InvokeResponseStatus { + INVOKE_NO_EXCEPTION, + INVOKE_USER_EXCEPTION, + INVOKE_SYSTEM_EXCEPTION, + INVOKE_LOCATION_FORWARD, + INVOKE_TRY_AGAIN + }; + + struct InvokeResponseHeader { + boolean byte_order; + ::IOP::ServiceContextList service_context; + InvokeResponseStatus status; + + // if status = INVOKE_NO_EXCEPTION, + // result then inouts and outs follow + + // if status = INVOKE_USER_EXCEPTION or + // INVOKE_SYSTEM_EXCEPTION, an exception follows + + // if status = INVOKE_LOCATION_FORWARD, an + // ::IOP::MultipleComponentsProfile follows + }; + + struct LocateRequestHeader { + boolean byte_order; + sequence <octet> object_key; + string endpoint_id; + string operation; + + // no body follows + }; + + module IOP { + + /* + * ::IOP:: added to get the right scope + */ + const ::IOP::ComponentId TAG_OBJECT_KEY = 10; + const ::IOP::ComponentId TAG_ENDPOINT_ID = 11; + const ::IOP::ComponentId TAG_LOCATION_POLICY = 12; + // illegal IDL + /* const octet LOCATE_NEVER = 0; + const octet LOCATE_OBJECT = 1; + const octet LOCATE_OPERATION = 2; + const octet LOCATE_ALWAYS = 3; + */ + }; +}; + +#endif diff --git a/lib/ic/test/ic_SUITE_data/Coss.idl b/lib/ic/test/ic_SUITE_data/Coss.idl new file mode 100644 index 0000000000..c84d4a8247 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/Coss.idl @@ -0,0 +1,1537 @@ +// This file contains OMG IDL and PIDL for the Common Object Services. +// CosNaming Module, p 3-6 CORBAservices, Naming Service V1.0, 3/94 + +// A few minor changes for the JacORB distribution: +// +// added am enclosing COSS module and changed scoped names accordingly +// +// corrected a few syntax errors +// +// commented out: +// #includes +// forward declaration of Object + +#include "Corba.idl" + +module COSS { + +module CosNaming { + + typedef string Istring; + struct NameComponent { + Istring id; + Istring kind; + }; + + typedef sequence <NameComponent> Name; + + enum BindingType {nobject, ncontext}; + + struct Binding { + Name binding_name; + BindingType binding_type; + }; + + typedef sequence <Binding> BindingList; + interface BindingIterator; + + interface NamingContext { + + enum NotFoundReason { missing_node, not_context, not_object}; + + exception NotFound { + NotFoundReason why; + Name rest_of_name; + }; + + exception CannotProceed { + NamingContext cxt; + Name rest_of_name; + }; + + exception InvalidName{}; + exception AlreadyBound {}; + exception NotEmpty{}; + + void bind(in Name n, in Object obj) + raises(NotFound, CannotProceed, InvalidName, AlreadyBound); + void rebind(in Name n, in Object obj) + raises(NotFound, CannotProceed, InvalidName); + void bind_context(in Name n, in NamingContext nc) + raises(NotFound, CannotProceed, InvalidName, AlreadyBound); + void rebind_context(in Name n, in NamingContext nc) + raises(NotFound, CannotProceed, InvalidName); + Object resolve (in Name n) + raises(NotFound, CannotProceed, InvalidName); + void unbind(in Name n) + raises(NotFound, CannotProceed, InvalidName); + NamingContext new_context(); + NamingContext bind_new_context(in Name n) + raises(NotFound, AlreadyBound, CannotProceed, InvalidName); + void destroy( ) + raises(NotEmpty); + void list (in unsigned long how_many, + out BindingList bl, out BindingIterator bi); + }; + + interface BindingIterator { + boolean next_one(out Binding b); + boolean next_n(in unsigned long how_many, + out BindingList bl); + void destroy(); + }; +}; + +// Names Library interface in PIDL, CORBAservices p 3- 14, Naming Service V1.0 3/94 +/* +interface LNameComponent { // PIDL + exception NotSet{}; + string get_id() + raises(NotSet); + void set_id(in string i); + string get_kind() + raises(NotSet); + void set_kind(in string k); + void destroy(); +}; + +interface LName { // PIDL + exception NoComponent{}; + exception OverFlow{}; + exception InvalidName{}; + LName insert_component(in unsigned long i, + in LNameComponent n) + raises(NoComponent, OverFlow); + LNameComponent get_component(in unsigned long i) + raises(NoComponent); + LNameComponent delete_component(in unsigned long i) + raises(NoComponent); + unsigned long num_components(); + boolean equal(in LName ln); + boolean less_than(in LName ln); + Name to_idl_form() + raises(InvalidName); + void from_idl_form(in Name n); + void destroy(); +}; + +LName create_lname(); // C/C++ +LNameComponent create_lname_component(); // C/C++ +*/ + +// CosEventComm Module, CORBAservices p 4-8, Event Service V1.0 3/94 + +module CosEventComm { + + exception Disconnected{}; + + interface PushConsumer { + void push (in any data) raises(Disconnected); + void disconnect_push_consumer(); + }; + + interface PushSupplier { + void disconnect_push_supplier(); + }; + + interface PullSupplier { + any pull () raises(Disconnected); + any try_pull (out boolean has_event) + raises(Disconnected); + void disconnect_pull_supplier(); + }; + + interface PullConsumer { + void disconnect_pull_consumer(); + }; + +}; + +// CosEventChannelAdmin Module, p 4-15 CORBAservices, Event +// Service V1.0, 3/94 + +// #include "CosEventComm.idl" + +module CosEventChannelAdmin { + + exception AlreadyConnected {}; + exception TypeError {}; + + interface ProxyPushConsumer: ::COSS::CosEventComm::PushConsumer { + void connect_push_supplier( + in ::COSS::CosEventComm::PushSupplier push_supplier) + raises(AlreadyConnected); + }; + + interface ProxyPullSupplier: ::COSS::CosEventComm::PullSupplier { + void connect_pull_consumer( + in ::COSS::CosEventComm::PullConsumer pull_consumer) + raises(AlreadyConnected); + }; + + interface ProxyPullConsumer: ::COSS::CosEventComm::PullConsumer { + void connect_pull_supplier( + in ::COSS::CosEventComm::PullSupplier pull_supplier) + raises(AlreadyConnected,TypeError); + }; + + interface ProxyPushSupplier: ::COSS::CosEventComm::PushSupplier { + void connect_push_consumer( + in ::COSS::CosEventComm::PushConsumer + push_consumer) + raises(AlreadyConnected, TypeError); + }; + + + interface ConsumerAdmin { + ProxyPushSupplier obtain_push_supplier(); + ProxyPullSupplier obtain_pull_supplier(); + }; + + interface SupplierAdmin { + ProxyPushConsumer obtain_push_consumer(); + ProxyPullConsumer obtain_pull_consumer(); + }; + + interface EventChannel { + ConsumerAdmin for_consumers(); + SupplierAdmin for_suppliers(); + void destroy(); + }; + +}; + + +// CosTyped Event Module, p 4-22 CORBAservices, Event Service +// V1.0, 3/94 + +// // #include "CosEventComm.idl" + +module CosTypedEventComm { + + interface TypedPushConsumer : ::COSS::CosEventComm::PushConsumer { + Object get_typed_consumer(); + }; + + interface TypedPullSupplier : ::COSS::CosEventComm::PullSupplier { + Object get_typed_supplier(); + }; + +}; + +// CosTypedEventChannelAdmin Module, p 4- 25 CORBAservices, +// Event Service V1.0, 3/94 + +// // #include "CosEventChannel.idl" +// // #include "CosTypedEventComm.idl" +module CosTypedEventChannelAdmin { + exception InterfaceNotSupported {}; + exception NoSuchImplementation {}; + typedef string Key; + + interface TypedProxyPushConsumer : + ::COSS::CosEventChannelAdmin::ProxyPushConsumer, + ::COSS::CosTypedEventComm::TypedPushConsumer { }; + + interface TypedProxyPullSupplier : + ::COSS::CosEventChannelAdmin::ProxyPullSupplier, + ::COSS::CosTypedEventComm::TypedPullSupplier { }; + + interface TypedSupplierAdmin : + ::COSS::CosEventChannelAdmin::SupplierAdmin { + TypedProxyPushConsumer obtain_typed_push_consumer( + in Key supported_interface) + raises(InterfaceNotSupported); + ::COSS::CosEventChannelAdmin::ProxyPullConsumer obtain_typed_pull_consumer ( + in Key uses_interface) + raises(NoSuchImplementation); + }; + + interface TypedConsumerAdmin : + ::COSS::CosEventChannelAdmin::ConsumerAdmin { + TypedProxyPullSupplier obtain_typed_pull_supplier( + in Key supported_interface) + raises (InterfaceNotSupported); + ::COSS::CosEventChannelAdmin::ProxyPushSupplier obtain_typed_push_supplier( + in Key uses_interface) + raises(NoSuchImplementation); + }; + + interface TypedEventChannel { + TypedConsumerAdmin for_consumers(); + TypedSupplierAdmin for_suppliers(); + void destroy (); + }; +}; + + +// CosPersistencePID Module, p 5-20 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +//#ifndef __COSPERSISTENCE +//#define __COSPERSISTENCE + +module CosPersistencePID { + + interface PID { + attribute string datastore_type; + string get_PIDString(); + }; +}; + + +// CosPersistencePDS Module, p 5-20 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePID.idl" + +module CosPersistencePDS { + +// interface Object; + interface PDS { + PDS connect (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void disconnect (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void store (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void restore (in Object obj, + in ::COSS::CosPersistencePID::PID p); + void delete (in Object obj, + in ::COSS::CosPersistencePID::PID p); + }; +}; + + +// CosPersistencePO Module, p 5-12 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// // #include "CosPersistencePDS.idl" +// CosPersistencePDS.idl +// // #includes CosPersistencePID.idl + +module CosPersistencePO { + + interface PO { + attribute ::COSS::CosPersistencePID::PID p; + ::COSS::CosPersistencePDS::PDS connect ( + in ::COSS::CosPersistencePID::PID p); + void disconnect (in ::COSS::CosPersistencePID::PID p); + void store (in ::COSS::CosPersistencePID::PID p); + void restore (in ::COSS::CosPersistencePID::PID p); + void delete (in ::COSS::CosPersistencePID::PID p); + }; + + interface SD { + void pre_store(); + void post_restore(); + }; +}; + + +// CosPersistencePOM Module, p 5-15 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePDS.idl" + +// CosPersistencePDS.idl // #includes CosPersistencePID.idl + +module CosPersistencePOM { + +// interface Object; + + interface POM { + ::COSS::CosPersistencePDS::PDS connect ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void disconnect ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void store ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void restore ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + void delete ( + in Object obj, + in ::COSS::CosPersistencePID::PID p); + }; + }; + +// CosPersistencePDS_DA Module, p 5-22 CORBAservices, +// Persistent Object Service, V1.0, 3/94 + +// #include "CosPersistencePDS.idl" +// CosPersistencePDS.idl // #includes CosPersistencePID.idl + +module CosPersistencePDS_DA { + + typedef string DAObjectID; + + interface PID_DA : ::COSS::CosPersistencePID::PID { + attribute DAObjectID oid; + }; + + interface DAObject { + boolean dado_same(in DAObject d); + DAObjectID dado_oid(); + PID_DA dado_pid(); + void dado_remove(); + void dado_free(); + }; + + interface DAObjectFactory { + DAObject create(); + }; + + interface DAObjectFactoryFinder { + DAObjectFactory find_factory(in string key); + }; + + interface PDS_DA : ::COSS::CosPersistencePDS::PDS { + DAObject get_data(); + void set_data(in DAObject new_data); + DAObject lookup(in DAObjectID id); + PID_DA get_pid(); + PID_DA get_object_pid(in DAObject dao); + DAObjectFactoryFinder data_factories(); + }; + + typedef sequence<string> AttributeNames; + interface DynamicAttributeAccess { + AttributeNames attribute_names(); + any attribute_get(in string name); + void attribute_set(in string name, in any value); + }; + + typedef string ClusterID; + typedef sequence<ClusterID> ClusterIDs; + interface PDS_ClusteredDA : PDS_DA{ + ClusterID cluster_id(); + string cluster_kind(); + ClusterIDs clusters_of(); + PDS_ClusteredDA create_cluster(in string kind); + PDS_ClusteredDA open_cluster(in ClusterID cluster); + PDS_ClusteredDA copy_cluster( + in PDS_DA source); + }; +}; + +// CosPersistenceDDO Module, p 5-32 CORBAservices, Persistent Object Service V1.0, 3/94 + +// #include "CosPersistencePID.idl" +module CosPersistenceDDO { + + interface DDO { + attribute string object_type; + attribute ::COSS::CosPersistencePID::PID p; + short add_data(); + short add_data_property (in short data_id); + short get_data_count(); + short get_data_property_count (in short data_id); + void get_data_property (in short data_id, + in short property_id, + out string property_name, + out any property_value); + void set_data_property (in short data_id, + in short property_id, + in string property_name, + in any property_value); + void get_data (in short data_id, + out string data_name, + out any data_value); + void set_data (in short data_id, + in string data_name, + in any data_value); + }; +}; + +// CosPersistenceDS_CLI module, p 5-34 CORBAservices, +// Persistent Object Service V1.0, 3/94 + +// #include "CosPersistenceDDO.idl" +// CosPersistenceDDO.idl // #includes CosPersistencePID.idl + +module CosPersistenceDS_CLI { + interface UserEnvironment { + void set_option (in long option,in any value); + void get_option (in long option,out any value); + void release(); + }; + + interface Connection { + void set_option (in long option,in any value); + void get_option (in long option,out any value); + }; + + interface ConnectionFactory { + Connection create_object ( + in UserEnvironment user_envir); + }; + + interface Cursor { + void set_position (in long position,in any value); + ::COSS::CosPersistenceDDO::DDO fetch_object(); + }; + + interface CursorFactory { + Cursor create_object ( + in Connection connection); + }; + + interface PID_CLI : ::COSS::CosPersistencePID::PID { + attribute string datastore_id; + attribute string id; + }; + + + + interface Datastore_CLI { + void connect (in Connection connection, + in string datastore_id, + in string user_name, + in string authentication); + void disconnect (in Connection connection); + Connection get_connection ( + in string datastore_id, + in string user_name); + void add_object (in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void delete_object ( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void update_object ( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + void retrieve_object( + in Connection connection, + in ::COSS::CosPersistenceDDO::DDO data_obj); + Cursor select_object( + in Connection connection, + in string key); + void transact (in UserEnvironment user_envir, + in short completion_type); + void assign_PID (in PID_CLI p); + void assign_PID_relative ( + in PID_CLI source_pid, + in PID_CLI target_pid); + boolean is_identical_PID ( + in PID_CLI pid_1, + in PID_CLI pid_2); + string get_object_type (in PID_CLI p); + void register_mapping_schema (in string schema_file); + Cursor execute (in Connection connection, + in string command); + }; + +}; + + +// CosLifeCycle Module, p 6-10 CORBAservices, LifeCycle Service V1.0, 3/94 + +// #include "Naming.idl" + +module CosLifeCycle +{ + typedef ::COSS::CosNaming::Name Key; + typedef Object Factory; + typedef sequence <Factory> Factories; + typedef struct NVP { + ::COSS::CosNaming::Istring name; + any value; + } NameValuePair; + typedef sequence <NameValuePair> Criteria; + + exception NoFactory { + Key search_key; + }; + exception NotCopyable { string reason; }; + exception NotMovable { string reason; }; + exception NotRemovable { string reason; }; + exception InvalidCriteria{ + Criteria invalid_criteria; + }; + exception CannotMeetCriteria { + Criteria unmet_criteria; + }; + + + interface FactoryFinder { + Factories find_factories(in Key factory_key) + raises(NoFactory); + }; + + interface LifeCycleObject { + LifeCycleObject copy(in FactoryFinder there, + in Criteria the_criteria) + raises(NoFactory, NotCopyable, InvalidCriteria, + CannotMeetCriteria); + void move(in FactoryFinder there, + in Criteria the_criteria) + raises(NoFactory, NotMovable, InvalidCriteria, + CannotMeetCriteria); + void remove() + raises(NotRemovable); + }; + + interface GenericFactory { + boolean supports(in Key k); + Object create_object( + in Key k, + in Criteria the_criteria) + raises (NoFactory, InvalidCriteria, + CannotMeetCriteria); + }; +}; + + + +// LifeCycleService Module, p 6- 55 CORBAservices, Life Cycle +// Service V1.0, 3/94 + +// #include "LifeCycle.idl" + +module LifeCycleService { + + typedef sequence <::COSS::CosLifeCycle::NameValuePair> PolicyList; + typedef sequence <::COSS::CosLifeCycle::Key> Keys; + typedef sequence <::COSS::CosLifeCycle::NameValuePair> PropertyList; + typedef sequence <::COSS::CosNaming::NameComponent> NameComponents; + + interface LifeCycleServiceAdmin { + + attribute PolicyList policies; + + void bind_generic_factory( + in ::COSS::CosLifeCycle::GenericFactory gf, + in ::COSS::CosNaming::NameComponent name, + in Keys key_set, + in PropertyList other_properties) + raises (::COSS::CosNaming::NamingContext::AlreadyBound, ::COSS::CosNaming::NamingContext::InvalidName); + + void unbind_generic_factory( + in ::COSS::CosNaming::NameComponent name) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + + ::COSS::CosLifeCycle::GenericFactory resolve_generic_factory( + in ::COSS::CosNaming::NameComponent name) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + + NameComponents list_generic_factories(); + + boolean match_service (in ::COSS::CosLifeCycle::GenericFactory f); + + string get_hint(); + + void get_link_properties( + in ::COSS::CosNaming::NameComponent name, + out Keys key_set, + out PropertyList other_properties) + raises (::COSS::CosNaming::NamingContext::NotFound, ::COSS::CosNaming::NamingContext::InvalidName); + }; +}; + +// CosTransactions Module, p 10-66 +// CORBAservices, Transaction Service V1.0, 3/94 + +module CosTransactions { +// DATATYPES +enum Status { + StatusActive, + StatusMarkedRollback, + StatusPrepared, + StatusCommitted, + StatusRolledBack, + StatusUnknown, + StatusNoTransaction +}; + +enum Vote { + VoteCommit, + VoteRollback, + VoteReadOnly +}; + +// Standard exceptions +exception TransactionRequired {}; +exception TransactionRolledBack {}; +exception InvalidTransaction {}; + +// Heuristic exceptions +exception HeuristicRollback {}; +exception HeuristicCommit {}; +exception HeuristicMixed {}; +exception HeuristicHazard {}; + +// Exception from Orb operations +exception WrongTransaction {}; + +// Other transaction-specific exceptions +exception SubtransactionsUnavailable {}; +exception NotSubtransaction {}; +exception Inactive {}; +exception NotPrepared {}; +exception NoTransaction {}; +exception InvalidControl {}; +exception Unavailable {}; + +// Forward references for interfaces defined later in module +interface Control; +interface Terminator; +interface Coordinator; +interface Resource; +interface RecoveryCoordinator; +interface SubtransactionAwareResource; +interface TransactionFactory; +interface TransactionalObject; +interface Current; + +// Current transaction pseudo object (PIDL) + interface Current { + void begin() + raises(SubtransactionsUnavailable); + void commit(in boolean report_heuristics) + raises( + NoTransaction, + HeuristicMixed, + HeuristicHazard + ); + void rollback() + raises(NoTransaction); + void rollback_only() + raises(NoTransaction); + + Status get_status(); + string get_transaction_name(); + void set_timeout(in unsigned long seconds); + + Control get_control(); + Control suspend(); + void resume(in Control which) + raises(InvalidControl); + }; + + interface TransactionFactory { + Control create(in unsigned long time_out); + }; + + interface Control { + Terminator get_terminator() + raises(Unavailable); + Coordinator get_coordinator() + raises(Unavailable); + }; + + interface Terminator { + void commit(in boolean report_heuristics) + raises( + HeuristicMixed, + HeuristicHazard + ); + void rollback(); + }; + + + interface Coordinator { + + Status get_status(); + Status get_parent_status(); + Status get_top_level_status(); + + boolean is_same_transaction(in Coordinator tc); + boolean is_related_transaction(in Coordinator tc); + boolean is_ancestor_transaction(in Coordinator tc); + boolean is_descendant_transaction(in Coordinator tc); + boolean is_top_level_transaction(); + + unsigned long hash_transaction(); + unsigned long hash_top_level_tran(); + + RecoveryCoordinator register_resource(in Resource r) + raises(Inactive); + + void register_subtran_aware(in SubtransactionAwareResource r) + raises(Inactive, NotSubtransaction); + + void rollback_only() + raises(Inactive); + + string get_transaction_name(); + + Control create_subtransaction() + raises(SubtransactionsUnavailable, Inactive); + }; + + interface RecoveryCoordinator { + Status replay_completion(in Resource r) + raises(NotPrepared); + }; + +}; // end module CosTransactions + + +// CosConcurrency Control Module, p 7-8 CORBAservices, +// Concurrency Control Service V1.0, 3/94 + +// #include <CosTransactions.idl> +module CosConcurrencyControl { + + enum lock_mode { + read, + write, + upgrade, + intention_read, + intention_write + }; + + exception LockNotHeld{}; + + interface LockCoordinator + { + void drop_locks(); + }; + + interface LockSet + { + void lock(in lock_mode mode); + boolean try_lock(in lock_mode mode); + + void unlock(in lock_mode mode) + raises(LockNotHeld); + void change_mode(in lock_mode held_mode, + in lock_mode new_mode) + raises(LockNotHeld); + LockCoordinator get_coordinator( + in ::COSS::CosTransactions::Coordinator which); + }; + + interface TransactionalLockSet + { + void lock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode); + boolean try_lock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode); + void unlock(in ::COSS::CosTransactions::Coordinator current, + in lock_mode mode) + raises(LockNotHeld); + void change_mode(in ::COSS::CosTransactions::Coordinator current, + in lock_mode held_mode, + in lock_mode new_mode) + raises(LockNotHeld); + LockCoordinator get_coordinator( + in ::COSS::CosTransactions::Coordinator which); + }; + + interface LockSetFactory + { + LockSet create(); + LockSet create_related(in LockSet which); + TransactionalLockSet create_transactional(); + TransactionalLockSet create_transactional_related(in + TransactionalLockSet which); + }; +}; + +// CosObjectIdentity Module, p 9-19 CORBAservices, Relationship +// Service V1.0, 3/94 + + +module CosObjectIdentity { + + typedef unsigned long ObjectIdentifier; + + interface IdentifiableObject { + readonly attribute ObjectIdentifier constant_random_id; + boolean is_identical ( + in IdentifiableObject other_object); + }; + +}; + + +// CosRelationships Module, p 9-21 CORBAservices, Relationship +// Service V1.0, 3/94 + +// #include <ObjectIdentity.idl> + +module CosRelationships { + + interface RoleFactory; + interface RelationshipFactory; + interface Relationship; + interface Role; + interface RelationshipIterator; + + typedef Object RelatedObject; + typedef sequence<Role> Roles; + typedef string RoleName; + typedef sequence<RoleName> RoleNames; + + struct NamedRole {RoleName name; Role aRole;}; + typedef sequence<NamedRole> NamedRoles; + + struct RelationshipHandle { + Relationship the_relationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + typedef sequence<RelationshipHandle> RelationshipHandles; + + interface RelationshipFactory { + struct NamedRoleType { + RoleName name; + ::CORBA::InterfaceDef named_role_type; + }; + typedef sequence<NamedRoleType> NamedRoleTypes; + readonly attribute ::CORBA::InterfaceDef relationship_type; + readonly attribute unsigned short degree; + readonly attribute NamedRoleTypes named_role_types; + exception RoleTypeError {NamedRoles culprits;}; + exception MaxCardinalityExceeded { + NamedRoles culprits;}; + exception DegreeError {unsigned short required_degree;}; + exception DuplicateRoleName {NamedRoles culprits;}; + exception UnknownRoleName {NamedRoles culprits;}; + + Relationship create (in NamedRoles named_roles) + raises (RoleTypeError, + MaxCardinalityExceeded, + DegreeError, + DuplicateRoleName, + UnknownRoleName); + }; + + interface Relationship : + ::COSS::CosObjectIdentity::IdentifiableObject { + exception CannotUnlink { + Roles offending_roles; + }; + readonly attribute NamedRoles named_roles; + void destroy () raises(CannotUnlink); + }; + + interface Role { + exception UnknownRoleName {}; + exception UnknownRelationship {}; + exception RelationshipTypeError {}; + exception CannotDestroyRelationship { + RelationshipHandles offenders; + }; + exception ParticipatingInRelationship { + RelationshipHandles the_relationships; + }; + readonly attribute RelatedObject related_object; + RelatedObject get_other_related_object ( + in RelationshipHandle rel, + in RoleName target_name) + raises (UnknownRoleName, + UnknownRelationship); + Role get_other_role (in RelationshipHandle rel, + in RoleName target_name) + raises (UnknownRoleName, UnknownRelationship); + void get_relationships ( + in unsigned long how_many, + out RelationshipHandles rels, + out RelationshipIterator iterator); + void destroy_relationships() + raises(CannotDestroyRelationship); + void destroy() raises(ParticipatingInRelationship); + boolean check_minimum_cardinality (); + void link (in RelationshipHandle rel, + in NamedRoles named_roles) + raises(RelationshipFactory::MaxCardinalityExceeded, + RelationshipTypeError); + void unlink (in RelationshipHandle rel) + raises (UnknownRelationship); + }; + + interface RoleFactory { + exception NilRelatedObject {}; + exception RelatedObjectTypeError {}; + readonly attribute ::CORBA::InterfaceDef role_type; + readonly attribute unsigned long max_cardinality; + readonly attribute unsigned long min_cardinality; +// the following isn't allowed in IDL, +// readonly attribute sequence <::CORBA::InterfaceDef> related_object_types; + typedef sequence <::CORBA::InterfaceDef> InterfaceDefSeq; + readonly attribute InterfaceDefSeq related_object_types; + Role create_role (in RelatedObject related_object) + raises (NilRelatedObject, RelatedObjectTypeError); + }; + + interface RelationshipIterator { + boolean next_one (out RelationshipHandle rel); + boolean next_n (in unsigned long how_many, + out RelationshipHandles rels); + void destroy (); + }; + +}; + +// CosCompoundExternalization Module, p 8-20 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Graphs.idl> +// #include <Stream.idl> + +// CosGraphs Module, p 9-39 CORBAservices, Relationship Service +// V1.0, 3/94 + +// #include <Relationships.idl> +// #include <ObjectIdentity.idl> + +module CosGraphs { + + interface TraversalFactory; + interface Traversal; + interface TraversalCriteria; + interface Node; + interface NodeFactory; + interface Role; + interface EdgeIterator; + + struct NodeHandle { + Node the_node; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + typedef sequence<NodeHandle> NodeHandles; + + struct NamedRole { + Role the_role; + ::COSS::CosRelationships::RoleName the_name; + }; + typedef sequence<NamedRole> NamedRoles; + + struct EndPoint { + NodeHandle the_node; + NamedRole the_role; + }; + typedef sequence<EndPoint> EndPoints; + + struct Edge { + EndPoint from; + ::COSS::CosRelationships::RelationshipHandle the_relationship; + EndPoints relatives; + }; + typedef sequence<Edge> Edges; + + enum PropagationValue {deep, shallow, none, inhibit}; + enum Mode {depthFirst, breadthFirst, bestFirst}; + + interface TraversalFactory { + Traversal create_traversal_on ( + in NodeHandle root_node, + in TraversalCriteria the_criteria, + in Mode how); + }; + + interface Traversal { + typedef unsigned long TraversalScopedId; + struct ScopedEndPoint { + EndPoint point; + TraversalScopedId id; + }; + typedef sequence<ScopedEndPoint> ScopedEndPoints; + struct ScopedRelationship { + ::COSS::CosRelationships::RelationshipHandle + scoped_relationship; + TraversalScopedId id; + }; + struct ScopedEdge { + ScopedEndPoint from; + ScopedRelationship the_relationship; + ScopedEndPoints relatives; + }; + typedef sequence<ScopedEdge> ScopedEdges; + boolean next_one (out ScopedEdge the_edge); + boolean next_n (in short how_many, + out ScopedEdges the_edges); + void destroy (); + }; + + interface TraversalCriteria { + struct WeightedEdge { + Edge the_edge; + unsigned long weight; + sequence<NodeHandle> next_nodes; + }; + typedef sequence<WeightedEdge> WeightedEdges; + void visit_node(in NodeHandle a_node, + in Mode search_mode); + boolean next_one (out WeightedEdge the_edge); + boolean next_n (in short how_many, + out WeightedEdges the_edges); + void destroy(); + }; + + interface Node: ::COSS::CosObjectIdentity::IdentifiableObject { + typedef sequence<Role> Roles; + exception NoSuchRole {}; + exception DuplicateRoleType {}; + + readonly attribute ::COSS::CosRelationships::RelatedObject + related_object; + readonly attribute Roles roles_of_node; + Roles roles_of_type ( + in ::CORBA::InterfaceDef role_type); + void add_role (in Role a_role) + raises (DuplicateRoleType); + void remove_role (in ::CORBA::InterfaceDef of_type) + raises (NoSuchRole); + }; + + interface NodeFactory { + Node create_node (in Object related_object); + }; + + interface Role : ::COSS::CosRelationships::Role { + void get_edges ( in long how_many, + out Edges the_edges, + out EdgeIterator the_rest); + }; + + interface EdgeIterator { + boolean next_one (out Edge the_edge); + boolean next_n ( in unsigned long how_many, + out Edges the_edges); + void destroy (); + }; + +}; + + + +// CosStream Module, 8-15 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <LifeCycle.idl> +// #include <ObjectIdentity.idl> +// #include <CompoundExternalization.idl> +module CosStream { + exception ObjectCreationError{}; + exception StreamDataFormatError{}; + interface StreamIO; + + interface Streamable: ::COSS::CosObjectIdentity::IdentifiableObject + { + readonly attribute ::COSS::CosLifeCycle::Key external_form_id; + void externalize_to_stream( + in StreamIO targetStreamIO); + void internalize_from_stream( + in StreamIO sourceStreamIO, + in ::COSS::CosLifeCycle::FactoryFinder there) + raises( ::COSS::CosLifeCycle::NoFactory, + ObjectCreationError, + StreamDataFormatError ); + }; + + interface StreamableFactory { + Streamable create_uninitialized(); + }; + + + interface StreamIO { + void write_string(in string aString); + void write_char(in char aChar); + void write_octet(in octet anOctet); + void write_unsigned_long( + in unsigned long anUnsignedLong); + void write_unsigned_short( + in unsigned short anUnsignedShort); + void write_long(in long aLong); + void write_short(in short aShort); + void write_float(in float aFloat); + void write_double(in double aDouble); + void write_boolean(in boolean aBoolean); + void write_object(in Streamable aStreamable); + // void write_graph(in ::COSS::CosCompoundExternalization::Node aNode); + string read_string() + raises(StreamDataFormatError); + char read_char() + raises(StreamDataFormatError ); + octet read_octet() + raises(StreamDataFormatError ); + unsigned long read_unsigned_long() + raises(StreamDataFormatError ); + unsigned short read_unsigned_short() + raises( StreamDataFormatError ); + long read_long() + raises(StreamDataFormatError ); + short read_short() + raises(StreamDataFormatError ); + float read_float() + raises(StreamDataFormatError ); + double read_double() + raises(StreamDataFormatError ); + boolean read_boolean() + raises(StreamDataFormatError ); + Streamable read_object( + in ::COSS::CosLifeCycle::FactoryFinder there, + in Streamable aStreamable) + raises(StreamDataFormatError ); +// void read_graph( +// in ::COSS::CosCompoundExternalization::Node starting_node, +// in ::COSS::CosLifeCycle::FactoryFinder there) +// raises(StreamDataFormatError ); + }; +}; + +module CosCompoundExternalization { + interface Node; + interface Role; + interface Relationship; + interface PropagationCriteriaFactory; + + struct RelationshipHandle { + Relationship theRelationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constantRandomId; + }; + + interface Node : ::COSS::CosGraphs::Node, ::COSS::CosStream::Streamable{ + void externalize_node (in ::COSS::CosStream::StreamIO sio); + void internalize_node (in ::COSS::CosStream::StreamIO sio, + in ::COSS::CosLifeCycle::FactoryFinder there, + out ::COSS::CosGraphs::Node::Roles rolesOfNode) + raises (::COSS::CosLifeCycle::NoFactory); + }; + + interface Role : ::COSS::CosGraphs::Role { + void externalize_role (in ::COSS::CosStream::StreamIO sio); + void internalize_role (in ::COSS::CosStream::StreamIO sio); + ::COSS::CosGraphs::PropagationValue externalize_propagation ( + in RelationshipHandle rel, + in ::COSS::CosRelationships::RoleName toRoleName, + out boolean sameForAll); + }; + + interface Relationship : + ::COSS::CosRelationships::Relationship { + void externalize_relationship ( + in ::COSS::CosStream::StreamIO sio); + void internalize_relationship( + in ::COSS::CosStream::StreamIO sio, + in ::COSS::CosGraphs::NamedRoles newRoles); + ::COSS::CosGraphs::PropagationValue externalize_propagation ( + in ::COSS::CosRelationships::RoleName fromRoleName, + in ::COSS::CosRelationships::RoleName toRoleName, + out boolean sameForAll); + }; + + interface PropagationCriteriaFactory { + ::COSS::CosGraphs::TraversalCriteria create_for_externalize( ); + }; + +}; + +// CosExternalization Module, 8-12 CORBAservices, +// Externalization Service V1.0, 3/94 + + +// #include <LifeCycle.idl> +// #include <Stream.idl> +module CosExternalization { + exception InvalidFileNameError{}; + exception ContextAlreadyRegistered{}; + interface Stream: ::COSS::CosLifeCycle::LifeCycleObject{ + void externalize( + in ::COSS::CosStream::Streamable theObject); + ::COSS::CosStream::Streamable internalize( + in ::COSS::CosLifeCycle::FactoryFinder there) + raises( ::COSS::CosLifeCycle::NoFactory, + ::COSS::CosStream::StreamDataFormatError ); + void begin_context() + raises( ContextAlreadyRegistered); + void end_context(); + void flush(); + }; + interface StreamFactory { + Stream create(); + }; + interface FileStreamFactory { + Stream create( + in string theFileName) + raises( InvalidFileNameError ); + }; +}; + +// CosContainment Module, p 9- 48 CORBAservices, Relationship +// Service V1.0, 3/94 + +// #include <Graphs.idl> + +module CosContainment { + + interface Relationship : + ::COSS::CosRelationships::Relationship {}; + + interface ContainsRole : ::COSS::CosGraphs::Role {}; + + interface ContainedInRole : ::COSS::CosGraphs::Role {}; + +}; + +// CosExternalizationContainment Module, p 8-26 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Containment.idl> +// #include <CompoundExternalization.idl> + +module CosExternalizationContainment { + + interface Relationship : + ::COSS::CosCompoundExternalization::Relationship, + ::COSS::CosContainment::Relationship {}; + + interface ContainsRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosContainment::ContainsRole {}; + + interface ContainedInRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosContainment::ContainedInRole {}; +}; + +// CosReference Module, p 9-50 CORBAservices, +// Relationship Service V1.0, 3/94 + +// #include <Graphs.idl> + +module CosReference { + + interface Relationship : + ::COSS::CosRelationships::Relationship {}; + + interface ReferencesRole : ::COSS::CosGraphs::Role {}; + + interface ReferencedByRole : ::COSS::CosGraphs::Role {}; + +}; + +// CosExternalizationReference Module, p 8-28 CORBAservices, +// Externalization Service V1.0, 3/94 + +// #include <Reference.idl> +// #include <CompoundExternalization.idl> + +module CosExternalizationReference { + + interface Relationship : + ::COSS::CosCompoundExternalization::Relationship, + ::COSS::CosReference::Relationship {}; + + interface ReferencesRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosReference::ReferencesRole {}; + + interface ReferencedByRole : + ::COSS::CosCompoundExternalization::Role, + ::COSS::CosReference::ReferencedByRole {}; +}; + +// PIDL for CosTSInteroperation Module, p 10-59 +// CORBAservices, Transaction Service V1.0, 3/94 +module CosTSInteroperation { // PIDL + struct otid_t { + long formatID; /*format identifier. 0 is OSI TP */ + long bequal_length; + sequence <octet> tid; + }; + struct TransIdentity { + ::COSS::CosTransactions::Coordinator coordinator; + ::COSS::CosTransactions::Terminator terminator; + otid_t otid; + }; + struct PropagationContext { + unsigned long timeout; + TransIdentity current; + sequence <TransIdentity> parents; + any implementation_specific_data; + }; +}; + +// PIDL for CosTSPortability Module, p 10-63 +// CORBAservices, Transaction Service V1.0, 3/94 + +module CosTSPortability { // PIDL + typedef long ReqId; + + interface Sender { + void sending_request(in ReqId id, + out ::COSS::CosTSInteroperation::PropagationContext ctx); + void received_reply(in ReqId id, + in ::COSS::CosTSInteroperation::PropagationContext ctx, + in ::CORBA::Environment env); + }; + + interface Receiver { + void received_request(in ReqId id, + in ::COSS::CosTSInteroperation::PropagationContext ctx); + void sending_reply(in ReqId id, + out::COSS::CosTSInteroperation::PropagationContext ctx); + }; +}; + +// CosCompoundLifeCycle Module, p 6-30 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <LifeCycle.idl> +// #include <Relationships.idl> +// #include <Graphs.idl> + +module CosCompoundLifeCycle { + interface OperationsFactory; + interface Operations; + interface Node; + interface Role; + interface Relationship; + interface PropagationCriteriaFactory; + + enum Operation {copy, move, remove}; + + struct RelationshipHandle { + Relationship the_relationship; + ::COSS::CosObjectIdentity::ObjectIdentifier constant_random_id; + }; + + interface OperationsFactory { + Operations create_compound_operations(); + }; + + interface Operations { + Node copy ( + in Node starting_node, + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move ( + in Node starting_node, + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void remove (in Node starting_node) + raises (::COSS::CosLifeCycle::NotRemovable); + void destroy(); + }; + + interface Node : ::COSS::CosGraphs::Node { + exception NotLifeCycleObject {}; + void copy_node ( in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria, + out Node new_node, + out ::COSS::CosGraphs::Node::Roles roles_of_new_node) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_node (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void remove_node () + raises (::COSS::CosLifeCycle::NotRemovable); + ::COSS::CosLifeCycle::LifeCycleObject get_life_cycle_object() + raises (NotLifeCycleObject); + }; + + interface Role : ::COSS::CosGraphs::Role { + Role copy_role (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_role (in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + ::COSS::CosGraphs::PropagationValue life_cycle_propagation ( + in Operation op, + in RelationshipHandle rel, + in ::COSS::CosRelationships::RoleName to_role_name, + out boolean same_for_all); + }; + + interface Relationship : + ::COSS::CosRelationships::Relationship { + Relationship copy_relationship ( + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria, + in ::COSS::CosGraphs::NamedRoles new_roles) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotCopyable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + void move_relationship ( + in ::COSS::CosLifeCycle::FactoryFinder there, + in ::COSS::CosLifeCycle::Criteria the_criteria) + raises (::COSS::CosLifeCycle::NoFactory, + ::COSS::CosLifeCycle::NotMovable, + ::COSS::CosLifeCycle::InvalidCriteria, + ::COSS::CosLifeCycle::CannotMeetCriteria); + ::COSS::CosGraphs::PropagationValue life_cycle_propagation ( + in Operation op, + in ::COSS::CosRelationships::RoleName from_role_name, + in ::COSS::CosRelationships::RoleName to_role_name, + out boolean same_for_all); + }; + + interface PropagationCriteriaFactory { + ::COSS::CosGraphs::TraversalCriteria create(in Operation op); + }; + +}; + +// CosLifeCycleContainment Module, p 6-42 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <Containment.idl> +// #include <CompoundLifeCycle.idl> + +module CosLifeCycleContainment { + + interface Relationship : + ::COSS::CosCompoundLifeCycle::Relationship, + ::COSS::CosContainment::Relationship {}; + + interface ContainsRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosContainment::ContainsRole {}; + + interface ContainedInRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosContainment::ContainedInRole {}; +}; + +// CosLifeCycleReference Module, p 6-44 CORBAservices, +// Life Cycle Service V1.0, 3/94 + +// #include <Reference.idl> +// #include <CompoundLifeCycle.idl> + +module CosLifeCycleReference { + + interface Relationship : + ::COSS::CosCompoundLifeCycle::Relationship, + ::COSS::CosReference::Relationship {}; + + interface ReferencesRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosReference::ReferencesRole {}; + + interface ReferencedByRole : + ::COSS::CosCompoundLifeCycle::Role, + ::COSS::CosReference::ReferencedByRole {}; +}; + + +}; // end module COSS diff --git a/lib/ic/test/ic_SUITE_data/attr.idl b/lib/ic/test/ic_SUITE_data/attr.idl new file mode 100644 index 0000000000..c74223eca6 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/attr.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +interface I1 { + attribute long a1, a2; + attribute char a3; +}; + +interface I2 : I1 { + attribute short a4; + readonly attribute char a5; +}; + diff --git a/lib/ic/test/ic_SUITE_data/c_err1.idl b/lib/ic/test/ic_SUITE_data/c_err1.idl new file mode 100644 index 0000000000..e1bc93dae8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err1.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// This file forces the bad_tk_match. This triggers when the type of +// the expression does not match the declared type of the constant +// + +const long c1 = TRUE; +const unsigned short c1b= TRUE; +const boolean c2 = +5; +const long c3 = 'c'; +const float c5 = 3; +const unsigned long c6 = -2; // Maybe not checked in compiler or suite + +const boolean c4 = 1 | 2; + + +// Now define some correct constants for use in reference checking + +const long longC = -9; +const short shortC = -9; +const unsigned long ulongC = 1; +const unsigned short ushortC = 0; + +const float floatC = 5.1; +const double doubleC = -2.111; + +const boolean boolC = TRUE; + +const char charC = 'f'; +const string stringC = "hej"; +const string<9> stringCb = "hejdu"; + +// Check the reference errors + +const long c19 = floatC; +const short c20 = doubleC; +const unsigned long c21 = charC; +const unsigned short c22 = stringC; +const float c23 = stringCb; +const double c24 = boolC; +const boolean c25 = longC; +const char c26 = shortC; +const string c27 = ushortC; +const string<9> c28 = ulongC; +const long c29 = 3+floatC; diff --git a/lib/ic/test/ic_SUITE_data/c_err2.idl b/lib/ic/test/ic_SUITE_data/c_err2.idl new file mode 100644 index 0000000000..8dac241c7f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err2.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Checks bad type of operands +// + + +const long c1 = 1 + TRUE; +const boolean c3 = TRUE | FALSE | 19.8; +const long c4 = 1 << TRUE; +const long c5 = TRUE >> TRUE; + + diff --git a/lib/ic/test/ic_SUITE_data/c_err3.idl b/lib/ic/test/ic_SUITE_data/c_err3.idl new file mode 100644 index 0000000000..dde9539f6f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_err3.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Checks ill-formed expressions (type conflict in operands) +// + + +const long c1 = 5|TRUE; +const long c2 = 5&TRUE; +const long c3 = 5^TRUE; + diff --git a/lib/ic/test/ic_SUITE_data/c_norm.idl b/lib/ic/test/ic_SUITE_data/c_norm.idl new file mode 100644 index 0000000000..6f6ef8ff79 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/c_norm.idl @@ -0,0 +1,163 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Check normal values and expressions for constants +// + +// Integer types +const long co1 = 077; +const long ch1 = 0xf1; +const long ch2 = 0XAB; +const long c1 = 1; +const short c2 = 3; +const unsigned long c3 = 1; +const unsigned short c4 = 3; + +// Unary ops +const long c1hb = -0x1; +const long c1b = -1; +const short c2b = -3; +const long c1c = +1; +const short c2c = +3; +// ~ not supported + +// Check binary ops +const long c1d = 9+1-3; +const long c1hd = 9+1-0xf3; +const short c2d = 7+3; +const short c2e = 7*3; +const long c1e = 1 | 7; +const long c1f = 7 & 9; +const long c1g = (1 | 7) & 9; +const long c1h = 1^7; + +//floats +const float c5 = 1.9; +const double c6 = 1.9; +const float c5b = -1.9; +const double c6b = -1.9; + +// Check type operand casting +const float c5c = 1/(9+2) * 2; +const double c6c = 1.9-1; +//const double c6d = 1; // Does not work yet + +// Booleans and expressions +const boolean c7 = TRUE; +const boolean c7b = FALSE; +const boolean c7c = TRUE | FALSE; +const boolean c7d = TRUE & FALSE; +const boolean c7e = TRUE&TRUE | FALSE&TRUE; +const boolean c7f = TRUE&TRUE ^ FALSE&TRUE; + +// Character and string +const char c8 = 'c'; +const char c8b = '\n'; +const string c9 = "hej"; +const string<9> c9b = "hejdu"; + + +// +// Check that value references work +// + +const long rc1 = c1g; +const long rc1h = c1h + 9; +const short rc2 = c2; +const unsigned long rc3 = c3; +const unsigned short rc4 = c4; + + +const float rc5c = c5c; +const double rc6c = c6c; +const double rc6d = c6c+1.3; + +const boolean rc7 = c7; +const boolean rc7c = c7c | TRUE; + +const char rc8 = c8; +const char rc8b = c8b; +const string rc9 = c9; +const string<9> rc9b = c9b; + + + + +// +// Now check that all typerefs work +// + +typedef long longT; +typedef short shortT; +typedef unsigned long ulongT; +typedef unsigned short ushortT; + +typedef float floatT; +typedef double doubleT; + +typedef char charT; +typedef string stringT; + +typedef boolean booleanT; + +const longT cc1 = 1; +const shortT cc2 = 3; +const ::longT cc1b = -1; +const ::shortT cc2b = -3; + +const floatT cc5 = 1.9; +const doubleT cc6 = 1.9; +const floatT cc5b = -1.9; +const doubleT cc6b = -1.9; +const floatT cc5c = 1/(9+2) * 2; +const doubleT cc6c = 1.9-1; + +const booleanT cc7 = TRUE; +const booleanT cc7b = TRUE; +const booleanT cc7c = TRUE | FALSE; +const booleanT cc7d = TRUE & FALSE; +const booleanT cc7e = TRUE&TRUE | FALSE&TRUE; + + +const charT cc8 = 'c'; +const charT cc8b = '\n'; +const stringT cc9 = "hej"; +const stringT cc9b = "hejdu"; + + +// +// Check value casting +// +const long longC = -9; +const short shortC = -9; +const unsigned long ulongC = 1; +const unsigned short ushortC = 0; + +const float floatC = 5.1; +const double doubleC = -2.111; + +const long c20 = shortC; +const long c21 = ulongC; +const long c22 = ushortC; +const short c23 = ushortC; +const double c34 = floatC; + + + diff --git a/lib/ic/test/ic_SUITE_data/enum.idl b/lib/ic/test/ic_SUITE_data/enum.idl new file mode 100644 index 0000000000..c164e4bf74 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/enum.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +enum E1 {kalle, sune}; + +enum E2 { el0, el1, el2, el3, el4, el5, el6, el7, el8, el9, el10, el11, el12, el13, +el14, el15, el16, el17, el18, el19, el20, el21, el22, el23, el24, el25, el26, el27, +el28, el29, el30, el31, el32, el33, el34, el35, el36, el37, el38, el39, el40, el41, +el42, el43, el44, el45, el46, el47, el48, el49, el50, el51, el52, el53, el54, el55, +el56, el57, el58, el59}; + + + + + diff --git a/lib/ic/test/ic_SUITE_data/forward.idl b/lib/ic/test/ic_SUITE_data/forward.idl new file mode 100644 index 0000000000..1e16265af5 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/forward.idl @@ -0,0 +1,34 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Check that forward declarations are handled correctly +// + + +interface i1; + + +interface i1 { + typedef long T; +}; + + +interface i1; + diff --git a/lib/ic/test/ic_SUITE_data/include.idl b/lib/ic/test/ic_SUITE_data/include.idl new file mode 100644 index 0000000000..24022bfa1e --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Check that errors are given with the correct file name reference + +#include "include2.idl" + + +typedef T1 T7; +typedef long T7; +typedef long T111; + + + diff --git a/lib/ic/test/ic_SUITE_data/include2.idl b/lib/ic/test/ic_SUITE_data/include2.idl new file mode 100644 index 0000000000..2f8f7fd62c --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include2.idl @@ -0,0 +1,26 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Check that errors are given with the correct file name reference + +#include "include3.idl" + + +typedef T7 T1; + diff --git a/lib/ic/test/ic_SUITE_data/include3.idl b/lib/ic/test/ic_SUITE_data/include3.idl new file mode 100644 index 0000000000..c5f89c6c63 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/include3.idl @@ -0,0 +1,25 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Check that errors are given with the correct file name reference + +typedef T7 T1; + + + diff --git a/lib/ic/test/ic_SUITE_data/inherit.idl b/lib/ic/test/ic_SUITE_data/inherit.idl new file mode 100644 index 0000000000..71b79c8748 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +interface I1 { + typedef long T1; + typedef struct S1 {long a; boolean b;} T2; + typedef string StringT, StringT_arr[10]; + + T1 op1( in StringT a, inout char b, out StringT_arr c ); + T2 op2( in char a, inout char b, out StringT_arr c ); + + const T1 LongC = 10; + const StringT StringC = "Hola bambino"; + +}; + + +interface I2 : I1 { + T1 op3( in long a); + + const long c1 = LongC; + const string c2 = StringC; +}; + +interface I3 : I1 {}; + +interface I4 : I3, I2 {}; // Check that branced inherit works + + + +// Now use cnstants to check that inheritance works as expected + +module m1 { + interface I1 { + typedef long T1; + + const T1 c1 = 9; + }; + + interface I2 : I1 { + const T1 c2 = c1+5; // c2 = 14 + const long c3 = c2+c1+4; // c3 = 27 + }; + + interface I3 : I2, I1 { + const long c1 = 50; // Overrides I1::c1 + const T1 c4 = c1+c2+c3; // c4=91 + const T1 c5 = I1::c1+c1+c2+c3; // 100 + }; +}; + diff --git a/lib/ic/test/ic_SUITE_data/inherit_err.idl b/lib/ic/test/ic_SUITE_data/inherit_err.idl new file mode 100644 index 0000000000..4cfc3ffbff --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit_err.idl @@ -0,0 +1,71 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Ops and attributes must not be redefined (shadowed) + +interface I1 { + long op1( in long a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + +interface I2 : I1 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + +interface I3 : I1 { + long op3 (in string<19> b); +}; + + +interface I4 : I3 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; + + long op3 (in string<19> b); +}; + + +interface I11 { + long op1( in float a, inout char b, out boolean c ); + long op2( in char a, inout char b, out boolean c ); + attribute long a1, a2; + readonly attribute char a3; +}; + + + +interface I5 : I1, I11 {}; + +interface I6 : I1 { + const long op1=0; + const long op2=0; + const long a1=0; + const long a2=0; + const long a3=0; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/inherit_warn.idl b/lib/ic/test/ic_SUITE_data/inherit_warn.idl new file mode 100644 index 0000000000..502bfac8d4 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/inherit_warn.idl @@ -0,0 +1,64 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Checks that shadow warnings comes out as expected +// + + +interface I1 { + typedef long T1; + typedef struct S1 {long a; boolean b;} T2; + typedef string StringT, StringT_arr[10]; + + T1 op1( in StringT a, inout char b, out StringT_arr c ); + T2 op2( in char a, inout char b, out StringT_arr c ); + + const T1 LongC = 10; + const StringT StringC = "Hola bambino"; + +}; + + +interface I2 : I1 { + typedef char T1; // Shadows I1::T1 + const boolean StringC = FALSE; // shadows I1::StringC + + T1 op3( in long a); + + const long c1 = LongC; + const boolean c2 = StringC; +}; + +interface I3 : I2 {}; // More shadows + +interface I4 : I1 { + T1 op4(); + const T1 c2 = 66; +}; + +interface I5 : I4 { + typedef string T1; // Shadows I1::T1 + const char LongC = 'a'; // Shadows I1::LongC +}; + + +interface I6 : I4, I3 { +}; + diff --git a/lib/ic/test/ic_SUITE_data/mult_ids.idl b/lib/ic/test/ic_SUITE_data/mult_ids.idl new file mode 100644 index 0000000000..46deaa9f55 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/mult_ids.idl @@ -0,0 +1,92 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% +// +// Check that multiply defined identifiers are detected +// + +typedef long T1; +typedef long T1; +typedef long T2; +exception T2 {}; + + +//Exceptions +exception Exc1 {}; +exception Exc1 {}; + + +// Enums +enum E1 {kalle}; +enum E1 {kalle}; +enum E2 {kalle, sune, kalle}; + + +// Structs +struct S1 {long a;}; +struct S1 {long a;}; +struct S2 {long a; short a;}; +struct S3 {long a,b; short a;}; +struct S4 {long a,a; short a;}; + + +// Constants +const long c1 = 0; +const long c1 = 0; + + +// Interfaces + +interface i1 {}; +interface i1 {}; + +interface i2 { + attribute long a1; + attribute long a1; +}; + +interface i3 { + attribute long a1, a2; + attribute long a2; +}; + +interface i4 { + attribute long a1, a1; +}; + +interface i5 { + long op1(); + long op1(); + + long op2(in long a, inout char a); +}; + + +// Unions + +union U1 switch (long) {case 1: long a;}; +union U1 switch (long) {case 1: long a;}; + +union U2 switch (long) { +case 1: long a; +default: char a; +}; + + + + + diff --git a/lib/ic/test/ic_SUITE_data/nasty.idl b/lib/ic/test/ic_SUITE_data/nasty.idl new file mode 100644 index 0000000000..15fd523c0f --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/nasty.idl @@ -0,0 +1,60 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Checks nasty name collisions +// + +typedef string T; + + +#define nasty01 version +#define nasty02 preproc +#define nasty03 pragma +#define nasty04 compile +#define nasty05 if +#define nasty06 receive +#define nasty07 foldr +#define nasty08 length +#define nasty09 ID + +interface I1 { + attribute T nasty01; + attribute T nasty02; + attribute T nasty03; + attribute T nasty04; + attribute T nasty05; + attribute T nasty06; + attribute T nasty07; + attribute T nasty08; + attribute T nasty09; +}; + +interface I2 { + T nasty01(); + T nasty02(); + T nasty03(); + T nasty04(); + T nasty05(); + T nasty06(); + T nasty07(); + T nasty08(); + T nasty09(); +}; + diff --git a/lib/ic/test/ic_SUITE_data/one.idl b/lib/ic/test/ic_SUITE_data/one.idl new file mode 100644 index 0000000000..99281d6079 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Test oneway operations + +interface I1 { + long op1(in char a, inout boolean b, out string c); + oneway void op2(in char a, in boolean b, in string c); + oneway void op3(); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_followed.idl b/lib/ic/test/ic_SUITE_data/one_followed.idl new file mode 100644 index 0000000000..da8ee74e25 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_followed.idl @@ -0,0 +1,54 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +// Test oneway operations followed by other operations + +interface I1 { + oneway void op1(); + oneway void op2(in char a, in boolean b, in string c); + long op3(in char a, inout boolean b, out string c); +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/one_out.idl b/lib/ic/test/ic_SUITE_data/one_out.idl new file mode 100644 index 0000000000..65f177ff22 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_out.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Test oneway operations not using in out params + +interface I1 { + oneway void op1(in char a, inout boolean b, in string c); + oneway void op2(in char a, out boolean b, in string c); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_raises.idl b/lib/ic/test/ic_SUITE_data/one_raises.idl new file mode 100644 index 0000000000..8290877363 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_raises.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Test oneway operations not using in out params + +exception hell {boolean burn; unsigned long for_how_long;}; +exception high_water {long mark;}; + +interface I1 { + oneway void op1(in char a) raises (hell); + oneway void op2(in char a) raises (hell); + oneway void op3() raises (hell, high_water); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/one_void.idl b/lib/ic/test/ic_SUITE_data/one_void.idl new file mode 100644 index 0000000000..e1d51c7abb --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/one_void.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Test oneway operations not using in out params + +typedef long T; + +interface I1 { + oneway char op1(in char a); + oneway T op2(in char a); +}; + + + diff --git a/lib/ic/test/ic_SUITE_data/raises_reg.idl b/lib/ic/test/ic_SUITE_data/raises_reg.idl new file mode 100644 index 0000000000..d4458811dc --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/raises_reg.idl @@ -0,0 +1,52 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#ifndef _RAISES_REG_IDL +#define _RAISES_REG_IDL + +module Raises_RegModule { + + exception Exception_1 {}; + + exception Exception_2 {}; + + interface R_R { + + void op() + raises(Raises_RegModule::Exception_1,Raises_RegModule::Exception_2); + + }; + +}; + +#endif + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_SUITE_data/struct.idl b/lib/ic/test/ic_SUITE_data/struct.idl new file mode 100644 index 0000000000..337ee170e3 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/struct.idl @@ -0,0 +1,53 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +struct S1 { + long a; + char b; + string<9> s; +}; + +struct S2 { + long a; + struct S3 { + long a; + short b, b1; + char c; + } b; + sequence <S1> c, c2, c3, c4, c5, c6, c7; +}; + + +// Check that structs are detected down in other types + + +typedef struct s4 {long a;} T1; +union U1 switch (long) { +case 1: + struct S5 {unsigned short a;} a; +case 2: + union U2 switch (char) { + case 'a': + boolean a; + case 'b': + struct s6 {long a; boolean b;} c; + } b; +}; + diff --git a/lib/ic/test/ic_SUITE_data/syntax1.idl b/lib/ic/test/ic_SUITE_data/syntax1.idl new file mode 100644 index 0000000000..83c7de7943 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax1.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Check syntax errors +// + + +typedef long T1 _; + + + diff --git a/lib/ic/test/ic_SUITE_data/syntax2.idl b/lib/ic/test/ic_SUITE_data/syntax2.idl new file mode 100644 index 0000000000..10498206c1 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax2.idl @@ -0,0 +1,27 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% +struct S2 { + long a_arr[99]; + struct S3 { + long a;_arr[99] + boolean b_arr[99]; + } b; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/syntax3.idl b/lib/ic/test/ic_SUITE_data/syntax3.idl new file mode 100644 index 0000000000..69ab6b9783 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax3.idl @@ -0,0 +1,20 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% +typdef long T1; + diff --git a/lib/ic/test/ic_SUITE_data/syntax4.idl b/lib/ic/test/ic_SUITE_data/syntax4.idl new file mode 100644 index 0000000000..077a251729 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax4.idl @@ -0,0 +1,23 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% +union U1 switch (long) { +case 1: long a; +2: short b; +}; + diff --git a/lib/ic/test/ic_SUITE_data/syntax5.idl b/lib/ic/test/ic_SUITE_data/syntax5.idl new file mode 100644 index 0000000000..10af9fc18c --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax5.idl @@ -0,0 +1,22 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% +union U1 switch (enum E1 {kalle, sune}) { +case kalle: long a; +sune: short b; +}; diff --git a/lib/ic/test/ic_SUITE_data/syntax6.idl b/lib/ic/test/ic_SUITE_data/syntax6.idl new file mode 100644 index 0000000000..dc15704d94 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/syntax6.idl @@ -0,0 +1,20 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +constant long c1 = 0; diff --git a/lib/ic/test/ic_SUITE_data/type.idl b/lib/ic/test/ic_SUITE_data/type.idl new file mode 100644 index 0000000000..67e1d502bd --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/type.idl @@ -0,0 +1,190 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Check all types in IDL +// + +typedef long T01; +typedef unsigned long T02; +typedef short T03; +typedef unsigned short T04; +typedef float T05; +typedef double T06; +typedef char T07; +typedef boolean T08; +typedef octet T09; +typedef any T10; +typedef Object T11; +typedef T01 T12; + +// Template types +typedef sequence <long> T21; +typedef sequence <unsigned long> T22; +typedef sequence <short, 2> T23; +typedef sequence <unsigned short, 6> T24; +typedef sequence <float, 12> T25; +typedef sequence <double> T26; +typedef sequence <char, 1> T27; +typedef sequence <boolean> T28; +typedef sequence <octet, 9> T29; +typedef sequence <any> T30; +typedef sequence <Object,2 > T31; +typedef sequence <T01> T32; +typedef sequence <sequence <sequence <T32> > > T33; + +struct S1 { + long a; + boolean b; +}; + +struct S2 { + long a; + struct S3 { + long a; + boolean b; + } b; +}; + +union U1 switch (enum E1 {kalle1, sune1}) { +case kalle1: long a; +default: boolean b; +case sune1: octet c; +}; + +union U2 switch (enum E2 {kalle2, sune2}) { +case kalle2: long a; +default: struct S4 { long a; short b;} b; +case sune2: octet c; +}; + +// Typedefs of above types + +typedef struct S11 { + long a; + boolean b; +} T41; + +typedef struct S21 { + long a; + struct S3 { + long a; + boolean b; + } b; +} T42; + +typedef union U11 switch (enum E3 {kalle3, sune3}) { +case kalle3: long a; +default: boolean b; +case sune3: octet c; +} T43; + +typedef union U21 switch (enum E4 {kalle4, sune4}) { +case kalle4: long a; +default: struct S4 { long a; short b;} b; +case sune4: octet c; +} T44; + + + + +// Array versions + +typedef long T01_arr[99]; +typedef unsigned long T02_arr[99]; +typedef short T03_arr[99]; +typedef unsigned short T04_arr[99]; +typedef float T05_arr[99]; +typedef double T06_arr[99]; +typedef char T07_arr[99]; +typedef boolean T08_arr[99]; +typedef octet T09_arr[99]; +typedef any T10_arr[99]; +typedef Object T11_arr[99]; +typedef T01 T12_arr[99]; + +typedef sequence <long> T21_arr[99]; +typedef sequence <unsigned long> T22_arr[99]; +typedef sequence <short, 2> T23_arr[99]; +typedef sequence <unsigned short, 6> T24_arr[99]; +typedef sequence <float, 12> T25_arr[99]; +typedef sequence <double> T26_arr[99]; +typedef sequence <char, 1> T27_arr[99]; +typedef sequence <boolean> T28_arr[99]; +typedef sequence <octet, 9> T29_arr[99]; +typedef sequence <any> T30_arr[99]; +typedef sequence <Object,2 > T31_arr[99]; +typedef sequence <T01> T32_arr[99]; +typedef sequence <sequence <sequence <T32> > > T33_arr[99]; + +struct S12 { + long a; + boolean b_arr[99]; +}; + +struct S22 { + long a_arr[99]; + struct S3 { + long a_arr[99]; + boolean b_arr[99]; + } b; +}; + +union U12 switch (enum E12 {kalle12, sune12}) { +case kalle12: long a_arr[99]; +default: boolean b; +case sune12: octet c; +}; + +union U22 switch (enum E22 {kalle22, sune22}) { +case kalle22: long a; +default: struct S4 { long a; short b;} b_arr[99]; +case sune22: octet c; +}; + +// Typedefs of above types + +typedef struct S13 { + long a_arr[99]; + boolean b; +} T41_arr[99]; + +typedef struct S23 { + long a; + struct S3 { + long a; + boolean b_arr[99]; + char c; + } b; +} T42_arr[99]; + +typedef union U13 switch (enum E13 {kalle13, sune13}) { +case kalle13: long a; +default: boolean b_arr[99]; +case sune13: octet c; +} T43_arr[99]; + +typedef union U23 switch (enum E23 {kalle23, sune23}) { +case kalle23: long a_arr[99]; +default: struct S4 { long a; short b;} b_arr[99]; +case sune23: octet c_arr[99]; +} T44_arr[99]; + + + diff --git a/lib/ic/test/ic_SUITE_data/typeid.idl b/lib/ic/test/ic_SUITE_data/typeid.idl new file mode 100644 index 0000000000..6e99f4a50d --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/typeid.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +interface I1 {}; + +module M1 { interface I1 {};}; + +module M2 { module M1 { interface I1 {};};}; + +module M3 { module M2 { module M1 { interface I1 {};};};}; + + diff --git a/lib/ic/test/ic_SUITE_data/u_case_mult.idl b/lib/ic/test/ic_SUITE_data/u_case_mult.idl new file mode 100644 index 0000000000..3c30e144d8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_case_mult.idl @@ -0,0 +1,54 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// Check that case labels are not duplicated + +union U1 switch (long) { +case 1 : long a; +case 1 : short b; +}; + +union U2 switch (char) { +case 'c' : long a; +case 'c' : short b; +}; + +union U2b switch (char) { +case 'c' : +case 'c' : long a; +case 'e': long b; +case 'c': long c; +}; + +union U3 switch (enum E1 {kalle, kula}) { +case kula : long a; +case kula : short b; +}; + +union U4 switch (boolean) { +case TRUE : long a; +case TRUE : short b; +}; + +union U5 switch (boolean) { +case TRUE : long a; +default: short p; +default: short pp; +}; + diff --git a/lib/ic/test/ic_SUITE_data/u_default.idl b/lib/ic/test/ic_SUITE_data/u_default.idl new file mode 100644 index 0000000000..e5d94a5e54 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_default.idl @@ -0,0 +1,51 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Checking that default labels are correct in TK +// + +interface i1 { + union U1 switch (long) { + default: long a; + case 1: case 2: long b; + }; + + union U2 switch (long) { + case 0: default: long a; + case 1: case 2: long b; + }; + + union U3 switch (long) { + case -1: long aa; + case 0: default: long a; + case 1: case 2: long b; + }; + + union U4 switch (long) { + case -1: long aa; + case 0: long a; + case 1: case 2: long b; + }; + + U1 op0(); + U2 op1(); + U3 op2(); + U4 op3(); +}; diff --git a/lib/ic/test/ic_SUITE_data/u_mult.idl b/lib/ic/test/ic_SUITE_data/u_mult.idl new file mode 100644 index 0000000000..b916861eec --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_mult.idl @@ -0,0 +1,61 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +// Check multiply defined declarators + +enum E2 {kal, kula, E1}; // legal, but used below + +// Now check that declarator a is multiply defined in all unions below +union U0 switch (long) { +case 0: long a; +case 1: short a; +}; +union U00 switch (char) { +case 'c' : long a; +case 'f' : char c; +case 'b' : short a; +}; +union U000 switch (boolean) { +case TRUE: long a; +case FALSE: short a; +}; +union U0000 switch (E2) { +case kal: long a; +case kula: short a; +}; + + + + +// Check that enum name duplication is found. + +union U1 switch (enum E1 {kalle, kula, E1}) { +case E1 : long a; // legal +case kalle : short E1; // illegal +}; + + +// This is legal, but ended up here anyway + +union U2 switch(::E2) { +case kal : long a; +case kula : short b; +default : boolean E1; +}; diff --git a/lib/ic/test/ic_SUITE_data/u_norm.idl b/lib/ic/test/ic_SUITE_data/u_norm.idl new file mode 100644 index 0000000000..e23796b8ca --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_norm.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +union U1 switch (long) { +case 1: long a; +case 2: case 3: short b; +}; + + +union U2 switch (unsigned short) { +case 10: boolean a; +case 188: char b; +default: string c; +}; + + +union U3 switch (enum E1 {kalle, kula, boll}) { +case kalle: long a; +case kula: U2 b; +}; + +enum E2 {Cissi, Anders}; + +union U4 switch (::E2) { +case Cissi: U1 a; +default: case Anders: unsigned long b; +}; + +union U5 switch(char) { +case 'e': long a; +case 'b': case 'f': char b; +default: struct S {long a; boolean b;} c; +}; + + +// Now check that references can be used as case values + +const long c1 = 9; +const long c2 = 10; + +union U6 switch (long) { +case c1: boolean a; +case ::c2: boolean b; +}; + + diff --git a/lib/ic/test/ic_SUITE_data/u_type.idl b/lib/ic/test/ic_SUITE_data/u_type.idl new file mode 100644 index 0000000000..44e3326305 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/u_type.idl @@ -0,0 +1,82 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + + +// +// Check that case values match declared discriminator type +// + + +const long longC = 0; +const short shortC = 0; +const char charC = 'c'; +const string stringC = "Yacht"; + +enum E1 {kalle, kula}; + +union U1 switch (long) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U2 switch (unsigned long) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U3 switch (short) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U4 switch (unsigned short) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case kalle : long f; +}; + +union U5 switch (char) { +case TRUE : long b; +case stringC : long d; +case shortC : long e; +case kalle : long f; +}; + + +union U6 switch (E1) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case shortC : long e; +}; + +union U7 switch (enum E2 {ja, nej, kanske}) { +case 'c' : long a; +case TRUE : long b; +case stringC : long d; +case shortC : long e; +}; + diff --git a/lib/ic/test/ic_SUITE_data/undef_id.idl b/lib/ic/test/ic_SUITE_data/undef_id.idl new file mode 100644 index 0000000000..01a35c4ef8 --- /dev/null +++ b/lib/ic/test/ic_SUITE_data/undef_id.idl @@ -0,0 +1,63 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1997-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% + +// +// Check that undefined ids are detected +// + +typedef T7 T1; + +const char c1 = ::c0; +const T01 c2 = 'h'; +const T7 c3 = 9; + +interface i1 { + T17 op(); + long op2( in T7 a); + attribute T7 a1, a2; + readonly attribute T17 a3; +}; + +union U1 switch (long) { +case 1: long a; +case ::g : short b; +}; + +union U2 switch (enum E1 {kalle, kula}) { +case kula1: long a; +case kalle : short b; +}; + +union U3 switch (long) { +case kula2: long a; +case ::E3::kalle : short b; +case ::E4::kalle : short c; +}; + +enum E2 {kalle2, kula2}; + +union U4 switch (E2) { +case kula1: long a; +case kula1: long b; +case c3: short c; +}; + + + + diff --git a/lib/ic/test/ic_be_SUITE.erl b/lib/ic/test/ic_be_SUITE.erl new file mode 100644 index 0000000000..e3caf7bdff --- /dev/null +++ b/lib/ic/test/ic_be_SUITE.erl @@ -0,0 +1,69 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. 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 : Test suite for the backends of the IDL compiler +%%%---------------------------------------------------------------------- + +-module(ic_be_SUITE). +-include("test_server.hrl"). + + +-export([all/1,plain/1]). + + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%% Top of cases + +all(suite) -> [plain]. + + + +plain(doc) -> + ["Checking code for the plain backend."]; +plain(suite) -> []; +plain(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(slask), + File = filename:join(DataDir, plain), + + ?line ok = ic:gen(File,stdopts(OutDir)++[{be,erl_plain}]), + + ok. + + + + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + + + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + diff --git a/lib/ic/test/ic_be_SUITE_data/plain.idl b/lib/ic/test/ic_be_SUITE_data/plain.idl new file mode 100644 index 0000000000..ee0a995807 --- /dev/null +++ b/lib/ic/test/ic_be_SUITE_data/plain.idl @@ -0,0 +1,33 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +module m { + + struct s { + long x; + long y; + }; + + interface i { + + void foo( in s a, out short b ); + + }; + +}; + diff --git a/lib/ic/test/ic_pp_SUITE.erl b/lib/ic/test/ic_pp_SUITE.erl new file mode 100644 index 0000000000..d68242bf3a --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE.erl @@ -0,0 +1,647 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. 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 : Test suite for the IDL preprocessor +%%---------------------------------------------------------------------- + +-module(ic_pp_SUITE). +-include("test_server.hrl"). + + + +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). +-define(GCC, "g++"). +-define(GCC_VER, "2.95.3"). + +-export([all/1]). +-export([arg/1]). +-export([arg_norm/1]). +-export([cascade/1]). +-export([cascade_norm/1]). +-export([comment/1]). +-export([comment_norm/1]). +-export([concat/1]). +-export([concat_norm/1]). +-export([define/1]). +-export([define_norm/1]). +-export(['if'/1]). +-export([if_norm/1]). +-export([if_zero/1]). +-export([misc/1]). +-export([misc_norm/1]). +-export([improp_nest_constr/1]). +-export([improp_nest_constr_norm/1]). +-export([inc/1]). +-export([inc_norm/1]). +-export([line/1]). +-export([line_norm/1]). +-export([nopara/1]). +-export([nopara_norm/1]). +-export([predef/1]). +-export([predef_norm/1]). +-export([predef_time/1]). +-export([predef_time_norm/1]). +-export([self_ref/1]). +-export([self_ref_norm/1]). +-export([separate/1]). +-export([separate_norm/1]). +-export([swallow_sc/1]). +-export([swallow_sc_norm/1]). +-export([unintended_grp/1]). +-export([unintended_grp_norm/1]). +-export([cases/0, init_all/1, finish_all/1]). + + +all(doc) -> ["Preprocessing tests for IC"]; +all(suite) -> + {req, [], {conf, init_all, cases(), finish_all}}. + +init_all(Config) -> + if + is_list(Config) -> + case os:type() of + {win32, _} -> + {skipped, "Very unplesent to run on windows"}; + _ -> + check_gcc(Config) + end; + true -> + exit("Config not a list") + end. + +check_gcc(Config) -> + case os:find_executable(?GCC) of + false -> + {skipped, + lists:flatten(io_lib:format("Can not run without ~s in path", + [?GCC]))}; + _ -> + case trim(os:cmd(?GCC++" --version")) of + ?GCC_VER++[] -> + Config; + ?GCC_VER++[D|_] when is_integer(D), D>=$0, D=<$9 -> + fail_gcc(?GCC_VER++[D]); + ?GCC_VER++_ -> + Config; + Ver -> + fail_gcc(Ver) + end + end. + +fail_gcc(Ver) -> + {skipped, lists:flatten(io_lib:format("Need ~s v~s, not ~s", + [?GCC, ?GCC_VER, Ver]))}. + +trim(S) -> lists:reverse(skip_white(lists:reverse(skip_white(S)))). + +skip_white([$\s|T]) -> skip_white(T); +skip_white([$\n|T]) -> skip_white(T); +skip_white([$\r|T]) -> skip_white(T); +skip_white([$\t|T]) -> skip_white(T); +skip_white(L) -> L. + + +finish_all(Config) -> + Config. + + +cases() -> + [arg, cascade, comment, concat, define, misc, 'if', improp_nest_constr, inc, + line, nopara, predef, predef_time, self_ref, separate, swallow_sc, + unintended_grp]. + + + +%%-------------------------------------------------------------------- +%% arg +%%-------------------------------------------------------------------- + +arg(suite) -> [arg_norm]; +arg(doc) -> ["Check #define with some arguments"]. + +arg_norm(doc) -> ["Checks arguments for #define."]; +arg_norm(suite) -> []; +arg_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(arg_norm), + File = filename:join(DataDir, arg), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% cascade +%%-------------------------------------------------------------------- + +cascade(suite) -> [cascade_norm]; +cascade(doc) -> ["Check cascade #define"]. + +cascade_norm(doc) -> ["Check cascade #define."]; +cascade_norm(suite) -> []; +cascade_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(cascade_norm), + File = filename:join(DataDir, cascade), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% comment +%%-------------------------------------------------------------------- + +comment(suite) -> [comment_norm]; +comment(doc) -> ["Check comments"]. + +comment_norm(doc) -> ["Check comments."]; +comment_norm(suite) -> []; +comment_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(comment_norm), + File = filename:join(DataDir, comment), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% concat +%%-------------------------------------------------------------------- + +concat(suite) -> [concat_norm]; +concat(doc) -> ["Check concatinations, i.e ## "]. + +concat_norm(doc) -> ["Check concatinations, i.e ## ."]; +concat_norm(suite) -> []; +concat_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(concat_norm), + File = filename:join(DataDir, concat), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% define +%%-------------------------------------------------------------------- + +define(suite) -> [define_norm]; +define(doc) -> ["Check misceleaneous #define"]. + +define_norm(doc) -> ["Check misceleaneous #define."]; +define_norm(suite) -> []; +define_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(define_norm), + File = filename:join(DataDir, define), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% if +%%-------------------------------------------------------------------- + +'if'(suite) -> [if_norm, if_zero]; +'if'(doc) -> ["Check #if, #elif, and #endif. Note these are not implementen and will ~n + result in an error message from internal_pp"]. + +if_norm(doc) -> ["Check #if, #elif, and #endif. ."]; +if_norm(suite) -> []; +if_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(if_norm), + File = filename:join(DataDir, 'if'), + + ?line ok = test_file(File, DataDir), + ok. + +if_zero(doc) -> ["Check #if 0"]; +if_zero(suite) -> []; +if_zero(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(if_zero), + File = filename:join(DataDir, if_zero), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% inc +%%-------------------------------------------------------------------- + +inc(suite) -> [inc_norm]; +inc(doc) -> ["Check #include"]. + +inc_norm(doc) -> ["Check #include."]; +inc_norm(suite) -> []; +inc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(inc_norm), + File = filename:join(DataDir, inc), + + ?line ok = test_file(File, DataDir), + ok. + + + +%%-------------------------------------------------------------------- +%% improp_nest_constr +%%-------------------------------------------------------------------- + +improp_nest_constr(suite) -> [improp_nest_constr_norm]; +improp_nest_constr(doc) -> ["Check improperly nested constructs"]. + +improp_nest_constr_norm(doc) -> ["Check improperly nested constructs."]; +improp_nest_constr_norm(suite) -> []; +improp_nest_constr_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(improp_nest_constr_norm), + File = filename:join(DataDir, improp_nest_constr), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% misc +%%-------------------------------------------------------------------- + +misc(suite) -> [misc_norm]; +misc(doc) -> ["Misceleaneous checks"]. + +misc_norm(doc) -> ["Misceleaneous checks."]; +misc_norm(suite) -> []; +misc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(misc_norm), + File = filename:join(DataDir, misc), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% line +%%-------------------------------------------------------------------- + +line(suite) -> [line_norm]; +line(doc) -> ["Checks #line"]. + +line_norm(doc) -> ["Checks #line."]; +line_norm(suite) -> []; +line_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(line_norm), + File = filename:join(DataDir, line), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% nopara +%%-------------------------------------------------------------------- + +nopara(suite) -> [nopara_norm]; +nopara(doc) -> ["Checks #define with no parameters"]. + +nopara_norm(doc) -> ["Checks #define with no parameters."]; +nopara_norm(suite) -> []; +nopara_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(nopara_norm), + File = filename:join(DataDir, nopara), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% predef +%%-------------------------------------------------------------------- + +predef(suite) -> [predef_norm]; +predef(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__"]. + +predef_norm(doc) -> ["Checks predefined macros. Note: not __TIME__ and __DATE__."]; +predef_norm(suite) -> []; +predef_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(predef_norm), + File = filename:join(DataDir, predef), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% predef_time +%%-------------------------------------------------------------------- + +predef_time(suite) -> [predef_time_norm]; +predef_time(doc) -> ["Checks the predefined macros __TIME__ and __DATE__"]. + +predef_time_norm(doc) -> ["Checks the predefined macros __TIME__ and __DATE__."]; +predef_time_norm(suite) -> []; +predef_time_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(predef_time_norm), + File = filename:join(DataDir, predef_time), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% self_ref +%%-------------------------------------------------------------------- + +self_ref(suite) -> [self_ref_norm]; +self_ref(doc) -> ["Checks self referring macros"]. + +self_ref_norm(doc) -> ["Checks self referring macros."]; +self_ref_norm(suite) -> []; +self_ref_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(self_ref_norm), + File = filename:join(DataDir, self_ref), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% separate +%%-------------------------------------------------------------------- + +separate(suite) -> [separate_norm]; +separate(doc) -> ["Checks separete expansion of macro arguments"]. + +separate_norm(doc) -> ["Checks separete expansion of macro arguments."]; +separate_norm(suite) -> []; +separate_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(separate_norm), + File = filename:join(DataDir, separate), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% swallow_sc +%%-------------------------------------------------------------------- + +swallow_sc(suite) -> [swallow_sc_norm]; +swallow_sc(doc) -> ["Checks swallowing an undesirable semicolon"]. + +swallow_sc_norm(doc) -> ["Checks swallowing an undesirable semicolon."]; +swallow_sc_norm(suite) -> []; +swallow_sc_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(swallow_sc_norm), + File = filename:join(DataDir, swallow_sc), + + ?line ok = test_file(File, DataDir), + ok. + + +%%-------------------------------------------------------------------- +%% unintended_grp +%%-------------------------------------------------------------------- + +unintended_grp(suite) -> [unintended_grp_norm]; +unintended_grp(doc) -> ["Checks unintended grouping of arithmetic"]. + +unintended_grp_norm(doc) -> ["Checks unintended grouping of arithmetic."]; +unintended_grp_norm(suite) -> []; +unintended_grp_norm(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + _OutDir = ?OUT(unintended_grp_norm), + File = filename:join(DataDir, unintended_grp), + + ?line ok = test_file(File, DataDir), + ok. + + + + + +test_file(FileT, DataDir) -> + case test_file_1(FileT, DataDir) of + ok -> ok; + Chars -> + io:put_chars(Chars), + {error,{FileT,DataDir}} + end. + +test_file_1(FileT, DataDir) -> + Tok = string:tokens(FileT, "/"), + FileName = lists:last(Tok), + File = FileT++".idl", + + ?line test_server:format("File ~p~n",[File]), + ?line test_server:format("FileName ~p~n",[FileName]), + + Flags = "-I"++DataDir, + + ?line test_server:format("Flags ~p~n",[Flags]), + + ?line Erl = pp_erl(File, Flags), + ?line Gcc = pp_gcc(File, Flags), + + ?line case Erl of + {error,_ErlError} -> + ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]); + {warning, _ErlWar} -> + ?line test_server:format("Internal_pp Result ~n==================~n~p~n~n",[Erl]); + _ -> + ?line test_server:format("Internal_pp Result ~n==================~n~s~n~n",[Erl]) + end, + + ?line case Gcc of + {error,GccError} -> + Error = string:tokens(GccError, "\n"), + ?line test_server:format(?GCC" Result ~n==========~n~p~n~n", + [Error]); + _ -> + ?line test_server:format(?GCC" Result ~n==========~n~s~n~n",[Gcc]) + end, + + + + ?line case {Erl,Gcc} of + {{warning,W}, {error,X}} -> + ?line case is_ok(W,X) of + yes -> + ok; + no -> + io_lib:format("Internal_pp found Warning = ~p ~n" + ?GCC" found Error = ~p~n",[W,X]) + end; + + + {{warning,W}, _} -> + io_lib:format(?GCC" did not find warnings while ~n" + "Internal_pp found the following Warning = ~p~n",[W]); + + {{error,E}, {error,X}} -> + ?line case is_ok(E,X) of + yes -> + ok; + no -> + io_lib:format("Internal_pp found Error = ~p ~n" + ?GCC" found Error = ~p~n",[E,X]) + end; + + {{error,E}, _} -> + ?line case FileName of + "if" -> + ?line case if_res(E) of + ok -> + ok; + _ -> + io_lib:format(?GCC" did not find errors while ~n" + "Internal_pp found the following Error = ~p~n",[E]) + end; + _ -> + io_lib:format(?GCC" did not find errors while ~n" + "Internal_pp found the following Error = ~p~n",[lists:flatten(E)]) + end; + + {_, {error,X}} -> + io_lib:format("Internal_pp did not find errors while ~n" + ?GCC" found the following Error = ~p~n",[X]); + + _ -> + + ?line file:write_file("/tmp/Erl.pp",list_to_binary(Erl)), + ?line file:write_file("/tmp/Gcc.pp",list_to_binary(Gcc)), + + ?line Res = os:cmd("diff -b -w /tmp/Erl.pp /tmp/Gcc.pp"), + ?line test_server:format("///////////{error,E} E ~p FileName~p~n",[Res,FileName]), + ?line case {Res, FileName} of + {[], _} -> + ?line test_server:format("Diff = [] OK!!!!!!~n"), + ok; + {_, "predef_time"} -> + Tokens = string:tokens(Res,"\n"), + ?line test_server:format("///////////{error,E} Tokens~p~n",[Tokens]), + case Tokens of + ["3c3",_,"---",_,"5c5",_,"---",_,"9c9",_,"---",_] -> + ok; + _ -> + io_lib:format("Diff Result = ~p~n",[Res]) + end; + _ -> + io_lib:format("Diff Result = ~p~n",[Res]) + end + end. + + + + + +pp_erl(File, Flags) -> + case ic_pp:run(File,Flags) of + {ok, [$#, $ , $1 | Rest], []} -> + [$#, $ , $1 | Rest]; + {ok, [$#, $ , $1 | _Rest], Warning} -> + {warning,Warning}; + {error,Error} -> + {error,Error} + end. + +pp_gcc(File, Flags) -> + Cmd = ?GCC" -x c++ -E", + Line = Cmd++" "++Flags++" "++File, + + case os:cmd(Line) of + [$#, $ , $1 | Rest] -> + [$#, $ , $1 | Rest]; + Res -> + + case string:str(Res,"# 1 \"") of + 0 -> + {error,Res}; + X -> + {error, string:sub_string(Res, 1, X-1)} + end + end. + + +is_ok([],_Gcc) -> + yes; +is_ok([{FileName,Line,Text}|T],Gcc) -> + Str = FileName++":"++integer_to_list(Line)++": "++Text, + case string:str(Gcc,Str) of + 0 -> + io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]), + no; + _X -> + is_ok(T,Gcc) + end; +is_ok([Str|T],Gcc) -> + case string:str(Gcc,Str) of + 0 -> + io:format("~n is_ok Internal_pp missed Error = ~s~n",[Str]), + no; + _X -> + is_ok(T,Gcc) + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + +if_res(E) -> + if_res(E,1). + +if_res([H|T],Nr) -> + %% Dir = "/clearcase/otp/libraries/ic/test/ic_pp_SUITE_data/if.idl", + case {Nr, H} of + {1, {_Dir, 2, "only '#if 0' is implemented at present"}} -> + if_res(T,Nr+1); + {2, {_Dir, 3, "only '#if 0' is implemented at present"}} -> + if_res(T,Nr+1); + {3, {_Dir, 5, "`else' command is not implemented at present"}} -> + if_res(T,Nr+1); + {4, {_Dir, 9, "`elif' command is not implemented at present"}} -> + if_res(T,Nr+1); + {5, {_Dir, 11, "`else' command is not implemented at present"}} -> + ok; + _ -> + error + end; +if_res(_, _) -> + error. + + + diff --git a/lib/ic/test/ic_pp_SUITE_data/arg.idl b/lib/ic/test/ic_pp_SUITE_data/arg.idl new file mode 100644 index 0000000000..b4d266121d --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/arg.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define xstr (s) str(s) +#define str(s) #s +#define foo 4 + +xstr(foo); + +#define x(kalle)stina +x(kurt) +x + +#define y(kalle) stina +y(kurt) +y + +#define a(kalle) stina +a(kurt) +a + +#define b (kalle) stina +b(kurt) diff --git a/lib/ic/test/ic_pp_SUITE_data/cascade.idl b/lib/ic/test/ic_pp_SUITE_data/cascade.idl new file mode 100644 index 0000000000..8dff1ee99f --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/cascade.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define BUFS 1020 +#define TABS BUFS +#undef BUFS +#define BUFS 37 + + +main() +{ + TABS; + +} diff --git a/lib/ic/test/ic_pp_SUITE_data/comment.idl b/lib/ic/test/ic_pp_SUITE_data/comment.idl new file mode 100644 index 0000000000..d2ca3e7872 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/comment.idl @@ -0,0 +1,72 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define T 12 +#define F T + +//comment +/*exception except {};*/ + +// comment + // comment +/* another */ + /* another */ +/* still +another */ + /* still + another */ +__LINE__ +/* yet \ + another */ +// yet \ + another +__LINE__ + +#include "all.c" +#include <all.c> +#include /* comment */ "all.c" +#include /* comment */ <all.c> +#include "all.c" /* comment */ +#include <all.c> /* comment */ +#include // "all.c" +#include // <all.c> +#include "all.c" // comment +#include <all.c> // comment +#include "all/*cc*/.c" +#include <all/*cc*/.c> + +main() +{ + printf(" %d \n",F); + a(); + +} +//comment +/*exception hell {};*/ +#undef T +#define T "3/*com\ +ment*/4" +a() +{ + printf(" %d \n",F); + printf(" %d \n",T); +} + +b() +{} + diff --git a/lib/ic/test/ic_pp_SUITE_data/concat.idl b/lib/ic/test/ic_pp_SUITE_data/concat.idl new file mode 100644 index 0000000000..b8527fadfc --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/concat.idl @@ -0,0 +1,60 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define sune kurt +#define a(name) a #name name##_command +#define b(name) b #name name## _command +#define c(name) c #name name ##_command +#define d(name) d #name name ## _command +#define e(name) e #name command ## _command +#define f(name) f #name command ## %_command +#define g(name) g #name name ## %_command +#define h(name) h #name %_command ## name +#define i(name) i #name name ## _ ## name +#define j(name) j #name name ## name +#define k(name) k #name name ## name +#define l(name) l #name !name ## name +#define m(name) m #name name ## !name +#define n(name) n #name !name ## !name +#define o(name) stina +#define p(name) name +#define q1(name) q1 #name j(name) ## j(name) +#define q2(name) q2 #name j(name) +#define q3(name) q3 #name !! ## j(name) +#define q4(name) q4 #name ## j(name) + +a(quit) +b(quit) +c(quit) +d(quit) +e(quit) +f(quit) +g(sune) +h(sune) +i(sune) +j(sune) +l(sune) +m(sune) +n(sune) +k(j(sune)) +k(o(sune)) +k(p(sune)) +q1(sune) +q2(sune) +q3(sune) +q4(sune) diff --git a/lib/ic/test/ic_pp_SUITE_data/define.idl b/lib/ic/test/ic_pp_SUITE_data/define.idl new file mode 100644 index 0000000000..6aac63dd1e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/define.idl @@ -0,0 +1,41 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define 8 +#define +#define a +#define _a +#define b dfs +#define 9 fdas +#define a8 +#define A +#define (c) fadfas +#define )c) fadfas +#define % c) fadfas +#define d(p) kfdsa +#define e(p) sinus(p) +#warning warning line +#define w%er percent +#define q() no_para +#warning warning line +#undef +#undef 8 +#undef a +#undef b +#undef _a d(kk) + diff --git a/lib/ic/test/ic_pp_SUITE_data/if.idl b/lib/ic/test/ic_pp_SUITE_data/if.idl new file mode 100644 index 0000000000..c381fa73ee --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/if.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define kurt 12 +#if !true +#if X == 1 +ett +#else +else +#endif +true +#elif kurt +trueelif +#else +trueelse +#endif +end diff --git a/lib/ic/test/ic_pp_SUITE_data/if_zero.idl b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl new file mode 100644 index 0000000000..d715f9d61e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/if_zero.idl @@ -0,0 +1,31 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#if 0 +pelle = mallan +#endif +pelle = stina +#if 0 +kalle = stina +#endif +kalle = mallan +#if 0 +kurt = fia +#endif +fia = kurt + diff --git a/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl new file mode 100644 index 0000000000..463ee3c695 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/improp_nest_constr.idl @@ -0,0 +1,30 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define double(x) (2*(x)) +#define call_with_1(x) x(1) + +#define strange(file) fprintf (file, "%s %d", + +main() +{ + call_with_1(double); + strange(stderr) p, 35) + +} + diff --git a/lib/ic/test/ic_pp_SUITE_data/inc.idl b/lib/ic/test/ic_pp_SUITE_data/inc.idl new file mode 100644 index 0000000000..0dcd637082 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/inc.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +int x; + +#include "head.h" +#warning line nr +main() +{ + printf(test()); +} + + + + + + + + +#define C false +#define Z on +#include "inc2.h" +#undef Z +"Ca" C +"Za" Z +#include "inc2.h" +"Cb" C +"Zb" Z + +main() +{ +#define Q(a,b) sinus(a,b kurt ## b) + if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q); + printf(" %d \n",F); + a(); +} +//comment +/*exception +hell {};*/ +#undef T +#define T "3/*com\ment*/4" +#define T 33 +#define F again +a () +{ + printf(" %d \n",F); + printf(" %d \n",T); +} + +b() +{} + diff --git a/lib/ic/test/ic_pp_SUITE_data/included1.idl b/lib/ic/test/ic_pp_SUITE_data/included1.idl new file mode 100644 index 0000000000..4cd26c4543 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/included1.idl @@ -0,0 +1,35 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-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% +#ifndef INCLUDED1_IDL +#define INCLUDED1_IDL + + +#ifndef SOMETHING +#endif + + +struct s { + + long l; + +}; + + + +#endif diff --git a/lib/ic/test/ic_pp_SUITE_data/included2.idl b/lib/ic/test/ic_pp_SUITE_data/included2.idl new file mode 100644 index 0000000000..7cc44eef3e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/included2.idl @@ -0,0 +1,41 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-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% +#ifndef INCLUDED2_IDL +#define INCLUDED2_IDL + +#include "included1.idl" + + +#ifdef SOMETHING +#endif + + +module m { + + struct t { + + s st; + + }; + + +}; + + +#endif diff --git a/lib/ic/test/ic_pp_SUITE_data/includer.idl b/lib/ic/test/ic_pp_SUITE_data/includer.idl new file mode 100644 index 0000000000..c6ebc234e8 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/includer.idl @@ -0,0 +1,45 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2000-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% +#ifndef INCLUDER_IDL +#define INCLUDER_IDL + +#include "included1.idl" +#include "included2.idl" + +#ifdef SOMETHING +#endif + + + +module n { + + interface j { + + s op(in m::t inpar); + + }; + +}; + + + + +#endif + + diff --git a/lib/ic/test/ic_pp_SUITE_data/line.idl b/lib/ic/test/ic_pp_SUITE_data/line.idl new file mode 100644 index 0000000000..5bd9c9446d --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/line.idl @@ -0,0 +1,45 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#line +#line 8 +#line 8a +#line 12 abc.c +#line 12 "kurt.c" +#warning fdafdsaf + + +#define T 12 +#define F T +#define Q(a) sinus(a) +#undef Q +# +#line 12 +#warning test of warning +#warning second of warning +#warning third of warning +#pragma kurt +#ident kurt +#kurt fdsafd +#line 20 +main() +{ + if (Q(34,56)=='NULL') printf(" T AAA%sEEEE \n",Q); + printf(" %d \n",F); +} +sune diff --git a/lib/ic/test/ic_pp_SUITE_data/misc.idl b/lib/ic/test/ic_pp_SUITE_data/misc.idl new file mode 100644 index 0000000000..9c18610fcf --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/misc.idl @@ -0,0 +1,44 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define str(s) #s +str(fool); +str(foo); +str(kurt); +#define xstr(s) str(s) +#define foo 4 +#define kurt sune +#define sune 17 + +xstr(fool); +xstr(foo); +xstr(kurt); + +#define a(b) b #8b +#define r(b) b # +#define t(b) b ## a +a(sinus) + +#define ww #www +ww + +#define x 14 + y +#define y 12 + #x +x + +#define e(a) cosinus(a) diff --git a/lib/ic/test/ic_pp_SUITE_data/nopara.idl b/lib/ic/test/ic_pp_SUITE_data/nopara.idl new file mode 100644 index 0000000000..1bb137da11 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/nopara.idl @@ -0,0 +1,35 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#11a +#define xstr str(s) + kurt*2; +#define asdf pragma +#asdf +#define asd #pragma asd + +#10 +#12 8kurt + +#define sss "stringing in the rain" +#define ddd "string +ing in the rain" asd +#line 20 +#include "head.h" qqqq +#include %!# +#include <sys.h> + diff --git a/lib/ic/test/ic_pp_SUITE_data/predef.idl b/lib/ic/test/ic_pp_SUITE_data/predef.idl new file mode 100644 index 0000000000..d8abcb25d5 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/predef.idl @@ -0,0 +1,33 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define b(q,w) kurt q w + + +b(__LINE__, __FILE__) +__LINE__ +__FILE__ + + + +b(__INCLUDE_LEVEL__, __BASE_FILE__) +__INCLUDE_LEVEL__ +__BASE_FILE__ + +Line __LINE__ +#include "predef.h" diff --git a/lib/ic/test/ic_pp_SUITE_data/predef_time.idl b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl new file mode 100644 index 0000000000..05e3ba9175 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/predef_time.idl @@ -0,0 +1,24 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define b(q,w) kurt q w +b(__DATE__, __TIME__) +__DATE__ +__TIME__ + +#include "predef_time.h" diff --git a/lib/ic/test/ic_pp_SUITE_data/self_ref.idl b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl new file mode 100644 index 0000000000..a44666272e --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/self_ref.idl @@ -0,0 +1,26 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define foo (4 + foo) + + +main() +{ + foo; + +} diff --git a/lib/ic/test/ic_pp_SUITE_data/separate.idl b/lib/ic/test/ic_pp_SUITE_data/separate.idl new file mode 100644 index 0000000000..a3faf9b986 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/separate.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define xstr(s) str(s) +#define str(s) #s +#define foo 4 +#define str1(s) #s lose(s) +#define foo1 4 + +main() +{ + str(foo); + str1(foo1); + xstr(foo); + +#define qxstr(s) qstr(s) + qxstr(qfoo); +#define qstr(s) #s + qstr( 4 ) ; +#define qfoo 4 + qstr(qfoo); +} diff --git a/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl new file mode 100644 index 0000000000..71ed329ca6 --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/swallow_sc.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +/* comment \ + ends */ +// comment\ +ends +Line __LINE__ +#define SKIP_SPACES(p, limit) \ +{register char *lim = (limit); \ + while (p != lim) { \ + if (*p++ != ' ') { \ + p--; break; }}} + + +main() +{ + if (*p != 0) + SKIP_SPACES (ppp, lim); + else + a = 17; +} diff --git a/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl new file mode 100644 index 0000000000..3618bab1bc --- /dev/null +++ b/lib/ic/test/ic_pp_SUITE_data/unintended_grp.idl @@ -0,0 +1,29 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +#define ceil_div( xz, yz) (xz + yz - 1) / yz +#define ceil_div2(xz, yz) ((xz) + (yz) - 1) / (yz) + +#define b kurt + +main() +{ + ceil_div(b & c, sizeof(int)); + ceil_div2(b & c, sizeof(int)); + +} diff --git a/lib/ic/test/ic_pragma_SUITE.erl b/lib/ic/test/ic_pragma_SUITE.erl new file mode 100644 index 0000000000..0edb5d4717 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE.erl @@ -0,0 +1,295 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. 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% +%% +%% +%%----------------------------------------------------------------- +%% File: ic_pragma_SUITE.erl +%% +%% Description: +%% Test suite for the IFR object registration when +%% pragmas are engaged +%% +%%----------------------------------------------------------------- +-module(ic_pragma_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, init_all/1, finish_all/1]). +-export([ifr_pragma_reg/1, pragma_error/1, uggly_pragmas/1]). + + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(REMAP_EXCEPT(F), case catch F of + {'EXCEPTION', E} -> exit(E); + R -> R + end). +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [ifr_pragma_reg,pragma_error,uggly_pragmas]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- +init_all(Config) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]), + Config. + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with pragmas +%%----------------------------------------------------------------- +ifr_pragma_reg(doc) -> + ["Checks that IFR object is correctly registered under pragma engagement."]; +ifr_pragma_reg(suite) -> []; +ifr_pragma_reg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_pragma_reg_run(Config)). + +ifr_pragma_reg_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_pragma_reg), + File0 = filename:join(DataDir, reg_m0), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_pragma_files()), + code:add_pathz(OutDir), + + %% OE_register for all files + ?line ok = 'oe_reg_m0':'oe_register'(), + + %% Pragma registration test + OE_IFR = orber_ifr:find_repository(), + io:format("~n##### Starting the test case #####~n"), + check_pragma_effect(OE_IFR,"IDL:M1/T1:1.0"), + check_pragma_effect(OE_IFR,"DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3"), + check_pragma_effect(OE_IFR,"IDL:P2/T3:1.0"), + check_pragma_effect(OE_IFR,"IDL:P1/M2/T4:2.4"), + + %% OE_unregister for all files + ?line ok = 'oe_reg_m0':'oe_unregister'(), + code:del_path(OutDir), + ok. + + +ifr_pragma_files() -> ['oe_reg_m0']. + + +check_pragma_effect(OE_IFR,ID) -> + io:format("Checking for existance of : ~s~n",[ID]), + case orber_ifr:lookup_id(OE_IFR,ID) of + [] -> + test_server:fail(ID ++ " does not exist"), + false; + {Def,_} -> + io:format("Id refers to = {~p,#Bin}~n",[Def]), + true + end. + + + + +%%----------------------------------------------------------------- +%% Test Case: Syntactical / Semantical error pragma definitions +%%----------------------------------------------------------------- +pragma_error(doc) -> + ["Finds errornous pragma definitions under compilation."]; +pragma_error(suite) -> []; +pragma_error(Config) when is_list(Config) -> + ?REMAP_EXCEPT(pragma_error_run(Config)). + +pragma_error_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(pragma_error), + File1 = filename:join(DataDir, reg_m1), + File2 = filename:join(DataDir, reg_m2), + File3 = filename:join(DataDir, reg_m3), + File4 = filename:join(DataDir, reg_m4), + File5 = filename:join(DataDir, reg_m5), + File6 = filename:join(DataDir, reg_m6), + + ?line error = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File5, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + + ?line error = ic:gen(File6, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ok. + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with realy uggly placed pragmas +%%----------------------------------------------------------------- +uggly_pragmas(doc) -> + ["Checks that IFR object is correctly registered under really uggly pragma engagement."]; +uggly_pragmas(suite) -> []; +uggly_pragmas(Config) when is_list(Config) -> + ?REMAP_EXCEPT(uggly_pragmas_run(Config)). + +uggly_pragmas_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_pragma_reg), + File0 = filename:join(DataDir, uggly), + + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}]), + + ?line ok = compile(OutDir, uggly_pragma_files()), + code:add_pathz(OutDir), + + %% OE_register for all files + ?line ok = 'oe_uggly':'oe_register'(), + + %% Pragma registration test + OE_IFR = orber_ifr:find_repository(), + io:format("~n##### Starting the test case #####~n"), + + check_pragma_effect(OE_IFR, "IDL:M:1.0"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:10"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:11"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:17"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:34"), + check_pragma_effect(OE_IFR, "IDL:Exc1:2.2"), + check_pragma_effect(OE_IFR, "IDL:Exc2:2.2"), + check_pragma_effect(OE_IFR, "IDL:S:1.0"), + check_pragma_effect(OE_IFR, "IDL:U:1.0"), + check_pragma_effect(OE_IFR, "LOCAL:SomeLocalId:23"), + + %% OE_unregister for all files + ?line ok = 'oe_uggly':'oe_unregister'(), + + code:del_path(OutDir), + ok. + + +uggly_pragma_files() -> ['oe_uggly']. + + + + +%%---------------------------- + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl new file mode 100644 index 0000000000..80f0f2cdd1 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m0.idl @@ -0,0 +1,77 @@ + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +// Normal pragmas + +module M1 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + +#pragma prefix "P1" + +module M2 { + + module M3 { + +#pragma prefix "P2" + + interface I1 { + void Op( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; + +#pragma version T4 2.4 + +}; + + + +/* + + Specified types with the following scoped names + and RepositoryIds + + ::M1::T1 IDL:M1/T1:1.0 + + ::M1::T2 DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3 + + ::M2::M3::T3 IDL:P2/T3:1.0 + + ::M2::T4 IDL:P1/M2/T4:2.4 + +*/ + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl new file mode 100644 index 0000000000..6c22788290 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m1.idl @@ -0,0 +1,75 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Bad pragma IDs + +// Completelly bad id +module M1 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "CompletelyBadId" + +}; + + +// Bad id, should start with DCE +module M2 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "BAD:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + +// Bad version in ID : not a short number +module M3 { + + typedef long T1; + + typedef long T2; + +#pragma ID T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:ABCD" + +}; + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl new file mode 100644 index 0000000000..1751751295 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m2.idl @@ -0,0 +1,40 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Bad pragma versions + + +// Bad major version : not a short number +module M1 { + + typedef long T4; + +#pragma version T4 2000000000.4 + +}; + +// Bad minor version : not a short number +module M2 { + + typedef long T4; + +#pragma version T4 2.4000000000000 + +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl new file mode 100644 index 0000000000..b7c9da249f --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m3.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Bad pragma prefixs + +module M2 { + + module M3 { + +#pragma prefix P2 // Should be "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl new file mode 100644 index 0000000000..0c7079e3dd --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m4.idl @@ -0,0 +1,64 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Unrecognmizable pragmas + +module M1 { + + typedef long T1; + + typedef long T2; + + + // Should be ID directive + +#pragma ShouldBeId T2 "DCE:d62207a2-011e-11ce-88b4-0800090b5d3e:3" + +}; + + // Should be prefix directive + +#pragma ShouldBePrefix "P1" + +module M2 { + + module M3 { + + // Should be prefix directive + +#pragma ShouldBePrefix "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; + + + // Should be version + +#pragma ShouldBeVersion T4 2.4 + +}; + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl new file mode 100644 index 0000000000..cbf053fac4 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m5.idl @@ -0,0 +1,28 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +// Version not in valid form : major.ninor + +module M1 { + + typedef long T4; + + #pragma version T4 2 + +}; diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl new file mode 100644 index 0000000000..b7c9da249f --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m6.idl @@ -0,0 +1,38 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Bad pragma prefixs + +module M2 { + + module M3 { + +#pragma prefix P2 // Should be "P2" + + interface I1 { + void foo( in short b, + out short c); + }; + typedef long T3; + }; + + + typedef long T4; +}; + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl new file mode 100644 index 0000000000..349c13b244 --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/reg_m7.idl @@ -0,0 +1,62 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% + +// Very uggly pragmas + + +#pragma prefix "P1" // Normal pragma + +module M4 { + + module M5 { + +#pragma prefix "P2" // Inside a parameter list + + interface I1 { + void Op( + #pragma prefix "P2" // Inside a parameter list + in short b, + #pragma prefix "P2" // Inside a parameter list + out short c + #pragma prefix "P2" // Inside a parameter list + ); + }; + typedef long T3; + }; + +}; + + + +/* + + Specified types with the following scoped names + and RepositoryIds + + ::M4::M5::T3 IDL:P2/T3:1.0 + +*/ + + + + + + + + diff --git a/lib/ic/test/ic_pragma_SUITE_data/uggly.idl b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl new file mode 100644 index 0000000000..8ed3ac57ec --- /dev/null +++ b/lib/ic/test/ic_pragma_SUITE_data/uggly.idl @@ -0,0 +1,204 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// Really uggly pragmas + + +struct S { + +#pragma ID TDL1 "LOCAL:SomeLocalId:1" +#pragma ID TDL1 "LOCAL:SomeLocalId:2" + +long a + +#pragma ID TDL1 "LOCAL:SomeLocalId:3" +#pragma ID TDL1 "LOCAL:SomeLocalId:4" + +; + +#pragma ID TDL1 "LOCAL:SomeLocalId:5" +#pragma ID TDL1 "LOCAL:SomeLocalId:6" + +long b + +#pragma ID TDL1 "LOCAL:SomeLocalId:7" +#pragma ID TDL1 "LOCAL:SomeLocalId:8" + +; + + +#pragma ID TDL1 "LOCAL:SomeLocalId:9" +#pragma ID TDL1 "LOCAL:SomeLocalId:10" + +}; + + +typedef long TDL1; + + +exception Exc1{ + +#pragma version Exc1 2.2 +#pragma ID TDL2 "LOCAL:SomeLocalId:11" + +}; + + +typedef long TDL2; + + +exception Exc2 { + +#pragma version Exc2 2.2 +#pragma ID TDL3 "LOCAL:SomeLocalId:11" + + long a + +#pragma ID TDL3 "LOCAL:SomeLocalId:12" +#pragma ID TDL3 "LOCAL:SomeLocalId:13" + + ; + +#pragma ID TDL3 "LOCAL:SomeLocalId:14" +#pragma ID TDL3 "LOCAL:SomeLocalId:15" + + long b + +#pragma ID TDL3 "LOCAL:SomeLocalId:16" + + ; + +#pragma ID TDL3 "LOCAL:SomeLocalId:17" + + +}; + +typedef long TDL3; + +enum E { +#pragma ID E "LOCAL:SomeLocalId:18" + a +#pragma ID E "LOCAL:SomeLocalId:19" + , +#pragma ID E "LOCAL:SomeLocalId:20" + b +#pragma ID E "LOCAL:SomeLocalId:21" +, +#pragma ID E "LOCAL:SomeLocalId:22" + c +#pragma ID E "LOCAL:SomeLocalId:23" +}; + + + +union U switch (long) { + +#pragma ID TDL4 "LOCAL:SomeLocalId:24" + + case 1: + +#pragma ID TDL4 "LOCAL:SomeLocalId:25" + + long a + +#pragma ID TDL4 "LOCAL:SomeLocalId:26" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:27" + + case 2: + +#pragma ID TDL4 "LOCAL:SomeLocalId:28" + + case 3: + +#pragma ID TDL4 "LOCAL:SomeLocalId:29" + +long b + +#pragma ID TDL4 "LOCAL:SomeLocalId:30" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:31" + + default : + +#pragma ID TDL4 "LOCAL:SomeLocalId:32" + +long c + +#pragma ID TDL4 "LOCAL:SomeLocalId:33" + +; + +#pragma ID TDL4 "LOCAL:SomeLocalId:34" + +}; + + +typedef long TDL4; + + + +module M { + + interface I { + + void fun1( + +#pragma version fun1 3.0 +#pragma ID TDL5 "LOCAL:SomeLocalId:35" + + in short b + +#pragma ID TDL5 "LOCAL:SomeLocalId:36" +#pragma ID TDL5 "LOCAL:SomeLocalId:37" + + , + +#pragma ID TDL5 "LOCAL:SomeLocalId:38" +#pragma ID TDL5 "LOCAL:SomeLocalId:39" + + out short c + +#pragma ID TDL5 "LOCAL:SomeLocalId:40" +#pragma ID TDL5 "LOCAL:SomeLocalId:41" + + ); + + + typedef long TDL5; + + + void fun2( + +#pragma ID TDL6 "LOCAL:SomeLocalId:42" +#pragma ID TDL6 "LOCAL:SomeLocalId:43" + + ); + + typedef long TDL6; + + }; + + + +}; + diff --git a/lib/ic/test/ic_register_SUITE.erl b/lib/ic/test/ic_register_SUITE.erl new file mode 100644 index 0000000000..ae7578199a --- /dev/null +++ b/lib/ic/test/ic_register_SUITE.erl @@ -0,0 +1,425 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. 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% +%% +%% +%%----------------------------------------------------------------- +%% File: ic_register_SUITE.erl +%% +%% Description: +%% Test suite for the IFR object registration +%% +%%----------------------------------------------------------------- +-module(ic_register_SUITE). + +-include("test_server.hrl"). +-include_lib("orber/include/corba.hrl"). +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, init_all/1, finish_all/1, ifr_reg_unreg/1]). +-export([ifr_inheritence_reg/1,ifr_reg_unreg_with_inheritence/1]). +-export([ifr_reg_unreg_with_inheritence_bad_order/1]). + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([]). + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(REMAP_EXCEPT(F), case catch F of + {'EXCEPTION', E} -> exit(E); + R -> R + end). +%% Standard options to the ic compiler, NOTE unholy use of OutDir + +-define(OUT(X), filename:join([?config(priv_dir, Config), gen, to_list(X)])). + + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["Description", "more description"]; +all(suite) -> {req, + [mnesia], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [ifr_reg_unreg,ifr_reg_unreg_with_inheritence, + ifr_reg_unreg_with_inheritence_bad_order,ifr_inheritence_reg]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_all(Config) -> + io:format("Setting up.....~n"), + mnesia:stop(), + mnesia:delete_schema([node()]), + mnesia:create_schema([node()]), + mnesia:start(), + orber:install([node()]), + orber:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + io:format("Setting down.....~n"), + orber:stop(), + orber:uninstall(), + mnesia:stop(), + mnesia:delete_schema([node()]), + Config. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR type registration +%%----------------------------------------------------------------- +ifr_reg_unreg(doc) -> + ["Checks that the generated register/unregister " + "code for the IFR is correct."]; +ifr_reg_unreg(suite) -> []; +ifr_reg_unreg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unregt_run(Config)). + +ifr_reg_unregt_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_files()), + code:add_pathz(OutDir), + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m8':'oe_unregister'(), + code:del_path(OutDir), + ok. + +ifr_reg_unreg_files() -> ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10']. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration when object inheritence +%% is applied and registered. +%%----------------------------------------------------------------- +ifr_reg_unreg_with_inheritence(doc) -> + ["Checks that the generated register/unregister " + "code for the IFR is correct, and works even when" + "the object inheritence is registered. This fixes" + "two bugs in ifr that caused crash when trying to" + "use OE_register/OE_unregister in a sequence of" + "compiled files that contained interfaces who" + "inherited others in sequence."]; +ifr_reg_unreg_with_inheritence(suite) -> []; +ifr_reg_unreg_with_inheritence(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_run(Config)). + +ifr_reg_unreg_with_inheritence_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File3 = filename:join(DataDir, reg_m11), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m11':'oe_register'(), + ?line ok = 'oe_reg_m12':'oe_register'(), + ?line ok = 'oe_reg_m8':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m11':'oe_unregister'(), + ?line ok = 'oe_reg_m12':'oe_unregister'(), + code:del_path(OutDir), + ok. + +ifr_reg_unreg_with_inheritence_files() -> + ['oe_reg_m8', 'oe_reg_m9', 'oe_reg_m10', 'oe_reg_m11', 'oe_reg_m12']. + + + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration when object inheritence +%% is applied and registered in a bad order. +%% Modules included and used from an ifr object +%% are not allready registered when the current +%% object is getting registered. +%%----------------------------------------------------------------- +ifr_reg_unreg_with_inheritence_bad_order(doc) -> + ["This tests that ifr registration is done with + the right write order." + "Modules included and used from an ifr object" + "are tested if allready registered when the " + "current object is getting registered."]; +ifr_reg_unreg_with_inheritence_bad_order(suite) -> []; +ifr_reg_unreg_with_inheritence_bad_order(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_reg_unreg_with_inheritence_bad_order_run(Config)). + +ifr_reg_unreg_with_inheritence_bad_order_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + case catch 'oe_reg_m12':'oe_register'() of + {'EXIT',Reason1} -> + io:format("IFR object missing detected : ~p~n",[Reason1]), + true; + _ -> + test_server:fail("Failed to detect object missing : IDL:M1:1.0~n") + end, + ?line ok = 'oe_reg_m9':'oe_register'(), + case catch 'oe_reg_m10':'oe_register'() of + {'EXIT',Reason2} -> + io:format("IFR object missing detected : ~p~n",[Reason2]), + true; + _ -> + test_server:fail("Failed to detect object missing : IDL:M0:1.0~n") + end, + ?line ok = 'oe_reg_m9':'oe_unregister'(), + code:del_path(OutDir), + ok. + + + +%%----------------------------------------------------------------- +%% Test Case: IFR registration with inheritence +%%----------------------------------------------------------------- +ifr_inheritence_reg(doc) -> + ["Checks that IFR object inheritence is correctly registered."]; +ifr_inheritence_reg(suite) -> []; +ifr_inheritence_reg(Config) when is_list(Config) -> + ?REMAP_EXCEPT(ifr_inh_reg_run(Config)). + +ifr_inh_reg_run(Config) -> + DataDir = ?config(data_dir, Config), + OutDir = ?OUT(ifr_reg_unreg), + File0 = filename:join(DataDir, reg_m8), + File1 = filename:join(DataDir, reg_m9), + File2 = filename:join(DataDir, reg_m10), + File3 = filename:join(DataDir, reg_m11), + File4 = filename:join(DataDir, reg_m12), + ?line ok = ic:gen(File0, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File0, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File1, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File1, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File2, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File2, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File3, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File3, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = ic:gen(File4, stdopts(OutDir)++[{preproc_flags, + "-I" ++ DataDir}] ), + ?line {ok, []} = ic:gen(File4, stdopts(OutDir)++[silent2, {preproc_flags, + "-I" ++ DataDir}]), + ?line ok = compile(OutDir, ifr_reg_unreg_with_inheritence_files()), + code:add_pathz(OutDir), + %% OE_register for all files + ?line ok = 'oe_reg_m8':'oe_register'(), + ?line ok = 'oe_reg_m9':'oe_register'(), + ?line ok = 'oe_reg_m10':'oe_register'(), + ?line ok = 'oe_reg_m11':'oe_register'(), + ?line ok = 'oe_reg_m12':'oe_register'(), + + %% Inheritence registration test + OE_IFR = orber_ifr:find_repository(), + %% Interfaces that not inherit from other interfaces + ?line [] = get_inh(OE_IFR, "IDL:m0/i0:1.0"), + ?line [] = get_inh(OE_IFR, "IDL:m1/i1:1.0"), + ?line [] = get_inh(OE_IFR, "IDL:m3/i3:1.0"), + %% Interfaces that inherit from other interfaces + ?line ["IDL:m1/i1:1.0"] = get_inh(OE_IFR, "IDL:m2/i2:1.0"), + ?line ["IDL:m1/i1:1.0","IDL:m2/i2:1.0"] = get_inh(OE_IFR, "IDL:m4/i4:1.0"), + ?line ["IDL:m3/i3:1.0"] = get_inh(OE_IFR, "IDL:m4/i5:1.0"), + + %% OE_unregister for all files + ?line ok = 'oe_reg_m8':'oe_unregister'(), + ?line ok = 'oe_reg_m9':'oe_unregister'(), + ?line ok = 'oe_reg_m10':'oe_unregister'(), + ?line ok = 'oe_reg_m11':'oe_unregister'(), + ?line ok = 'oe_reg_m12':'oe_unregister'(), + code:del_path(OutDir), + ok. + + +get_inh(OE_IFR,ID) -> + OE_CURRENT = orber_ifr:lookup_id(OE_IFR,ID), + INH_LIST = orber_ifr:get_base_interfaces(OE_CURRENT), + case INH_LIST of + [] -> + io:format("~nInterface ~p inherits from nobody.~n",[ID]), + []; + _ -> + print_inh_list_ids(ID, INH_LIST, []) + end. + +print_inh_list_ids(_ID, [], Acc) -> + lists:reverse(Acc); +print_inh_list_ids(ID, [H|T], Acc) -> + io:format("~n"), + Parent = orber_ifr:get_id(H), + io:format("Interface ~p inherits from ~p.~n", [ID, Parent]), + print_inh_list_ids(ID, T, [Parent|Acc]). + + + + +stdopts(OutDir) -> + [{outdir, OutDir}, {maxerrs, infinity}]. + + +compile(Dir, Files) -> + compile(Dir, Files, []). + +compile(Dir, Files, Opts) -> + {ok, Cwd} = file:get_cwd(), + file:set_cwd(Dir), + io:format("Changing to ~p~n", [Dir]), + case catch do_compile(Files, Opts) of + ok -> + file:set_cwd(Cwd); + Err -> + file:set_cwd(Cwd), + test_server:fail(Err) + end. + +do_compile([], _Opts) -> ok; +do_compile([F | Fs], Opts) -> + io:format("Compiling ~p", [F]), + case compile:file(F, Opts) of + ok -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + {ok, _, _} -> + io:format(" ok~n", []), + do_load(F, Opts), + do_compile(Fs, Opts); + Err -> + io:format(" error: ~p~n", [Err]), + Err + end. + +do_load(File, Opts) -> + case lists:member(load, Opts) of + true -> + io:format("Loading file ~p", [File]), + code:purge(File), + R = code:load_abs(File), + io:format("Loaded: ~p", [R]); + false -> + ok + end. + + +to_list(X) when is_atom(X) -> atom_to_list(X); +to_list(X) -> X. + + + + + + + + + + + + + + + + + + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m10.idl b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl new file mode 100644 index 0000000000..9c1f126b64 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m10.idl @@ -0,0 +1,37 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// +// IDL for testing register/unregister in the IFR when using included specs +// +#include "reg_m9.idl" + +typedef sequence<long> Sequence1; + +#include "reg_m8.idl" + +module m2 { + + interface i2 : m1::i1 + { + short op3( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m11.idl b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl new file mode 100644 index 0000000000..607d695357 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m11.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// +// IDL for testing register/unregister in the IFR when using included specs +// + +module m3 { + + interface i3 + { + short op4( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m12.idl b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl new file mode 100644 index 0000000000..3dd9267655 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m12.idl @@ -0,0 +1,40 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// +// IDL for testing register/unregister in the IFR when using included specs +// Special case with multiple inheritence. +// +#include "reg_m10.idl" +#include "reg_m11.idl" + +module m4 { + + interface i4 : m2::i2 + { + short op5( in long a, inout char b, out long c ); + }; + + interface i5 : m3::i3 + { + short op6( in long a, inout char b, out long c ); + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m8.idl b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl new file mode 100644 index 0000000000..dc7432c05d --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m8.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// +// IDL for testing register/unregister in the IFR when using included specs +// +module m0 { + + interface i0 { + void op1( in short c ); + float op2( in char a); + + }; + + +}; + diff --git a/lib/ic/test/ic_register_SUITE_data/reg_m9.idl b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl new file mode 100644 index 0000000000..e937c41608 --- /dev/null +++ b/lib/ic/test/ic_register_SUITE_data/reg_m9.idl @@ -0,0 +1,32 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 1998-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% +// +// IDL for testing register/unregister in the IFR when using included specs +// +module m1 { + + interface i1 { + void op1( in short c ); + float op2( in char a); + + }; + + +}; + diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl new file mode 100644 index 0000000000..ee77ef0c4e --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE.erl @@ -0,0 +1,330 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. 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 : Test suite for the backends of the IDL compiler +%%%---------------------------------------------------------------------- + +-module(java_client_erl_server_SUITE). +-include("test_server.hrl"). + + +-export([all/1,init_all/1,finish_all/1,init_per_testcase/2,fin_per_testcase/2]). +-export([marshal_ll/1,marshal_ull/1, + marshal_l/1,marshal_ul/1, + marshal_s/1,marshal_us/1, + marshal_c/1,marshal_wc/1, + marshal_str/1, + marshal_any_3/1,marshal_any_2/1]). + + +%% Top of cases + +all(doc) -> + "Test of IC with a Java-client and an Erlang generic server. " + "The communication is via Erlang distribution."; +all(suite) -> {conf,init_all,cases(),finish_all}. + +cases() -> [marshal_ll,marshal_ull, + marshal_l,marshal_ul, + marshal_s,marshal_us, + marshal_c,marshal_wc, + marshal_str, + marshal_any_3,marshal_any_2]. + +init_all(Config) when is_list(Config) -> + case case code:priv_dir(jinterface) of + {error,bad_name} -> + false; + P -> + filelib:is_dir(P) + end + of + true -> + case find_executable(["java"]) of + false -> + {skip,"Found no Java VM"}; + Path -> + [{java,Path}|Config] + end; + false -> + {skip,"No jinterface application"} + end. + + +find_executable([]) -> + false; +find_executable([E|T]) -> + case os:find_executable(E) of + false -> find_executable(T); + Path -> Path + end. + +finish_all(Config) -> Config. + + + +%% Add/remove code path and watchdog before/after each test case. +%% +init_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:add_patha(DataDir), + + %% Since other test suites use the module m_i et,al, we have + %% to make sure we are using the right modules. + code:purge(m_i), + code:purge(m_i_impl), + code:purge(oe_java_erl_test), + code:load_file(m_i), + code:load_file(m_i_impl), + code:load_file(oe_java_erl_test), + + WatchDog = test_server:timetrap(test_server:seconds(20)), + [{watchdog, WatchDog}| Config]. + +fin_per_testcase(_Case, Config) -> + DataDir = ?config(data_dir, Config), + code:del_path(DataDir), + WatchDog = ?config(watchdog, Config), + test_server:timetrap_cancel(WatchDog). + + + +%%-------------------------------------------------------------------- +%% +%% Test cases + +marshal_ll(doc) -> + ["Testing marshalling of IDL long long"]; +marshal_ll(suite) -> []; +marshal_ll(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ll}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ll]), + ?line ok = m_i:stop(Server), + ok. + +marshal_ull(doc) -> + ["Testing marshalling of IDL unsigned long long"]; +marshal_ull(suite) -> []; +marshal_ull(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ull}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ull]), + ?line ok = m_i:stop(Server), + ok. + +marshal_l(doc) -> + ["Testing marshalling of IDL long"]; +marshal_l(suite) -> []; +marshal_l(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_l}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_l]), + ?line ok = m_i:stop(Server), + ok. + +marshal_ul(doc) -> + ["Testing marshalling of IDL unsigned long"]; +marshal_ul(suite) -> []; +marshal_ul(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_ul}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_ul]), + ?line ok = m_i:stop(Server), + ok. + +marshal_s(doc) -> + ["Testing marshalling of IDL short"]; +marshal_s(suite) -> []; +marshal_s(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_s}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_s]), + ?line ok = m_i:stop(Server), + ok. + +marshal_us(doc) -> + ["Testing marshalling of IDL unsigned short"]; +marshal_us(suite) -> []; +marshal_us(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_us}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_us]), + ?line ok = m_i:stop(Server), + ok. + +marshal_c(doc) -> + ["Testing marshalling of IDL char"]; +marshal_c(suite) -> []; +marshal_c(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_c}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_c]), + ?line ok = m_i:stop(Server), + ok. + +marshal_wc(doc) -> + ["Testing marshalling of IDL char"]; +marshal_wc(suite) -> []; +marshal_wc(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_wc}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_wc]), + ?line ok = m_i:stop(Server), + ok. + +marshal_str(doc) -> + ["Testing marshalling of IDL string"]; +marshal_str(suite) -> []; +marshal_str(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_str}), + ?line ok = java(?config(java, Config), DataDir, +%%% "-DOtpConnection.trace=4 " + "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_str]), + ?line ok = m_i:stop(Server), + ok. + +marshal_any_3(doc) -> + ["Testing marshalling of IDL any"]; +marshal_any_3(suite) -> []; +marshal_any_3(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_3}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_any_3]), + ?line ok = m_i:stop(Server), + ok. + +marshal_any_2(doc) -> + ["Testing marshalling of IDL any"]; +marshal_any_2(suite) -> []; +marshal_any_2(Config) when is_list(Config) -> + ?line DataDir = ?config(data_dir, Config), + ?line {ok,Server} = m_i:oe_create_link([], {local,marshal_any_2}), + ?line ok = java(?config(java, Config), DataDir, "JavaClient", + ["JavaClient",node(),erlang:get_cookie(),marshal_any_2]), + ?line ok = m_i:stop(Server), + ok. + +%%-------------------------------------------------------------------- +%% +%% Utilities + + +java(Java, Dir, ClassAndArgs) -> + cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs). + +java(Java, Dir, Class, Args) -> + java(Java, Dir, Class++" "++to_string(Args)). + +to_string([H|T]) when is_integer(H) -> + integer_to_list(H)++" "++to_string(T); +to_string([H|T]) when is_atom(H) -> + atom_to_list(H)++" "++to_string(T); +to_string([H|T]) when is_list(H) -> + lists:flatten(H)++" "++to_string(T); +to_string([]) -> []. + +% javac(Dir, File) -> +% cmd("javac -d "++Dir++" -classpath "++classpath(Dir)++" "++ +% filename:join(Dir, File)). + +classpath(Dir) -> + PS = + case os:type() of + {win32, _} -> ";"; + _ -> ":" + end, + Dir++PS++ + filename:join([code:lib_dir(ic),"priv","ic.jar"])++PS++ + filename:join([code:lib_dir(jinterface),"priv","OtpErlang.jar"])++PS++ + case os:getenv("CLASSPATH") of + false -> ""; + Classpath -> Classpath + end. + + +cmd(Cmd) -> + PortOpts = [{line,80},eof,exit_status,stderr_to_stdout], + io:format("<cmd> ~s~n", [Cmd]), + case catch open_port({spawn,Cmd}, PortOpts) of + Port when is_port(Port) -> + Result = cmd_loop(Port, []), + io:format("<cmd=~w>~n", [Result]), + case Result of + 0 -> ok; + ExitCode when is_integer(ExitCode) -> {error,ExitCode}; + Error -> Error + end; + {'EXIT',Reason} -> + {error,Reason} + end. + +cmd_loop(Port, Line) -> + receive + {Port,eof} -> + receive + {Port,{exit_status,ExitStatus}} -> + ExitStatus + after 1 -> + undefined + end; + {Port,{exit_status,ExitStatus}} -> + receive + {Port,eof} -> + ok after 1 -> ok end, + ExitStatus; + {Port,{data,{Tag,Data}}} -> + case Tag of + eol -> + io:put_chars([Line|cr_to_nl(Data)]), + io:nl(), + cmd_loop(Port, []); + noeol -> + cmd_loop(Port, [Line|cr_to_nl(Data)]) + end; + {'EXIT',Port,Reason} -> + {error,Reason}; + Other -> + io:format("WARNING: Unexpected at ~s:~p: ~p~n", + [?MODULE_STRING,?LINE,Other]), + cmd_loop(Port, Line) + end. + +%% Convert lonely CR to NL, and CRLF to NL +%% +cr_to_nl([$\r,$\n|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([$\r|T]) -> + [$\n|cr_to_nl(T)]; +cr_to_nl([C|T]) -> + [C|cr_to_nl(T)]; +cr_to_nl([]) -> + []. diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java new file mode 100644 index 0000000000..1881279ac8 --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/JavaClient.java @@ -0,0 +1,759 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2003-2009. 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% + * + */ +public class JavaClient { + + public static void main(String[] argv) + { + System.out.println("Hello World!"); + if (argv.length < 4) { + System.out.println("Too few arguments!"); + System.exit(1); + } + // for (int j = 0; j < argv.length; j++) + // System.out.println(argv[j]); + try { + if (argv[3].equals("marshal_ll")) { + System.out.println("marshal_ll"); + marshal_ll(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_ull")) { + marshal_ull(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_l")) { + marshal_l(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_ul")) { + marshal_ul(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_s")) { + marshal_s(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_us")) { + marshal_us(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_c")) { + marshal_c(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_wc")) { + marshal_wc(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_str")) { + marshal_str(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_any_3")) { + marshal_any_3(argv[0], argv[1], argv[2], argv[3]); + } + else if (argv[3].equals("marshal_any_2")) { + marshal_any_2(argv[0], argv[1], argv[2], argv[3]); + } + else { + System.out.println("Unknown test: "+argv[3]); + System.exit(2); + } + } catch (java.lang.Exception e) { + System.out.println("Exception!: "+e); + System.exit(3); + } + System.exit(0); + } + + + + static void marshal_ll(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + System.out.println("Just warming up.."+i); + verify_ll(i, 3, 2, 1); + verify_ll(i, 5, 4, 3); + verify_ll(i, -128, 0, 1); + // The small integer border + verify_ll(i, 255, 0, 1); + verify_ll(i, 256, 0, 1); + // The integer border + verify_ll(i, (1L<<26)-1L, 0L, 1); + verify_ll(i, 1L<<26, 0L, 1); + verify_ll(i, -(1L<<26), 0L, 1); + verify_ll(i, (1L<<27)-1L, 0L, 1); + verify_ll(i, 1L<<27, 0L, 1); + verify_ll(i, -(1L<<27), 0L, 1); + // Bignum byte borders + verify_ll(i, (1L<<32)-1L, 0L, 1); + verify_ll(i, 1L<<32, 0L, 1); + verify_ll(i, -(1L<<32)+1L, 0L, 1); + verify_ll(i, -(1L<<32), 0L, 1); + verify_ll(i, (1L<<40)-1L, 0L, 1); + verify_ll(i, 1L<<40, 0L, 1); + verify_ll(i, -(1L<<40)+1L, 0L, 1); + verify_ll(i, -(1L<<40), 0L, 1); + verify_ll(i, (1L<<48)-1L, 0L, 1); + verify_ll(i, 1L<<48, 0L, 1); + verify_ll(i, -(1L<<48)+1L, 0L, 1); + verify_ll(i, -(1L<<48), 0L, 1); + // Java long border + verify_ll(i, java.lang.Long.MAX_VALUE, 0L, 1); + verify_ll(i, java.lang.Long.MIN_VALUE, 0L, 1); + verify_ll(i, -1L, 0L, 1); + // Impossible decodes + verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 1); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 1L, 1); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, -1); + verify_ll_bad(i, java.lang.Long.MAX_VALUE, -1L, 2); + verify_ll_bad(i, java.lang.Long.MIN_VALUE, 0L, 2); + } + + static void marshal_ull(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_ull(i, 3, 2, 1); + verify_ull(i, 5, 4, 3); + // The small integer border + verify_ull(i, 255, 0, 1); + verify_ull(i, 256, 0, 1); + // The integer border + verify_ull(i, (1L<<26)-1L, 0L, 1); + verify_ull(i, 1L<<26, 0L, 1); + verify_ull(i, (1L<<27)-1L, 0L, 1); + verify_ull(i, 1L<<27, 0L, 1); + // Bignum byte borders + verify_ull(i, (1L<<32)-1L, 0L, 1); + verify_ull(i, 1L<<32, 0L, 1); + verify_ull(i, (1L<<40)-1L, 0L, 1); + verify_ull(i, 1L<<40, 0L, 1); + verify_ull(i, (1L<<48)-1L, 0L, 1); + verify_ull(i, 1L<<48, 0L, 1); + // Java long border + verify_ull(i, java.lang.Long.MAX_VALUE, 0L, 1); + verify_ull(i, java.lang.Long.MIN_VALUE, 0L, 1); + verify_ull(i, -1L, 0L, 1); + verify_ull(i, java.lang.Long.MAX_VALUE, + java.lang.Long.MIN_VALUE, 1); + // Impossible decodes + verify_ull_bad(i, -1L, -1L, 1); + verify_ull_bad(i, java.lang.Long.MAX_VALUE, -1L, 2); + } + + static void marshal_l(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_l(i, 3, 2, 1); + verify_l(i, 5, 4, 3); + verify_l(i, -128, 0, 1); + // The small integer border + verify_l(i, 255, 0, 1); + verify_l(i, 256, 0, 1); + // The integer border + verify_l(i, (1<<26)-1, 0, 1); + verify_l(i, 1<<26, 0, 1); + verify_l(i, -(1<<26), 0, 1); + verify_l(i, (1<<27)-1, 0, 1); + verify_l(i, 1<<27, 0, 1); + verify_l(i, -(1<<27), 0, 1); + // Java int border + verify_l(i, java.lang.Integer.MAX_VALUE, 0, 1); + verify_l(i, java.lang.Integer.MIN_VALUE, 0, 1); + // Impossible decodes + verify_l_bad(i, java.lang.Integer.MAX_VALUE, -1, 1); + verify_l_bad(i, java.lang.Integer.MIN_VALUE, 1, 1); + verify_l_bad(i, java.lang.Integer.MIN_VALUE, 0, -1); + } + + static void marshal_ul(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_ul(i, 3, 2, 1); + verify_ul(i, 5, 4, 3); + // The small integer border + verify_ul(i, 255, 0, 1); + verify_ul(i, 256, 0, 1); + // The integer border + verify_ul(i, (1<<26)-1, 0, 1); + verify_ul(i, 1<<26, 0, 1); + verify_ul(i, (1<<27)-1, 0, 1); + verify_ul(i, 1<<27, 0, 1); + // Java int border + verify_ul(i, java.lang.Integer.MAX_VALUE, 0, 1); + verify_ul(i, java.lang.Integer.MIN_VALUE, 0, 1); + verify_ul(i, -1, 0, 1); + verify_ul(i, java.lang.Integer.MAX_VALUE, + java.lang.Integer.MIN_VALUE, 1); + // Impossible decodes + verify_ul_bad(i, -1, -1, 1); + } + + static void marshal_s(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_s(i, 3, 2, 1); + verify_s(i, 5, 4, 3); + verify_s(i, -128, 0, 1); + // The small integer border + verify_s(i, 255, 0, 1); + verify_s(i, 256, 0, 1); + // Java short border + verify_s(i, java.lang.Short.MAX_VALUE, 0, 1); + verify_s(i, java.lang.Short.MIN_VALUE, 0, 1); + // Impossible decodes + verify_s_bad(i, java.lang.Short.MAX_VALUE, -1, 1); + verify_s_bad(i, java.lang.Short.MIN_VALUE, 1, 1); + verify_s_bad(i, java.lang.Short.MIN_VALUE, 0, -1); + } + + static void marshal_us(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_us(i, 3, 2, 1); + verify_us(i, 5, 4, 3); + // The small integer border + verify_us(i, 255, 0, 1); + verify_us(i, 256, 0, 1); + // Java short border + verify_us(i, java.lang.Short.MAX_VALUE, 0, 1); + verify_us(i, java.lang.Short.MIN_VALUE, 0, 1); + verify_us(i, -1, 0, 1); + verify_us(i, java.lang.Short.MAX_VALUE, + java.lang.Short.MIN_VALUE, 1); + // Impossible decodes + verify_us_bad(i, -1, -1, 1); + } + + static void marshal_c(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_c(i, '\3', '\2', 1); + verify_c(i, '\5', '\4', 3); + // The small integer border + verify_c(i, '\u00FF', '\0', 1); + verify_c(i, '\u0100', '\0', 1); + // Java char border + verify_c(i, java.lang.Character.MAX_VALUE, '\0', 1); + verify_c(i, java.lang.Character.MIN_VALUE, '\0', 1); + verify_c(i, java.lang.Character.MAX_VALUE, + java.lang.Character.MIN_VALUE, 1); + // Impossible decodes + verify_c_bad(i, '\u8000', '\0', 2); + } + + static void marshal_wc(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_wc(i, '\3', '\2', 1); + verify_wc(i, '\5', '\4', 3); + // The small integer border + verify_wc(i, '\u00FF', '\0', 1); + verify_wc(i, '\u0100', '\0', 1); + // Java char border + verify_wc(i, java.lang.Character.MAX_VALUE, '\0', 1); + verify_wc(i, java.lang.Character.MIN_VALUE, '\0', 1); + verify_wc(i, java.lang.Character.MAX_VALUE, + java.lang.Character.MIN_VALUE, 1); + // Impossible decodes + verify_c_bad(i, '\u8000', '\0', 2); + } + + static void marshal_str(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + // Just warming up.. + verify_str(i, 100, 100); + verify_str(i, 100, 1); + // Erlang string border + verify_str(i, 65535, 1); + verify_str(i, 2, 65535); + // Erlang string border out + verify_str(i, 65536, 1); + verify_str(i, 65536, 65536); + } + + static void marshal_any_3(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + com.ericsson.otp.ic.Any x = new com.ericsson.otp.ic.Any(); + com.ericsson.otp.ic.Any y = new com.ericsson.otp.ic.Any(); + com.ericsson.otp.ic.Any z = new com.ericsson.otp.ic.Any(); + + x.insert_longlong(java.lang.Long.MAX_VALUE); + y.insert_longlong(1L); + z.insert_longlong(java.lang.Long.MAX_VALUE-1L); + System.out.println("verify_any_3 longlong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_longlong(java.lang.Long.MIN_VALUE); + y.insert_longlong(-1L); + z.insert_longlong(java.lang.Long.MIN_VALUE+1L); + System.out.println("verify_any_3 longlong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulonglong(-1L); + y.insert_longlong(1L); + z.insert_ulonglong(-2L); + System.out.println("verify_any_3 ulonglong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulonglong(0L); + y.insert_longlong(-1L); + z.insert_ulonglong(1L); + System.out.println("verify_any_3 ulonglong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_long(java.lang.Integer.MAX_VALUE); + y.insert_long(1); + z.insert_long(java.lang.Integer.MAX_VALUE-1); + System.out.println("verify_any_3 long max"); + verify_any_3(i, x, y, 1, z); + + x.insert_long(java.lang.Integer.MIN_VALUE); + y.insert_long(-1); + z.insert_long(java.lang.Integer.MIN_VALUE+1); + System.out.println("verify_any_3 long min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulong(-1); + y.insert_long(1); + z.insert_ulong(-2); + System.out.println("verify_any_3 ulong max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ulong(0); + y.insert_long(-1); + z.insert_ulong(1); + System.out.println("verify_any_3 ulong min"); + verify_any_3(i, x, y, 1, z); + + x.insert_short(java.lang.Short.MAX_VALUE); + y.insert_short((short)1); + z.insert_short((short)(java.lang.Short.MAX_VALUE-1)); + System.out.println("verify_any_3 short max"); + verify_any_3(i, x, y, 1, z); + + x.insert_short(java.lang.Short.MIN_VALUE); + y.insert_short((short)-1); + z.insert_short((short)(java.lang.Short.MIN_VALUE+1)); + System.out.println("verify_any_3 short min"); + verify_any_3(i, x, y, 1, z); + + x.insert_ushort((short)-1); + y.insert_short((short)1); + z.insert_ushort((short)-2); + System.out.println("verify_any_3 ushort max"); + verify_any_3(i, x, y, 1, z); + + x.insert_ushort((short)0); + y.insert_short((short)-1); + z.insert_ushort((short)1); + System.out.println("verify_any_3 ushort min"); + verify_any_3(i, x, y, 1, z); + + x.insert_char('\377'); + y.insert_char('\1'); + z.insert_char('\376'); + System.out.println("verify_any_3 char max"); + verify_any_3(i, x, y, 1, z); + + x.insert_wchar('\uFFFF'); + y.insert_wchar('\u0001'); + z.insert_wchar('\uFFFE'); + System.out.println("verify_any_3 char max"); + verify_any_3(i, x, y, 1, z); + } + + static void marshal_any_2(String selfNode, String peerNode, + String cookie, String serverName) + throws java.lang.Exception + { + m._iStub i = new m._iStub(selfNode, peerNode, cookie, serverName); + m.s s = new m.s(); + com.ericsson.otp.ic.Any a = new com.ericsson.otp.ic.Any(); + // + s.ull_x = -1L; + s.ll_x = java.lang.Long.MAX_VALUE; + s.ll_y = 1L; + s.ull_z = -2L; + s.ll_z = java.lang.Long.MAX_VALUE-1L; + // + s.ul_x = -1; + s.l_x = java.lang.Integer.MAX_VALUE; + s.l_y = 1; + s.ul_z = -2; + s.l_z = java.lang.Integer.MAX_VALUE-1; + // + s.us_x = (short)-1; + s.s_x = java.lang.Short.MAX_VALUE; + s.s_y = (short)1; + s.us_z = (short)-2; + s.s_z = (short)(java.lang.Short.MAX_VALUE-1); + // + s.c_x = '\377'; + s.c_y = '\1'; + s.c_z = '\376'; + s.wc_x = '\uFFFF'; + s.wc_y = '\u0001'; + s.wc_z = '\uFFFE'; + m.sHelper.insert(a, s); + verify_any_2(i, a, 1); + + s.ull_x = 0L; + s.ll_x = java.lang.Long.MIN_VALUE; + s.ll_y = -1L; + s.ull_z = 1L; + s.ll_z = java.lang.Long.MIN_VALUE+1L; + // + s.ul_x = 0; + s.l_x = java.lang.Integer.MIN_VALUE; + s.l_y = -1; + s.ul_z = 1; + s.l_z = java.lang.Integer.MIN_VALUE+1; + // + s.us_x = (short)0; + s.s_x = java.lang.Short.MIN_VALUE; + s.s_y = (short)-1; + s.us_z = (short)1; + s.s_z = (short)(java.lang.Short.MIN_VALUE+1); + // + s.c_x = '\0'; + s.c_y = '\0'; + s.c_z = '\0'; + s.wc_x = '\u0000'; + s.wc_y = '\u0000'; + s.wc_z = '\u0000'; + m.sHelper.insert(a, s); + verify_any_2(i, a, 1); + } + + + static void verify_ll(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + System.out.println("verify_ll "+a); + a.ll_x = x; + a.ll_y = y; + long expected = (x - y)*(short)b; + long result = i.marshal_ll(a, (short)b); + if (result == expected) { + System.out.println("verify_ll("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ll("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_ull(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.ull_x = x; + a.ll_y = y; + long expected = (x - y)*(short)b; + long result = i.marshal_ull(a, (short)b); + if (result == expected) { + System.out.println("verify_ull("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ull("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_l(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.l_x = x; + a.l_y = y; + int expected = (x - y)*(short)b; + int result = i.marshal_l(a, (short)b); + if (result == expected) { + System.out.println("verify_l("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_l("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_ul(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.ul_x = x; + a.l_y = y; + int expected = (x - y)*(short)b; + int result = i.marshal_ul(a, (short)b); + if (result == expected) { + System.out.println("verify_ul("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_ul("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_s(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.s_x = (short)x; + a.s_y = (short)y; + short expected = (short)((x - y)*(short)b); + short result = i.marshal_s(a, (short)b); + if (result == expected) { + System.out.println("verify_s("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_s("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_us(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.us_x = (short)x; + a.s_y = (short)y; + short expected = (short)((x - y)*(short)b); + short result = i.marshal_us(a, (short)b); + if (result == expected) { + System.out.println("verify_us("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_us("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_c(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.c_x = x; + a.c_y = y; + char expected = (char)(((int)x - (int)y)*(short)b); + char result = i.marshal_c(a, (short)b); + if (result == expected) { + System.out.println("verify_c("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_c("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_wc(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + m.s a = new m.s(); + a.wc_x = x; + a.wc_y = y; + char expected = (char)(((int)x - (int)y)*(short)b); + char result = i.marshal_wc(a, (short)b); + if (result == expected) { + System.out.println("verify_wc("+x+", "+y+", "+b+") => " + +result); + } else { + System.out.println("verify_wc("+x+", "+y+", "+b+") => " + +result+" != "+expected); + System.exit(4); + } + } + + static void verify_str(m._iStub i, int a_len, int b_len) + throws java.lang.Exception + { + String a = mk_str(a_len); + String b = mk_str(b_len); + String expected = a + b; + String result = i.strcat(a, b); + if (result.equals(expected)) { + System.out.println("verify_str(\""+a+"\", \""+b+"\") => \"" + +result+"\""); + } else { + System.out.println("verify_str(\""+a+"\", \""+b+"\") => \"" + +result+"\" != \""+expected.length()+"\""); + System.exit(4); + } + } + + static String mk_str(int len) + throws StringIndexOutOfBoundsException + { + StringBuffer s = new StringBuffer(); + // 17 characters is prime relative all bases of two - on purpose + do s.append("qwertyuiopasdfghj"); while (s.length() < len); + return s.substring(0, len); + } + + static void verify_any_3(m._iStub i, + com.ericsson.otp.ic.Any x, + com.ericsson.otp.ic.Any y, + int b, + com.ericsson.otp.ic.Any expected) + throws java.lang.Exception + { + com.ericsson.otp.ic.Any result = i.marshal_any_3(x, y, (short)b); + if (! expected.equal(result)) { + System.exit(4); + } + } + + static void verify_any_2(m._iStub i, com.ericsson.otp.ic.Any a, int b) + throws java.lang.Exception + { + com.ericsson.otp.ic.Any result = i.marshal_any_2(a, (short)b); + if (! a.equal(result)) { + System.exit(4); + } + } + + + + static void verify_ll_bad(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + try { + verify_ll(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_ull_bad(m._iStub i, long x, long y, int b) + throws java.lang.Exception + { + try { + verify_ull(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_l_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_l(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_ul_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_ul(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_s_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_s(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_us_bad(m._iStub i, int x, int y, int b) + throws java.lang.Exception + { + try { + verify_us(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_c_bad(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + try { + verify_c(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + + static void verify_wc_bad(m._iStub i, char x, char y, int b) + throws java.lang.Exception + { + try { + verify_wc(i, x, y, b); + System.out.println("Expected exception missing!"); + System.exit(5); + } catch (com.ericsson.otp.erlang.OtpErlangDecodeException e) { + System.out.println("Expected exception: "+e); + } + } + +} diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src new file mode 100644 index 0000000000..de1503401c --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/Makefile.src @@ -0,0 +1,88 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 2003-2009. 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% +# +# +# Makefile.src for java_client_erl_server test +# Note: This file *must* work for both Unix and Windows +# +# We use both `rm' (Unix) and `del' (Windows) for removing files, but +# with a `-' in front so that the error in not finding `rm' (`del') on +# Windows (Unix) is ignored. +# +# VxWorks? XXX +# + +.SUFFIXES: +.SUFFIXES: .erl .idl .@EMULATOR@ .java + + +JAVAC = @JAVAC@ +ERLC = erlc + +# ic variables available from ts: +# +# ic_libpath: @ic_libpath@ +# ic_include_path: @ic_include_path@ + +IC_INCLUDE_PATH = @ic_include_path@ +IC_CLASSPATH = @ic_classpath@ + +JINTERFACE_CLASSPATH = @jinterface_classpath@ + +CLASSPATH = .@PS@$(IC_CLASSPATH)@PS@$(JINTERFACE_CLASSPATH)@PS@ + +GEN_JAVA_FILES = \ + m@DS@_iImplBase.java \ + m@DS@_iStub.java \ + +GEN_HRL_FILES = \ + m.hrl \ + m_i.hrl \ + oe_java_erl_test.hrl + +GEN_ERL_FILES = \ + m_i.erl \ + oe_java_erl_test.erl + +JAVA_FILES = $(GEN_JAVA_FILES) JavaClient.java +CLASS_FILES = $(JAVA_FILES:.java=.class) +ERL_FILES = $(GEN_ERL_FILES) m_i_impl.erl +EBINS = $(ERL_FILES:.erl=.@EMULATOR@) + + +all: $(CLASS_FILES) $(EBINS) + +clean: + -rm -f $(GEN_JAVA_FILES) $(CLASS_FILES) \ + $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS) + -del /F /Q $(GEN_JAVA_FILES) $(CLASS_FILES) \ + $(GEN_ERL_FILES) $(GEN_HRL_FILES) $(EBINS) + +$(GEN_JAVA_FILES) : java_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,java}" java_erl_test.idl + +$(CLASS_FILES) : $(JAVA_FILES) + $(JAVAC) -classpath $(CLASSPATH) $(JAVA_FILES) + +$(GEN_ERL_FILES) $(GEN_HRL_FILES): java_erl_test.idl + $(ERLC) -I $(IC_INCLUDE_PATH) "+{be,erl_genserv}" java_erl_test.idl + +.erl.@EMULATOR@: + $(ERLC) -I $(IC_INCLUDE_PATH) $< diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl new file mode 100644 index 0000000000..b72c972d3b --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/java_erl_test.idl @@ -0,0 +1,68 @@ + + +// %CopyrightBegin% +// +// Copyright Ericsson AB 2003-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% +module m { + + struct s { + long long ll_x; + unsigned long long ull_x; + long long ll_y; + long long ll_z; + unsigned long long ull_z; + + long l_x; + unsigned long ul_x; + long l_y; + long l_z; + unsigned long ul_z; + + short s_x; + unsigned short us_x; + short s_y; + short s_z; + unsigned short us_z; + + char c_x; + char c_y; + char c_z; + + wchar wc_x; + wchar wc_y; + wchar wc_z; + }; + + interface i { + long long marshal_ll( in s a, in short b ); + unsigned long long marshal_ull( in s a, in short b ); + + long marshal_l( in s a, in short b ); + unsigned long marshal_ul( in s a, in short b ); + + short marshal_s( in s a, in short b ); + unsigned short marshal_us( in s a, in short b ); + + char marshal_c( in s a, in short b ); + wchar marshal_wc( in s a, in short b ); + + string strcat( in string a, in string b ); + + any marshal_any_3( in any x, in any y, in short b ); + any marshal_any_2( in any a, in short b ); + }; + +}; diff --git a/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl new file mode 100644 index 0000000000..77e532288f --- /dev/null +++ b/lib/ic/test/java_client_erl_server_SUITE_data/m_i_impl.erl @@ -0,0 +1,169 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2003-2009. 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% +%% +%%-------------------------------------------------------------------- +-module(m_i_impl). + +-export([marshal_ll/3,marshal_ull/3, + marshal_l/3,marshal_ul/3, + marshal_s/3,marshal_us/3, + marshal_c/3,marshal_wc/3, + strcat/3, + marshal_any_3/4,marshal_any_2/3]). +-export([init/1,terminate/2,code_change/3]). + +-include("m.hrl"). + +-define(TK_M_S, {tk_struct, + "IDL:m/s:1.0", + "s", + [{"ll_x",tk_longlong}, + {"ull_x",tk_ulonglong}, + {"ll_y",tk_longlong}, + {"ll_z",tk_longlong}, + {"ull_z",tk_ulonglong}, + {"l_x",tk_long}, + {"ul_x",tk_ulong}, + {"l_y",tk_long}, + {"l_z",tk_long}, + {"ul_z",tk_ulong}, + {"s_x",tk_short}, + {"us_x",tk_ushort}, + {"s_y",tk_short}, + {"s_z",tk_short}, + {"us_z",tk_ushort}, + {"c_x",tk_char}, + {"c_y",tk_char}, + {"c_z",tk_char}, + {"wc_x",tk_wchar}, + {"wc_y",tk_wchar}, + {"wc_z",tk_wchar}|_]}). + + + +marshal_ll(State, #m_s{ll_x = X, ll_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_ull(State, #m_s{ull_x = X, ll_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_l(State, #m_s{l_x = X, l_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_ul(State, #m_s{ul_x = X, l_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_s(State, #m_s{s_x = X, s_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_us(State, #m_s{us_x = X, s_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + + +marshal_c(State, #m_s{c_x = X, c_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_wc(State, #m_s{wc_x = X, wc_y = Y}=_A, B) when integer(B) -> + R = (X - Y)*B, + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +strcat(State, A, B) when list(A), list(B) -> + R = A++B, + io:format("~p", [{?MODULE,?LINE,[length(A),length(B),A,B,R]}]), + {reply, R, State}; +strcat(State, A, B) -> + io:format("~p", [{?MODULE,?LINE,[A,B]}]), + {reply, [], State}. + +marshal_any_3(State, {any,TkX,_}=X, {any,_,_}=Y, B) when integer(B) -> + R = any(mul(sub(any(X), any(Y)), B), TkX), + io:format("~p", [{?MODULE,?LINE,[X,Y,B,R]}]), + {reply, R, State}. + +marshal_any_2(State, + {any,TkA,#m_s{ll_x=LL_X, ull_x=ULL_X, ll_y=LL_Y, + l_x=L_X, ul_x=UL_X, l_y=L_Y, + s_x=S_X, us_x=US_X, s_y=S_Y, + c_x=C_X, c_y=C_Y, + wc_x=WC_X, wc_y=WC_Y} = A}, + B) when integer(B) -> + {check_type_code,?TK_M_S} = {check_type_code,TkA}, + ULL_Z = (ULL_X - LL_Y) * B, + LL_Z = (LL_X - LL_Y) * B, + UL_Z = (UL_X - L_Y) * B, + L_Z = (L_X - L_Y) * B, + US_Z = (US_X - S_Y) * B, + S_Z = (S_X - S_Y) * B, + C_Z = (C_X - C_Y) * B, + WC_Z = (WC_X - WC_Y) * B, + R = A#m_s{ll_z=LL_Z, ull_z=ULL_Z, + l_z=L_Z, ul_z=UL_Z, + s_z=S_Z, us_z=US_Z, + c_z=C_Z, wc_z=WC_Z}, + io:format("~p", [{?MODULE,?LINE,[A,B,R]}]), + {reply, {any,TkA,R}, State}. + + + +init(_Env) -> + {ok, []}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + + +any({any,tk_longlong,X}) -> X; +any({any,tk_long,X}) -> X; +any({any,tk_short,X}) -> X; +any({any,tk_ulonglong,X}) -> X; +any({any,tk_ulong,X}) -> X; +any({any,tk_ushort,X}) -> X; +any({any,tk_char,X}) -> X; +any({any,tk_wchar,X}) -> X. + +any(X, Tk) when integer(X) -> {any,Tk,X}. + +sub(X, Y) when integer(X), integer(Y) -> + X - Y. + +mul(X, Y) when integer(X), integer(Y) -> + X * Y. + +napp(0, L) -> L; +napp(N, L) when integer(N), N >= 1 -> napp(N-1, L)++L. |