diff options
516 files changed, 34315 insertions, 13550 deletions
diff --git a/.gitignore b/.gitignore index 6034a21f87..d67116d6e3 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,65 @@ powerpc-unknown-linux-gnu # Mac OS X a.out.dSYM/ +# Windows +*.pdb +tcltk85_win32_bin.tar.gz +erts/autoconf/win32.config.cache +erts/emulator/obj/ +erts/emulator/pcre/obj/ +erts/emulator/pcre/win32/ +erts/emulator/win32/ +erts/emulator/zlib/obj/ +erts/emulator/zlib/win32/ +erts/epmd/src/win32/ +erts/etc/common/Install.ini +erts/etc/common/win32/ +erts/etc/win32/cygwin_tools/vc/coffix.exe +erts/include/internal/win32/ +erts/include/win32/ +erts/lib/internal/win32/ +erts/lib/win32/ +erts/lib_src/obj/ +erts/lib_src/win32/ +erts/obj/win32/ +erts/win32/ +erts/etc/win32/nsis/erlang.nsh +lib/asn1/priv/lib/ +lib/asn1/priv/obj/ +lib/common_test/priv/win32/ +lib/crypto/c_src/win32/ +lib/crypto/priv/lib/ +lib/crypto/priv/obj/ +lib/erl_interface/obj.md/ +lib/erl_interface/obj.mdd/ +lib/erl_interface/src/win32/ +lib/gs/priv/tcl/ +lib/gs/tcl/binaries/ +lib/ic/c_src/win32/ +lib/ic/priv/lib/win32/ +lib/ic/priv/obj/win32/ +lib/megaco/src/flex/win32/ +lib/odbc/c_src/win32/ +lib/odbc/priv/bin/odbcserver.exe +lib/odbc/priv/obj/win32/odbcserver.o +lib/orber/c_src/win32/ +lib/os_mon/c_src/win32/ +lib/os_mon/priv/bin/win32/ +lib/os_mon/priv/obj/win32/ +lib/runtime_tools/c_src/win32/ +lib/runtime_tools/priv/lib/ +lib/runtime_tools/priv/obj/ +lib/ssl/c_src/win32/ +lib/ssl/priv/bin/win32/ +lib/ssl/priv/obj/win32/ +lib/tools/bin/win32/ +lib/tools/c_src/win32/ +lib/tools/obj/win32/ +lib/wx/c_src/win32/ +lib/wx/priv/win32/ +lib/wx/win32/ +make/win32/ + # Anchored from $ERL_TOP /bin /config.log @@ -286,10 +345,12 @@ a.out.dSYM/ /lib/wx/api_gen/wx_xml/* /lib/wx/api_gen/gl_xml/* /lib/wx/api_gen/??_doxygen -/lib/wx/api_gen/??xml_generated +/lib/wx/api_gen/*_generated /lib/wx/wx-*.ez /lib/wx/CONF_INFO /lib/wx/doc/src/wx*.xml +/lib/wx/priv/wxe_driver.* +/lib/wx/priv/erl_gl.* # xmerl diff --git a/INSTALL-WIN32.md b/INSTALL-WIN32.md index 6481ca1b06..59b9086c39 100644 --- a/INSTALL-WIN32.md +++ b/INSTALL-WIN32.md @@ -92,7 +92,9 @@ Frequently Asked Questions A: The SMP version of Erlang needs features in the Visual Studio 2005. Can't live without them. Besides the new compiler gives the Erlang - emulator a ~40% performance boost(!) + emulator a ~40% performance boost(!). Alternatively you can build Erlang + successfully using the free (proprietary) Visual Studio 2008 Express + edition C++ compiler. * Q: Can/will I build a Cygwin binary with the procedure you describe? @@ -208,20 +210,15 @@ Frequently Asked Questions * (Buy and) Install Microsoft Visual studio 2005 and SP1 (or higher) - * Get and install Sun's JDK 1.4.2 + * Alternatively install the free MS Visual Studio 2008 Express [msvc++] + and the Windows SDK [32bit-SDK] or [64bit-SDK] depending on the Windows + platform you are running. - * Get and install NSIS 2.01 or higher (up to 2.30 tried and working) + * Get and install Sun's JDK 1.4.2 - * Get and install OpenSSL 0.9.7c or higher + * Get and install NSIS 2.01 or higher (up to 2.46 tried and working) - * Get and unpack wxWidgets-2.8.9 or higher to `/opt/local/pgm` inside - cygwin. - * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/build/msw/wx.dsw` - * Enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and - `wxUSE_GRAPHICS_CONTEXT` in `include/wx/msw/setup.h` - * Build all unicode release (and unicode debug) packages - * Open `/cygwin/opt/local/pgm/wxWidgets-2.8.9/contrib/build/stc/stc.dsw` - * Build the unicode release (and unicode debug) packages + * Get and install OpenSSL 0.9.7c or higher (up to 1.0.0a tried & working) * Get the Erlang source distribution (from <http://www.erlang.org/download.html>) and unpack with Cygwin's `tar`. @@ -363,6 +360,15 @@ Well' here's the list: your `PATH` to allow the environment to find mc.exe. The next Visual Studio (2010) is expected to include this tool. + Alternatively install the free MS Visual Studio 2008 Express [msvc++] and + the Windows SDK [32bit-SDK] or [64bit-SDK] depending on the Windows + platform you are running, which includes the missing mc.exe message + compiler. + +[msvc++]: http://download.microsoft.com/download/E/8/E/E8EEB394-7F42-4963-A2D8-29559B738298/VS2008ExpressWithSP1ENUX1504728.iso +[32bit-SDK]: http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDK_EN_DVD.iso +[64bit-SDK]: http://download.microsoft.com/download/2/E/9/2E911956-F90F-4BFB-8231-E292A7B6F287/GRMSDKX_EN_DVD.iso + * Sun's Java JDK 1.5.0 or higher. Our Java code (jinterface, ic) is written for JDK 1.5.0. Get it for Windows and install it, the JRE is not enough. If you don't care about Java, you can skip this step, the @@ -401,9 +407,10 @@ Well' here's the list: on the `Related` link and then on the `Binaries` link (upper right corner of the page last time I looked), you can then reach the "Shining Lights Productions" Web site for Windows binaries - distributions. Get the latest or 0.9.7c if you get trouble with the - latest. It's a nifty installer. The rest should be handled by - `configure`, you needn't put anything in the path or anything. + distributions. Get the latest 32-bit installer, or use 0.9.7c if you get + trouble with the latest, and install to C:\OpenSSL which is where the + Makefiles are expecting to find it. It's a nifty installer. The rest should + be handled by `configure`, you needn't put anything in the path or anything. If you want to build openssl for windows yourself (which might be possible, as you wouldn't be reading this if you weren't a @@ -422,18 +429,51 @@ Well' here's the list: release (2.9.\* is a developer release which currently does not work with wxErlang). - Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm` + Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`. Open from explorer (i.e. by double clicking the file) - `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\build\msw\wx.dsw` + `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\build\msw\wx.dsw` In Microsoft Visual Studio, click File/Open/File, locate and - open: `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\include\wx\msw\setup.h` + open: `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\include\wx\msw\setup.h` enable `wxUSE_GLCANVAS`, `wxUSE_POSTSCRIPT` and `wxUSE_GRAPHICS_CONTEXT` Build it by clicking Build/Batch Build and select all unicode release (and unicode debug) packages. - Open `C:\cygwin\opt\local\pgm\wxMSW-2.8.10\contrib/build/stc/stc.dsw` + Open `C:\cygwin\opt\local\pgm\wxMSW-2.8.11\contrib/build/stc/stc.dsw` and batch build all unicode packages. + If you are using Visual C++ 9.0 or higher (Visual Studio 2008 onwards) you + will also need to convert and re-create the project dependencies in the new + .sln "Solution" format. + + * Open VSC++ & the project `wxMSW-2.8.11\build\msw\wx.dsw`, accepting the + automatic conversion to the newer VC++ format and save as + `\wxMSW-2.8.11\build\msw\wx.sln` + + * right-click on the project, and set up the project dependencies for + `wx.dsw` to achieve the below build order + + jpeg, png, tiff, zlib, regex, expat, base, net, odbc, core, + gl, html, media, qa, adv, dbgrid, xrc, aui, richtext, xml + + Build all unicode release (and unicode debug) packages either from the + GUI or alternatively launch a new prompt from somewhere like Start -> + Programs -> Microsoft Visual C++ -> Visual Studio Tools -> VS2008 Cmd Prompt + and cd to where you unpacked wxMSW + + pushd c:\wxMSW*\build\msw + vcbuild /useenv /platform:Win32 /M4 wx.sln "Unicode Release|Win32" + vcbuild /useenv /platform:Win32 /M4 wx.sln "Unicode Debug|Win32" + + Open VSC++ & convert `C:\wxMSW-2.8.11\contrib\build\stc\stc.dsw` to + `C:\wxMSW-2.8.11\contrib\build\stc\stc.sln` + + * build the unicode release (and unicode debug) packages from the GUI or + alternatively open a VS2008 Cmd Prompt and cd to where you unpacked wxMSW + + pushd c:\wxMSW*\contrib\build\stc + vcbuild /useenv /platform:Win32 /M4 stc.sln "Unicode Release|Win32" + vcbuild /useenv /platform:Win32 /M4 stc.sln "Unicode Debug|Win32" + * The Erlang source distribution (from <http://www.erlang.org/download.html>). The same as for Unix platforms. Preferably use tar from within Cygwin to unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`). diff --git a/INSTALL.md b/INSTALL.md index 2567b791e5..1061c5187a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -277,7 +277,8 @@ Some of the available `configure` options are: x86 processors before pentium 4 (back to 486) in the ethread library. If not passed the ethread library (part of the runtime system) will use instructions that first appeared on the pentium 4 processor when building - for x86. + for x86. This option will be automatically enabled if required on the + build machine. * `--with-libatomic_ops=PATH` - Use the `libatomic_ops` library for atomic memory accesses. If `configure` should inform you about no native atomic implementation available, you typically want to try using the diff --git a/Makefile.in b/Makefile.in index 4b6e2e1190..ca92bf604d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -393,7 +393,7 @@ endif # --------------------------------------------------------------- # Target only used when building commercial ERTS patches # --------------------------------------------------------------- -release_docs docs: +release_docs docs: mod2app ifeq ($(OTP_SMALL_BUILD),true) cd $(ERL_TOP)/lib && \ ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@ @@ -408,6 +408,9 @@ endif cd $(ERL_TOP)/system/doc && \ ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@ +mod2app: + $(ERL_TOP)/lib/erl_docgen/priv/bin/xref_mod_app.escript -topdir $(ERL_TOP) -outfile $(ERL_TOP)/make/$(TARGET)/mod2app.xml + # ---------------------------------------------------------------------- ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts ELINK=$(BOOTSTRAP_ROOT)/bootstrap/erts/bin/elink diff --git a/README.bootstrap b/README.bootstrap index b0c8a1cc20..f42bc7aa47 100644 --- a/README.bootstrap +++ b/README.bootstrap @@ -45,13 +45,11 @@ preloaded files are to be updated, the source code is built using a special Makefile in the $ERL_TOP/preloaded/src directory, which creates beam files in the same directory. When they seem to compile successfully, they can be used in an emulator build by being copied -to the ebin directory (although, in Clearcase that requires checking -out the files in the ebin directory first). For developers using the -main Clearcase branch, otp_build {prepare,update,commit}_preloaded can -be used to ease the process (there are also similar targets in the +to the ebin directory. otp_build update_preloaded can be used to +ease the process (there are also similar targets in the $ERL_TOP/preloaded/src/Makefile). -In prebuilt open source distributions, these .beam files are also +In prebuilt open source distributions, these beam files are also present, but to update them one might need to change permission on the $ERL_TOP/preloaded/ebin directory, then build and then manually copy the beam files from the source directory to ../ebin. If patches are @@ -60,4 +58,4 @@ always note this specially as the preloaded/ebin directory needs updating, or provide the new derived files in the patch or as complete binaries. -/Patrik, OTP
\ No newline at end of file +/Patrik, OTP diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot Binary files differindex e09d7405b2..c7f5785eee 100644 --- a/bootstrap/bin/start.boot +++ b/bootstrap/bin/start.boot diff --git a/bootstrap/bin/start.script b/bootstrap/bin/start.script index 0ed5340fe2..c5106e3709 100644 --- a/bootstrap/bin/start.script +++ b/bootstrap/bin/start.script @@ -1,6 +1,6 @@ -%% script generated at {2010,9,10} {14,53,47} +%% script generated at {2010,12,3} {17,41,47} {script, - {"OTP APN 181 01","R14B"}, + {"OTP APN 181 01","R14B01"}, [{preLoaded, [erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip, zlib]}, @@ -43,7 +43,7 @@ {application_controller,start, [{application,kernel, [{description,"ERTS CXC 138 10"}, - {vsn,"2.14.1"}, + {vsn,"2.14.2"}, {id,[]}, {modules, [application,application_controller,application_master, @@ -80,7 +80,7 @@ {application,load, [{application,stdlib, [{description,"ERTS CXC 138 10"}, - {vsn,"1.17.1"}, + {vsn,"1.17.2"}, {id,[]}, {modules, [array,base64,beam_lib,binary,c,calendar,dets, diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot Binary files differindex e09d7405b2..c7f5785eee 100644 --- a/bootstrap/bin/start_clean.boot +++ b/bootstrap/bin/start_clean.boot diff --git a/bootstrap/bin/start_clean.script b/bootstrap/bin/start_clean.script index 0ed5340fe2..c5106e3709 100644 --- a/bootstrap/bin/start_clean.script +++ b/bootstrap/bin/start_clean.script @@ -1,6 +1,6 @@ -%% script generated at {2010,9,10} {14,53,47} +%% script generated at {2010,12,3} {17,41,47} {script, - {"OTP APN 181 01","R14B"}, + {"OTP APN 181 01","R14B01"}, [{preLoaded, [erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip, zlib]}, @@ -43,7 +43,7 @@ {application_controller,start, [{application,kernel, [{description,"ERTS CXC 138 10"}, - {vsn,"2.14.1"}, + {vsn,"2.14.2"}, {id,[]}, {modules, [application,application_controller,application_master, @@ -80,7 +80,7 @@ {application,load, [{application,stdlib, [{description,"ERTS CXC 138 10"}, - {vsn,"1.17.1"}, + {vsn,"1.17.2"}, {id,[]}, {modules, [array,base64,beam_lib,binary,c,calendar,dets, diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam Binary files differindex 75c6383ba3..7a40486b42 100644 --- a/bootstrap/lib/compiler/ebin/beam_asm.beam +++ b/bootstrap/lib/compiler/ebin/beam_asm.beam diff --git a/bootstrap/lib/compiler/ebin/beam_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam Binary files differindex 4d71b65e23..41be7667fc 100644 --- a/bootstrap/lib/compiler/ebin/beam_block.beam +++ b/bootstrap/lib/compiler/ebin/beam_block.beam diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam Binary files differindex 7b9c08439e..c335748e8a 100644 --- a/bootstrap/lib/compiler/ebin/beam_utils.beam +++ b/bootstrap/lib/compiler/ebin/beam_utils.beam diff --git a/bootstrap/lib/compiler/ebin/compiler.app b/bootstrap/lib/compiler/ebin/compiler.app index d201d5fd0d..3fd5add16b 100644 --- a/bootstrap/lib/compiler/ebin/compiler.app +++ b/bootstrap/lib/compiler/ebin/compiler.app @@ -18,7 +18,7 @@ {application, compiler, [{description, "ERTS CXC 138 10"}, - {vsn, "4.7"}, + {vsn, "4.7.1"}, {modules, [ beam_asm, beam_block, diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup index 99b234c847..10c9fd3dde 100644 --- a/bootstrap/lib/compiler/ebin/compiler.appup +++ b/bootstrap/lib/compiler/ebin/compiler.appup @@ -1 +1 @@ -{"4.6.5",[],[]}. +{"4.7.1",[],[]}. diff --git a/bootstrap/lib/compiler/ebin/core_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam Binary files differindex e7db1d3f72..813c444d9c 100644 --- a/bootstrap/lib/compiler/ebin/core_lint.beam +++ b/bootstrap/lib/compiler/ebin/core_lint.beam diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam Binary files differindex 631c5d6aba..5e39a05dc5 100644 --- a/bootstrap/lib/compiler/ebin/core_parse.beam +++ b/bootstrap/lib/compiler/ebin/core_parse.beam diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam Binary files differindex 5555d01b2a..7cdb5fe92a 100644 --- a/bootstrap/lib/compiler/ebin/v3_codegen.beam +++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam Binary files differindex 5d889ea4f3..7a60d7b23d 100644 --- a/bootstrap/lib/compiler/ebin/v3_core.beam +++ b/bootstrap/lib/compiler/ebin/v3_core.beam diff --git a/bootstrap/lib/compiler/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl index 80fed200ae..6e3fead4a3 100644 --- a/bootstrap/lib/compiler/egen/core_parse.erl +++ b/bootstrap/lib/compiler/egen/core_parse.erl @@ -13,7 +13,7 @@ tok_val(T) -> element(3, T). tok_line(T) -> element(2, T). --file("/usr/local/otp_product/releases/sles10_64_R14A_patched/lib/parsetools-2.0.3/include/yeccpre.hrl", 0). +-file("/usr/local/otp/releases/sles10_64_R14B_patched/lib/parsetools-2.0.4/include/yeccpre.hrl", 0). %% %% %CopyrightBegin% %% @@ -42,8 +42,8 @@ tok_line(T) -> element(2, T). parse(Tokens) -> yeccpars0(Tokens, {no_func, no_line}, 0, [], []). --spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> - yecc_ret(). +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> % Fun or {M, F} yeccpars0([], {{F, A}, no_line}, 0, [], []); parse_and_scan({M, F, A}) -> @@ -60,7 +60,7 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function,{return_error,2}}). +-compile({nowarn_unused_function, return_error/2}). -spec return_error(integer(), any()) -> no_return(). return_error(Line, Message) -> throw({error, {Line, ?MODULE, Message}}). @@ -73,10 +73,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> error: Error -> Stacktrace = erlang:get_stacktrace(), try yecc_error_type(Error, Stacktrace) of - {syntax_error, Token} -> - yeccerror(Token); - {missing_in_goto_table=Tag, Symbol, State} -> - Desc = {Symbol, State, Tag}, + Desc -> erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, Stacktrace) catch _:_ -> erlang:raise(error, Error, Stacktrace) @@ -86,13 +83,15 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> Error end. -yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) -> +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) -> case atom_to_list(F) of - "yeccpars2" ++ _ -> - {syntax_error, Token}; "yeccgoto_" ++ SymbolL -> {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - {missing_in_goto_table, Symbol, State} + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} end. yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> @@ -157,11 +156,13 @@ yecctoken_end_location(Token) -> yecctoken_location(Token) end. +-compile({nowarn_unused_function, yeccerror/1}). yeccerror(Token) -> Text = yecctoken_to_string(Token), Location = yecctoken_location(Token), {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. +-compile({nowarn_unused_function, yecctoken_to_string/1}). yecctoken_to_string(Token) -> case catch erl_scan:token_info(Token, text) of {text, Txt} -> Txt; @@ -174,6 +175,7 @@ yecctoken_location(Token) -> _ -> element(2, Token) end. +-compile({nowarn_unused_function, yecctoken2string/1}). yecctoken2string({atom, _, A}) -> io_lib:write(A); yecctoken2string({integer,_,N}) -> io_lib:write(N); yecctoken2string({float,_,F}) -> io_lib:write(F); @@ -194,7 +196,7 @@ yecctoken2string(Other) -> --file("/ldisk/pan/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 197). +-file("/ldisk/pan/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 199). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); @@ -845,38 +847,54 @@ yeccpars2(321=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2(323=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_323(S, Cat, Ss, Stack, T, Ts, Tzr); yeccpars2(Other, _, _, _, _, _, _) -> - erlang:error({yecc_bug,"1.3",{missing_state_in_action_table, Other}}). + erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). yeccpars2_0(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 2, Ss, Stack, T, Ts, Tzr); yeccpars2_0(S, module, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 3, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 3, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_1(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> - {ok, hd(Stack)}. + {ok, hd(Stack)}; +yeccpars2_1(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_2(S, module, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 315, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 315, Ss, Stack, T, Ts, Tzr); +yeccpars2_2(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_3(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 4, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 4, Ss, Stack, T, Ts, Tzr); +yeccpars2_3(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_4(S, '[', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 6, Ss, Stack, T, Ts, Tzr); +yeccpars2_4(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_5(S, attributes, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr); +yeccpars2_5(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_6(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr); yeccpars2_6(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_6(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_7(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_exported_name(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_8(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 16, Ss, Stack, T, Ts, Tzr); +yeccpars2_8(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_9(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr); @@ -890,10 +908,14 @@ yeccpars2_10(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_module_export(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_11(S, '/', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr); +yeccpars2_11(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_12(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_12(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -901,7 +923,9 @@ yeccpars2_13(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_function_name(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_14(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr); +yeccpars2_14(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -922,15 +946,21 @@ yeccpars2_17(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_58(_S, Cat, [17 | Ss], NewStack, T, Ts, Tzr). yeccpars2_18(S, '[', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 19, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 19, Ss, Stack, T, Ts, Tzr); +yeccpars2_18(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_19(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 22, Ss, Stack, T, Ts, Tzr); yeccpars2_19(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr); +yeccpars2_19(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_20(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr); +yeccpars2_20(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_21(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr); @@ -944,7 +974,9 @@ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_module_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_23(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 24, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 24, Ss, Stack, T, Ts, Tzr); +yeccpars2_23(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_24(S, '[', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 30, Ss, Stack, T, Ts, Tzr); @@ -962,7 +994,9 @@ yeccpars2_cont_24(S, float, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_24(S, integer, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr); yeccpars2_cont_24(S, string, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr); +yeccpars2_cont_24(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_literal(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1025,7 +1059,9 @@ yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_37(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr); +yeccpars2_37(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_38(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr); @@ -1055,7 +1091,9 @@ yeccpars2_43(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars2_43(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr); yeccpars2_43(S, '|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr); +yeccpars2_43(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_44(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -1076,7 +1114,9 @@ yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_48: see yeccpars2_24 yeccpars2_49(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr); +yeccpars2_49(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_50(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1091,7 +1131,9 @@ yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tail_literal(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_53(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr); +yeccpars2_53(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1104,7 +1146,9 @@ yeccpars2_55(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_module_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_56(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 314, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 314, Ss, Stack, T, Ts, Tzr); +yeccpars2_56(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_57(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_function_name(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1121,18 +1165,26 @@ yeccpars2_59(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_313(_S, Cat, [59 | Ss], NewStack, T, Ts, Tzr). yeccpars2_60(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr); +yeccpars2_60(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_61: see yeccpars2_14 yeccpars2_62(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr); +yeccpars2_62(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_63(S, '[', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); +yeccpars2_63(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_64(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 95, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 95, Ss, Stack, T, Ts, Tzr); +yeccpars2_64(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_65(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 73, Ss, Stack, T, Ts, Tzr); @@ -1147,7 +1199,9 @@ yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_atomic_constant(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_68(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 94, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 94, Ss, Stack, T, Ts, Tzr); +yeccpars2_68(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_69(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 92, Ss, Stack, T, Ts, Tzr); @@ -1197,7 +1251,9 @@ yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_85(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_80(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 82, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 82, Ss, Stack, T, Ts, Tzr); +yeccpars2_80(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_81(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -1214,7 +1270,9 @@ yeccpars2_83(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars2_83(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 86, Ss, Stack, T, Ts, Tzr); yeccpars2_83(S, '|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr); +yeccpars2_83(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_84(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1234,7 +1292,9 @@ yeccpars2_85(S, integer, Ss, Stack, T, Ts, Tzr) -> yeccpars2_85(S, string, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 78, Ss, Stack, T, Ts, Tzr); yeccpars2_85(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 79, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 79, Ss, Stack, T, Ts, Tzr); +yeccpars2_85(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_86_(Stack), @@ -1243,7 +1303,9 @@ yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_87: see yeccpars2_85 yeccpars2_88(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 89, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 89, Ss, Stack, T, Ts, Tzr); +yeccpars2_88(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_89(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1277,7 +1339,9 @@ yeccpars2_95(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_96(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 99, Ss, Stack, T, Ts, Tzr); yeccpars2_96(S, 'fun', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr); +yeccpars2_96(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_97(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1288,23 +1352,31 @@ yeccpars2_98(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_function_definition(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_99(S, 'fun', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr); +yeccpars2_99(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_100(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 101, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 101, Ss, Stack, T, Ts, Tzr); +yeccpars2_100(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_101(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 105, Ss, Stack, T, Ts, Tzr); yeccpars2_101(S, ')', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 106, Ss, Stack, T, Ts, Tzr); yeccpars2_101(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); +yeccpars2_101(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_102(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_variable(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_103(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 306, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 306, Ss, Stack, T, Ts, Tzr); +yeccpars2_103(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_104(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr); @@ -1313,10 +1385,14 @@ yeccpars2_104(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_variables(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_105(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); +yeccpars2_105(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_106(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 108, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 108, Ss, Stack, T, Ts, Tzr); +yeccpars2_106(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_107(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_107_(Stack), @@ -1368,7 +1444,9 @@ yeccpars2_cont_108(S, 'receive', Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_108(S, 'try', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 143, Ss, Stack, T, Ts, Tzr); yeccpars2_cont_108(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 144, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 144, Ss, Stack, T, Ts, Tzr); +yeccpars2_cont_108(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_109(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_single_expression(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1433,7 +1511,9 @@ yeccpars2_128(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_129(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 287, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 287, Ss, Stack, T, Ts, Tzr); +yeccpars2_129(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_130(S, char, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 32, Ss, Stack, T, Ts, Tzr); @@ -1509,7 +1589,9 @@ yeccpars2_139(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars2_139(S, '<', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr); yeccpars2_139(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); +yeccpars2_139(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_140(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 61, Ss, Stack, T, Ts, Tzr); @@ -1562,7 +1644,9 @@ yeccpars2_144(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_108(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_145(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 150, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 150, Ss, Stack, T, Ts, Tzr); +yeccpars2_145(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_146(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr); @@ -1588,12 +1672,16 @@ yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_151(S, 'of', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr); +yeccpars2_151(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_152: see yeccpars2_139 yeccpars2_153(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 159, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 159, Ss, Stack, T, Ts, Tzr); +yeccpars2_153(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_154(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_154_(Stack), @@ -1604,10 +1692,14 @@ yeccpars2_155(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars2_155(S, '>', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr); yeccpars2_155(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); +yeccpars2_155(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_156(S, '>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr); +yeccpars2_156(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -1622,12 +1714,16 @@ yeccpars2_158(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_159: see yeccpars2_108 yeccpars2_160(S, 'catch', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr); +yeccpars2_160(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_161: see yeccpars2_139 yeccpars2_162(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr); +yeccpars2_162(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_163: see yeccpars2_108 @@ -1651,7 +1747,9 @@ yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_other_pattern(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_169(S, 'when', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 240, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 240, Ss, Stack, T, Ts, Tzr); +yeccpars2_169(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_clause(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1675,7 +1773,9 @@ yeccpars2_175(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_clause_pattern(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_176(S, 'after', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr); +yeccpars2_176(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_177(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr); @@ -1704,7 +1804,9 @@ yeccpars2_177(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_178(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr); +yeccpars2_178(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_179(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr); @@ -1777,7 +1879,9 @@ yeccpars2_183(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_184(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 201, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 201, Ss, Stack, T, Ts, Tzr); +yeccpars2_184(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_185(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 199, Ss, Stack, T, Ts, Tzr); @@ -1811,10 +1915,14 @@ yeccpars2_188(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_variable(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_189(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr); +yeccpars2_189(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_190(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr); +yeccpars2_190(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_191(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr); @@ -1839,7 +1947,9 @@ yeccpars2_192(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_193: see yeccpars2_63 yeccpars2_194(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 195, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 195, Ss, Stack, T, Ts, Tzr); +yeccpars2_194(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_195(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -1849,7 +1959,9 @@ yeccpars2_195(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_196: see yeccpars2_63 yeccpars2_197(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 198, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 198, Ss, Stack, T, Ts, Tzr); +yeccpars2_197(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -1869,7 +1981,9 @@ yeccpars2_201(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tuple_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_202(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr); +yeccpars2_202(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_203: see yeccpars2_108 @@ -1883,7 +1997,9 @@ yeccpars2_205(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars2_205(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr); yeccpars2_205(S, '|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 209, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 209, Ss, Stack, T, Ts, Tzr); +yeccpars2_205(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_206(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1899,7 +2015,9 @@ yeccpars2_208(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_209: see yeccpars2_191 yeccpars2_210(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr); +yeccpars2_210(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_211(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1914,7 +2032,9 @@ yeccpars2_213(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tail_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_214(S, '>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr); +yeccpars2_214(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_215(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -1932,12 +2052,16 @@ yeccpars2_217(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_pattern(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_218(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr); +yeccpars2_218(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_219: see yeccpars2_63 yeccpars2_220(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 221, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 221, Ss, Stack, T, Ts, Tzr); +yeccpars2_220(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -1947,10 +2071,14 @@ yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_222(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr); yeccpars2_222(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr); +yeccpars2_222(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_223(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 236, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 236, Ss, Stack, T, Ts, Tzr); +yeccpars2_223(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_224(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 234, Ss, Stack, T, Ts, Tzr); @@ -1959,10 +2087,14 @@ yeccpars2_224(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segment_patterns(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_225(S, '<', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr); +yeccpars2_225(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_226(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr); +yeccpars2_226(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_227(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -1972,15 +2104,21 @@ yeccpars2_227(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_228: see yeccpars2_191 yeccpars2_229(S, '>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 230, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 230, Ss, Stack, T, Ts, Tzr); +yeccpars2_229(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_230(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 231, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 231, Ss, Stack, T, Ts, Tzr); +yeccpars2_230(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_231: see yeccpars2_191 yeccpars2_232(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 233, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 233, Ss, Stack, T, Ts, Tzr); +yeccpars2_232(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_,_|Nss] = Ss, @@ -1988,7 +2126,9 @@ yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segment_pattern(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_234(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 225, Ss, Stack, T, Ts, Tzr); +yeccpars2_234(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -1996,7 +2136,9 @@ yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segment_patterns(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_236(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 237, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 237, Ss, Stack, T, Ts, Tzr); +yeccpars2_236(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_237(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2016,7 +2158,9 @@ yeccpars2_239(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_240: see yeccpars2_108 yeccpars2_241(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr); +yeccpars2_241(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_242: see yeccpars2_108 @@ -2026,7 +2170,9 @@ yeccpars2_243(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_244(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr); +yeccpars2_244(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_245(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2053,7 +2199,9 @@ yeccpars2_246(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_108(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_247(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 249, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 249, Ss, Stack, T, Ts, Tzr); +yeccpars2_247(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_248(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -2066,7 +2214,9 @@ yeccpars2_249(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_arg_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_250(S, in, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 251, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 251, Ss, Stack, T, Ts, Tzr); +yeccpars2_250(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_251: see yeccpars2_108 @@ -2076,12 +2226,16 @@ yeccpars2_252(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_letrec_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_253(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr); +yeccpars2_253(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_254: see yeccpars2_108 yeccpars2_255(S, in, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr); +yeccpars2_255(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_256: see yeccpars2_108 @@ -2103,7 +2257,9 @@ yeccpars2_260(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_catch_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_261(S, 'of', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr); +yeccpars2_261(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_262(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr); @@ -2123,7 +2279,9 @@ yeccpars2_262(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_24(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_263(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr); +yeccpars2_263(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_264(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2131,7 +2289,9 @@ yeccpars2_264(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_case_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_265(S, ':', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr); +yeccpars2_265(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_266: see yeccpars2_108 @@ -2154,7 +2314,9 @@ yeccpars2_271(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars2_271(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr); yeccpars2_271(S, '|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr); +yeccpars2_271(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_272(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2170,7 +2332,9 @@ yeccpars2_274(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_275: see yeccpars2_108 yeccpars2_276(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 277, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 277, Ss, Stack, T, Ts, Tzr); +yeccpars2_276(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2185,7 +2349,9 @@ yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_280(S, '>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 282, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 282, Ss, Stack, T, Ts, Tzr); +yeccpars2_280(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -2198,12 +2364,16 @@ yeccpars2_282(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expression(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_283(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 284, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 284, Ss, Stack, T, Ts, Tzr); +yeccpars2_283(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_284: see yeccpars2_63 yeccpars2_285(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr); +yeccpars2_285(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2213,10 +2383,14 @@ yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_287(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr); yeccpars2_287(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 291, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 291, Ss, Stack, T, Ts, Tzr); +yeccpars2_287(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_288(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr); +yeccpars2_288(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_289(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 299, Ss, Stack, T, Ts, Tzr); @@ -2225,10 +2399,14 @@ yeccpars2_289(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segments(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_290(S, '<', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr); +yeccpars2_290(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_291(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr); +yeccpars2_291(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_292(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -2238,15 +2416,21 @@ yeccpars2_292(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_293: see yeccpars2_108 yeccpars2_294(S, '>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 295, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 295, Ss, Stack, T, Ts, Tzr); +yeccpars2_294(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_295(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr); +yeccpars2_295(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_296: see yeccpars2_108 yeccpars2_297(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr); +yeccpars2_297(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_,_|Nss] = Ss, @@ -2254,7 +2438,9 @@ yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segment(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_299(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr); +yeccpars2_299(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2262,7 +2448,9 @@ yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_segments(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_301(S, '#', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr); +yeccpars2_301(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_302(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2270,12 +2458,16 @@ yeccpars2_302(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_303(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 196, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 196, Ss, Stack, T, Ts, Tzr); +yeccpars2_303(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_304(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 105, Ss, Stack, T, Ts, Tzr); yeccpars2_304(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); +yeccpars2_304(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2283,7 +2475,9 @@ yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_anno_variables(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_306(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 307, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 307, Ss, Stack, T, Ts, Tzr); +yeccpars2_306(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_307: see yeccpars2_108 @@ -2293,12 +2487,16 @@ yeccpars2_308(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_309(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr); +yeccpars2_309(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_310: see yeccpars2_63 yeccpars2_311(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 312, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 312, Ss, Stack, T, Ts, Tzr); +yeccpars2_311(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_312(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2316,7 +2514,9 @@ yeccpars2_314(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_module_definition(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_315(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 316, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 316, Ss, Stack, T, Ts, Tzr); +yeccpars2_315(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_316: see yeccpars2_4 @@ -2331,15 +2531,21 @@ yeccpars2_318(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_58(_S, Cat, [318 | Ss], NewStack, T, Ts, Tzr). yeccpars2_319(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 320, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 320, Ss, Stack, T, Ts, Tzr); +yeccpars2_319(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_320(S, '-|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 321, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 321, Ss, Stack, T, Ts, Tzr); +yeccpars2_320(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_321: see yeccpars2_63 yeccpars2_322(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr); +yeccpars2_322(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_323(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_,_,_,_,_|Nss] = Ss, diff --git a/bootstrap/lib/kernel/ebin/code.beam b/bootstrap/lib/kernel/ebin/code.beam Binary files differindex dc4cf6cf41..18947d98c3 100644 --- a/bootstrap/lib/kernel/ebin/code.beam +++ b/bootstrap/lib/kernel/ebin/code.beam diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam Binary files differindex 167a70e99d..93f0a3754a 100644 --- a/bootstrap/lib/kernel/ebin/dist_util.beam +++ b/bootstrap/lib/kernel/ebin/dist_util.beam diff --git a/bootstrap/lib/kernel/ebin/erl_epmd.beam b/bootstrap/lib/kernel/ebin/erl_epmd.beam Binary files differindex 68ef714e17..847ed69e23 100644 --- a/bootstrap/lib/kernel/ebin/erl_epmd.beam +++ b/bootstrap/lib/kernel/ebin/erl_epmd.beam diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam Binary files differindex 3671dea4f1..343cee3fe7 100644 --- a/bootstrap/lib/kernel/ebin/file.beam +++ b/bootstrap/lib/kernel/ebin/file.beam diff --git a/bootstrap/lib/kernel/ebin/file_io_server.beam b/bootstrap/lib/kernel/ebin/file_io_server.beam Binary files differindex ce14722f4c..f7c170fd28 100644 --- a/bootstrap/lib/kernel/ebin/file_io_server.beam +++ b/bootstrap/lib/kernel/ebin/file_io_server.beam diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam Binary files differindex 70e35c2076..0c39512bb3 100644 --- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam +++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam Binary files differindex 63088b2e1b..622110bcdb 100644 --- a/bootstrap/lib/kernel/ebin/inet.beam +++ b/bootstrap/lib/kernel/ebin/inet.beam diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app index 2b2c82d89c..5ea0891375 100644 --- a/bootstrap/lib/kernel/ebin/kernel.app +++ b/bootstrap/lib/kernel/ebin/kernel.app @@ -21,7 +21,7 @@ {application, kernel, [ {description, "ERTS CXC 138 10"}, - {vsn, "2.14.1"}, + {vsn, "2.14.2"}, {modules, [application, application_controller, application_master, diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup index 013c65b3e2..77f9f42fea 100644 --- a/bootstrap/lib/kernel/ebin/kernel.appup +++ b/bootstrap/lib/kernel/ebin/kernel.appup @@ -1 +1 @@ -{"2.14",[],[]}. +{"2.14.2",[],[]}. diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam Binary files differindex 471ab154e8..e1db5986dc 100644 --- a/bootstrap/lib/kernel/ebin/kernel.beam +++ b/bootstrap/lib/kernel/ebin/kernel.beam diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam Binary files differindex 2202b9105d..af54466541 100644 --- a/bootstrap/lib/stdlib/ebin/c.beam +++ b/bootstrap/lib/stdlib/ebin/c.beam diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam Binary files differindex 3e133f4ff2..4b6e3756e9 100644 --- a/bootstrap/lib/stdlib/ebin/dets.beam +++ b/bootstrap/lib/stdlib/ebin/dets.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam Binary files differindex 2ad134d371..968b9bcb28 100644 --- a/bootstrap/lib/stdlib/ebin/dets_v8.beam +++ b/bootstrap/lib/stdlib/ebin/dets_v8.beam diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam Binary files differindex 2eabd08ed4..355c5819cf 100644 --- a/bootstrap/lib/stdlib/ebin/dets_v9.beam +++ b/bootstrap/lib/stdlib/ebin/dets_v9.beam diff --git a/bootstrap/lib/stdlib/ebin/digraph.beam b/bootstrap/lib/stdlib/ebin/digraph.beam Binary files differindex fa37407d53..c68611ccdc 100644 --- a/bootstrap/lib/stdlib/ebin/digraph.beam +++ b/bootstrap/lib/stdlib/ebin/digraph.beam diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam Binary files differindex 8115d9c474..0483b561d4 100644 --- a/bootstrap/lib/stdlib/ebin/epp.beam +++ b/bootstrap/lib/stdlib/ebin/epp.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex 5ebd228586..9b54fff03b 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_parse.beam b/bootstrap/lib/stdlib/ebin/erl_parse.beam Binary files differindex 426bd23e36..4d07a75daf 100644 --- a/bootstrap/lib/stdlib/ebin/erl_parse.beam +++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam Binary files differindex 6b25af9b1b..9ade9e2edd 100644 --- a/bootstrap/lib/stdlib/ebin/ets.beam +++ b/bootstrap/lib/stdlib/ebin/ets.beam diff --git a/bootstrap/lib/stdlib/ebin/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam Binary files differindex 8a59a62379..7c1ba41e59 100644 --- a/bootstrap/lib/stdlib/ebin/filelib.beam +++ b/bootstrap/lib/stdlib/ebin/filelib.beam diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam Binary files differindex 4cdb6064d2..69af1ef3c2 100644 --- a/bootstrap/lib/stdlib/ebin/filename.beam +++ b/bootstrap/lib/stdlib/ebin/filename.beam diff --git a/bootstrap/lib/stdlib/ebin/ordsets.beam b/bootstrap/lib/stdlib/ebin/ordsets.beam Binary files differindex c3f2c3b7b1..48effb764e 100644 --- a/bootstrap/lib/stdlib/ebin/ordsets.beam +++ b/bootstrap/lib/stdlib/ebin/ordsets.beam diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app index 6ab708e43c..6aac1e2f19 100644 --- a/bootstrap/lib/stdlib/ebin/stdlib.app +++ b/bootstrap/lib/stdlib/ebin/stdlib.app @@ -19,7 +19,7 @@ %% {application, stdlib, [{description, "ERTS CXC 138 10"}, - {vsn, "1.17.1"}, + {vsn, "1.17.2"}, {modules, [array, base64, beam_lib, diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup index 097f2b47ed..ca89dcf43a 100644 --- a/bootstrap/lib/stdlib/ebin/stdlib.appup +++ b/bootstrap/lib/stdlib/ebin/stdlib.appup @@ -1 +1 @@ -{"1.17",[],[]}. +{"1.17.2",[],[]}. diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam Binary files differindex 3c3eaf6ed2..0de0b44cb8 100644 --- a/bootstrap/lib/stdlib/ebin/string.beam +++ b/bootstrap/lib/stdlib/ebin/string.beam diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam Binary files differindex 54811dad66..13cb6032a9 100644 --- a/bootstrap/lib/stdlib/ebin/supervisor.beam +++ b/bootstrap/lib/stdlib/ebin/supervisor.beam diff --git a/bootstrap/lib/stdlib/ebin/timer.beam b/bootstrap/lib/stdlib/ebin/timer.beam Binary files differindex 1020f78632..1f84ff37ac 100644 --- a/bootstrap/lib/stdlib/ebin/timer.beam +++ b/bootstrap/lib/stdlib/ebin/timer.beam diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam Binary files differindex 4ca769b9a2..cc3a3c1859 100644 --- a/bootstrap/lib/stdlib/ebin/unicode.beam +++ b/bootstrap/lib/stdlib/ebin/unicode.beam diff --git a/bootstrap/lib/stdlib/egen/erl_parse.erl b/bootstrap/lib/stdlib/egen/erl_parse.erl index 75c491aa37..f15deb37f1 100644 --- a/bootstrap/lib/stdlib/egen/erl_parse.erl +++ b/bootstrap/lib/stdlib/egen/erl_parse.erl @@ -556,7 +556,7 @@ get_attribute(L, Name) -> get_attributes(L) -> erl_scan:attributes_info(L). --file("/usr/local/otp_product/releases/sles10_64_R14A_patched/lib/parsetools-2.0.3/include/yeccpre.hrl", 0). +-file("/usr/local/otp/releases/sles10_64_R14B_patched/lib/parsetools-2.0.4/include/yeccpre.hrl", 0). %% %% %CopyrightBegin% %% @@ -585,8 +585,8 @@ get_attributes(L) -> parse(Tokens) -> yeccpars0(Tokens, {no_func, no_line}, 0, [], []). --spec parse_and_scan({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) -> - yecc_ret(). +-spec parse_and_scan({function() | {atom(), atom()}, [_]} + | {atom(), atom(), [_]}) -> yecc_ret(). parse_and_scan({F, A}) -> % Fun or {M, F} yeccpars0([], {{F, A}, no_line}, 0, [], []); parse_and_scan({M, F, A}) -> @@ -603,7 +603,7 @@ format_error(Message) -> %% To be used in grammar files to throw an error message to the parser %% toplevel. Doesn't have to be exported! --compile({nowarn_unused_function,{return_error,2}}). +-compile({nowarn_unused_function, return_error/2}). -spec return_error(integer(), any()) -> no_return(). return_error(Line, Message) -> throw({error, {Line, ?MODULE, Message}}). @@ -616,10 +616,7 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> error: Error -> Stacktrace = erlang:get_stacktrace(), try yecc_error_type(Error, Stacktrace) of - {syntax_error, Token} -> - yeccerror(Token); - {missing_in_goto_table=Tag, Symbol, State} -> - Desc = {Symbol, State, Tag}, + Desc -> erlang:raise(error, {yecc_bug, ?CODE_VERSION, Desc}, Stacktrace) catch _:_ -> erlang:raise(error, Error, Stacktrace) @@ -629,13 +626,15 @@ yeccpars0(Tokens, Tzr, State, States, Vstack) -> Error end. -yecc_error_type(function_clause, [{?MODULE,F,[State,_,_,_,Token,_,_]} | _]) -> +yecc_error_type(function_clause, [{?MODULE,F,ArityOrArgs} | _]) -> case atom_to_list(F) of - "yeccpars2" ++ _ -> - {syntax_error, Token}; "yeccgoto_" ++ SymbolL -> {ok,[{atom,_,Symbol}],_} = erl_scan:string(SymbolL), - {missing_in_goto_table, Symbol, State} + State = case ArityOrArgs of + [S,_,_,_,_,_,_] -> S; + _ -> state_is_unknown + end, + {Symbol, State, missing_in_goto_table} end. yeccpars1([Token | Tokens], Tzr, State, States, Vstack) -> @@ -700,11 +699,13 @@ yecctoken_end_location(Token) -> yecctoken_location(Token) end. +-compile({nowarn_unused_function, yeccerror/1}). yeccerror(Token) -> Text = yecctoken_to_string(Token), Location = yecctoken_location(Token), {error, {Location, ?MODULE, ["syntax error before: ", Text]}}. +-compile({nowarn_unused_function, yecctoken_to_string/1}). yecctoken_to_string(Token) -> case catch erl_scan:token_info(Token, text) of {text, Txt} -> Txt; @@ -717,6 +718,7 @@ yecctoken_location(Token) -> _ -> element(2, Token) end. +-compile({nowarn_unused_function, yecctoken2string/1}). yecctoken2string({atom, _, A}) -> io_lib:write(A); yecctoken2string({integer,_,N}) -> io_lib:write(N); yecctoken2string({float,_,F}) -> io_lib:write(F); @@ -737,7 +739,7 @@ yecctoken2string(Other) -> --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 740). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 742). yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr); @@ -1670,12 +1672,14 @@ yeccpars2(462=S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2(464=S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_464(S, Cat, Ss, Stack, T, Ts, Tzr); yeccpars2(Other, _, _, _, _, _, _) -> - erlang:error({yecc_bug,"1.3",{missing_state_in_action_table, Other}}). + erlang:error({yecc_bug,"1.4",{missing_state_in_action_table, Other}}). yeccpars2_0(S, '-', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 9, Ss, Stack, T, Ts, Tzr); yeccpars2_0(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr); +yeccpars2_0(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_1_(Stack), @@ -1688,7 +1692,9 @@ yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_rule_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_3(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 459, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 459, Ss, Stack, T, Ts, Tzr); +yeccpars2_3(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) -> NewStack = yeccpars2_4_(Stack), @@ -1701,21 +1707,31 @@ yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_function_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_6(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 453, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 453, Ss, Stack, T, Ts, Tzr); +yeccpars2_6(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_7(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) -> - {ok, hd(Stack)}. + {ok, hd(Stack)}; +yeccpars2_7(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_8(S, dot, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 452, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 452, Ss, Stack, T, Ts, Tzr); +yeccpars2_8(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_9(S, atom, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr); yeccpars2_9(S, spec, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr); +yeccpars2_9(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_10(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); +yeccpars2_10(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_11(S, 'when', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr); @@ -1779,7 +1795,9 @@ yeccpars2_cont_13(S, 'receive', Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_13(S, string, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr); yeccpars2_cont_13(S, 'try', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 66, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 66, Ss, Stack, T, Ts, Tzr); +yeccpars2_cont_13(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -1832,7 +1850,9 @@ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_26(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr); +yeccpars2_26(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_27(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr); @@ -1953,7 +1973,9 @@ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_44(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr); +yeccpars2_44(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_45(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); @@ -1992,7 +2014,9 @@ yeccpars2_48(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_49(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr); +yeccpars2_49(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_50(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr); @@ -2063,7 +2087,9 @@ yeccpars2_58(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_59(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr); yeccpars2_59(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr); +yeccpars2_59(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_60: see yeccpars2_45 @@ -2074,7 +2100,9 @@ yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_63(S, '[', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 127, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 127, Ss, Stack, T, Ts, Tzr); +yeccpars2_63(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_64(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); @@ -2141,7 +2169,9 @@ yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_69(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 71, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 71, Ss, Stack, T, Ts, Tzr); +yeccpars2_69(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -2201,7 +2231,9 @@ yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_78(S, 'after', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr); yeccpars2_78(S, 'catch', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 75, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 75, Ss, Stack, T, Ts, Tzr); +yeccpars2_78(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_79(S, ';', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 80, Ss, Stack, T, Ts, Tzr); @@ -2222,7 +2254,9 @@ yeccpars2_82(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_83(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr); +yeccpars2_83(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_84: see yeccpars2_45 @@ -2259,7 +2293,9 @@ yeccpars2_91(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_92(S, 'after', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 109, Ss, Stack, T, Ts, Tzr); yeccpars2_92(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 110, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 110, Ss, Stack, T, Ts, Tzr); +yeccpars2_92(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_93(S, ';', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr); @@ -2335,7 +2371,9 @@ yeccpars2_110(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_111(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 112, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 112, Ss, Stack, T, Ts, Tzr); +yeccpars2_111(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_112(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2343,7 +2381,9 @@ yeccpars2_112(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_113(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr); +yeccpars2_113(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_114(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2358,14 +2398,18 @@ yeccpars2_115(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_116(S, 'after', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 121, Ss, Stack, T, Ts, Tzr); yeccpars2_116(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 122, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 122, Ss, Stack, T, Ts, Tzr); +yeccpars2_116(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_117: see yeccpars2_45 %% yeccpars2_118: see yeccpars2_83 yeccpars2_119(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 120, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 120, Ss, Stack, T, Ts, Tzr); +yeccpars2_119(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_120(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2382,7 +2426,9 @@ yeccpars2_122(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_123: see yeccpars2_83 yeccpars2_124(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 125, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 125, Ss, Stack, T, Ts, Tzr); +yeccpars2_124(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_|Nss] = Ss, @@ -2390,17 +2436,23 @@ yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_126(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 141, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 141, Ss, Stack, T, Ts, Tzr); +yeccpars2_126(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_127: see yeccpars2_45 yeccpars2_128(S, '||', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr); +yeccpars2_128(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_129: see yeccpars2_45 yeccpars2_130(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 140, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 140, Ss, Stack, T, Ts, Tzr); +yeccpars2_130(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_131(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 138, Ss, Stack, T, Ts, Tzr); @@ -2450,7 +2502,9 @@ yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_query_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_142(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr); +yeccpars2_142(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_143(S, ';', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 146, Ss, Stack, T, Ts, Tzr); @@ -2478,7 +2532,9 @@ yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_if_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_149(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr); +yeccpars2_149(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_150(S, ';', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr); @@ -2495,19 +2551,29 @@ yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_152(S, '/', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 153, Ss, Stack, T, Ts, Tzr); yeccpars2_152(S, ':', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 154, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 154, Ss, Stack, T, Ts, Tzr); +yeccpars2_152(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_153(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr); +yeccpars2_153(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_154(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr); +yeccpars2_154(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_155(S, '/', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 156, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 156, Ss, Stack, T, Ts, Tzr); +yeccpars2_155(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_156(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr); +yeccpars2_156(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_|Nss] = Ss, @@ -2544,12 +2610,16 @@ yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_165(S, 'of', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 166, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 166, Ss, Stack, T, Ts, Tzr); +yeccpars2_165(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_166: see yeccpars2_45 yeccpars2_167(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 168, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 168, Ss, Stack, T, Ts, Tzr); +yeccpars2_167(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2557,7 +2627,9 @@ yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_case_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_169(S, 'end', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 170, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 170, Ss, Stack, T, Ts, Tzr); +yeccpars2_169(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2588,7 +2660,9 @@ yeccpars2_175(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_176: see yeccpars2_45 yeccpars2_177(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr); +yeccpars2_177(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_178(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2600,7 +2674,9 @@ yeccpars2_179(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars2_179(S, ']', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr); yeccpars2_179(S, '|', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr); +yeccpars2_179(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_180(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2633,7 +2709,9 @@ yeccpars2_184(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_185(S, '>>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 190, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 190, Ss, Stack, T, Ts, Tzr); +yeccpars2_185(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_186(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr); @@ -2678,7 +2756,9 @@ yeccpars2_190(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_191: see yeccpars2_45 yeccpars2_192(S, '>>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr); +yeccpars2_192(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_193(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -2707,7 +2787,9 @@ yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_bin_element(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_199(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 202, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 202, Ss, Stack, T, Ts, Tzr); +yeccpars2_199(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_200(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -2727,7 +2809,9 @@ yeccpars2_202(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_bit_type(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_203(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 204, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 204, Ss, Stack, T, Ts, Tzr); +yeccpars2_203(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_204(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2752,7 +2836,9 @@ yeccpars2_208(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_209(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr); +yeccpars2_209(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_210(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2762,7 +2848,9 @@ yeccpars2_210(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_211(S, '.', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 213, Ss, Stack, T, Ts, Tzr); yeccpars2_211(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr); +yeccpars2_211(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -2770,7 +2858,9 @@ yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_213(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr); +yeccpars2_213(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_214(S, '}', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr); @@ -2778,7 +2868,9 @@ yeccpars2_214(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_224(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_215(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr); +yeccpars2_215(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_216(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 224, Ss, Stack, T, Ts, Tzr); @@ -2787,10 +2879,14 @@ yeccpars2_216(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_record_fields(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_217(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr); +yeccpars2_217(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_218(S, '=', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 220, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 220, Ss, Stack, T, Ts, Tzr); +yeccpars2_218(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_219(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -2814,7 +2910,9 @@ yeccpars2_223(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_224(S, atom, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 217, Ss, Stack, T, Ts, Tzr); yeccpars2_224(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 218, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 218, Ss, Stack, T, Ts, Tzr); +yeccpars2_224(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_225(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3005,7 +3103,9 @@ yeccpars2_270(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_function_call(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_271(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr); +yeccpars2_271(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_272: see yeccpars2_181 @@ -3020,12 +3120,16 @@ yeccpars2_274(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_275(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 276, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 276, Ss, Stack, T, Ts, Tzr); +yeccpars2_275(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_276(S, '.', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 278, Ss, Stack, T, Ts, Tzr); yeccpars2_276(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr); +yeccpars2_276(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3033,7 +3137,9 @@ yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_278(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 279, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 279, Ss, Stack, T, Ts, Tzr); +yeccpars2_278(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -3051,12 +3157,16 @@ yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_expr_600(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_282(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 283, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 283, Ss, Stack, T, Ts, Tzr); +yeccpars2_282(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_283(S, '.', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 285, Ss, Stack, T, Ts, Tzr); yeccpars2_283(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr); +yeccpars2_283(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3064,7 +3174,9 @@ yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_285(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr); +yeccpars2_285(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -3074,7 +3186,9 @@ yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_287(S, '->', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr); yeccpars2_287(S, ':-', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr); +yeccpars2_287(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_288(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3121,7 +3235,9 @@ yeccpars2_292(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_293(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr); yeccpars2_293(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr); +yeccpars2_293(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3129,10 +3245,14 @@ yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_295(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr); +yeccpars2_295(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_296(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr); +yeccpars2_296(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_297(S, '/', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr); @@ -3142,10 +3262,14 @@ yeccpars2_297(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_spec_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_298(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr); +yeccpars2_298(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_299(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 300, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 300, Ss, Stack, T, Ts, Tzr); +yeccpars2_299(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_300(S, '/', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr); @@ -3155,10 +3279,14 @@ yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_301(S, integer, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr); +yeccpars2_301(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_302(S, '::', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 303, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 303, Ss, Stack, T, Ts, Tzr); +yeccpars2_302(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_303(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_,_|Nss] = Ss, @@ -3166,7 +3294,9 @@ yeccpars2_303(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_304(S, '::', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 305, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 305, Ss, Stack, T, Ts, Tzr); +yeccpars2_304(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3176,7 +3306,9 @@ yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_306: see yeccpars2_295 yeccpars2_307(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 423, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 423, Ss, Stack, T, Ts, Tzr); +yeccpars2_307(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_308(S, ';', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 421, Ss, Stack, T, Ts, Tzr); @@ -3219,7 +3351,9 @@ yeccpars2_cont_310(S, 'fun', Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_310(S, integer, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 328, Ss, Stack, T, Ts, Tzr); yeccpars2_cont_310(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 330, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 330, Ss, Stack, T, Ts, Tzr); +yeccpars2_cont_310(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type_400(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -3269,7 +3403,9 @@ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type_500(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_316(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr); +yeccpars2_316(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_top_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -3289,7 +3425,9 @@ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_321(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 384, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 384, Ss, Stack, T, Ts, Tzr); +yeccpars2_321(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_322(S, '+', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr); @@ -3305,12 +3443,16 @@ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_323(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 380, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 380, Ss, Stack, T, Ts, Tzr); +yeccpars2_323(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_324(S, '>>', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 365, Ss, Stack, T, Ts, Tzr); yeccpars2_324(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 366, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 366, Ss, Stack, T, Ts, Tzr); +yeccpars2_324(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_325(S, '+', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr); @@ -3335,7 +3477,9 @@ yeccpars2_326(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_327(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 337, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 337, Ss, Stack, T, Ts, Tzr); +yeccpars2_327(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_328(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -3361,7 +3505,9 @@ yeccpars2_330(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_331(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 333, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 333, Ss, Stack, T, Ts, Tzr); +yeccpars2_331(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_332(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -3397,10 +3543,14 @@ yeccpars2_336(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_337(S, '(', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 340, Ss, Stack, T, Ts, Tzr); yeccpars2_337(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 341, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 341, Ss, Stack, T, Ts, Tzr); +yeccpars2_337(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_338(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 346, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 346, Ss, Stack, T, Ts, Tzr); +yeccpars2_338(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_339(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_fun_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr). @@ -3428,10 +3578,14 @@ yeccpars2_341(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_342(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 343, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 343, Ss, Stack, T, Ts, Tzr); +yeccpars2_342(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_343(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 344, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 344, Ss, Stack, T, Ts, Tzr); +yeccpars2_343(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_344: see yeccpars2_322 @@ -3461,10 +3615,14 @@ yeccpars2_347(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_348(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 349, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 349, Ss, Stack, T, Ts, Tzr); +yeccpars2_348(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_349(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 350, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 350, Ss, Stack, T, Ts, Tzr); +yeccpars2_349(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_350(S, ')', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 352, Ss, Stack, T, Ts, Tzr); @@ -3482,7 +3640,9 @@ yeccpars2_350(S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr). yeccpars2_351(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 353, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 353, Ss, Stack, T, Ts, Tzr); +yeccpars2_351(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_352(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -3495,7 +3655,9 @@ yeccpars2_353(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_354(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr); +yeccpars2_354(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_355(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3510,7 +3672,9 @@ yeccpars2_356(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_357(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 359, Ss, Stack, T, Ts, Tzr); yeccpars2_357(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 360, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 360, Ss, Stack, T, Ts, Tzr); +yeccpars2_357(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -3518,7 +3682,9 @@ yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_359(S, '...', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 361, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 361, Ss, Stack, T, Ts, Tzr); +yeccpars2_359(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_360(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3526,7 +3692,9 @@ yeccpars2_360(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_361(S, ']', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 362, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 362, Ss, Stack, T, Ts, Tzr); +yeccpars2_361(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -3534,12 +3702,16 @@ yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_363(S, '>>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr); +yeccpars2_363(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_364(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 372, Ss, Stack, T, Ts, Tzr); yeccpars2_364(S, '>>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr); +yeccpars2_364(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_365(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_|Nss] = Ss, @@ -3547,7 +3719,9 @@ yeccpars2_365(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_366(S, ':', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 367, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 367, Ss, Stack, T, Ts, Tzr); +yeccpars2_366(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_367(S, var, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 369, Ss, Stack, T, Ts, Tzr); @@ -3572,7 +3746,9 @@ yeccpars2_371(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_bin_unit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_372(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 375, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 375, Ss, Stack, T, Ts, Tzr); +yeccpars2_372(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_373(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3580,16 +3756,24 @@ yeccpars2_373(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_374(S, '>>', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 378, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 378, Ss, Stack, T, Ts, Tzr); +yeccpars2_374(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_375(S, ':', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 376, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 376, Ss, Stack, T, Ts, Tzr); +yeccpars2_375(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_376(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr); +yeccpars2_376(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_377(S, '*', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr); +yeccpars2_377(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_378(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_,_|Nss] = Ss, @@ -3609,7 +3793,9 @@ yeccpars2_381(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_382(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr); +yeccpars2_382(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_383(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3617,15 +3803,21 @@ yeccpars2_383(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_384(S, '{', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 385, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 385, Ss, Stack, T, Ts, Tzr); +yeccpars2_384(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_385(S, atom, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr); yeccpars2_385(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 389, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 389, Ss, Stack, T, Ts, Tzr); +yeccpars2_385(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_386(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr); +yeccpars2_386(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_387(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 392, Ss, Stack, T, Ts, Tzr); @@ -3634,7 +3826,9 @@ yeccpars2_387(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_field_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_388(S, '::', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 390, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 390, Ss, Stack, T, Ts, Tzr); +yeccpars2_388(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_389(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3649,7 +3843,9 @@ yeccpars2_391(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_field_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_392(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr); +yeccpars2_392(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_393(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3674,7 +3870,9 @@ yeccpars2_397(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_top_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_398(S, '->', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr); +yeccpars2_398(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_399: see yeccpars2_322 @@ -3742,7 +3940,9 @@ yeccpars2_408(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_409(S, atom, Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 412, Ss, Stack, T, Ts, Tzr); yeccpars2_409(S, var, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 413, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 413, Ss, Stack, T, Ts, Tzr); +yeccpars2_409(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_410(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3756,10 +3956,14 @@ yeccpars2_411(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_type_guards(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr). yeccpars2_412(S, '(', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 416, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 416, Ss, Stack, T, Ts, Tzr); +yeccpars2_412(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_413(S, '::', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr); +yeccpars2_413(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_414: see yeccpars2_322 @@ -3771,7 +3975,9 @@ yeccpars2_415(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_416: see yeccpars2_322 yeccpars2_417(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr); +yeccpars2_417(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_418(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_,_|Nss] = Ss, @@ -3823,14 +4029,18 @@ yeccpars2_427(_S, Cat, Ss, Stack, T, Ts, Tzr) -> %% yeccpars2_428: see yeccpars2_45 yeccpars2_429(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 449, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 449, Ss, Stack, T, Ts, Tzr); +yeccpars2_429(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_430(S, ')', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr); yeccpars2_430(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 431, Ss, Stack, T, Ts, Tzr); yeccpars2_430(S, '::', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 432, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 432, Ss, Stack, T, Ts, Tzr); +yeccpars2_430(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_431(S, '#', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr); @@ -3870,12 +4080,16 @@ yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_435(S, ')', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 448, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 448, Ss, Stack, T, Ts, Tzr); +yeccpars2_435(_, _, _, _, T, _, _) -> + yeccerror(T). %% yeccpars2_436: see yeccpars2_68 yeccpars2_437(S, '}', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 447, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 447, Ss, Stack, T, Ts, Tzr); +yeccpars2_437(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_438(S, ',', Ss, Stack, T, Ts, Tzr) -> yeccpars1(S, 444, Ss, Stack, T, Ts, Tzr); @@ -3950,7 +4164,9 @@ yeccpars2_453(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_454(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 456, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 456, Ss, Stack, T, Ts, Tzr); +yeccpars2_454(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_455(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3973,7 +4189,9 @@ yeccpars2_459(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr). yeccpars2_460(S, atom, Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 462, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 462, Ss, Stack, T, Ts, Tzr); +yeccpars2_460(_, _, _, _, T, _, _) -> + yeccerror(T). yeccpars2_461(_S, Cat, Ss, Stack, T, Ts, Tzr) -> [_,_|Nss] = Ss, @@ -3989,7 +4207,9 @@ yeccpars2_463(_S, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_464(464, Cat, [463 | Ss], NewStack, T, Ts, Tzr). yeccpars2_464(S, ':-', Ss, Stack, T, Ts, Tzr) -> - yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr). + yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr); +yeccpars2_464(_, _, _, _, T, _, _) -> + yeccerror(T). yeccgoto_add_op(33, Cat, Ss, Stack, T, Ts, Tzr) -> yeccpars2_230(249, Cat, Ss, Stack, T, Ts, Tzr); @@ -7975,7 +8195,7 @@ yeccpars2_39_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7978). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8198). -compile({inline,yeccpars2_46_/1}). -file("erl_parse.yrl", 434). yeccpars2_46_(__Stack0) -> @@ -7984,7 +8204,7 @@ yeccpars2_46_(__Stack0) -> { [ ] , ? line ( __1 ) } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7987). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8207). -compile({inline,yeccpars2_70_/1}). -file("erl_parse.yrl", 325). yeccpars2_70_(__Stack0) -> @@ -7993,7 +8213,7 @@ yeccpars2_70_(__Stack0) -> { tuple , ? line ( __1 ) , [ ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7996). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8216). -compile({inline,yeccpars2_71_/1}). -file("erl_parse.yrl", 326). yeccpars2_71_(__Stack0) -> @@ -8002,7 +8222,7 @@ yeccpars2_71_(__Stack0) -> { tuple , ? line ( __1 ) , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8005). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8225). -compile({inline,yeccpars2_73_/1}). -file("erl_parse.yrl", 408). yeccpars2_73_(__Stack0) -> @@ -8034,7 +8254,7 @@ yeccpars2_81_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8037). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8257). -compile({inline,yeccpars2_82_/1}). -file("erl_parse.yrl", 406). yeccpars2_82_(__Stack0) -> @@ -8067,7 +8287,7 @@ yeccpars2_88_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8070). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8290). -compile({inline,yeccpars2_89_/1}). -file("erl_parse.yrl", 381). yeccpars2_89_(__Stack0) -> @@ -8106,7 +8326,7 @@ yeccpars2_98_(__Stack0) -> [ ] end | __Stack0]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8109). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8329). -compile({inline,yeccpars2_100_/1}). -file("erl_parse.yrl", 427). yeccpars2_100_(__Stack0) -> @@ -8123,7 +8343,7 @@ yeccpars2_102_(__Stack0) -> [ ] end | __Stack0]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8126). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8346). -compile({inline,yeccpars2_104_/1}). -file("erl_parse.yrl", 424). yeccpars2_104_(__Stack0) -> @@ -8133,7 +8353,7 @@ yeccpars2_104_(__Stack0) -> { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8136). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8356). -compile({inline,yeccpars2_106_/1}). -file("erl_parse.yrl", 421). yeccpars2_106_(__Stack0) -> @@ -8175,7 +8395,7 @@ yeccpars2_114_(__Stack0) -> { [ ] , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8178). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8398). -compile({inline,yeccpars2_115_/1}). -file("erl_parse.yrl", 452). yeccpars2_115_(__Stack0) -> @@ -8184,7 +8404,7 @@ yeccpars2_115_(__Stack0) -> { string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8187). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8407). -compile({inline,yeccpars2_120_/1}). -file("erl_parse.yrl", 386). yeccpars2_120_(__Stack0) -> @@ -8193,7 +8413,7 @@ yeccpars2_120_(__Stack0) -> { 'receive' , ? line ( __1 ) , [ ] , __3 , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8196). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8416). -compile({inline,yeccpars2_122_/1}). -file("erl_parse.yrl", 384). yeccpars2_122_(__Stack0) -> @@ -8202,7 +8422,7 @@ yeccpars2_122_(__Stack0) -> { 'receive' , ? line ( __1 ) , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8205). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8425). -compile({inline,yeccpars2_125_/1}). -file("erl_parse.yrl", 388). yeccpars2_125_(__Stack0) -> @@ -8219,7 +8439,7 @@ yeccpars2_131_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8222). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8442). -compile({inline,yeccpars2_135_/1}). -file("erl_parse.yrl", 323). yeccpars2_135_(__Stack0) -> @@ -8228,7 +8448,7 @@ yeccpars2_135_(__Stack0) -> { b_generate , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8231). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8451). -compile({inline,yeccpars2_137_/1}). -file("erl_parse.yrl", 322). yeccpars2_137_(__Stack0) -> @@ -8245,7 +8465,7 @@ yeccpars2_139_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8248). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8468). -compile({inline,yeccpars2_140_/1}). -file("erl_parse.yrl", 315). yeccpars2_140_(__Stack0) -> @@ -8254,7 +8474,7 @@ yeccpars2_140_(__Stack0) -> { lc , ? line ( __1 ) , __2 , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8257). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8477). -compile({inline,yeccpars2_141_/1}). -file("erl_parse.yrl", 431). yeccpars2_141_(__Stack0) -> @@ -8271,7 +8491,7 @@ yeccpars2_143_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8274). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8494). -compile({inline,yeccpars2_145_/1}). -file("erl_parse.yrl", 371). yeccpars2_145_(__Stack0) -> @@ -8288,7 +8508,7 @@ yeccpars2_147_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8291). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8511). -compile({inline,yeccpars2_148_/1}). -file("erl_parse.yrl", 365). yeccpars2_148_(__Stack0) -> @@ -8312,7 +8532,7 @@ yeccpars2_151_(__Stack0) -> [ ] end | __Stack0]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8315). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8535). -compile({inline,yeccpars2_157_/1}). -file("erl_parse.yrl", 394). yeccpars2_157_(__Stack0) -> @@ -8321,7 +8541,7 @@ yeccpars2_157_(__Stack0) -> { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8324). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8544). -compile({inline,yeccpars2_158_/1}). -file("erl_parse.yrl", 392). yeccpars2_158_(__Stack0) -> @@ -8347,7 +8567,7 @@ yeccpars2_162_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8350). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570). -compile({inline,yeccpars2_163_/1}). -file("erl_parse.yrl", 396). yeccpars2_163_(__Stack0) -> @@ -8356,7 +8576,7 @@ yeccpars2_163_(__Stack0) -> build_fun ( ? line ( __1 ) , __2 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8359). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8579). -compile({inline,yeccpars2_164_/1}). -file("erl_parse.yrl", 214). yeccpars2_164_(__Stack0) -> @@ -8365,7 +8585,7 @@ yeccpars2_164_(__Stack0) -> { 'catch' , ? line ( __1 ) , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8368). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8588). -compile({inline,yeccpars2_168_/1}). -file("erl_parse.yrl", 375). yeccpars2_168_(__Stack0) -> @@ -8374,7 +8594,7 @@ yeccpars2_168_(__Stack0) -> { 'case' , ? line ( __1 ) , __2 , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8377). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8597). -compile({inline,yeccpars2_170_/1}). -file("erl_parse.yrl", 270). yeccpars2_170_(__Stack0) -> @@ -8383,7 +8603,7 @@ yeccpars2_170_(__Stack0) -> { block , ? line ( __1 ) , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8386). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8606). -compile({inline,yeccpars2_172_/1}). -file("erl_parse.yrl", 279). yeccpars2_172_(__Stack0) -> @@ -8392,7 +8612,7 @@ yeccpars2_172_(__Stack0) -> { nil , ? line ( __1 ) } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8395). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8615). -compile({inline,yeccpars2_173_/1}). -file("erl_parse.yrl", 280). yeccpars2_173_(__Stack0) -> @@ -8401,7 +8621,7 @@ yeccpars2_173_(__Stack0) -> { cons , ? line ( __1 ) , __2 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8404). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8624). -compile({inline,yeccpars2_175_/1}). -file("erl_parse.yrl", 282). yeccpars2_175_(__Stack0) -> @@ -8418,7 +8638,7 @@ yeccpars2_178_(__Stack0) -> __2 end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8421). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8641). -compile({inline,yeccpars2_180_/1}). -file("erl_parse.yrl", 284). yeccpars2_180_(__Stack0) -> @@ -8442,7 +8662,7 @@ yeccpars2_186_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8445). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8665). -compile({inline,yeccpars2_187_/1}). -file("erl_parse.yrl", 287). yeccpars2_187_(__Stack0) -> @@ -8459,7 +8679,7 @@ yeccpars2_189_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8462). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8682). -compile({inline,yeccpars2_190_/1}). -file("erl_parse.yrl", 288). yeccpars2_190_(__Stack0) -> @@ -8468,7 +8688,7 @@ yeccpars2_190_(__Stack0) -> { bin , ? line ( __1 ) , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8471). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691). -compile({inline,yeccpars2_193_/1}). -file("erl_parse.yrl", 317). yeccpars2_193_(__Stack0) -> @@ -8492,7 +8712,7 @@ yeccpars2_197_(__Stack0) -> __2 end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8495). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8715). -compile({inline,yeccpars2_198_/1}). -file("erl_parse.yrl", 294). yeccpars2_198_(__Stack0) -> @@ -8541,7 +8761,7 @@ yeccpars2_206_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8544). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8764). -compile({inline,yeccpars2_207_/1}). -file("erl_parse.yrl", 296). yeccpars2_207_(__Stack0) -> @@ -8550,7 +8770,7 @@ yeccpars2_207_(__Stack0) -> ? mkop1 ( __1 , __2 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8553). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8773). -compile({inline,yeccpars2_208_/1}). -file("erl_parse.yrl", 256). yeccpars2_208_(__Stack0) -> @@ -8567,7 +8787,7 @@ yeccpars2_210_(__Stack0) -> __2 end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8570). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8790). -compile({inline,yeccpars2_212_/1}). -file("erl_parse.yrl", 340). yeccpars2_212_(__Stack0) -> @@ -8592,7 +8812,7 @@ yeccpars2_219_(__Stack0) -> [ ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8595). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8815). -compile({inline,yeccpars2_221_/1}). -file("erl_parse.yrl", 356). yeccpars2_221_(__Stack0) -> @@ -8601,7 +8821,7 @@ yeccpars2_221_(__Stack0) -> { record_field , ? line ( __1 ) , __1 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8604). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8824). -compile({inline,yeccpars2_223_/1}). -file("erl_parse.yrl", 357). yeccpars2_223_(__Stack0) -> @@ -8626,7 +8846,7 @@ yeccpars2_226_(__Stack0) -> __2 end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8629). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8849). -compile({inline,yeccpars2_227_/1}). -file("erl_parse.yrl", 338). yeccpars2_227_(__Stack0) -> @@ -8643,7 +8863,7 @@ yeccpars2_229_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8646). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8866). -compile({inline,yeccpars2_232_/1}). -file("erl_parse.yrl", 217). yeccpars2_232_(__Stack0) -> @@ -8652,7 +8872,7 @@ yeccpars2_232_(__Stack0) -> { match , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8655). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8875). -compile({inline,yeccpars2_233_/1}). -file("erl_parse.yrl", 218). yeccpars2_233_(__Stack0) -> @@ -8661,7 +8881,7 @@ yeccpars2_233_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8664). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8884). -compile({inline,yeccpars2_235_/1}). -file("erl_parse.yrl", 221). yeccpars2_235_(__Stack0) -> @@ -8670,7 +8890,7 @@ yeccpars2_235_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8673). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8893). -compile({inline,yeccpars2_237_/1}). -file("erl_parse.yrl", 224). yeccpars2_237_(__Stack0) -> @@ -8679,7 +8899,7 @@ yeccpars2_237_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8682). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8902). -compile({inline,yeccpars2_247_/1}). -file("erl_parse.yrl", 228). yeccpars2_247_(__Stack0) -> @@ -8688,7 +8908,7 @@ yeccpars2_247_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8691). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8911). -compile({inline,yeccpars2_260_/1}). -file("erl_parse.yrl", 236). yeccpars2_260_(__Stack0) -> @@ -8697,7 +8917,7 @@ yeccpars2_260_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8700). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8920). -compile({inline,yeccpars2_268_/1}). -file("erl_parse.yrl", 240). yeccpars2_268_(__Stack0) -> @@ -8706,7 +8926,7 @@ yeccpars2_268_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8709). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8929). -compile({inline,yeccpars2_269_/1}). -file("erl_parse.yrl", 232). yeccpars2_269_(__Stack0) -> @@ -8715,7 +8935,7 @@ yeccpars2_269_(__Stack0) -> ? mkop2 ( __1 , __2 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8718). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8938). -compile({inline,yeccpars2_270_/1}). -file("erl_parse.yrl", 362). yeccpars2_270_(__Stack0) -> @@ -8724,7 +8944,7 @@ yeccpars2_270_(__Stack0) -> { call , ? line ( __1 ) , __1 , element ( 1 , __2 ) } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8727). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8947). -compile({inline,yeccpars2_273_/1}). -file("erl_parse.yrl", 252). yeccpars2_273_(__Stack0) -> @@ -8733,7 +8953,7 @@ yeccpars2_273_(__Stack0) -> { remote , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8736). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8956). -compile({inline,yeccpars2_274_/1}). -file("erl_parse.yrl", 258). yeccpars2_274_(__Stack0) -> @@ -8742,7 +8962,7 @@ yeccpars2_274_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8745). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8965). -compile({inline,yeccpars2_277_/1}). -file("erl_parse.yrl", 344). yeccpars2_277_(__Stack0) -> @@ -8751,7 +8971,7 @@ yeccpars2_277_(__Stack0) -> { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8754). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8974). -compile({inline,yeccpars2_279_/1}). -file("erl_parse.yrl", 342). yeccpars2_279_(__Stack0) -> @@ -8760,7 +8980,7 @@ yeccpars2_279_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8763). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8983). -compile({inline,yeccpars2_280_/1}). -file("erl_parse.yrl", 435). yeccpars2_280_(__Stack0) -> @@ -8769,7 +8989,7 @@ yeccpars2_280_(__Stack0) -> { __2 , ? line ( __1 ) } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8772). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8992). -compile({inline,yeccpars2_281_/1}). -file("erl_parse.yrl", 244). yeccpars2_281_(__Stack0) -> @@ -8778,7 +8998,7 @@ yeccpars2_281_(__Stack0) -> ? mkop1 ( __1 , __2 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8781). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9001). -compile({inline,yeccpars2_284_/1}). -file("erl_parse.yrl", 348). yeccpars2_284_(__Stack0) -> @@ -8787,7 +9007,7 @@ yeccpars2_284_(__Stack0) -> { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8790). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9010). -compile({inline,yeccpars2_286_/1}). -file("erl_parse.yrl", 346). yeccpars2_286_(__Stack0) -> @@ -8796,7 +9016,7 @@ yeccpars2_286_(__Stack0) -> { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8799). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9019). -compile({inline,yeccpars2_288_/1}). -file("erl_parse.yrl", 493). yeccpars2_288_(__Stack0) -> @@ -8805,7 +9025,7 @@ yeccpars2_288_(__Stack0) -> { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8808). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9028). -compile({inline,yeccpars2_289_/1}). -file("erl_parse.yrl", 203). yeccpars2_289_(__Stack0) -> @@ -8870,7 +9090,7 @@ yeccpars2_318_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8873). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9093). -compile({inline,yeccpars2_332_/1}). -file("erl_parse.yrl", 152). yeccpars2_332_(__Stack0) -> @@ -8879,7 +9099,7 @@ yeccpars2_332_(__Stack0) -> { type , ? line ( __1 ) , tuple , [ ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8882). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9102). -compile({inline,yeccpars2_333_/1}). -file("erl_parse.yrl", 153). yeccpars2_333_(__Stack0) -> @@ -8888,7 +9108,7 @@ yeccpars2_333_(__Stack0) -> { type , ? line ( __1 ) , tuple , __2 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8891). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9111). -compile({inline,yeccpars2_335_/1}). -file("erl_parse.yrl", 116). yeccpars2_335_(__Stack0) -> @@ -8897,7 +9117,7 @@ yeccpars2_335_(__Stack0) -> { ann_type , ? line ( __1 ) , [ __1 , __3 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8900). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9120). -compile({inline,yeccpars2_341_/1}). -file("erl_parse.yrl", 159). yeccpars2_341_(__Stack0) -> @@ -8906,7 +9126,7 @@ yeccpars2_341_(__Stack0) -> { type , ? line ( __1 ) , 'fun' , [ ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8909). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9129). -compile({inline,yeccpars2_345_/1}). -file("erl_parse.yrl", 163). yeccpars2_345_(__Stack0) -> @@ -8924,7 +9144,7 @@ yeccpars2_346_(__Stack0) -> __3 end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8927). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9147). -compile({inline,yeccpars2_352_/1}). -file("erl_parse.yrl", 144). yeccpars2_352_(__Stack0) -> @@ -8934,7 +9154,7 @@ yeccpars2_352_(__Stack0) -> [ __1 , __3 , [ ] ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8937). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9157). -compile({inline,yeccpars2_353_/1}). -file("erl_parse.yrl", 146). yeccpars2_353_(__Stack0) -> @@ -8952,7 +9172,7 @@ yeccpars2_355_(__Stack0) -> build_gen_type ( __1 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8955). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9175). -compile({inline,yeccpars2_356_/1}). -file("erl_parse.yrl", 142). yeccpars2_356_(__Stack0) -> @@ -8962,7 +9182,7 @@ yeccpars2_356_(__Stack0) -> normalise ( __1 ) , __3 } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8965). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9185). -compile({inline,yeccpars2_358_/1}). -file("erl_parse.yrl", 148). yeccpars2_358_(__Stack0) -> @@ -8971,7 +9191,7 @@ yeccpars2_358_(__Stack0) -> { type , ? line ( __1 ) , nil , [ ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8974). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9194). -compile({inline,yeccpars2_360_/1}). -file("erl_parse.yrl", 149). yeccpars2_360_(__Stack0) -> @@ -8980,7 +9200,7 @@ yeccpars2_360_(__Stack0) -> { type , ? line ( __1 ) , list , [ __2 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8983). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9203). -compile({inline,yeccpars2_362_/1}). -file("erl_parse.yrl", 150). yeccpars2_362_(__Stack0) -> @@ -8990,7 +9210,7 @@ yeccpars2_362_(__Stack0) -> nonempty_list , [ __2 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8993). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9213). -compile({inline,yeccpars2_365_/1}). -file("erl_parse.yrl", 179). yeccpars2_365_(__Stack0) -> @@ -9017,7 +9237,7 @@ yeccpars2_371_(__Stack0) -> build_bin_type ( [ __1 , __3 ] , __5 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9020). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9240). -compile({inline,yeccpars2_373_/1}). -file("erl_parse.yrl", 182). yeccpars2_373_(__Stack0) -> @@ -9027,7 +9247,7 @@ yeccpars2_373_(__Stack0) -> [ __2 , abstract ( 0 , ? line ( __1 ) ) ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9030). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9250). -compile({inline,yeccpars2_378_/1}). -file("erl_parse.yrl", 187). yeccpars2_378_(__Stack0) -> @@ -9036,7 +9256,7 @@ yeccpars2_378_(__Stack0) -> { type , ? line ( __1 ) , binary , [ __2 , __4 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9039). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9259). -compile({inline,yeccpars2_379_/1}). -file("erl_parse.yrl", 184). yeccpars2_379_(__Stack0) -> @@ -9046,7 +9266,7 @@ yeccpars2_379_(__Stack0) -> [ abstract ( 0 , ? line ( __1 ) ) , __2 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9049). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9269). -compile({inline,yeccpars2_381_/1}). -file("erl_parse.yrl", 167). yeccpars2_381_(__Stack0) -> @@ -9056,7 +9276,7 @@ yeccpars2_381_(__Stack0) -> [ { type , ? line ( __1 ) , product , [ ] } , __4 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9059). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9279). -compile({inline,yeccpars2_383_/1}). -file("erl_parse.yrl", 138). yeccpars2_383_(__Stack0) -> @@ -9073,7 +9293,7 @@ yeccpars2_387_(__Stack0) -> [ __1 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9076). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9296). -compile({inline,yeccpars2_389_/1}). -file("erl_parse.yrl", 154). yeccpars2_389_(__Stack0) -> @@ -9082,7 +9302,7 @@ yeccpars2_389_(__Stack0) -> { type , ? line ( __1 ) , record , [ __2 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9085). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9305). -compile({inline,yeccpars2_391_/1}). -file("erl_parse.yrl", 176). yeccpars2_391_(__Stack0) -> @@ -9100,7 +9320,7 @@ yeccpars2_393_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9103). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9323). -compile({inline,yeccpars2_394_/1}). -file("erl_parse.yrl", 155). yeccpars2_394_(__Stack0) -> @@ -9110,7 +9330,7 @@ yeccpars2_394_(__Stack0) -> record , [ __2 | __4 ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9113). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9333). -compile({inline,yeccpars2_395_/1}). -file("erl_parse.yrl", 135). yeccpars2_395_(__Stack0) -> @@ -9127,7 +9347,7 @@ yeccpars2_397_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9130). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9350). -compile({inline,yeccpars2_400_/1}). -file("erl_parse.yrl", 170). yeccpars2_400_(__Stack0) -> @@ -9145,7 +9365,7 @@ yeccpars2_402_(__Stack0) -> lift_unions ( __1 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9148). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9368). -compile({inline,yeccpars2_405_/1}). -file("erl_parse.yrl", 122). yeccpars2_405_(__Stack0) -> @@ -9156,7 +9376,7 @@ yeccpars2_405_(__Stack0) -> skip_paren ( __3 ) ] } end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9159). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9379). -compile({inline,yeccpars2_406_/1}). -file("erl_parse.yrl", 127). yeccpars2_406_(__Stack0) -> @@ -9166,7 +9386,7 @@ yeccpars2_406_(__Stack0) -> __2 , skip_paren ( __3 ) ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9169). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9389). -compile({inline,yeccpars2_408_/1}). -file("erl_parse.yrl", 131). yeccpars2_408_(__Stack0) -> @@ -9176,7 +9396,7 @@ yeccpars2_408_(__Stack0) -> __2 , skip_paren ( __3 ) ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9179). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9399). -compile({inline,yeccpars2_410_/1}). -file("erl_parse.yrl", 103). yeccpars2_410_(__Stack0) -> @@ -9202,7 +9422,7 @@ yeccpars2_415_(__Stack0) -> build_def ( __1 , __3 ) end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9205). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9425). -compile({inline,yeccpars2_418_/1}). -file("erl_parse.yrl", 109). yeccpars2_418_(__Stack0) -> @@ -9332,7 +9552,7 @@ yeccpars2_446_(__Stack0) -> [ __1 | __3 ] end | __Stack]. --file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9335). +-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9555). -compile({inline,yeccpars2_447_/1}). -file("erl_parse.yrl", 90). yeccpars2_447_(__Stack0) -> diff --git a/configure.in b/configure.in index d0879c6291..36b33ec399 100644 --- a/configure.in +++ b/configure.in @@ -106,7 +106,8 @@ AC_SUBST(CROSS_COMPILING) AC_ARG_ENABLE(bootstrap-only, -[ --enable-bootstrap-only enable bootstrap only configuration], +AS_HELP_STRING([--enable-bootstrap-only], + [enable bootstrap only configuration]), [ if test "X$enableval" = "Xyes"; then BOOTSTRAP_ONLY=yes else @@ -192,53 +193,62 @@ AC_MSG_RESULT([$OTP_REL]) AC_SUBST(OTP_REL) AC_ARG_ENABLE(threads, -[ --enable-threads enable async thread support - --disable-threads disable async thread support]) +AS_HELP_STRING([--enable-threads], [enable async thread support]) +AS_HELP_STRING([--disable-threads], [disable async thread support])) AC_ARG_ENABLE(halfword-emulator, -[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds) - --disable-halfword-emulator disable halfword emulator (only for 64bit builds)]) +AS_HELP_STRING([--enable-halfword-emulator], + [enable halfword emulator (only for 64bit builds)])) AC_ARG_ENABLE(smp-support, -[ --enable-smp-support enable smp support - --disable-smp-support disable smp support]) +AS_HELP_STRING([--enable-smp-support], [enable smp support]) +AS_HELP_STRING([--disable-smp-support], [disable smp support])) AC_ARG_WITH(termcap, -[ --with-termcap use termcap (default) - --without-termcap do not use any termcap libraries (ncurses,curses,termcap,termlib)]) +AS_HELP_STRING([--with-termcap], [use termcap (default)]) +AS_HELP_STRING([--without-termcap], + [do not use any termcap libraries (ncurses,curses,termcap,termlib)])) AC_ARG_ENABLE(kernel-poll, -[ --enable-kernel-poll enable kernel poll support]) +AS_HELP_STRING([--enable-kernel-poll], [enable kernel poll support]) +AS_HELP_STRING([--disable-kernel-poll], [disable kernel poll support])) + +AC_ARG_ENABLE(sctp, +AS_HELP_STRING([--enable-sctp], [enable sctp support]) +AS_HELP_STRING([--disable-sctp], [disable sctp support])) AC_ARG_ENABLE(hipe, -[ --enable-hipe enable hipe support - --disable-hipe disable hipe support]) - +AS_HELP_STRING([--enable-hipe], [enable hipe support]) +AS_HELP_STRING([--disable-hipe], [disable hipe support])) + +AC_ARG_ENABLE(native-libs, +AS_HELP_STRING([--enable-native-libs], + [compile Erlang libraries to native code])) + AC_ARG_WITH(javac, -[ --with-javac=JAVAC specify Java compiler to use - --with-javac use a Java compiler if found (default) - --without-javac don't use any Java compiler]) +AS_HELP_STRING([--with-javac=JAVAC], [specify Java compiler to use]) +AS_HELP_STRING([--with-javac], [use a Java compiler if found (default)]) +AS_HELP_STRING([--without-javac], [don't use any Java compiler])) AC_ARG_ENABLE(megaco_flex_scanner_lineno, -[ --enable-megaco-flex-scanner-lineno enable megaco flex scanner lineno - --disable-megaco-flex-scanner-lineno disable megaco flex scanner lineno]) +AS_HELP_STRING([--disable-megaco-flex-scanner-lineno], + [disable megaco flex scanner lineno])) AC_ARG_ENABLE(megaco_reentrant_flex_scanner, -[ --enable-megaco-reentrant-flex-scanner enable reentrans megaco flex scanner - --disable-megaco-reentrant-flex-scanner disable reentrans megaco flex scanner]) +AS_HELP_STRING([--disable-megaco-reentrant-flex-scanner], + [disable reentrant megaco flex scanner])) AC_ARG_WITH(ssl, -[ --with-ssl=PATH specify location of OpenSSL include and lib - --with-ssl use SSL (default) - --without-ssl don't use SSL]) +AS_HELP_STRING([--with-ssl=PATH], [specify location of OpenSSL include and lib]) +AS_HELP_STRING([--with-ssl], [use SSL (default)]) +AS_HELP_STRING([--without-ssl], [don't use SSL])) AC_ARG_ENABLE(dynamic-ssl-lib, -[ --enable-dynamic-ssl-lib force using dynamic openssl libraries - --disable-dynamic-ssl-lib disable using dynamic openssl libraries]) +AS_HELP_STRING([--disable-dynamic-ssl-lib], + [disable using dynamic openssl libraries])) AC_ARG_ENABLE(shared-zlib, -[ --enable-shared-zlib enable using shared zlib library - --disable-shared-zlib disable shared zlib, compile own zlib source (default)]) +AS_HELP_STRING([--enable-shared-zlib], [enable using shared zlib library])) dnl This functionality has been lost along the way... :( dnl It could perhaps be nice to reintroduce some day; therefore, @@ -256,7 +266,8 @@ dnl esac ], erl_mandir='$(erlang_libdir)/man') dnl AC_SUBST(erl_mandir) AC_ARG_ENABLE(darwin-universal, -[ --enable-darwin-universal build universal binaries on darwin i386], +AS_HELP_STRING([--enable-darwin-universal], + [build universal binaries on darwin i386]), [ case "$enableval" in no) enable_darwin_universal=no ;; *) enable_darwin_univeral=yes ;; @@ -265,7 +276,7 @@ AC_ARG_ENABLE(darwin-universal, AC_ARG_ENABLE(darwin-64bit, -[ --enable-darwin-64bit build 64bit binaries on darwin], +AS_HELP_STRING([--enable-darwin-64bit], [build 64bit binaries on darwin]), [ case "$enableval" in no) enable_darwin_64bit=no ;; *) enable_darwin_64bit=yes ;; @@ -273,7 +284,8 @@ AC_ARG_ENABLE(darwin-64bit, ],enable_darwin_64bit=no) AC_ARG_ENABLE(m64-build, -[ --enable-m64-build build 64bit binaries using the -m64 flag to (g)cc], +AS_HELP_STRING([--enable-m64-build], + [build 64bit binaries using the -m64 flag to (g)cc]), [ case "$enableval" in no) enable_m64_build=no ;; *) enable_m64_build=yes ;; @@ -281,7 +293,8 @@ AC_ARG_ENABLE(m64-build, ],enable_m64_build=no) AC_ARG_ENABLE(m32-build, -[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc], +AS_HELP_STRING([--enable-m32-build], + [build 32bit binaries using the -m32 flag to (g)cc]), [ case "$enableval" in no) enable_m32_build=no ;; *) @@ -293,6 +306,14 @@ AC_ARG_ENABLE(m32-build, esac ],enable_m32_build=no) +AC_ARG_ENABLE(ethread-pre-pentium4-compatibility, + AS_HELP_STRING([--enable-ethread-pre-pentium4-compatibility], + [enable compatibility with x86 processors before pentium 4 (back to 486) in the ethread library])) + +AC_ARG_WITH(libatomic_ops, + AS_HELP_STRING([--with-libatomic_ops=PATH], + [specify and prefer usage of libatomic_ops in the ethread library])) + dnl OK, we might have darwin switches off different kinds, lets dnl check it all before continuing. TMPSYS=`uname -s`-`uname -m` diff --git a/erts/Makefile.in b/erts/Makefile.in index dc8edcd928..2e63fc469e 100644 --- a/erts/Makefile.in +++ b/erts/Makefile.in @@ -87,17 +87,20 @@ endif # in the same directory... local_setup: @cd start_scripts && $(MAKE) + @echo `ls $(ERL_TOP)/bin/` @rm -f $(ERL_TOP)/bin/erl $(ERL_TOP)/bin/erlc $(ERL_TOP)/bin/cerl \ $(ERL_TOP)/bin/erl.exe $(ERL_TOP)/bin/erlc.exe \ $(ERL_TOP)/bin/escript $(ERL_TOP)/bin/escript.exe \ $(ERL_TOP)/bin/dialyzer $(ERL_TOP)/bin/dialyzer.exe \ $(ERL_TOP)/bin/typer $(ERL_TOP)/bin/typer.exe \ $(ERL_TOP)/bin/run_test $(ERL_TOP)/bin/run_test.exe \ + $(ERL_TOP)/bin/ct_run $(ERL_TOP)/bin/ct_run.exe \ $(ERL_TOP)/bin/start*.boot $(ERL_TOP)/bin/start*.script @if [ "X$(TARGET)" = "Xwin32" ]; then \ cp $(ERL_TOP)/bin/$(TARGET)/dialyzer.exe $(ERL_TOP)/bin/dialyzer.exe; \ cp $(ERL_TOP)/bin/$(TARGET)/typer.exe $(ERL_TOP)/bin/typer.exe; \ - cp $(ERL_TOP)/bin/$(TARGET)/run_test.exe $(ERL_TOP)/bin/run_test.exe; \ + cp $(ERL_TOP)/bin/$(TARGET)/ct_run.exe $(ERL_TOP)/bin/ct_run.exe; \ + cp $(ERL_TOP)/bin/$(TARGET)/ct_run.exe $(ERL_TOP)/bin/run_test.exe; \ cp $(ERL_TOP)/bin/$(TARGET)/erlc.exe $(ERL_TOP)/bin/erlc.exe; \ cp $(ERL_TOP)/bin/$(TARGET)/erl.exe $(ERL_TOP)/bin/erl.exe; \ cp $(ERL_TOP)/bin/$(TARGET)/werl.exe $(ERL_TOP)/bin/werl.exe; \ @@ -117,7 +120,8 @@ local_setup: $(ERL_TOP)/erts/etc/unix/cerl.src > $(ERL_TOP)/bin/cerl; \ cp $(ERL_TOP)/bin/$(TARGET)/dialyzer $(ERL_TOP)/bin/dialyzer; \ cp $(ERL_TOP)/bin/$(TARGET)/typer $(ERL_TOP)/bin/typer; \ - cp $(ERL_TOP)/bin/$(TARGET)/run_test $(ERL_TOP)/bin/run_test; \ + cp $(ERL_TOP)/bin/$(TARGET)/ct_run $(ERL_TOP)/bin/ct_run; \ + ln -s $(ERL_TOP)/bin/ct_run $(ERL_TOP)/bin/run_test; \ cp $(ERL_TOP)/bin/$(TARGET)/erlc $(ERL_TOP)/bin/erlc; \ cp $(ERL_TOP)/bin/$(TARGET)/escript $(ERL_TOP)/bin/escript; \ chmod 755 $(ERL_TOP)/bin/erl $(ERL_TOP)/bin/erlc \ diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 3b1edd7605..443d8622bf 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -386,14 +386,24 @@ AC_DEFUN(LM_SYS_IPV6, AC_CACHE_VAL(ac_cv_sys_ipv6_support, [ok_so_far=yes AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], [struct in6_addr a6; struct sockaddr_in6 s6;], ok_so_far=yes, ok_so_far=no) if test $ok_so_far = yes; then ac_cv_sys_ipv6_support=yes else AC_TRY_COMPILE([#include <sys/types.h> -#include <netinet/in.h>], +#ifdef __WIN32__ +#include <winsock2.h> +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#endif], [struct in_addr6 a6; struct sockaddr_in6 s6;], ac_cv_sys_ipv6_support=in_addr6, ac_cv_sys_ipv6_support=no) fi @@ -994,8 +1004,8 @@ case "$THR_LIB_NAME" in case "$host_cpu" in sun4u | sparc64 | sun4v) - ethr_have_native_atomics=yes;; - i86pc | i386 | i486 | i586 | i686 | x86_64 | amd64) + ethr_have_native_atomics=yes;; + i86pc | i*86 | x86_64 | amd64) ethr_have_native_atomics=yes;; macppc | ppc | "Power Macintosh") ethr_have_native_atomics=yes;; @@ -1090,7 +1100,7 @@ test "X$disable_native_ethr_impls" = "Xyes" && AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls], - [enable prefer gcc native ethread implementations]), + [prefer gcc native ethread implementations]), [ case "$enableval" in yes) enable_prefer_gcc_native_ethr_impls=yes ;; *) enable_prefer_gcc_native_ethr_impls=no ;; @@ -1099,21 +1109,60 @@ AC_ARG_ENABLE(prefer-gcc-native-ethr-impls, test $enable_prefer_gcc_native_ethr_impls = yes && AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations]) +AC_ARG_WITH(libatomic_ops, + AS_HELP_STRING([--with-libatomic_ops=PATH], + [specify and prefer usage of libatomic_ops in the ethread library])) + AC_ARG_ENABLE(ethread-pre-pentium4-compatibility, AS_HELP_STRING([--enable-ethread-pre-pentium4-compatibility], [enable compatibility with x86 processors before pentium 4 (back to 486) in the ethread library]), -[ case "$enableval" in - yes) enable_ethread_pre_pentium4_compatibility=yes ;; - *) enable_ethread_pre_pentium4_compatibilit=no ;; - esac ], enable_ethread_pre_pentium4_compatibilit=no) +[ + case "$enable_ethread_pre_pentium4_compatibility" in + yes|no) ;; + *) enable_ethread_pre_pentium4_compatibility=check;; + esac +], +[enable_ethread_pre_pentium4_compatibility=check]) + +test "$cross_compiling" != "yes" || enable_ethread_pre_pentium4_compatibility=no + +case "$enable_ethread_pre_pentium4_compatibility-$host_cpu" in + check-i86pc | check-i*86) + AC_MSG_CHECKING([whether pre pentium 4 compatibility should forced]) + AC_RUN_IFELSE([ +#if defined(__GNUC__) +# if defined(ETHR_PREFER_LIBATOMIC_OPS_NATIVE_IMPLS) +# define CHECK_LIBATOMIC_OPS__ +# else +# define CHECK_GCC_ASM__ +# endif +#elif defined(ETHR_HAVE_LIBATOMIC_OPS) +# define CHECK_LIBATOMIC_OPS__ +#endif +#if defined(CHECK_LIBATOMIC_OPS__) +#include "atomic_ops.h" +#endif +int main(void) +{ +#if defined(CHECK_GCC_ASM__) + __asm__ __volatile__("mfence" : : : "memory"); +#elif defined(CHECK_LIBATOMIC_OPS__) + AO_nop_full(); +#endif + return 0; +} + ], + [enable_ethread_pre_pentium4_compatibility=no], + [enable_ethread_pre_pentium4_compatibility=yes], + [enable_ethread_pre_pentium4_compatibility=no]) + AC_MSG_RESULT([$enable_ethread_pre_pentium4_compatibility]);; + *) + ;; +esac -test $enable_ethread_pre_pentium4_compatibilit = yes && +test $enable_ethread_pre_pentium4_compatibility = yes && AC_DEFINE(ETHR_PRE_PENTIUM4_COMPAT, 1, [Define if you want compatibilty with x86 processors before pentium4.]) -AC_ARG_WITH(libatomic_ops, - AS_HELP_STRING([--with-libatomic_ops=PATH], - [use libatomic_ops with the ethread library])) - AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \ [Define if you have all ethread defines]) diff --git a/erts/autoconf/win32.config.cache.static b/erts/autoconf/win32.config.cache.static index 31dfe510cd..d25b1df9d9 100755 --- a/erts/autoconf/win32.config.cache.static +++ b/erts/autoconf/win32.config.cache.static @@ -61,7 +61,6 @@ ac_cv_func_fork=${ac_cv_func_fork=no} ac_cv_func_fork_works=${ac_cv_func_fork_works=no} ac_cv_func_fpsetmask=${ac_cv_func_fpsetmask=no} ac_cv_func_fstat=${ac_cv_func_fstat=yes} -ac_cv_func_getaddrinfo=${ac_cv_func_getaddrinfo=no} ac_cv_func_gethostbyaddr=${ac_cv_func_gethostbyaddr=no} ac_cv_func_gethostbyaddr_r=${ac_cv_func_gethostbyaddr_r=no} ac_cv_func_gethostbyname=${ac_cv_func_gethostbyname=no} @@ -71,7 +70,6 @@ ac_cv_func_gethostname=${ac_cv_func_gethostname=no} ac_cv_func_gethrtime=${ac_cv_func_gethrtime=no} ac_cv_func_getipnodebyaddr=${ac_cv_func_getipnodebyaddr=no} ac_cv_func_getipnodebyname=${ac_cv_func_getipnodebyname=no} -ac_cv_func_getnameinfo=${ac_cv_func_getnameinfo=no} ac_cv_func_getpagesize=${ac_cv_func_getpagesize=no} ac_cv_func_gettimeofday=${ac_cv_func_gettimeofday=no} ac_cv_func_gmtime_r=${ac_cv_func_gmtime_r=no} @@ -212,7 +210,6 @@ ac_cv_sizeof_void_p=${ac_cv_sizeof_void_p=4} ac_cv_struct_exception=${ac_cv_struct_exception=no} ac_cv_struct_sockaddr_sa_len=${ac_cv_struct_sockaddr_sa_len=no} ac_cv_struct_tm=${ac_cv_struct_tm=time.h} -ac_cv_sys_ipv6_support=${ac_cv_sys_ipv6_support=no} ac_cv_sys_multicast_support=${ac_cv_sys_multicast_support=no} ac_cv_type_char=${ac_cv_type_char=yes} ac_cv_type_int=${ac_cv_type_int=yes} diff --git a/erts/configure.in b/erts/configure.in index 8c6f2ac076..6e983a07b0 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -110,7 +110,8 @@ ENABLE_ALLOC_TYPE_VARS= AC_SUBST(ENABLE_ALLOC_TYPE_VARS) AC_ARG_ENABLE(bootstrap-only, -[ --enable-bootstrap-only enable bootstrap only configuration], +AS_HELP_STRING([--enable-bootstrap-only], + [enable bootstrap only configuration]), [ if test "X$enableval" = "Xyes"; then # Disable stuff not necessary in a bootstrap only system in order # to speed up things by reducing the amount of stuff needing to be @@ -126,46 +127,46 @@ AC_ARG_ENABLE(bootstrap-only, ]) AC_ARG_ENABLE(threads, -[ --enable-threads enable async thread support - --disable-threads disable async thread support], +AS_HELP_STRING([--enable-threads], [enable async thread support]) +AS_HELP_STRING([--disable-threads], [disable async thread support]), [ case "$enableval" in no) enable_threads=no ;; *) enable_threads=yes ;; esac ], enable_threads=unknown) AC_ARG_ENABLE(halfword-emulator, -[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds) - --disable-halfword-emulator disable halfword emulator (only for 64bit builds)], +AS_HELP_STRING([--enable-halfword-emulator], + [enable halfword emulator (only for 64bit builds)]), [ case "$enableval" in no) enable_halfword_emualtor=no ;; *) enable_halfword_emulator=yes ;; esac ], enable_halfword_emulator=unknown) AC_ARG_ENABLE(smp-support, -[ --enable-smp-support enable smp support - --disable-smp-support disable smp support], +AS_HELP_STRING([--enable-smp-support], [enable smp support]) +AS_HELP_STRING([--disable-smp-support], [disable smp support]), [ case "$enableval" in no) enable_smp_support=no ;; *) enable_smp_support=yes ;; esac ], enable_smp_support=unknown) AC_ARG_WITH(termcap, -[ --with-termcap use termcap (default) - --without-termcap do not use any termcap libraries (ncurses,curses,termcap,termlib)], +AS_HELP_STRING([--with-termcap], [use termcap (default)]) +AS_HELP_STRING([--without-termcap], + [do not use any termcap libraries (ncurses,curses,termcap,termlib)]), [], [with_termcap=yes]) AC_ARG_ENABLE(hybrid-heap, -[ --enable-hybrid-heap enable hybrid heap - --disable-hybrid-heap disable hybrid heap], +AS_HELP_STRING([--enable-hybrid-heap], [enable hybrid heap]), [ case "$enableval" in no) enable_hybrid_heap=no ;; *) enable_hybrid_heap=yes ;; esac ], enable_hybrid_heap=unknown) AC_ARG_ENABLE(lock-checking, -[ --enable-lock-checking enable lock checking], +AS_HELP_STRING([--enable-lock-checking], [enable lock checking]), [ case "$enableval" in no) enable_lock_check=no ;; *) enable_lock_check=yes ;; @@ -174,16 +175,15 @@ AC_ARG_ENABLE(lock-checking, enable_lock_check=no) AC_ARG_ENABLE(lock-counter, -[ --enable-lock-counter enable lock counters - --disable-lock-counter disable lock counters], +AS_HELP_STRING([--enable-lock-counter], [enable lock counters]), [ case "$enableval" in no) enable_lock_count=no ;; *) enable_lock_count=yes ;; esac ], enable_lock_count=no) AC_ARG_ENABLE(kernel-poll, -[ --enable-kernel-poll enable kernel poll support - --disable-kernel-poll disable kernel poll support], +AS_HELP_STRING([--enable-kernel-poll], [enable kernel poll support]) +AS_HELP_STRING([--disable-kernel-poll], [disable kernel poll support]), [ case "$enableval" in no) enable_kernel_poll=no ;; *) enable_kernel_poll=yes ;; @@ -191,25 +191,27 @@ AC_ARG_ENABLE(kernel-poll, AC_ARG_ENABLE(sctp, -[ --enable-sctp enable sctp support - --disable-sctp disable sctp support], +AS_HELP_STRING([--enable-sctp], [enable sctp support]) +AS_HELP_STRING([--disable-sctp], [disable sctp support]), [ case "$enableval" in no) enable_sctp=no ;; *) enable_sctp=yes ;; esac ], enable_sctp=unknown) AC_ARG_ENABLE(hipe, -[ --enable-hipe enable hipe support - --disable-hipe disable hipe support]) +AS_HELP_STRING([--enable-hipe], [enable hipe support]) +AS_HELP_STRING([--disable-hipe], [disable hipe support])) AC_ARG_ENABLE(native-libs, -[ --enable-native-libs compile Erlang libraries to native code]) +AS_HELP_STRING([--enable-native-libs], + [compile Erlang libraries to native code])) AC_ARG_ENABLE(tsp, -[ --enable-tsp compile tsp app]) +AS_HELP_STRING([--enable-tsp], [compile tsp app])) AC_ARG_ENABLE(fp-exceptions, -[ --enable-fp-exceptions Use hardware floating point exceptions (default if hipe enabled)], +AS_HELP_STRING([--enable-fp-exceptions], + [use hardware floating point exceptions (default if hipe enabled)]), [ case "$enableval" in no) enable_fp_exceptions=no ;; *) enable_fp_exceptions=yes ;; @@ -217,7 +219,8 @@ AC_ARG_ENABLE(fp-exceptions, ],enable_fp_exceptions=auto) AC_ARG_ENABLE(darwin-universal, -[ --enable-darwin-universal build universal binaries on darwin i386], +AS_HELP_STRING([--enable-darwin-universal], + [build universal binaries on darwin i386]), [ case "$enableval" in no) enable_darwin_universal=no ;; *) enable_darwin_univeral=yes ;; @@ -226,7 +229,7 @@ AC_ARG_ENABLE(darwin-universal, AC_ARG_ENABLE(darwin-64bit, -[ --enable-darwin-64bit build 64bit binaries on darwin], +AS_HELP_STRING([--enable-darwin-64bit], [build 64bit binaries on darwin]), [ case "$enableval" in no) enable_darwin_64bit=no ;; *) enable_darwin_64bit=yes ;; @@ -234,7 +237,8 @@ AC_ARG_ENABLE(darwin-64bit, ],enable_darwin_64bit=no) AC_ARG_ENABLE(m64-build, -[ --enable-m64-build build 64bit binaries using the -m64 flag to (g)cc], +AS_HELP_STRING([--enable-m64-build], + [build 64bit binaries using the -m64 flag to (g)cc]), [ case "$enableval" in no) enable_m64_build=no ;; *) enable_m64_build=yes ;; @@ -242,7 +246,8 @@ AC_ARG_ENABLE(m64-build, ],enable_m64_build=no) AC_ARG_ENABLE(m32-build, -[ --enable-m32-build build 32bit binaries using the -m32 flag to (g)cc], +AS_HELP_STRING([--enable-m32-build], + [build 32bit binaries using the -m32 flag to (g)cc]), [ case "$enableval" in no) enable_m32_build=no ;; *) @@ -255,7 +260,7 @@ AC_ARG_ENABLE(m32-build, ],enable_m32_build=no) AC_ARG_ENABLE(fixalloc, -[ --disable-fixalloc disable the use of fix_alloc]) +AS_HELP_STRING([--disable-fixalloc], [disable the use of fix_alloc])) if test x${enable_fixalloc} = xno ; then AC_DEFINE(NO_FIX_ALLOC,[], [Define if you don't want the fix allocator in Erlang]) @@ -263,8 +268,9 @@ fi AC_SUBST(PERFCTR_PATH) AC_ARG_WITH(perfctr, -[ --with-perfctr=PATH specify location of perfctr include and lib - --without-perfctr don't use perfctr (default)]) +AS_HELP_STRING([--with-perfctr=PATH], + [specify location of perfctr include and lib]) +AS_HELP_STRING([--without-perfctr], [don't use perfctr (default)])) if test "x$with_perfctr" = "xno" -o "x$with_perfctr" = "x" ; then PERFCTR_PATH= @@ -278,7 +284,8 @@ else fi AC_ARG_ENABLE(clock-gettime, -[ --enable-clock-gettime Use clock-gettime for time correction], +AS_HELP_STRING([--enable-clock-gettime], + [use clock-gettime for time correction]), [ case "$enableval" in no) clock_gettime_correction=no ;; *) clock_gettime_correction=yes ;; @@ -1293,8 +1300,7 @@ dnl zlib dnl ------------- AC_ARG_ENABLE(shared-zlib, -[ --enable-shared-zlib enable using shared zlib library - --disable-shared-zlib disable shared zlib, compile own zlib source (default)], +AS_HELP_STRING([--enable-shared-zlib], [enable using shared zlib library]), [ case "$enableval" in no) enable_shared_zlib=no ;; *) enable_shared_zlib=yes ;; @@ -1473,7 +1479,7 @@ AC_CHECK_HEADERS(fcntl.h limits.h unistd.h syslog.h dlfcn.h ieeefp.h \ sys/ioctl.h sys/time.h sys/uio.h \ sys/socket.h sys/sockio.h sys/socketio.h \ net/errno.h malloc.h mach-o/dyld.h arpa/nameser.h \ - pty.h util.h utmp.h langinfo.h poll.h) + pty.h util.h utmp.h langinfo.h poll.h sdkddkver.h) AC_CHECK_HEADER(sys/resource.h, [AC_DEFINE(HAVE_SYS_RESOURCE_H, 1, @@ -1673,18 +1679,62 @@ LIBS="$LIBS $EMU_THR_X_LIBS" dnl Check if we have these, in which case we'll try to build dnl inet_gethost with ipv6 support. -AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes, have_getaddrinfo=no) +AC_CHECK_HEADERS(windows.h) +AC_CHECK_HEADERS(winsock2.h) +AC_CHECK_HEADERS(ws2tcpip.h,[],[],[ +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +]) +dnl AC_CHECK_FUNC(getaddrinfo, have_getaddrinfo=yes, have_getaddrinfo=no) +AC_MSG_CHECKING(for getaddrinfo) +AC_TRY_LINK([ +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +#ifndef __WIN32__ +#include <sys/socket.h> +#include <netdb.h> +#endif +], +[ +getaddrinfo("","",NULL,NULL); +],have_getaddrinfo=yes, have_getaddrinfo=no) if test $have_getaddrinfo = yes; then + AC_MSG_RESULT([yes]) AC_MSG_CHECKING([whether getaddrinfo accepts enough flags]) - AC_TRY_RUN([ + AC_TRY_COMPILE([ #include <stdlib.h> #include <string.h> +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +#ifndef __WIN32__ #include <sys/socket.h> #include <netdb.h> -int main(int argc, char **argv) { +#endif +], +[ struct addrinfo hints, *ai; memset(&hints, 0, sizeof(hints)); - hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG); + hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_INET6; if (getaddrinfo("::", NULL, &hints, &ai) == 0) { @@ -1693,26 +1743,48 @@ int main(int argc, char **argv) { } else { exit(1); } -} - ],, have_getaddrinfo=no, - [ - case X$erl_xcomp_getaddrinfo in - X) have_getaddrinfo=cross;; - Xyes|Xno) have_getaddrinfo=$erl_xcomp_getaddrinfo;; - *) AC_MSG_ERROR([Bad erl_xcomp_getaddrinfo value: $erl_xcomp_getaddrinfo]);; - esac - ]) +],, have_getaddrinfo=no) AC_MSG_RESULT($have_getaddrinfo) case $have_getaddrinfo in yes) AC_DEFINE(HAVE_GETADDRINFO, [1], [Define to 1 if you have a good `getaddrinfo' function.]);; - cross) - AC_MSG_WARN([result no guessed because of cross compilation]);; *) ;; esac +else + AC_MSG_RESULT([no]) +fi +AC_MSG_CHECKING(for getnameinfo) +AC_TRY_LINK([ +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_WINSOCK2_H +#include <winsock2.h> +#endif +#ifdef HAVE_WINDOWS_H +#include <windows.h> +#endif +#ifdef HAVE_WS2TCPIP_H +#include <ws2tcpip.h> +#endif +#ifndef __WIN32__ +#include <sys/socket.h> +#include <netdb.h> +#endif +], +[ +getnameinfo(NULL,0,NULL,0,NULL,0,0); +],have_getnameinfo=yes, have_getnameinfo=no) +if test $have_getnameinfo = yes; then + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_GETNAMEINFO, [1], + [Define to 1 if you have a good `getnameinfo' function.]) +else + AC_MSG_RESULT([no]) fi -AC_CHECK_FUNCS([getnameinfo getipnodebyname getipnodebyaddr gethostbyname2]) + + +AC_CHECK_FUNCS([getipnodebyname getipnodebyaddr gethostbyname2]) AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlopen \ pread pwrite writev memmove strerror strerror_r strncasecmp \ @@ -1788,7 +1860,7 @@ AC_CHECK_FUNCS([fdatasync]) dnl Find which C libraries are required to use fdatasync AC_SEARCH_LIBS(fdatasync, [rt]) -AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h) +AC_CHECK_HEADERS(net/if_dl.h ifaddrs.h netpacket/packet.h) AC_CHECK_FUNCS([getifaddrs]) dnl ---------------------------------------------------------------------- @@ -1852,6 +1924,27 @@ if test $processor_bind_functionality = yes; then AC_DEFINE(HAVE_PROCESSOR_BIND, 1, [Define if you have processor_bind functionality]) fi +AC_MSG_CHECKING([for cpuset_getaffinity/cpuset_setaffinity]) +AC_TRY_COMPILE([ +#include <sys/param.h> +#include <sys/cpuset.h> +], +[ + int res; + cpuset_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(1, &cpuset); + res = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset_t), &cpuset); + res = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(cpuset_t), &cpuset); + res = CPU_ISSET(1, &cpuset); + CPU_CLR(1, &cpuset); +], + cpuset_xetaffinity=yes, + cpuset_xetaffinity=no) +AC_MSG_RESULT([$cpuset_xetaffinity]) +if test $cpuset_xetaffinity = yes; then + AC_DEFINE(HAVE_CPUSET_xETAFFINITY, 1, [Define if you have cpuset_getaffinity/cpuset_setaffinity]) +fi AC_CACHE_CHECK([for 'end' symbol], erts_cv_have_end_symbol, @@ -3431,9 +3524,12 @@ AC_SUBST(STATIC_ZLIB_LIBS) std_ssl_locations="/usr/local /usr/sfw /opt/local /usr /usr/pkg /usr/local/openssl /usr/lib/openssl /usr/openssl /usr/local/ssl /usr/lib/ssl /usr/ssl" AC_ARG_WITH(ssl-zlib, -[ --with-ssl-zlib=PATH specify location of ZLib to be used by OpenSSL - --with-ssl-zlib link SSL with Zlib (default if found) - --without-ssl-zlib don't link SSL with ZLib]) +AS_HELP_STRING([--with-ssl-zlib=PATH], + [specify location of ZLib to be used by OpenSSL]) +AS_HELP_STRING([--with-ssl-zlib], + [link SSL with Zlib (default if found)]) +AS_HELP_STRING([--without-ssl-zlib], + [don't link SSL with ZLib])) if test "x$with_ssl_zlib" = "xno"; then @@ -3502,13 +3598,13 @@ fi AC_ARG_WITH(ssl, -[ --with-ssl=PATH specify location of OpenSSL include and lib - --with-ssl use SSL (default) - --without-ssl don't use SSL]) +AS_HELP_STRING([--with-ssl=PATH], [specify location of OpenSSL include and lib]) +AS_HELP_STRING([--with-ssl], [use SSL (default)]) +AS_HELP_STRING([--without-ssl], [don't use SSL])) AC_ARG_ENABLE(dynamic-ssl-lib, -[ --enable-dynamic-ssl-lib enable using dynamic openssl libraries - --disable-dynamic-ssl-lib disable using dynamic openssl libraries], +AS_HELP_STRING([--disable-dynamic-ssl-lib], + [disable using dynamic openssl libraries]), [ case "$enableval" in no) enable_dynamic_ssl=no ;; *) enable_dynamic_ssl=yes ;; @@ -3971,9 +4067,9 @@ esac AC_ARG_WITH(javac, -[ --with-javac=JAVAC specify Java compiler to use - --with-javac use a Java compiler if found (default) - --without-javac don't use any Java compiler]) +AS_HELP_STRING([--with-javac=JAVAC], [specify Java compiler to use]) +AS_HELP_STRING([--with-javac], [use a Java compiler if found (default)]) +AS_HELP_STRING([--without-javac], [don't use any Java compiler])) dnl dnl Then there are a number of apps which needs a java compiler... diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml index 006a6160de..db455312ec 100644 --- a/erts/doc/src/driver.xml +++ b/erts/doc/src/driver.xml @@ -196,11 +196,14 @@ static ErlDrvData start(ErlDrvPort port, char *command) <p>We call disconnect to log out from the database. (This should have been done from Erlang, but just in case.)</p> <code type="none"><![CDATA[ - static int do_disconnect(our_data_t* data, ei_x_buff* x); +static int do_disconnect(our_data_t* data, ei_x_buff* x); static void stop(ErlDrvData drv_data) { - do_disconnect((our_data_t*)drv_data, NULL); + our_data_t* data = (our_data_t*)drv_data; + + do_disconnect(data, NULL); + driver_free(data); } ]]></code> <p>We use the binary format only to return data to the emulator; diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml index e71b48bd92..dd949d4048 100644 --- a/erts/doc/src/driver_entry.xml +++ b/erts/doc/src/driver_entry.xml @@ -172,7 +172,7 @@ typedef struct erl_drv_entry { added to the driver list.) The driver should return 0, or if the driver can't initialize, -1.</p> </item> - <tag><marker id="start"/>int (*start)(ErlDrvPort port, char* command)</tag> + <tag><marker id="start"/>ErlDrvData (*start)(ErlDrvPort port, char* command)</tag> <item> <p>This is called when the driver is instantiated, when <c>open_port/2</c> is called. The driver should return a @@ -188,7 +188,9 @@ typedef struct erl_drv_entry { <p>This is called when the port is closed, with <c>port_close/1</c> or <c>Port ! {self(), close}</c>. Note that terminating the port owner process also closes the - port.</p> + port. If <c>drv_data</c> is a pointer to memory allocated in + <c>start</c>, then <c>stop</c> is the place to deallocate that + memory.</p> </item> <tag><marker id="output"/>void (*output)(ErlDrvData drv_data, char *buf, int len)</tag> <item> diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml index f01cf90a36..474230cb38 100644 --- a/erts/doc/src/epmd.xml +++ b/erts/doc/src/epmd.xml @@ -119,7 +119,7 @@ <tag><c><![CDATA[-port No]]></c></tag> <item> <p>Let this instance of epmd listen to another TCP port than - default 4369. This can be also be set using the + default 4369. This can also be set using the <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the section <seealso marker="#environment_variables">Environment variables</seealso> below</p> @@ -186,7 +186,7 @@ <tag><c><![CDATA[-port No]]></c></tag> <item> <p>Contacts the <c>epmd</c> listening on the given TCP port number - (default 4369). This can be also be set using the + (default 4369). This can also be set using the <c><![CDATA[ERL_EPMD_PORT]]></c> environment variable, see the section <seealso marker="#environment_variables">Environment variables</seealso> below</p> diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index e36d0adb0d..77bd952d41 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -541,6 +541,28 @@ <p>Calling <c>erlang:halt/1</c> with a string argument will still produce a crash dump.</p> </item> + <tag><c><![CDATA[+e Number]]></c></tag> + <item> + <p>Set max number of ETS tables.</p> + </item> + <tag><c><![CDATA[+ec]]></c></tag> + <item> + <p>Force the <c>compressed</c> option on all ETS tables. + Only intended for test and evaluation.</p> + </item> + <tag><c><![CDATA[+fnl]]></c></tag> + <item> + <p>The VM works with file names as if they are encoded using the ISO-latin-1 encoding, disallowing Unicode characters with codepoints beyond 255. This is default on operating systems that have transparent file naming, i.e. all Unixes except MacOSX.</p> + </item> + <tag><c><![CDATA[+fnu]]></c></tag> + <item> + <p>The VM works with file names as if they are encoded using UTF-8 (or some other system specific Unicode encoding). This is the default on operating systems that enforce Unicode encoding, i.e. Windows and MacOSX.</p> + <p>By enabling Unicode file name translation on systems where this is not default, you open up to the possibility that some file names can not be interpreted by the VM and therefore will be returned to the program as raw binaries. The option is therefore considered experimental.</p> + </item> + <tag><c><![CDATA[+fna]]></c></tag> + <item> + <p>Selection between <c>+fnl</c> and <c>+fnu</c> is done based on the current locale settings in the OS, meaning that if you have set your terminal for UTF-8 encoding, the filesystem is expected to use the same encoding for filenames (use with care).</p> + </item> <tag><c><![CDATA[+hms Size]]></c></tag> <item> <p>Sets the default heap size of processes to the size @@ -686,7 +708,7 @@ </p></item> </taglist> <p>Binding of schedulers is currently only supported on newer - Linux, Solaris, and Windows systems.</p> + Linux, Solaris, FreeBSD, and Windows systems.</p> <p>If no CPU topology is available when the <c>+sbt</c> flag is processed and <c>BindType</c> is any other type than <c>u</c>, the runtime system will fail to start. CPU @@ -906,6 +928,25 @@ <seealso marker="kernel:error_logger#warning_map/0">error_logger(3)</seealso> for further information.</p> </item> + <tag><c><![CDATA[+zFlag Value]]></c></tag> + <item> + <p>Miscellaneous flags.</p> + <taglist> + <tag><marker id="+zdbbl"><c>+zdbbl size</c></marker></tag> + <item> + <p>Set the distribution buffer busy limit + (<seealso marker="erlang#system_info_dist_buf_busy_limit">dist_buf_busy_limit</seealso>) + in kilobytes. Valid range is 1-2097151. Default is 1024.</p> + <p>A larger buffer limit will allow processes to buffer + more outgoing messages over the distribution. When the + buffer limit has been reached, sending processes will be + suspended until the buffer size has shrunk. The buffer + limit is per distribution channel. A higher limit will + give lower latency and higher throughput at the expense + of higher memory usage.</p> + </item> + </taglist> + </item> </taglist> </section> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 59ac3dc66c..78d58a1e56 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -2781,14 +2781,17 @@ os_prompt%</pre> <name>open_port(PortName, PortSettings) -> port()</name> <fsummary>Open a port</fsummary> <type> - <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, Command} | {fd, In, Out}</v> + <v>PortName = {spawn, Command} | {spawn_driver, Command} | {spawn_executable, FileName} | {fd, In, Out}</v> <v> Command = string()</v> + <v> FileName = [ FileNameChar ] | binary()</v> + <v> FileNameChar = int() (1..255 or any Unicode codepoint, see description)</v> <v> In = Out = int()</v> <v>PortSettings = [Opt]</v> - <v> Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ string() ]} | {arg0, string()} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v> + <v> Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof</v> <v> N = 1 | 2 | 4</v> <v> L = int()</v> <v> Dir = string()</v> + <v> ArgString = [ FileNameChar ] | binary()</v> <v> Env = [{Name, Val}]</v> <v> Name = string()</v> <v> Val = string() | false</v> @@ -2851,7 +2854,26 @@ os_prompt%</pre> executed, the appropriate command interpreter will implicitly be invoked, but there will still be no command argument expansion or implicit PATH search.</p> - + + <p>The name of the executable as well as the arguments + given in <c>args</c> and <c>arg0</c> is subject to + Unicode file name translation if the system is running + in Unicode file name mode. To avoid + translation or force i.e. UTF-8, supply the executable + and/or arguments as a binary in the correct + encoding. See the <seealso + marker="kernel:file">file</seealso> module, the + <seealso marker="kernel:file#native_name_encoding/0"> + file:native_name_encoding/0</seealso> function and the + <seealso marker="stdlib:unicode_usage">stdlib users guide + </seealso> for details.</p> + + <note>The characters in the name (if given as a list) + can only be > 255 if the Erlang VM is started in + Unicode file name translation mode, otherwise the name + of the executable is limited to the ISO-latin-1 + character set.</note> + <p>If the <c>Command</c> cannot be run, an error exception, with the posix error code as the reason, is raised. The error reason may differ between operating @@ -2954,6 +2976,21 @@ os_prompt%</pre> should not be given in this list. The proper executable name will automatically be used as argv[0] where applicable.</p> + <p>When the Erlang VM is running in Unicode file name + mode, the arguments can contain any Unicode characters and + will be translated into whatever is appropriate on the + underlying OS, which means UTF-8 for all platforms except + Windows, which has other (more transparent) ways of + dealing with Unicode arguments to programs. To avoid + Unicode translation of arguments, they can be supplied as + binaries in whatever encoding is deemed appropriate.</p> + + <note>The characters in the arguments (if given as a + list of characters) can only be > 255 if the Erlang + VM is started in Unicode file name mode, + otherwise the arguments are limited to the + ISO-latin-1 character set.</note> + <p>If one, for any reason, wants to explicitly set the program name in the argument vector, the <c>arg0</c> option can be used.</p> @@ -2969,6 +3006,9 @@ os_prompt%</pre> responds to this is highly system dependent and no specific effect is guaranteed.</p> + <p>The unicode file name translation rules of the + <c>args</c> option apply to this option as well.</p> + </item> <tag><c>exit_status</c></tag> @@ -5178,7 +5218,7 @@ true</pre> <seealso marker="#system_info_scheduler_bindings">erlang:system_info(scheduler_bindings)</seealso>. </p> <p>Schedulers can currently only be bound on newer Linux, - Solaris, and Windows systems, but more systems will be + Solaris, FreeBSD, and Windows systems, but more systems will be supported in the future. </p> <p>In order for the runtime system to be able to bind schedulers, @@ -5559,7 +5599,7 @@ true</pre> <item> <p>Returns the automatically detected <c>CpuTopology</c>. The emulator currently only detects the CPU topology on some newer - Linux, Solaris, and Windows systems. On Windows system with + Linux, Solaris, FreeBSD, and Windows systems. On Windows system with more than 32 logical processors the CPU topology is not detected. </p> <p>For more information see the documentation of the @@ -5624,6 +5664,13 @@ true</pre> The return value will always be <c>false</c> since the elib_malloc allocator has been removed.</p> </item> + <tag><marker id="system_info_dist_buf_busy_limit"><c>dist_buf_busy_limit</c></marker></tag> + <item> + <p>Returns the value of the distribution buffer busy limit + in bytes. This limit can be set on startup by passing the + <seealso marker="erl#+zdbbl">+zdbbl</seealso> command line + flag to <c>erl</c>.</p> + </item> <tag><c>fullsweep_after</c></tag> <item> <p>Returns <c>{fullsweep_after, int()}</c> which is the diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index efe2dada9c..1703ce0942 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -30,6 +30,54 @@ </header> <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 5.8.1.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fix that the documentation top index generator can + handle an Ericsson internal application group. </p> + <p> + Own Id: OTP-8875</p> + </item> + <item> + <p>In embedded mode, on_load handlers that called + <c>code:priv_dir/1</c> or other functions in <c>code</c> + would hang the system. Since the <c>crypto</c> + application now contains an on_loader handler that calls + <c>code:priv_dir/1</c>, including the <c>crypto</c> + application in the boot file would prevent the system + from starting.</p> + <p>Also extended the <c>-init_debug</c> option to print + information about on_load handlers being run to + facilitate debugging.</p> + <p> + Own Id: OTP-8902 Aux Id: seq11703 </p> + </item> + </list> + </section> + +</section> + +<section><title>Erts 5.8.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Windows 2003 and Windows XP pre SP3 would sometimes not + start the Erlang R14B VM at all due to a bug in the cpu + topology detection. The bug affects Windows only, no + other platform is even remotely affected. The bug is now + corrected.</p> + <p> + Own Id: OTP-8876</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 5.8.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 903abe6f5c..6c33e2ca16 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -531,8 +531,9 @@ TABLES= $(TARGET)/erl_bif_table.c $(TARGET)/erl_bif_table.h \ $(TARGET)/erl_atom_table.c $(TARGET)/erl_atom_table.h \ $(TARGET)/erl_pbifs.c -$(TABLES): $(ATOMS) $(BIFS) - LANG=C $(PERL) utils/make_tables -src $(TARGET) -include $(TARGET) $^ +$(TABLES): $(ATOMS) $(BIFS) utils/make_tables + LANG=C $(PERL) utils/make_tables -src $(TARGET) -include $(TARGET)\ + $(ATOMS) $(BIFS) $(TTF_DIR)/erl_alloc_types.h: beam/erl_alloc.types utils/make_alloc_types LANG=C $(PERL) utils/make_alloc_types -src $< -dst $@ $(ENABLE_ALLOC_TYPE_VARS) @@ -733,7 +734,7 @@ RUN_OBJS = \ $(OBJDIR)/erl_fun.o $(OBJDIR)/erl_bif_port.o \ $(OBJDIR)/erl_term.o $(OBJDIR)/erl_node_tables.o \ $(OBJDIR)/erl_monitors.o $(OBJDIR)/erl_process_dump.o \ - $(OBJDIR)/erl_bif_timer.o \ + $(OBJDIR)/erl_bif_timer.o $(OBJDIR)/erl_cpu_topology.o \ $(OBJDIR)/erl_drv_thread.o $(OBJDIR)/erl_bif_chksum.o \ $(OBJDIR)/erl_bif_re.o $(OBJDIR)/erl_unicode.o \ $(OBJDIR)/packet_parser.o $(OBJDIR)/safe_hash.o \ @@ -795,7 +796,8 @@ endif OS_OBJS += $(OBJDIR)/erl_mseg.o \ $(OBJDIR)/erl_$(ERLANG_OSTYPE)_sys_ddll.o \ - $(OBJDIR)/erl_mtrace_sys_wrap.o + $(OBJDIR)/erl_mtrace_sys_wrap.o \ + $(OBJDIR)/erl_sys_common_misc.o HIPE_x86_OS_OBJS=$(HIPE_x86_$(OPSYS)_OBJS) HIPE_x86_OBJS=$(OBJDIR)/hipe_x86.o $(OBJDIR)/hipe_x86_glue.o $(OBJDIR)/hipe_x86_bifs.o $(OBJDIR)/hipe_x86_signal.o $(OBJDIR)/hipe_x86_stack.o $(HIPE_x86_OS_OBJS) diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h index 50f5f4fbd6..a84ee7bb23 100644 --- a/erts/emulator/beam/bif.h +++ b/erts/emulator/beam/bif.h @@ -135,7 +135,6 @@ do { \ (Proc)->arity = 1; \ (Proc)->def_arg_reg[0] = (Eterm) (A0); \ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ - (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -146,7 +145,6 @@ do { \ (Proc)->def_arg_reg[0] = (Eterm) (A0); \ (Proc)->def_arg_reg[1] = (Eterm) (A1); \ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ - (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) @@ -158,7 +156,6 @@ do { \ (Proc)->def_arg_reg[1] = (Eterm) (A1); \ (Proc)->def_arg_reg[2] = (Eterm) (A2); \ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \ - (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \ (Proc)->freason = TRAP; \ (Ret) = THE_NON_VALUE; \ } while (0) diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 0674aae77f..60b4b1946b 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -795,6 +795,13 @@ bif erlang:nif_error/1 bif erlang:nif_error/2 # +# Helpers for unicode filenames +# +bif prim_file:internal_name2native/1 +bif prim_file:internal_native2name/1 +bif prim_file:internal_normalize_utf8/1 +bif file:native_name_encoding/0 +# # Obsolete # diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index 8ee8fbcb29..4be869f269 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -217,8 +217,8 @@ erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, ErtsAlcType_t al return bytes; } -static Eterm -bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs) +Eterm +erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs) { if (bitoffs == 0) { while (size) { @@ -263,7 +263,7 @@ BIF_RETTYPE binary_to_list_1(BIF_ALIST_1) Eterm* hp = HAlloc(BIF_P, 2 * size); byte* bytes = binary_bytes(real_bin)+offset; - BIF_RET(bin_bytes_to_list(NIL, hp, bytes, size, bitoffs)); + BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes, size, bitoffs)); } error: @@ -295,7 +295,7 @@ BIF_RETTYPE binary_to_list_3(BIF_ALIST_3) } i = stop-start+1; hp = HAlloc(BIF_P, 2*i); - BIF_RET(bin_bytes_to_list(NIL, hp, bytes+start-1, i, bitoffs)); + BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes+start-1, i, bitoffs)); error: BIF_ERROR(BIF_P, BADARG); @@ -339,7 +339,7 @@ BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1) previous = CONS(hp, make_binary(last), previous); hp += 2; } - BIF_RET(bin_bytes_to_list(previous, hp, bytes, size, bitoffs)); + BIF_RET(erts_bin_bytes_to_list(previous, hp, bytes, size, bitoffs)); } diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 16b6aeac3f..694460d702 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -97,6 +97,8 @@ dist_msg_dbg(ErtsDistExternal *edep, char *what, byte *buf, int sz) #define PASS_THROUGH 'p' /* This code should go */ int erts_is_alive; /* System must be blocked on change */ +int erts_dist_buf_busy_limit; + /* distribution trap functions */ Export* dsend2_trap = NULL; @@ -160,7 +162,7 @@ Uint erts_dist_cache_size(void) static ErtsProcList * get_suspended_on_de(DistEntry *dep, Uint32 unset_qflgs) { - ERTS_SMP_LC_ASSERT(erts_smp_lc_spinlock_is_locked(&dep->qlock)); + ERTS_SMP_LC_ASSERT(erts_smp_lc_mtx_is_locked(&dep->qlock)); dep->qflgs &= ~unset_qflgs; if (dep->qflgs & ERTS_DE_QFLG_EXIT) { /* No resume when exit has been scheduled */ @@ -453,17 +455,17 @@ int erts_do_net_exits(DistEntry *dep, Eterm reason) if (dep->status & ERTS_DE_SFLG_EXITING) { #ifdef DEBUG - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qflgs & ERTS_DE_QFLG_EXIT); - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); #endif } else { dep->status |= ERTS_DE_SFLG_EXITING; - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(!(dep->qflgs & ERTS_DE_QFLG_EXIT)); dep->qflgs |= ERTS_DE_QFLG_EXIT; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); } erts_smp_de_links_lock(dep); @@ -577,7 +579,7 @@ static void clear_dist_entry(DistEntry *dep) erts_smp_de_links_unlock(dep); #endif - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); if (!dep->out_queue.last) obuf = dep->finalized_out_queue.first; @@ -593,7 +595,7 @@ static void clear_dist_entry(DistEntry *dep) dep->status = 0; suspendees = get_suspended_on_de(dep, ERTS_DE_QFLGS_ALL); - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); erts_smp_atomic_set(&dep->dist_cmd_scheduled, 0); dep->send = NULL; erts_smp_de_rwunlock(dep); @@ -611,10 +613,10 @@ static void clear_dist_entry(DistEntry *dep) } if (obufsize) { - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qsize >= obufsize); dep->qsize -= obufsize; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); } } @@ -1453,8 +1455,6 @@ int erts_net_message(Port *prt, return -1; } -#define ERTS_DE_BUSY_LIMIT (128*1024) - static int dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy) { @@ -1538,18 +1538,18 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy) } else { ErtsProcList *plp = NULL; - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); dep->qsize += size_obuf(obuf); - if (dep->qsize >= ERTS_DE_BUSY_LIMIT) + if (dep->qsize >= erts_dist_buf_busy_limit) dep->qflgs |= ERTS_DE_QFLG_BUSY; if (!force_busy && (dep->qflgs & ERTS_DE_QFLG_BUSY)) { - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); plp = erts_proclist_create(c_p); plp->next = NULL; erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL); suspended = 1; - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); } /* Enqueue obuf on dist entry */ @@ -1575,7 +1575,7 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy) } } - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); erts_schedule_dist_command(NULL, dep); erts_smp_de_runlock(dep); @@ -1708,10 +1708,8 @@ erts_dist_command(Port *prt, int reds_limit) { Sint reds = ERTS_PORT_REDS_DIST_CMD_START; int prt_busy; - int de_busy; Uint32 status; Uint32 flags; - Uint32 qflgs; Sint obufsize = 0; ErtsDistOutputQueue oq, foq; DistEntry *dep = prt->dist_entry; @@ -1746,13 +1744,12 @@ erts_dist_command(Port *prt, int reds_limit) * a mess. */ - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); oq.first = dep->out_queue.first; oq.last = dep->out_queue.last; dep->out_queue.first = NULL; dep->out_queue.last = NULL; - qflgs = dep->qflgs; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); foq.first = dep->finalized_out_queue.first; foq.last = dep->finalized_out_queue.last; @@ -1763,17 +1760,8 @@ erts_dist_command(Port *prt, int reds_limit) goto preempted; prt_busy = (int) (prt->status & ERTS_PORT_SFLG_PORT_BUSY); - de_busy = (int) (qflgs & ERTS_DE_QFLG_BUSY); - if (prt_busy) { - if (!de_busy) { - erts_smp_spin_lock(&dep->qlock); - dep->qflgs |= ERTS_DE_QFLG_BUSY; - erts_smp_spin_unlock(&dep->qlock); - de_busy = 1; - } - } - else if (foq.first) { + if (!prt_busy && foq.first) { int preempt = 0; do { Uint size; @@ -1791,10 +1779,7 @@ erts_dist_command(Port *prt, int reds_limit) free_dist_obuf(fob); preempt = reds > reds_limit || (prt->status & ERTS_PORT_SFLGS_DEAD); if (prt->status & ERTS_PORT_SFLG_PORT_BUSY) { - erts_smp_spin_lock(&dep->qlock); - dep->qflgs |= ERTS_DE_QFLG_BUSY; - erts_smp_spin_unlock(&dep->qlock); - de_busy = prt_busy = 1; + prt_busy = 1; break; } } while (foq.first && !preempt); @@ -1877,10 +1862,7 @@ erts_dist_command(Port *prt, int reds_limit) free_dist_obuf(fob); preempt = reds > reds_limit || (prt->status & ERTS_PORT_SFLGS_DEAD); if (prt->status & ERTS_PORT_SFLG_PORT_BUSY) { - erts_smp_spin_lock(&dep->qlock); - dep->qflgs |= ERTS_DE_QFLG_BUSY; - erts_smp_spin_unlock(&dep->qlock); - de_busy = prt_busy = 1; + prt_busy = 1; if (oq.first && !preempt) goto finalize_only; } @@ -1907,22 +1889,23 @@ erts_dist_command(Port *prt, int reds_limit) * dist entry in a non-busy state and resume suspended * processes. */ - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qsize >= obufsize); dep->qsize -= obufsize; obufsize = 0; - if (de_busy && !prt_busy && dep->qsize < ERTS_DE_BUSY_LIMIT) { + if (!prt_busy + && (dep->qflgs & ERTS_DE_QFLG_BUSY) + && dep->qsize < erts_dist_buf_busy_limit) { ErtsProcList *suspendees; int resumed; suspendees = get_suspended_on_de(dep, ERTS_DE_QFLG_BUSY); - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); resumed = erts_resume_processes(suspendees); reds += resumed*ERTS_PORT_REDS_DIST_CMD_RESUMED; - de_busy = 0; } else - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); } ASSERT(!oq.first && !oq.last); @@ -1931,10 +1914,10 @@ erts_dist_command(Port *prt, int reds_limit) if (obufsize != 0) { ASSERT(obufsize > 0); - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qsize >= obufsize); dep->qsize -= obufsize; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); } ASSERT(foq.first || !foq.last); @@ -1984,9 +1967,9 @@ erts_dist_command(Port *prt, int reds_limit) foq.last = NULL; #ifdef DEBUG - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qsize == obufsize); - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); #endif } else { @@ -1995,14 +1978,14 @@ erts_dist_command(Port *prt, int reds_limit) * Unhandle buffers need to be put back first * in out_queue. */ - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); dep->qsize -= obufsize; obufsize = 0; oq.last->next = dep->out_queue.first; dep->out_queue.first = oq.first; if (!dep->out_queue.last) dep->out_queue.last = oq.last; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); } erts_schedule_dist_command(prt, NULL); @@ -2026,10 +2009,10 @@ erts_kill_dist_connection(DistEntry *dep, Uint32 connection_id) dep->status |= ERTS_DE_SFLG_EXITING; - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(!(dep->qflgs & ERTS_DE_QFLG_EXIT)); dep->qflgs |= ERTS_DE_QFLG_EXIT; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); erts_schedule_dist_command(NULL, dep); } @@ -2400,13 +2383,13 @@ BIF_RETTYPE setnode_3(BIF_ALIST_3) ErtsProcList *plp = erts_proclist_create(BIF_P); plp->next = NULL; erts_suspend(BIF_P, ERTS_PROC_LOCK_MAIN, NULL); - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); if (dep->suspended.last) dep->suspended.last->next = plp; else dep->suspended.first = plp; dep->suspended.last = plp; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); goto yield; } @@ -2434,9 +2417,9 @@ BIF_RETTYPE setnode_3(BIF_ALIST_3) ASSERT(dep->send); #ifdef DEBUG - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); ASSERT(dep->qsize == 0); - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); #endif erts_set_dist_entry_connected(dep, BIF_ARG_2, flags); diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index fa19c7fb45..9ccc3e5ba9 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -38,6 +38,7 @@ #define DFLAG_UNICODE_IO 0x1000 #define DFLAG_DIST_HDR_ATOM_CACHE 0x2000 #define DFLAG_SMALL_ATOM_TAGS 0x4000 +#define DFLAGS_INTERNAL_TAGS 0x8000 /* All flags that should be enabled when term_to_binary/1 is used. */ #define TERM_TO_BINARY_DFLAGS (DFLAG_EXTENDED_REFERENCES \ @@ -99,7 +100,8 @@ typedef struct { #define ERTS_DE_IS_CONNECTED(DEP) \ (!ERTS_DE_IS_NOT_CONNECTED((DEP))) - +#define ERTS_DE_BUSY_LIMIT (1024*1024) +extern int erts_dist_buf_busy_limit; extern int erts_is_alive; /* @@ -153,10 +155,10 @@ erts_dsig_prepare(ErtsDSigData *dsdp, } if (no_suspend) { failure = ERTS_DSIG_PREP_CONNECTED; - erts_smp_spin_lock(&dep->qlock); + erts_smp_mtx_lock(&dep->qlock); if (dep->qflgs & ERTS_DE_QFLG_BUSY) failure = ERTS_DSIG_PREP_WOULD_SUSPEND; - erts_smp_spin_unlock(&dep->qlock); + erts_smp_mtx_unlock(&dep->qlock); if (failure == ERTS_DSIG_PREP_WOULD_SUSPEND) goto fail; } diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c index 07b4167b27..7793f60f4f 100644 --- a/erts/emulator/beam/erl_alloc.c +++ b/erts/emulator/beam/erl_alloc.c @@ -1348,6 +1348,13 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init) argv[j++] = argv[i]; } *argc = j; +#if HALFWORD_HEAP + /* If halfword heap, silently ignore any disabling of internal + allocators */ + for (i = 0; i < aui_sz; ++i) + aui[i]->enable = 1; +#endif + } diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 7df9f19af0..408ffd12f7 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -247,7 +247,7 @@ type CPUDATA LONG_LIVED SYSTEM cpu_data type TMP_CPU_IDS SHORT_LIVED SYSTEM tmp_cpu_ids type EXT_TERM_DATA SHORT_LIVED PROCESSES external_term_data type ZLIB STANDARD SYSTEM zlib -type RDR_GRPS_MAP LONG_LIVED SYSTEM reader_groups_map +type CPU_GRPS_MAP LONG_LIVED SYSTEM cpu_groups_map +if smp type ASYNC SHORT_LIVED SYSTEM async diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c index b6a445c55c..684fa5d12f 100644 --- a/erts/emulator/beam/erl_bif_binary.c +++ b/erts/emulator/beam/erl_bif_binary.c @@ -1477,7 +1477,7 @@ BIF_RETTYPE binary_matches_3(BIF_ALIST_3) goto badarg; } if (hsend == 0) { - BIF_RET(am_nomatch); + BIF_RET(NIL); } if (is_tuple(BIF_ARG_2)) { tp = tuple_val(BIF_ARG_2); diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 40d8dc097c..75d8db880c 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -38,6 +38,7 @@ #include "erl_instrument.h" #include "dist.h" #include "erl_gc.h" +#include "erl_cpu_topology.h" #ifdef HIPE #include "hipe_arch.h" #endif @@ -1687,6 +1688,8 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */ return erts_get_cpu_topology_term(BIF_P, *tp); } else if (ERTS_IS_ATOM_STR("cpu_topology", sel) && arity == 2) { Eterm res = erts_get_cpu_topology_term(BIF_P, *tp); + if (res == THE_NON_VALUE) + goto badarg; ERTS_BIF_PREP_TRAP1(ret, erts_format_cpu_topology_trap, BIF_P, res); return ret; #if defined(PURIFY) || defined(VALGRIND) @@ -1999,6 +2002,8 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(db_get_trace_control_word_0(BIF_P)); } else if (ERTS_IS_ATOM_STR("ets_realloc_moves", BIF_ARG_1)) { BIF_RET((erts_ets_realloc_always_moves) ? am_true : am_false); + } else if (ERTS_IS_ATOM_STR("ets_always_compress", BIF_ARG_1)) { + BIF_RET((erts_ets_always_compress) ? am_true : am_false); } else if (ERTS_IS_ATOM_STR("snifs", BIF_ARG_1)) { Uint size = 0; Uint *szp; @@ -2345,9 +2350,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) /* Arguments that are unusual follow ... */ else if (ERTS_IS_ATOM_STR("logical_processors", BIF_ARG_1)) { int no; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - no = erts_get_cpu_configured(erts_cpuinfo); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); + erts_get_logical_processors(&no, NULL, NULL); if (no > 0) BIF_RET(make_small((Uint) no)); else { @@ -2357,9 +2360,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } else if (ERTS_IS_ATOM_STR("logical_processors_online", BIF_ARG_1)) { int no; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - no = erts_get_cpu_online(erts_cpuinfo); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); + erts_get_logical_processors(NULL, &no, NULL); if (no > 0) BIF_RET(make_small((Uint) no)); else { @@ -2369,9 +2370,7 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) } else if (ERTS_IS_ATOM_STR("logical_processors_available", BIF_ARG_1)) { int no; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - no = erts_get_cpu_available(erts_cpuinfo); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); + erts_get_logical_processors(NULL, NULL, &no); if (no > 0) BIF_RET(make_small((Uint) no)); else { @@ -2533,6 +2532,13 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(erts_nif_taints(BIF_P)); } else if (ERTS_IS_ATOM_STR("reader_groups_map", BIF_ARG_1)) { BIF_RET(erts_get_reader_groups_map(BIF_P)); + } else if (ERTS_IS_ATOM_STR("dist_buf_busy_limit", BIF_ARG_1)) { + Uint hsz = 0; + + (void) erts_bld_uint(NULL, &hsz, erts_dist_buf_busy_limit); + hp = hsz ? HAlloc(BIF_P, hsz) : NULL; + res = erts_bld_uint(&hp, NULL, erts_dist_buf_busy_limit); + BIF_RET(res); } BIF_ERROR(BIF_P, BADARG); diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c index 378c5e73fd..fbc92b9730 100644 --- a/erts/emulator/beam/erl_bif_port.c +++ b/erts/emulator/beam/erl_bif_port.c @@ -610,6 +610,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) int binary_io; int soft_eof; Sint linebuf; + Eterm edir = NIL; byte dir[MAXPATHLEN]; /* These are the defaults */ @@ -686,19 +687,10 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) } else if (option == am_arg0) { char *a0; - int n; - if (is_nil(*tp)) { - n = 0; - } else if( (n = is_string(*tp)) == 0) { + + if ((a0 = erts_convert_filename_to_native(*tp, ERTS_ALC_T_TMP, 1)) == NULL) { goto badarg; } - a0 = (char *) erts_alloc(ERTS_ALC_T_TMP, - (n + 1) * sizeof(byte)); - if (intlist_to_buf(*tp, a0, n) != n) { - erl_exit(1, "%s:%d: Internal error\n", - __FILE__, __LINE__); - } - a0[n] = '\0'; if (opts.argv == NULL) { opts.argv = erts_alloc(ERTS_ALC_T_TMP, 2 * sizeof(char **)); @@ -711,22 +703,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) opts.argv[0] = a0; } } else if (option == am_cd) { - Eterm iolist; - DeclareTmpHeap(heap,4,p); - int r; - - UseTmpHeap(4,p); - heap[0] = *tp; - heap[1] = make_list(heap+2); - heap[2] = make_small(0); - heap[3] = NIL; - iolist = make_list(heap); - r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN); - UnUseTmpHeap(4,p); - if (r < 0) { - goto badarg; - } - opts.wd = (char *) dir; + edir = *tp; } else { goto badarg; } @@ -838,19 +815,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) goto badarg; } name = tp[1]; - if (is_atom(name)) { - name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, - atom_tab(atom_val(name))->len+1); - sys_memcpy((void *) name_buf, - (void *) atom_tab(atom_val(name))->name, - atom_tab(atom_val(name))->len); - name_buf[atom_tab(atom_val(name))->len] = '\0'; - } else if ((i = is_string(name))) { - name_buf = (char *) erts_alloc(ERTS_ALC_T_TMP, i + 1); - if (intlist_to_buf(name, name_buf, i) != i) - erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__); - name_buf[i] = '\0'; - } else { + if ((name_buf = erts_convert_filename_to_native(name,ERTS_ALC_T_TMP,0)) == NULL) { goto badarg; } opts.spawn_type = ERTS_SPAWN_EXECUTABLE; @@ -892,7 +857,33 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) /* Argument vector only if explicit spawn_executable */ goto badarg; } - + + if (edir != NIL) { + /* A working directory is expressed differently if spawn_executable, i.e. Unicode is handles + for spawn_executable... */ + if (opts.spawn_type != ERTS_SPAWN_EXECUTABLE) { + Eterm iolist; + DeclareTmpHeap(heap,4,p); + int r; + + UseTmpHeap(4,p); + heap[0] = edir; + heap[1] = make_list(heap+2); + heap[2] = make_small(0); + heap[3] = NIL; + iolist = make_list(heap); + r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN); + UnUseTmpHeap(4,p); + if (r < 0) { + goto badarg; + } + opts.wd = (char *) dir; + } else { + if ((opts.wd = erts_convert_filename_to_native(edir,ERTS_ALC_T_TMP,0)) == NULL) { + goto badarg; + } + } + } if (driver != &spawn_driver && opts.exit_status) { goto badarg; @@ -941,6 +932,9 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) if (opts.argv) { free_args(opts.argv); } + if (opts.wd && opts.wd != ((char *)dir)) { + erts_free(ERTS_ALC_T_TMP, (void *) opts.wd); + } return port_num; badarg: @@ -950,6 +944,7 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump) #undef OPEN_PORT_ERROR } +/* Arguments can be given i unicode and as raw binaries, convert filename is used to convert */ static char **convert_args(Eterm l) { char **pp; @@ -966,22 +961,14 @@ static char **convert_args(Eterm l) pp[i++] = erts_default_arg0; while (is_list(l)) { str = CAR(list_val(l)); - - if (is_nil(str)) { - n = 0; - } else if( (n = is_string(str)) == 0) { - /* Not a string... */ + if ((b = erts_convert_filename_to_native(str,ERTS_ALC_T_TMP,1)) == NULL) { int j; for (j = 1; j < i; ++j) erts_free(ERTS_ALC_T_TMP, pp[j]); erts_free(ERTS_ALC_T_TMP, pp); return NULL; - } - b = (char *) erts_alloc(ERTS_ALC_T_TMP, (n + 1) * sizeof(byte)); - pp[i++] = (char *) b; - if (intlist_to_buf(str, b, n) != n) - erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__); - b[n] = '\0'; + } + pp[i++] = b; l = CDR(list_val(l)); } pp[i] = NULL; diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index a569fe2e85..bdf0fe23fc 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -152,6 +152,8 @@ do { \ void erts_init_binary(void); byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, ErtsAlcType_t, unsigned extra); +/* Used by unicode module */ +Eterm erts_bin_bytes_to_list(Eterm previous, Eterm* hp, byte* bytes, Uint size, Uint bitoffs); /* * Common implementation for erlang:list_to_binary/1 and binary:list_to_bin/1 diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c new file mode 100644 index 0000000000..db95c4a5d4 --- /dev/null +++ b/erts/emulator/beam/erl_cpu_topology.c @@ -0,0 +1,2359 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* + * Description: CPU topology and related functionality + * + * Author: Rickard Green + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <ctype.h> + +#include "global.h" +#include "error.h" +#include "bif.h" +#include "erl_cpu_topology.h" + +#define ERTS_MAX_READER_GROUPS 8 + +/* + * Cpu topology hierarchy. + */ +#define ERTS_TOPOLOGY_NODE 0 +#define ERTS_TOPOLOGY_PROCESSOR 1 +#define ERTS_TOPOLOGY_PROCESSOR_NODE 2 +#define ERTS_TOPOLOGY_CORE 3 +#define ERTS_TOPOLOGY_THREAD 4 +#define ERTS_TOPOLOGY_LOGICAL 5 + +#define ERTS_TOPOLOGY_MAX_DEPTH 6 + +typedef struct { + int bind_id; + int bound_id; +} ErtsCpuBindData; + +static erts_cpu_info_t *cpuinfo; + +static int max_main_threads; +static int reader_groups; + +static ErtsCpuBindData *scheduler2cpu_map; +static erts_smp_rwmtx_t cpuinfo_rwmtx; + +typedef enum { + ERTS_CPU_BIND_UNDEFINED, + ERTS_CPU_BIND_SPREAD, + ERTS_CPU_BIND_PROCESSOR_SPREAD, + ERTS_CPU_BIND_THREAD_SPREAD, + ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD, + ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD, + ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD, + ERTS_CPU_BIND_NO_SPREAD, + ERTS_CPU_BIND_NONE +} ErtsCpuBindOrder; + +#define ERTS_CPU_BIND_DEFAULT_BIND \ + ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD + +static int no_cpu_groups_callbacks; +static ErtsCpuBindOrder cpu_bind_order; + +static erts_cpu_topology_t *user_cpudata; +static int user_cpudata_size; +static erts_cpu_topology_t *system_cpudata; +static int system_cpudata_size; + +typedef struct { + int level[ERTS_TOPOLOGY_MAX_DEPTH+1]; +} erts_avail_cput; + +typedef struct { + int id; + int sub_levels; + int cpu_groups; +} erts_cpu_groups_count_t; + +typedef struct { + int logical; + int cpu_group; +} erts_cpu_groups_map_array_t; + +typedef struct erts_cpu_groups_callback_list_t_ erts_cpu_groups_callback_list_t; +struct erts_cpu_groups_callback_list_t_ { + erts_cpu_groups_callback_list_t *next; + erts_cpu_groups_callback_t callback; + void *arg; +}; + +typedef struct erts_cpu_groups_map_t_ erts_cpu_groups_map_t; +struct erts_cpu_groups_map_t_ { + erts_cpu_groups_map_t *next; + int groups; + erts_cpu_groups_map_array_t *array; + int size; + int logical_processors; + erts_cpu_groups_callback_list_t *callback_list; +}; + +typedef struct { + erts_cpu_groups_callback_t callback; + int ix; + void *arg; +} erts_cpu_groups_callback_call_t; + +static erts_cpu_groups_map_t *cpu_groups_maps; + +static erts_cpu_groups_map_t *reader_groups_map; + +#define ERTS_TOPOLOGY_CG ERTS_TOPOLOGY_MAX_DEPTH + +#define ERTS_MAX_CPU_TOPOLOGY_ID ((int) 0xffff) + +#ifdef ERTS_SMP +static void cpu_bind_order_sort(erts_cpu_topology_t *cpudata, + int size, + ErtsCpuBindOrder bind_order, + int mk_seq); +static void write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size); +#endif + +static void reader_groups_callback(int, ErtsSchedulerData *, int, void *); +static erts_cpu_groups_map_t *add_cpu_groups(int groups, + erts_cpu_groups_callback_t callback, + void *arg); +static void update_cpu_groups_maps(void); +static void make_cpu_groups_map(erts_cpu_groups_map_t *map, int test); +static int cpu_groups_lookup(erts_cpu_groups_map_t *map, + ErtsSchedulerData *esdp); + +static void create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, + int *cpudata_size); +static void destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata); + +static int +int_cmp(const void *vx, const void *vy) +{ + return *((int *) vx) - *((int *) vy); +} + +static int +cpu_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->core != y->core) + return x->core - y->core; + if (x->processor_node != y->processor_node) + return x->processor_node - y->processor_node; + if (x->processor != y->processor) + return x->processor - y->processor; + if (x->node != y->node) + return x->node - y->node; + return 0; +} + +static int +cpu_processor_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->processor_node != y->processor_node) + return x->processor_node - y->processor_node; + if (x->core != y->core) + return x->core - y->core; + if (x->node != y->node) + return x->node - y->node; + if (x->processor != y->processor) + return x->processor - y->processor; + return 0; +} + +static int +cpu_thread_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->node != y->node) + return x->node - y->node; + if (x->processor != y->processor) + return x->processor - y->processor; + if (x->processor_node != y->processor_node) + return x->processor_node - y->processor_node; + if (x->core != y->core) + return x->core - y->core; + return 0; +} + +static int +cpu_thread_no_node_processor_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->node != y->node) + return x->node - y->node; + if (x->core != y->core) + return x->core - y->core; + if (x->processor != y->processor) + return x->processor - y->processor; + return 0; +} + +static int +cpu_no_node_processor_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->node != y->node) + return x->node - y->node; + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->core != y->core) + return x->core - y->core; + if (x->processor != y->processor) + return x->processor - y->processor; + return 0; +} + +static int +cpu_no_node_thread_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->node != y->node) + return x->node - y->node; + if (x->thread != y->thread) + return x->thread - y->thread; + if (x->processor != y->processor) + return x->processor - y->processor; + if (x->core != y->core) + return x->core - y->core; + return 0; +} + +static int +cpu_no_spread_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->node != y->node) + return x->node - y->node; + if (x->processor != y->processor) + return x->processor - y->processor; + if (x->processor_node != y->processor_node) + return x->processor_node - y->processor_node; + if (x->core != y->core) + return x->core - y->core; + if (x->thread != y->thread) + return x->thread - y->thread; + return 0; +} + +static ERTS_INLINE void +make_cpudata_id_seq(erts_cpu_topology_t *cpudata, int size, int no_node) +{ + int ix; + int node = -1; + int processor = -1; + int processor_node = -1; + int processor_node_node = -1; + int core = -1; + int thread = -1; + int old_node = -1; + int old_processor = -1; + int old_processor_node = -1; + int old_core = -1; + int old_thread = -1; + + for (ix = 0; ix < size; ix++) { + if (!no_node || cpudata[ix].node >= 0) { + if (old_node == cpudata[ix].node) + cpudata[ix].node = node; + else { + old_node = cpudata[ix].node; + old_processor = processor = -1; + if (!no_node) + old_processor_node = processor_node = -1; + old_core = core = -1; + old_thread = thread = -1; + if (no_node || cpudata[ix].node >= 0) + cpudata[ix].node = ++node; + } + } + if (old_processor == cpudata[ix].processor) + cpudata[ix].processor = processor; + else { + old_processor = cpudata[ix].processor; + if (!no_node) + processor_node_node = old_processor_node = processor_node = -1; + old_core = core = -1; + old_thread = thread = -1; + cpudata[ix].processor = ++processor; + } + if (no_node && cpudata[ix].processor_node < 0) + old_processor_node = -1; + else { + if (old_processor_node == cpudata[ix].processor_node) { + if (no_node) + cpudata[ix].node = cpudata[ix].processor_node = node; + else { + if (processor_node_node >= 0) + cpudata[ix].node = processor_node_node; + cpudata[ix].processor_node = processor_node; + } + } + else { + old_processor_node = cpudata[ix].processor_node; + old_core = core = -1; + old_thread = thread = -1; + if (no_node) + cpudata[ix].node = cpudata[ix].processor_node = ++node; + else { + cpudata[ix].node = processor_node_node = ++node; + cpudata[ix].processor_node = ++processor_node; + } + } + } + if (!no_node && cpudata[ix].processor_node < 0) + cpudata[ix].processor_node = 0; + if (old_core == cpudata[ix].core) + cpudata[ix].core = core; + else { + old_core = cpudata[ix].core; + old_thread = thread = -1; + cpudata[ix].core = ++core; + } + if (old_thread == cpudata[ix].thread) + cpudata[ix].thread = thread; + else + old_thread = cpudata[ix].thread = ++thread; + } +} + +static void +cpu_bind_order_sort(erts_cpu_topology_t *cpudata, + int size, + ErtsCpuBindOrder bind_order, + int mk_seq) +{ + if (size > 1) { + int no_node = 0; + int (*cmp_func)(const void *, const void *); + switch (bind_order) { + case ERTS_CPU_BIND_SPREAD: + cmp_func = cpu_spread_order_cmp; + break; + case ERTS_CPU_BIND_PROCESSOR_SPREAD: + cmp_func = cpu_processor_spread_order_cmp; + break; + case ERTS_CPU_BIND_THREAD_SPREAD: + cmp_func = cpu_thread_spread_order_cmp; + break; + case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: + no_node = 1; + cmp_func = cpu_thread_no_node_processor_spread_order_cmp; + break; + case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: + no_node = 1; + cmp_func = cpu_no_node_processor_spread_order_cmp; + break; + case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: + no_node = 1; + cmp_func = cpu_no_node_thread_spread_order_cmp; + break; + case ERTS_CPU_BIND_NO_SPREAD: + cmp_func = cpu_no_spread_order_cmp; + break; + default: + cmp_func = NULL; + erl_exit(ERTS_ABORT_EXIT, + "Bad cpu bind type: %d\n", + (int) cpu_bind_order); + break; + } + + if (mk_seq) + make_cpudata_id_seq(cpudata, size, no_node); + + qsort(cpudata, size, sizeof(erts_cpu_topology_t), cmp_func); + } +} + +static int +processor_order_cmp(const void *vx, const void *vy) +{ + erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; + erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; + + if (x->processor != y->processor) + return x->processor - y->processor; + if (x->node != y->node) + return x->node - y->node; + if (x->processor_node != y->processor_node) + return x->processor_node - y->processor_node; + if (x->core != y->core) + return x->core - y->core; + if (x->thread != y->thread) + return x->thread - y->thread; + return 0; +} + +#ifdef ERTS_SMP +void +erts_sched_check_cpu_bind_prep_suspend(ErtsSchedulerData *esdp) +{ + erts_cpu_groups_map_t *cgm; + erts_cpu_groups_callback_list_t *cgcl; + erts_cpu_groups_callback_call_t *cgcc; + int cgcc_ix; + + /* Unbind from cpu */ + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + if (scheduler2cpu_map[esdp->no].bound_id >= 0 + && erts_unbind_from_cpu(cpuinfo) == 0) { + esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1; + } + + cgcc = erts_alloc(ERTS_ALC_T_TMP, + (no_cpu_groups_callbacks + * sizeof(erts_cpu_groups_callback_call_t))); + cgcc_ix = 0; + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { + for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) { + cgcc[cgcc_ix].callback = cgcl->callback; + cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp); + cgcc[cgcc_ix].arg = cgcl->arg; + cgcc_ix++; + } + } + ASSERT(no_cpu_groups_callbacks == cgcc_ix); + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + + for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++) + cgcc[cgcc_ix].callback(1, + esdp, + cgcc[cgcc_ix].ix, + cgcc[cgcc_ix].arg); + + erts_free(ERTS_ALC_T_TMP, cgcc); + + if (esdp->no <= max_main_threads) + erts_thr_set_main_status(0, 0); + +} + +void +erts_sched_check_cpu_bind_post_suspend(ErtsSchedulerData *esdp) +{ + ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(esdp->run_queue)); + + if (esdp->no <= max_main_threads) + erts_thr_set_main_status(1, (int) esdp->no); + + /* Make sure we check if we should bind to a cpu or not... */ + if (esdp->run_queue->flags & ERTS_RUNQ_FLG_SHARED_RUNQ) + erts_smp_atomic_set(&esdp->chk_cpu_bind, 1); + else + esdp->run_queue->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND; +} + +#endif + +void +erts_sched_check_cpu_bind(ErtsSchedulerData *esdp) +{ + int res, cpu_id, cgcc_ix; + erts_cpu_groups_map_t *cgm; + erts_cpu_groups_callback_list_t *cgcl; + erts_cpu_groups_callback_call_t *cgcc; +#ifdef ERTS_SMP + if (erts_common_run_queue) + erts_smp_atomic_set(&esdp->chk_cpu_bind, 0); + else { + esdp->run_queue->flags &= ~ERTS_RUNQ_FLG_CHK_CPU_BIND; + } +#endif + erts_smp_runq_unlock(esdp->run_queue); + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + cpu_id = scheduler2cpu_map[esdp->no].bind_id; + if (cpu_id >= 0 && cpu_id != scheduler2cpu_map[esdp->no].bound_id) { + res = erts_bind_to_cpu(cpuinfo, cpu_id); + if (res == 0) + esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = cpu_id; + else { + erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); + erts_dsprintf(dsbufp, "Scheduler %d failed to bind to cpu %d: %s\n", + (int) esdp->no, cpu_id, erl_errno_id(-res)); + erts_send_error_to_logger_nogl(dsbufp); + if (scheduler2cpu_map[esdp->no].bound_id >= 0) + goto unbind; + } + } + else if (cpu_id < 0) { + unbind: + /* Get rid of old binding */ + res = erts_unbind_from_cpu(cpuinfo); + if (res == 0) + esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1; + else if (res != -ENOTSUP) { + erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); + erts_dsprintf(dsbufp, "Scheduler %d failed to unbind from cpu %d: %s\n", + (int) esdp->no, cpu_id, erl_errno_id(-res)); + erts_send_error_to_logger_nogl(dsbufp); + } + } + + cgcc = erts_alloc(ERTS_ALC_T_TMP, + (no_cpu_groups_callbacks + * sizeof(erts_cpu_groups_callback_call_t))); + cgcc_ix = 0; + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { + for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) { + cgcc[cgcc_ix].callback = cgcl->callback; + cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp); + cgcc[cgcc_ix].arg = cgcl->arg; + cgcc_ix++; + } + } + + ASSERT(no_cpu_groups_callbacks == cgcc_ix); + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + + for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++) + cgcc[cgcc_ix].callback(0, + esdp, + cgcc[cgcc_ix].ix, + cgcc[cgcc_ix].arg); + + erts_free(ERTS_ALC_T_TMP, cgcc); + + erts_smp_runq_lock(esdp->run_queue); +} + +#ifdef ERTS_SMP +void +erts_sched_init_check_cpu_bind(ErtsSchedulerData *esdp) +{ + int cgcc_ix; + erts_cpu_groups_map_t *cgm; + erts_cpu_groups_callback_list_t *cgcl; + erts_cpu_groups_callback_call_t *cgcc; + + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + + cgcc = erts_alloc(ERTS_ALC_T_TMP, + (no_cpu_groups_callbacks + * sizeof(erts_cpu_groups_callback_call_t))); + cgcc_ix = 0; + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { + for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) { + cgcc[cgcc_ix].callback = cgcl->callback; + cgcc[cgcc_ix].ix = cpu_groups_lookup(cgm, esdp); + cgcc[cgcc_ix].arg = cgcl->arg; + cgcc_ix++; + } + } + + ASSERT(no_cpu_groups_callbacks == cgcc_ix); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + + for (cgcc_ix = 0; cgcc_ix < no_cpu_groups_callbacks; cgcc_ix++) + cgcc[cgcc_ix].callback(0, + esdp, + cgcc[cgcc_ix].ix, + cgcc[cgcc_ix].arg); + + erts_free(ERTS_ALC_T_TMP, cgcc); + + if (esdp->no <= max_main_threads) + erts_thr_set_main_status(1, (int) esdp->no); +} +#endif + +static void +write_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size) +{ + int s_ix = 1; + int cpu_ix; + + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + + if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) { + + cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1); + + for (cpu_ix = 0; cpu_ix < size && cpu_ix < erts_no_schedulers; cpu_ix++) + if (erts_is_cpu_available(cpuinfo, cpudata[cpu_ix].logical)) + scheduler2cpu_map[s_ix++].bind_id = cpudata[cpu_ix].logical; + } + + if (s_ix <= erts_no_schedulers) + for (; s_ix <= erts_no_schedulers; s_ix++) + scheduler2cpu_map[s_ix].bind_id = -1; +} + +int +erts_init_scheduler_bind_type_string(char *how) +{ + if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP) + return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED; + + if (!system_cpudata && !user_cpudata) + return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY; + + if (sys_strcmp(how, "db") == 0) + cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; + else if (sys_strcmp(how, "s") == 0) + cpu_bind_order = ERTS_CPU_BIND_SPREAD; + else if (sys_strcmp(how, "ps") == 0) + cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; + else if (sys_strcmp(how, "ts") == 0) + cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; + else if (sys_strcmp(how, "tnnps") == 0) + cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; + else if (sys_strcmp(how, "nnps") == 0) + cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; + else if (sys_strcmp(how, "nnts") == 0) + cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; + else if (sys_strcmp(how, "ns") == 0) + cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; + else if (sys_strcmp(how, "u") == 0) + cpu_bind_order = ERTS_CPU_BIND_NONE; + else + return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE; + + return ERTS_INIT_SCHED_BIND_TYPE_SUCCESS; +} + +static Eterm +bound_schedulers_term(ErtsCpuBindOrder order) +{ + switch (order) { + case ERTS_CPU_BIND_SPREAD: { + ERTS_DECL_AM(spread); + return AM_spread; + } + case ERTS_CPU_BIND_PROCESSOR_SPREAD: { + ERTS_DECL_AM(processor_spread); + return AM_processor_spread; + } + case ERTS_CPU_BIND_THREAD_SPREAD: { + ERTS_DECL_AM(thread_spread); + return AM_thread_spread; + } + case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: { + ERTS_DECL_AM(thread_no_node_processor_spread); + return AM_thread_no_node_processor_spread; + } + case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: { + ERTS_DECL_AM(no_node_processor_spread); + return AM_no_node_processor_spread; + } + case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: { + ERTS_DECL_AM(no_node_thread_spread); + return AM_no_node_thread_spread; + } + case ERTS_CPU_BIND_NO_SPREAD: { + ERTS_DECL_AM(no_spread); + return AM_no_spread; + } + case ERTS_CPU_BIND_NONE: { + ERTS_DECL_AM(unbound); + return AM_unbound; + } + default: + ASSERT(0); + return THE_NON_VALUE; + } +} + +Eterm +erts_bound_schedulers_term(Process *c_p) +{ + ErtsCpuBindOrder order; + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + order = cpu_bind_order; + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + return bound_schedulers_term(order); +} + +Eterm +erts_bind_schedulers(Process *c_p, Eterm how) +{ + int notify = 0; + Eterm res; + erts_cpu_topology_t *cpudata; + int cpudata_size; + ErtsCpuBindOrder old_cpu_bind_order; + + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + + if (erts_bind_to_cpu(cpuinfo, -1) == -ENOTSUP) { + ERTS_BIF_PREP_ERROR(res, c_p, EXC_NOTSUP); + } + else { + + old_cpu_bind_order = cpu_bind_order; + + if (ERTS_IS_ATOM_STR("default_bind", how)) + cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; + else if (ERTS_IS_ATOM_STR("spread", how)) + cpu_bind_order = ERTS_CPU_BIND_SPREAD; + else if (ERTS_IS_ATOM_STR("processor_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("thread_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; + else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; + else if (ERTS_IS_ATOM_STR("no_spread", how)) + cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; + else if (ERTS_IS_ATOM_STR("unbound", how)) + cpu_bind_order = ERTS_CPU_BIND_NONE; + else { + cpu_bind_order = old_cpu_bind_order; + ERTS_BIF_PREP_ERROR(res, c_p, BADARG); + goto done; + } + + create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); + + if (!cpudata) { + cpu_bind_order = old_cpu_bind_order; + ERTS_BIF_PREP_ERROR(res, c_p, BADARG); + goto done; + } + + write_schedulers_bind_change(cpudata, cpudata_size); + notify = 1; + + destroy_tmp_cpu_topology_copy(cpudata); + + res = bound_schedulers_term(old_cpu_bind_order); + } + + done: + + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + + if (notify) + erts_sched_notify_check_cpu_bind(); + + return res; +} + +int +erts_sched_bind_atthrcreate_prepare(void) +{ + ErtsSchedulerData *esdp = erts_get_scheduler_data(); + return esdp != NULL && erts_is_scheduler_bound(esdp); +} + +int +erts_sched_bind_atthrcreate_child(int unbind) +{ + int res = 0; + if (unbind) { + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + res = erts_unbind_from_cpu(cpuinfo); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + } + return res; +} + +void +erts_sched_bind_atthrcreate_parent(int unbind) +{ + +} + +int +erts_sched_bind_atfork_prepare(void) +{ + ErtsSchedulerData *esdp = erts_get_scheduler_data(); + int unbind = esdp != NULL && erts_is_scheduler_bound(esdp); + if (unbind) + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + return unbind; +} + +int +erts_sched_bind_atfork_child(int unbind) +{ + if (unbind) { + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx) + || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + return erts_unbind_from_cpu(cpuinfo); + } + return 0; +} + +char * +erts_sched_bind_atvfork_child(int unbind) +{ + if (unbind) { + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx) + || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + return erts_get_unbind_from_cpu_str(cpuinfo); + } + return "false"; +} + +void +erts_sched_bind_atfork_parent(int unbind) +{ + if (unbind) + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); +} + +Eterm +erts_fake_scheduler_bindings(Process *p, Eterm how) +{ + ErtsCpuBindOrder fake_cpu_bind_order; + erts_cpu_topology_t *cpudata; + int cpudata_size; + Eterm res; + + if (ERTS_IS_ATOM_STR("default_bind", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; + else if (ERTS_IS_ATOM_STR("spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_SPREAD; + else if (ERTS_IS_ATOM_STR("processor_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("thread_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; + else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; + else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; + else if (ERTS_IS_ATOM_STR("no_spread", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; + else if (ERTS_IS_ATOM_STR("unbound", how)) + fake_cpu_bind_order = ERTS_CPU_BIND_NONE; + else { + ERTS_BIF_PREP_ERROR(res, p, BADARG); + return res; + } + + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + + if (!cpudata || fake_cpu_bind_order == ERTS_CPU_BIND_NONE) + ERTS_BIF_PREP_RET(res, am_false); + else { + int i; + Eterm *hp; + + cpu_bind_order_sort(cpudata, cpudata_size, fake_cpu_bind_order, 1); + +#ifdef ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA + + erts_fprintf(stderr, "node: "); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].node); + erts_fprintf(stderr, "\n"); + erts_fprintf(stderr, "processor: "); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].processor); + erts_fprintf(stderr, "\n"); + if (fake_cpu_bind_order != ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD + && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD + && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD) { + erts_fprintf(stderr, "processor_node:"); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].processor_node); + erts_fprintf(stderr, "\n"); + } + erts_fprintf(stderr, "core: "); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].core); + erts_fprintf(stderr, "\n"); + erts_fprintf(stderr, "thread: "); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].thread); + erts_fprintf(stderr, "\n"); + erts_fprintf(stderr, "logical: "); + for (i = 0; i < cpudata_size; i++) + erts_fprintf(stderr, " %2d", cpudata[i].logical); + erts_fprintf(stderr, "\n"); +#endif + + hp = HAlloc(p, cpudata_size+1); + ERTS_BIF_PREP_RET(res, make_tuple(hp)); + *hp++ = make_arityval((Uint) cpudata_size); + for (i = 0; i < cpudata_size; i++) + *hp++ = make_small((Uint) cpudata[i].logical); + } + + destroy_tmp_cpu_topology_copy(cpudata); + + return res; +} + +Eterm +erts_get_schedulers_binds(Process *c_p) +{ + int ix; + ERTS_DECL_AM(unbound); + Eterm *hp = HAlloc(c_p, erts_no_schedulers+1); + Eterm res = make_tuple(hp); + + *(hp++) = make_arityval(erts_no_schedulers); + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + for (ix = 1; ix <= erts_no_schedulers; ix++) + *(hp++) = (scheduler2cpu_map[ix].bound_id >= 0 + ? make_small(scheduler2cpu_map[ix].bound_id) + : AM_unbound); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + return res; +} + +/* + * CPU topology + */ + +typedef struct { + int *id; + int used; + int size; +} ErtsCpuTopIdSeq; + +typedef struct { + ErtsCpuTopIdSeq logical; + ErtsCpuTopIdSeq thread; + ErtsCpuTopIdSeq core; + ErtsCpuTopIdSeq processor_node; + ErtsCpuTopIdSeq processor; + ErtsCpuTopIdSeq node; +} ErtsCpuTopEntry; + +static void +init_cpu_top_entry(ErtsCpuTopEntry *cte) +{ + int size = 10; + cte->logical.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->logical.size = size; + cte->thread.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->thread.size = size; + cte->core.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->core.size = size; + cte->processor_node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->processor_node.size = size; + cte->processor.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->processor.size = size; + cte->node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, + sizeof(int)*size); + cte->node.size = size; +} + +static void +destroy_cpu_top_entry(ErtsCpuTopEntry *cte) +{ + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->logical.id); + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->thread.id); + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->core.id); + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor_node.id); + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor.id); + erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->node.id); +} + +static int +get_cput_value_or_range(int *v, int *vr, char **str) +{ + long l; + char *c = *str; + errno = 0; + if (!isdigit((unsigned char)*c)) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID; + l = strtol(c, &c, 10); + if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID; + *v = (int) l; + if (*c == '-') { + c++; + if (!isdigit((unsigned char)*c)) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + l = strtol(c, &c, 10); + if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + *vr = (int) l; + } + *str = c; + return ERTS_INIT_CPU_TOPOLOGY_OK; +} + +static int +get_cput_id_seq(ErtsCpuTopIdSeq *idseq, char **str) +{ + int ix = 0; + int need_size = 0; + char *c = *str; + + while (1) { + int res; + int val; + int nids; + int val_range = -1; + res = get_cput_value_or_range(&val, &val_range, &c); + if (res != ERTS_INIT_CPU_TOPOLOGY_OK) + return res; + if (val_range < 0 || val_range == val) + nids = 1; + else { + if (val_range > val) + nids = val_range - val + 1; + else + nids = val - val_range + 1; + } + need_size += nids; + if (need_size > idseq->size) { + idseq->size = need_size + 10; + idseq->id = erts_realloc(ERTS_ALC_T_TMP_CPU_IDS, + idseq->id, + sizeof(int)*idseq->size); + } + if (nids == 1) + idseq->id[ix++] = val; + else if (val_range > val) { + for (; val <= val_range; val++) + idseq->id[ix++] = val; + } + else { + for (; val >= val_range; val--) + idseq->id[ix++] = val; + } + if (*c != ',') + break; + c++; + } + *str = c; + idseq->used = ix; + return ERTS_INIT_CPU_TOPOLOGY_OK; +} + +static int +get_cput_entry(ErtsCpuTopEntry *cput, char **str) +{ + int h; + char *c = *str; + + cput->logical.used = 0; + cput->thread.id[0] = 0; + cput->thread.used = 1; + cput->core.id[0] = 0; + cput->core.used = 1; + cput->processor_node.id[0] = -1; + cput->processor_node.used = 1; + cput->processor.id[0] = 0; + cput->processor.used = 1; + cput->node.id[0] = -1; + cput->node.used = 1; + + h = ERTS_TOPOLOGY_MAX_DEPTH; + while (*c != ':' && *c != '\0') { + int res; + ErtsCpuTopIdSeq *idseqp; + switch (*c++) { + case 'L': + if (h <= ERTS_TOPOLOGY_LOGICAL) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->logical; + h = ERTS_TOPOLOGY_LOGICAL; + break; + case 't': + case 'T': + if (h <= ERTS_TOPOLOGY_THREAD) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->thread; + h = ERTS_TOPOLOGY_THREAD; + break; + case 'c': + case 'C': + if (h <= ERTS_TOPOLOGY_CORE) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->core; + h = ERTS_TOPOLOGY_CORE; + break; + case 'p': + case 'P': + if (h <= ERTS_TOPOLOGY_PROCESSOR) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->processor; + h = ERTS_TOPOLOGY_PROCESSOR; + break; + case 'n': + case 'N': + if (h <= ERTS_TOPOLOGY_PROCESSOR) { + do_node: + if (h <= ERTS_TOPOLOGY_NODE) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->node; + h = ERTS_TOPOLOGY_NODE; + } + else { + int p_node = 0; + char *p_chk = c; + while (*p_chk != '\0' && *p_chk != ':') { + if (*p_chk == 'p' || *p_chk == 'P') { + p_node = 1; + break; + } + p_chk++; + } + if (!p_node) + goto do_node; + if (h <= ERTS_TOPOLOGY_PROCESSOR_NODE) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; + idseqp = &cput->processor_node; + h = ERTS_TOPOLOGY_PROCESSOR_NODE; + } + break; + default: + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE; + } + res = get_cput_id_seq(idseqp, &c); + if (res != ERTS_INIT_CPU_TOPOLOGY_OK) + return res; + } + + if (cput->logical.used < 1) + return ERTS_INIT_CPU_TOPOLOGY_MISSING_LID; + + if (*c == ':') { + c++; + } + + if (cput->thread.used != 1 + && cput->thread.used != cput->logical.used) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + if (cput->core.used != 1 + && cput->core.used != cput->logical.used) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + if (cput->processor_node.used != 1 + && cput->processor_node.used != cput->logical.used) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + if (cput->processor.used != 1 + && cput->processor.used != cput->logical.used) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + if (cput->node.used != 1 + && cput->node.used != cput->logical.used) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; + + *str = c; + return ERTS_INIT_CPU_TOPOLOGY_OK; +} + +static int +verify_topology(erts_cpu_topology_t *cpudata, int size) +{ + if (size > 0) { + int *logical; + int node, processor, no_nodes, i; + + /* Verify logical ids */ + logical = erts_alloc(ERTS_ALC_T_TMP, sizeof(int)*size); + + for (i = 0; i < size; i++) + logical[i] = cpudata[i].logical; + + qsort(logical, size, sizeof(int), int_cmp); + for (i = 0; i < size-1; i++) { + if (logical[i] == logical[i+1]) { + erts_free(ERTS_ALC_T_TMP, logical); + return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS; + } + } + + erts_free(ERTS_ALC_T_TMP, logical); + + qsort(cpudata, size, sizeof(erts_cpu_topology_t), processor_order_cmp); + + /* Verify unique entities */ + + for (i = 1; i < size; i++) { + if (cpudata[i-1].processor == cpudata[i].processor + && cpudata[i-1].node == cpudata[i].node + && (cpudata[i-1].processor_node + == cpudata[i].processor_node) + && cpudata[i-1].core == cpudata[i].core + && cpudata[i-1].thread == cpudata[i].thread) { + return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES; + } + } + + /* Verify numa nodes */ + node = cpudata[0].node; + processor = cpudata[0].processor; + no_nodes = cpudata[0].node < 0 && cpudata[0].processor_node < 0; + for (i = 1; i < size; i++) { + if (no_nodes) { + if (cpudata[i].node >= 0 || cpudata[i].processor_node >= 0) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; + } + else { + if (cpudata[i].processor == processor && cpudata[i].node != node) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; + node = cpudata[i].node; + processor = cpudata[i].processor; + if (node >= 0 && cpudata[i].processor_node >= 0) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; + if (node < 0 && cpudata[i].processor_node < 0) + return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; + } + } + } + + return ERTS_INIT_CPU_TOPOLOGY_OK; +} + +int +erts_init_cpu_topology_string(char *topology_str) +{ + ErtsCpuTopEntry cput; + int need_size; + char *c; + int ix; + int error = ERTS_INIT_CPU_TOPOLOGY_OK; + + if (user_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); + user_cpudata_size = 10; + + user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(erts_cpu_topology_t) + * user_cpudata_size)); + + init_cpu_top_entry(&cput); + + ix = 0; + need_size = 0; + + c = topology_str; + if (*c == '\0') { + error = ERTS_INIT_CPU_TOPOLOGY_MISSING; + goto fail; + } + do { + int r; + error = get_cput_entry(&cput, &c); + if (error != ERTS_INIT_CPU_TOPOLOGY_OK) + goto fail; + need_size += cput.logical.used; + if (user_cpudata_size < need_size) { + user_cpudata_size = need_size + 10; + user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA, + user_cpudata, + (sizeof(erts_cpu_topology_t) + * user_cpudata_size)); + } + + ASSERT(cput.thread.used == 1 + || cput.thread.used == cput.logical.used); + ASSERT(cput.core.used == 1 + || cput.core.used == cput.logical.used); + ASSERT(cput.processor_node.used == 1 + || cput.processor_node.used == cput.logical.used); + ASSERT(cput.processor.used == 1 + || cput.processor.used == cput.logical.used); + ASSERT(cput.node.used == 1 + || cput.node.used == cput.logical.used); + + for (r = 0; r < cput.logical.used; r++) { + user_cpudata[ix].logical = cput.logical.id[r]; + user_cpudata[ix].thread = + cput.thread.id[cput.thread.used == 1 ? 0 : r]; + user_cpudata[ix].core = + cput.core.id[cput.core.used == 1 ? 0 : r]; + user_cpudata[ix].processor_node = + cput.processor_node.id[cput.processor_node.used == 1 ? 0 : r]; + user_cpudata[ix].processor = + cput.processor.id[cput.processor.used == 1 ? 0 : r]; + user_cpudata[ix].node = + cput.node.id[cput.node.used == 1 ? 0 : r]; + ix++; + } + } while (*c != '\0'); + + if (user_cpudata_size != ix) { + user_cpudata_size = ix; + user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA, + user_cpudata, + (sizeof(erts_cpu_topology_t) + * user_cpudata_size)); + } + + error = verify_topology(user_cpudata, user_cpudata_size); + if (error == ERTS_INIT_CPU_TOPOLOGY_OK) { + destroy_cpu_top_entry(&cput); + return ERTS_INIT_CPU_TOPOLOGY_OK; + } + + fail: + if (user_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); + user_cpudata_size = 0; + destroy_cpu_top_entry(&cput); + return error; +} + +#define ERTS_GET_CPU_TOPOLOGY_ERROR -1 +#define ERTS_GET_USED_CPU_TOPOLOGY 0 +#define ERTS_GET_DETECTED_CPU_TOPOLOGY 1 +#define ERTS_GET_DEFINED_CPU_TOPOLOGY 2 + +static Eterm get_cpu_topology_term(Process *c_p, int type); + +Eterm +erts_set_cpu_topology(Process *c_p, Eterm term) +{ + erts_cpu_topology_t *cpudata = NULL; + int cpudata_size = 0; + Eterm res; + + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + res = get_cpu_topology_term(c_p, ERTS_GET_USED_CPU_TOPOLOGY); + if (term == am_undefined) { + if (user_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); + user_cpudata = NULL; + user_cpudata_size = 0; + + if (cpu_bind_order != ERTS_CPU_BIND_NONE && system_cpudata) { + cpudata_size = system_cpudata_size; + cpudata = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(erts_cpu_topology_t) + * cpudata_size)); + + sys_memcpy((void *) cpudata, + (void *) system_cpudata, + sizeof(erts_cpu_topology_t)*cpudata_size); + } + } + else if (is_not_list(term)) { + error: + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + res = THE_NON_VALUE; + goto done; + } + else { + Eterm list = term; + int ix = 0; + + cpudata_size = 100; + cpudata = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(erts_cpu_topology_t) + * cpudata_size)); + + while (is_list(list)) { + Eterm *lp = list_val(list); + Eterm cpu = CAR(lp); + Eterm* tp; + Sint id; + + if (is_not_tuple(cpu)) + goto error; + + tp = tuple_val(cpu); + + if (arityval(tp[0]) != 7 || tp[1] != am_cpu) + goto error; + + if (ix >= cpudata_size) { + cpudata_size += 100; + cpudata = erts_realloc(ERTS_ALC_T_TMP, + cpudata, + (sizeof(erts_cpu_topology_t) + * cpudata_size)); + } + + id = signed_val(tp[2]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].node = (int) id; + + id = signed_val(tp[3]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].processor = (int) id; + + id = signed_val(tp[4]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].processor_node = (int) id; + + id = signed_val(tp[5]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].core = (int) id; + + id = signed_val(tp[6]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].thread = (int) id; + + id = signed_val(tp[7]); + if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) + goto error; + cpudata[ix].logical = (int) id; + + list = CDR(lp); + ix++; + } + + if (is_not_nil(list)) + goto error; + + cpudata_size = ix; + + if (ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(cpudata, cpudata_size)) + goto error; + + if (user_cpudata_size != cpudata_size) { + if (user_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); + user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + sizeof(erts_cpu_topology_t)*cpudata_size); + user_cpudata_size = cpudata_size; + } + + sys_memcpy((void *) user_cpudata, + (void *) cpudata, + sizeof(erts_cpu_topology_t)*cpudata_size); + } + + update_cpu_groups_maps(); + + write_schedulers_bind_change(cpudata, cpudata_size); + + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + erts_sched_notify_check_cpu_bind(); + + done: + + if (cpudata) + erts_free(ERTS_ALC_T_TMP, cpudata); + + return res; +} + +static void +create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, int *cpudata_size) +{ + if (user_cpudata) { + *cpudata_size = user_cpudata_size; + *cpudata = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(erts_cpu_topology_t) + * (*cpudata_size))); + sys_memcpy((void *) *cpudata, + (void *) user_cpudata, + sizeof(erts_cpu_topology_t)*(*cpudata_size)); + } + else if (system_cpudata) { + *cpudata_size = system_cpudata_size; + *cpudata = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(erts_cpu_topology_t) + * (*cpudata_size))); + sys_memcpy((void *) *cpudata, + (void *) system_cpudata, + sizeof(erts_cpu_topology_t)*(*cpudata_size)); + } + else { + *cpudata = NULL; + *cpudata_size = 0; + } +} + +static void +destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata) +{ + if (cpudata) + erts_free(ERTS_ALC_T_TMP, cpudata); +} + + +static Eterm +bld_topology_term(Eterm **hpp, + Uint *hszp, + erts_cpu_topology_t *cpudata, + int size) +{ + Eterm res = NIL; + int i; + + if (size == 0) + return am_undefined; + + for (i = size-1; i >= 0; i--) { + res = erts_bld_cons(hpp, + hszp, + erts_bld_tuple(hpp, + hszp, + 7, + am_cpu, + make_small(cpudata[i].node), + make_small(cpudata[i].processor), + make_small(cpudata[i].processor_node), + make_small(cpudata[i].core), + make_small(cpudata[i].thread), + make_small(cpudata[i].logical)), + res); + } + return res; +} + +static Eterm +get_cpu_topology_term(Process *c_p, int type) +{ +#ifdef DEBUG + Eterm *hp_end; +#endif + Eterm *hp; + Uint hsz; + Eterm res = THE_NON_VALUE; + erts_cpu_topology_t *cpudata = NULL; + int size = 0; + + switch (type) { + case ERTS_GET_USED_CPU_TOPOLOGY: + if (user_cpudata) + goto defined; + else + goto detected; + case ERTS_GET_DETECTED_CPU_TOPOLOGY: + detected: + if (!system_cpudata) + res = am_undefined; + else { + size = system_cpudata_size; + cpudata = erts_alloc(ERTS_ALC_T_TMP, + (sizeof(erts_cpu_topology_t) + * size)); + sys_memcpy((void *) cpudata, + (void *) system_cpudata, + sizeof(erts_cpu_topology_t)*size); + } + break; + case ERTS_GET_DEFINED_CPU_TOPOLOGY: + defined: + if (!user_cpudata) + res = am_undefined; + else { + size = user_cpudata_size; + cpudata = user_cpudata; + } + break; + default: + erl_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type); + break; + } + + if (res == am_undefined) { + ASSERT(!cpudata); + return res; + } + + hsz = 0; + + bld_topology_term(NULL, &hsz, + cpudata, size); + + hp = HAlloc(c_p, hsz); + +#ifdef DEBUG + hp_end = hp + hsz; +#endif + + res = bld_topology_term(&hp, NULL, + cpudata, size); + + ASSERT(hp_end == hp); + + if (cpudata && cpudata != system_cpudata && cpudata != user_cpudata) + erts_free(ERTS_ALC_T_TMP, cpudata); + + return res; +} + +Eterm +erts_get_cpu_topology_term(Process *c_p, Eterm which) +{ + Eterm res; + int type; + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + if (ERTS_IS_ATOM_STR("used", which)) + type = ERTS_GET_USED_CPU_TOPOLOGY; + else if (ERTS_IS_ATOM_STR("detected", which)) + type = ERTS_GET_DETECTED_CPU_TOPOLOGY; + else if (ERTS_IS_ATOM_STR("defined", which)) + type = ERTS_GET_DEFINED_CPU_TOPOLOGY; + else + type = ERTS_GET_CPU_TOPOLOGY_ERROR; + if (type == ERTS_GET_CPU_TOPOLOGY_ERROR) + res = THE_NON_VALUE; + else + res = get_cpu_topology_term(c_p, type); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + return res; +} + +static void +get_logical_processors(int *conf, int *onln, int *avail) +{ + if (conf) + *conf = erts_get_cpu_configured(cpuinfo); + if (onln) + *onln = erts_get_cpu_online(cpuinfo); + if (avail) + *avail = erts_get_cpu_available(cpuinfo); +} + +void +erts_get_logical_processors(int *conf, int *onln, int *avail) +{ + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + get_logical_processors(conf, onln, avail); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); +} + +void +erts_pre_early_init_cpu_topology(int *max_rg_p, + int *conf_p, + int *onln_p, + int *avail_p) +{ + cpu_groups_maps = NULL; + no_cpu_groups_callbacks = 0; + *max_rg_p = ERTS_MAX_READER_GROUPS; + cpuinfo = erts_cpu_info_create(); + get_logical_processors(conf_p, onln_p, avail_p); +} + +void +erts_early_init_cpu_topology(int no_schedulers, + int *max_main_threads_p, + int max_reader_groups, + int *reader_groups_p) +{ + user_cpudata = NULL; + user_cpudata_size = 0; + + system_cpudata_size = erts_get_cpu_topology_size(cpuinfo); + system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(erts_cpu_topology_t) + * system_cpudata_size)); + + cpu_bind_order = ERTS_CPU_BIND_UNDEFINED; + + if (!erts_get_cpu_topology(cpuinfo, system_cpudata) + || ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata, + system_cpudata_size)) { + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + system_cpudata = NULL; + system_cpudata_size = 0; + } + + max_main_threads = erts_get_cpu_configured(cpuinfo); + if (max_main_threads > no_schedulers) + max_main_threads = no_schedulers; + *max_main_threads_p = max_main_threads; + + reader_groups = max_main_threads; + if (reader_groups <= 1 || max_reader_groups <= 1) + reader_groups = 0; + if (reader_groups > max_reader_groups) + reader_groups = max_reader_groups; + *reader_groups_p = reader_groups; +} + +void +erts_init_cpu_topology(void) +{ + int ix; + + erts_smp_rwmtx_init(&cpuinfo_rwmtx, "cpu_info"); + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + + scheduler2cpu_map = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(ErtsCpuBindData) + * (erts_no_schedulers+1))); + for (ix = 1; ix <= erts_no_schedulers; ix++) { + scheduler2cpu_map[ix].bind_id = -1; + scheduler2cpu_map[ix].bound_id = -1; + } + + if (cpu_bind_order == ERTS_CPU_BIND_UNDEFINED) { + int ncpus = erts_get_cpu_configured(cpuinfo); + if (ncpus < 1 || erts_no_schedulers < ncpus) + cpu_bind_order = ERTS_CPU_BIND_NONE; + else + cpu_bind_order = ((system_cpudata || user_cpudata) + && (erts_bind_to_cpu(cpuinfo, -1) != -ENOTSUP) + ? ERTS_CPU_BIND_DEFAULT_BIND + : ERTS_CPU_BIND_NONE); + } + + reader_groups_map = add_cpu_groups(reader_groups, + reader_groups_callback, + NULL); + + if (cpu_bind_order == ERTS_CPU_BIND_NONE) + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + else { + erts_cpu_topology_t *cpudata; + int cpudata_size; + create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); + write_schedulers_bind_change(cpudata, cpudata_size); + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + erts_sched_notify_check_cpu_bind(); + destroy_tmp_cpu_topology_copy(cpudata); + } +} + +int +erts_update_cpu_info(void) +{ + int changed; + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + changed = erts_cpu_info_update(cpuinfo); + if (changed) { + erts_cpu_topology_t *cpudata; + int cpudata_size; + + if (system_cpudata) + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + + system_cpudata_size = erts_get_cpu_topology_size(cpuinfo); + if (!system_cpudata_size) + system_cpudata = NULL; + else { + system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, + (sizeof(erts_cpu_topology_t) + * system_cpudata_size)); + + if (!erts_get_cpu_topology(cpuinfo, system_cpudata) + || (ERTS_INIT_CPU_TOPOLOGY_OK + != verify_topology(system_cpudata, + system_cpudata_size))) { + erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); + system_cpudata = NULL; + system_cpudata_size = 0; + } + } + + update_cpu_groups_maps(); + + create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); + write_schedulers_bind_change(cpudata, cpudata_size); + destroy_tmp_cpu_topology_copy(cpudata); + } + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); + if (changed) + erts_sched_notify_check_cpu_bind(); + return changed; +} + +/* + * reader groups map + */ + +void +reader_groups_callback(int suspending, + ErtsSchedulerData *esdp, + int group, + void *unused) +{ + if (reader_groups && esdp->no <= max_main_threads) + erts_smp_rwmtx_set_reader_group(suspending ? 0 : group+1); +} + +static Eterm get_cpu_groups_map(Process *c_p, + erts_cpu_groups_map_t *map, + int offset); +Eterm +erts_debug_reader_groups_map(Process *c_p, int groups) +{ + Eterm res; + erts_cpu_groups_map_t test; + + test.array = NULL; + test.groups = groups; + make_cpu_groups_map(&test, 1); + if (!test.array) + res = NIL; + else { + res = get_cpu_groups_map(c_p, &test, 1); + erts_free(ERTS_ALC_T_TMP, test.array); + } + return res; +} + + +Eterm +erts_get_reader_groups_map(Process *c_p) +{ + Eterm res; + erts_smp_rwmtx_rlock(&cpuinfo_rwmtx); + res = get_cpu_groups_map(c_p, reader_groups_map, 1); + erts_smp_rwmtx_runlock(&cpuinfo_rwmtx); + return res; +} + +/* + * CPU groups + */ + +static Eterm +get_cpu_groups_map(Process *c_p, + erts_cpu_groups_map_t *map, + int offset) +{ +#ifdef DEBUG + Eterm *endp; +#endif + Eterm res = NIL, tuple; + Eterm *hp; + int i; + + hp = HAlloc(c_p, map->logical_processors*(2+3)); +#ifdef DEBUG + endp = hp + map->logical_processors*(2+3); +#endif + for (i = map->size - 1; i >= 0; i--) { + if (map->array[i].logical >= 0) { + tuple = TUPLE2(hp, + make_small(map->array[i].logical), + make_small(map->array[i].cpu_group + offset)); + hp += 3; + res = CONS(hp, tuple, res); + hp += 2; + } + } + ASSERT(hp == endp); + return res; +} + +static void +make_available_cpu_topology(erts_avail_cput *no, + erts_avail_cput *avail, + erts_cpu_topology_t *cpudata, + int *size, + int test) +{ + int len = *size; + erts_cpu_topology_t last; + int a, i, j; + + no->level[ERTS_TOPOLOGY_NODE] = -1; + no->level[ERTS_TOPOLOGY_PROCESSOR] = -1; + no->level[ERTS_TOPOLOGY_PROCESSOR_NODE] = -1; + no->level[ERTS_TOPOLOGY_CORE] = -1; + no->level[ERTS_TOPOLOGY_THREAD] = -1; + no->level[ERTS_TOPOLOGY_LOGICAL] = -1; + + last.node = INT_MIN; + last.processor = INT_MIN; + last.processor_node = INT_MIN; + last.core = INT_MIN; + last.thread = INT_MIN; + last.logical = INT_MIN; + + a = 0; + + for (i = 0; i < len; i++) { + + if (!test && !erts_is_cpu_available(cpuinfo, cpudata[i].logical)) + continue; + + if (last.node != cpudata[i].node) + goto node; + if (last.processor != cpudata[i].processor) + goto processor; + if (last.processor_node != cpudata[i].processor_node) + goto processor_node; + if (last.core != cpudata[i].core) + goto core; + ASSERT(last.thread != cpudata[i].thread); + goto thread; + + node: + no->level[ERTS_TOPOLOGY_NODE]++; + processor: + no->level[ERTS_TOPOLOGY_PROCESSOR]++; + processor_node: + no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++; + core: + no->level[ERTS_TOPOLOGY_CORE]++; + thread: + no->level[ERTS_TOPOLOGY_THREAD]++; + + no->level[ERTS_TOPOLOGY_LOGICAL]++; + + for (j = 0; j < ERTS_TOPOLOGY_LOGICAL; j++) + avail[a].level[j] = no->level[j]; + + avail[a].level[ERTS_TOPOLOGY_LOGICAL] = cpudata[i].logical; + avail[a].level[ERTS_TOPOLOGY_CG] = 0; + + ASSERT(last.logical != cpudata[i].logical); + + last = cpudata[i]; + a++; + } + + no->level[ERTS_TOPOLOGY_NODE]++; + no->level[ERTS_TOPOLOGY_PROCESSOR]++; + no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++; + no->level[ERTS_TOPOLOGY_CORE]++; + no->level[ERTS_TOPOLOGY_THREAD]++; + no->level[ERTS_TOPOLOGY_LOGICAL]++; + + *size = a; +} + +static void +cpu_group_insert(erts_cpu_groups_map_t *map, + int logical, int cpu_group) +{ + int start = logical % map->size; + int ix = start; + + do { + if (map->array[ix].logical < 0) { + map->array[ix].logical = logical; + map->array[ix].cpu_group = cpu_group; + return; + } + ix++; + if (ix == map->size) + ix = 0; + } while (ix != start); + + erl_exit(ERTS_ABORT_EXIT, "Reader groups map full\n"); +} + + +static int +sub_levels(erts_cpu_groups_count_t *cgc, int level, int aix, + int avail_sz, erts_avail_cput *avail) +{ + int sub_level = level+1; + int last = -1; + cgc->sub_levels = 0; + + do { + if (last != avail[aix].level[sub_level]) { + cgc->sub_levels++; + last = avail[aix].level[sub_level]; + } + aix++; + } + while (aix < avail_sz && cgc->id == avail[aix].level[level]); + cgc->cpu_groups = 0; + return aix; +} + +static int +write_cpu_groups(int *cgp, erts_cpu_groups_count_t *cgcp, + int level, int a, + int avail_sz, erts_avail_cput *avail) +{ + int cg = *cgp; + int sub_level = level+1; + int sl_per_gr = cgcp->sub_levels / cgcp->cpu_groups; + int xsl = cgcp->sub_levels % cgcp->cpu_groups; + int sls = 0; + int last = -1; + int xsl_cg_lim = (cgcp->cpu_groups - xsl) + cg + 1; + + ASSERT(level < 0 || avail[a].level[level] == cgcp->id); + + do { + if (last != avail[a].level[sub_level]) { + if (!sls) { + sls = sl_per_gr; + cg++; + if (cg >= xsl_cg_lim) + sls++; + } + last = avail[a].level[sub_level]; + sls--; + } + avail[a].level[ERTS_TOPOLOGY_CG] = cg; + a++; + } while (a < avail_sz && (level < 0 + || avail[a].level[level] == cgcp->id)); + + ASSERT(cgcp->cpu_groups == cg - *cgp); + + *cgp = cg; + + return a; +} + +static int +cg_count_sub_levels_compare(const void *vx, const void *vy) +{ + erts_cpu_groups_count_t *x = (erts_cpu_groups_count_t *) vx; + erts_cpu_groups_count_t *y = (erts_cpu_groups_count_t *) vy; + if (x->sub_levels != y->sub_levels) + return y->sub_levels - x->sub_levels; + return x->id - y->id; +} + +static int +cg_count_id_compare(const void *vx, const void *vy) +{ + erts_cpu_groups_count_t *x = (erts_cpu_groups_count_t *) vx; + erts_cpu_groups_count_t *y = (erts_cpu_groups_count_t *) vy; + return x->id - y->id; +} + +static void +make_cpu_groups_map(erts_cpu_groups_map_t *map, int test) +{ + int i, spread_level, avail_sz; + erts_avail_cput no, *avail; + erts_cpu_topology_t *cpudata; + ErtsAlcType_t alc_type = (test + ? ERTS_ALC_T_TMP + : ERTS_ALC_T_CPU_GRPS_MAP); + + if (map->array) + erts_free(alc_type, map->array); + + map->array = NULL; + map->logical_processors = 0; + map->size = 0; + + if (!map->groups) + return; + + create_tmp_cpu_topology_copy(&cpudata, &avail_sz); + + if (!cpudata) + return; + + cpu_bind_order_sort(cpudata, + avail_sz, + ERTS_CPU_BIND_NO_SPREAD, + 1); + + avail = erts_alloc(ERTS_ALC_T_TMP, + sizeof(erts_avail_cput)*avail_sz); + + make_available_cpu_topology(&no, avail, cpudata, + &avail_sz, test); + + destroy_tmp_cpu_topology_copy(cpudata); + + map->size = avail_sz*2+1; + + map->array = erts_alloc(alc_type, + (sizeof(erts_cpu_groups_map_array_t) + * map->size));; + map->logical_processors = avail_sz; + + for (i = 0; i < map->size; i++) { + map->array[i].logical = -1; + map->array[i].cpu_group = -1; + } + + spread_level = ERTS_TOPOLOGY_CORE; + for (i = ERTS_TOPOLOGY_NODE; i < ERTS_TOPOLOGY_THREAD; i++) { + if (no.level[i] > map->groups) { + spread_level = i; + break; + } + } + + if (no.level[spread_level] <= map->groups) { + int a, cg, last = -1; + cg = -1; + ASSERT(spread_level == ERTS_TOPOLOGY_CORE); + for (a = 0; a < avail_sz; a++) { + if (last != avail[a].level[spread_level]) { + cg++; + last = avail[a].level[spread_level]; + } + cpu_group_insert(map, + avail[a].level[ERTS_TOPOLOGY_LOGICAL], + cg); + } + } + else { /* map->groups < no.level[spread_level] */ + erts_cpu_groups_count_t *cg_count; + int a, cg, tl, toplevels; + + tl = spread_level-1; + + if (spread_level == ERTS_TOPOLOGY_NODE) + toplevels = 1; + else + toplevels = no.level[tl]; + + cg_count = erts_alloc(ERTS_ALC_T_TMP, + toplevels*sizeof(erts_cpu_groups_count_t)); + + if (toplevels == 1) { + cg_count[0].id = 0; + cg_count[0].sub_levels = no.level[spread_level]; + cg_count[0].cpu_groups = map->groups; + } + else { + int cgs_per_tl, cgs; + cgs = map->groups; + cgs_per_tl = cgs / toplevels; + + a = 0; + for (i = 0; i < toplevels; i++) { + cg_count[i].id = avail[a].level[tl]; + a = sub_levels(&cg_count[i], tl, a, avail_sz, avail); + } + + qsort(cg_count, + toplevels, + sizeof(erts_cpu_groups_count_t), + cg_count_sub_levels_compare); + + for (i = 0; i < toplevels; i++) { + if (cg_count[i].sub_levels < cgs_per_tl) { + cg_count[i].cpu_groups = cg_count[i].sub_levels; + cgs -= cg_count[i].sub_levels; + } + else { + cg_count[i].cpu_groups = cgs_per_tl; + cgs -= cgs_per_tl; + } + } + + while (cgs > 0) { + for (i = 0; i < toplevels; i++) { + if (cg_count[i].sub_levels == cg_count[i].cpu_groups) + break; + else { + cg_count[i].cpu_groups++; + if (--cgs == 0) + break; + } + } + } + + qsort(cg_count, + toplevels, + sizeof(erts_cpu_groups_count_t), + cg_count_id_compare); + } + + a = i = 0; + cg = -1; + while (a < avail_sz) { + a = write_cpu_groups(&cg, &cg_count[i], tl, + a, avail_sz, avail); + i++; + } + + ASSERT(map->groups == cg + 1); + + for (a = 0; a < avail_sz; a++) + cpu_group_insert(map, + avail[a].level[ERTS_TOPOLOGY_LOGICAL], + avail[a].level[ERTS_TOPOLOGY_CG]); + + erts_free(ERTS_ALC_T_TMP, cg_count); + } + + erts_free(ERTS_ALC_T_TMP, avail); +} + +static erts_cpu_groups_map_t * +add_cpu_groups(int groups, + erts_cpu_groups_callback_t callback, + void *arg) +{ + int use_groups = groups; + erts_cpu_groups_callback_list_t *cgcl; + erts_cpu_groups_map_t *cgm; + + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + + if (use_groups > max_main_threads) + use_groups = max_main_threads; + + if (!use_groups) + return NULL; + + no_cpu_groups_callbacks++; + cgcl = erts_alloc(ERTS_ALC_T_CPU_GRPS_MAP, + sizeof(erts_cpu_groups_callback_list_t)); + cgcl->callback = callback; + cgcl->arg = arg; + + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { + if (cgm->groups == use_groups) { + cgcl->next = cgm->callback_list; + cgm->callback_list = cgcl; + return cgm; + } + } + + + cgm = erts_alloc(ERTS_ALC_T_CPU_GRPS_MAP, + sizeof(erts_cpu_groups_map_t)); + cgm->next = cpu_groups_maps; + cgm->groups = use_groups; + cgm->array = NULL; + cgm->size = 0; + cgm->logical_processors = 0; + cgm->callback_list = cgcl; + + cgcl->next = NULL; + + make_cpu_groups_map(cgm, 0); + + cpu_groups_maps = cgm; + + return cgm; +} + +static void +remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg) +{ + erts_cpu_groups_map_t *prev_cgm, *cgm; + erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl; + + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + + no_cpu_groups_callbacks--; + + prev_cgm = NULL; + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) { + prev_cgcl = NULL; + for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) { + if (cgcl->callback == callback && cgcl->arg == arg) { + if (prev_cgcl) + prev_cgcl->next = cgcl->next; + else + cgm->callback_list = cgcl->next; + erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl); + if (!cgm->callback_list) { + if (prev_cgm) + prev_cgm->next = cgm->next; + else + cpu_groups_maps = cgm->next; + if (cgm->array) + erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array); + erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm); + } + return; + } + prev_cgcl = cgcl; + } + prev_cgm = cgm; + } + + erl_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n"); +} + +static int +cpu_groups_lookup(erts_cpu_groups_map_t *map, + ErtsSchedulerData *esdp) +{ + int start, logical, ix; + + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rlocked(&cpuinfo_rwmtx) + || erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + + if (esdp->cpu_id < 0) + return (((int) esdp->no) - 1) % map->groups; + + logical = esdp->cpu_id; + start = logical % map->size; + ix = start; + + do { + if (map->array[ix].logical == logical) { + int group = map->array[ix].cpu_group; + ASSERT(0 <= group && group < map->groups); + return group; + } + ix++; + if (ix == map->size) + ix = 0; + } while (ix != start); + + erl_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical); +} + +static void +update_cpu_groups_maps(void) +{ + erts_cpu_groups_map_t *cgm; + ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx)); + + for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) + make_cpu_groups_map(cgm, 0); +} + +void +erts_add_cpu_groups(int groups, + erts_cpu_groups_callback_t callback, + void *arg) +{ + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + add_cpu_groups(groups, callback, arg); + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); +} + +void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback, + void *arg) +{ + erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx); + remove_cpu_groups(callback, arg); + erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx); +} diff --git a/erts/emulator/beam/erl_cpu_topology.h b/erts/emulator/beam/erl_cpu_topology.h new file mode 100644 index 0000000000..c5a9520b61 --- /dev/null +++ b/erts/emulator/beam/erl_cpu_topology.h @@ -0,0 +1,105 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* + * Description: CPU topology and related functionality + * + * Author: Rickard Green + */ + +#ifndef ERL_CPU_TOPOLOGY_H__ +#define ERL_CPU_TOPOLOGY_H__ + +void erts_pre_early_init_cpu_topology(int *max_rg_p, + int *conf_p, + int *onln_p, + int *avail_p); +void erts_early_init_cpu_topology(int no_schedulers, + int *max_main_threads_p, + int max_reader_groups, + int *reader_groups_p); +void erts_init_cpu_topology(void); + + +#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS 0 +#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED 1 +#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY 2 +#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE 3 + +int erts_init_scheduler_bind_type_string(char *how); + + +#define ERTS_INIT_CPU_TOPOLOGY_OK 0 +#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID 1 +#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE 2 +#define ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY 3 +#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE 4 +#define ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES 5 +#define ERTS_INIT_CPU_TOPOLOGY_MISSING_LID 6 +#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS 7 +#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES 8 +#define ERTS_INIT_CPU_TOPOLOGY_MISSING 9 + +int erts_init_cpu_topology_string(char *topology_str); + +void erts_sched_check_cpu_bind(ErtsSchedulerData *esdp); +#ifdef ERTS_SMP +void erts_sched_init_check_cpu_bind(ErtsSchedulerData *esdp); +void erts_sched_check_cpu_bind_prep_suspend(ErtsSchedulerData *esdp); +void erts_sched_check_cpu_bind_post_suspend(ErtsSchedulerData *esdp); +#endif + +int erts_update_cpu_info(void); + +Eterm erts_bind_schedulers(Process *c_p, Eterm how); +Eterm erts_get_schedulers_binds(Process *c_p); + +Eterm erts_get_reader_groups_map(Process *c_p); + +Eterm erts_set_cpu_topology(Process *c_p, Eterm term); +Eterm erts_get_cpu_topology_term(Process *c_p, Eterm which); + +int erts_update_cpu_info(void); +void erts_get_logical_processors(int *conf, int *onln, int *avail); + +int erts_sched_bind_atthrcreate_prepare(void); +int erts_sched_bind_atthrcreate_child(int unbind); +void erts_sched_bind_atthrcreate_parent(int unbind); + +int erts_sched_bind_atfork_prepare(void); +int erts_sched_bind_atfork_child(int unbind); +char *erts_sched_bind_atvfork_child(int unbind); +void erts_sched_bind_atfork_parent(int unbind); + +Eterm erts_fake_scheduler_bindings(Process *p, Eterm how); +Eterm erts_debug_cpu_groups_map(Process *c_p, int groups); + + +typedef void (*erts_cpu_groups_callback_t)(int, + ErtsSchedulerData *, + int, + void *); + +void erts_add_cpu_groups(int groups, + erts_cpu_groups_callback_t callback, + void *arg); +void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback, + void *arg); + +#endif diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index 52d5f86ee0..8577354d27 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -179,6 +179,7 @@ extern DbTableMethod db_tree; int user_requested_db_max_tabs; int erts_ets_realloc_always_moves; +int erts_ets_always_compress; static int db_max_tabs; static DbTable *meta_pid_to_tab; /* Pid mapped to owned tables */ static DbTable *meta_pid_to_fixed_tab; /* Pid mapped to fixed tables */ @@ -931,7 +932,7 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3) position > arityval(handle.dbterm->tpl[0])) { goto finalize; } - oldcnt = handle.dbterm->tpl[position]; + oldcnt = db_do_read_element(&handle, position); if (is_big(oldcnt)) { halloc_size += BIG_NEED_SIZE(big_arity(oldcnt)); } @@ -1276,7 +1277,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) UWord heir_data; Uint32 status; Sint keypos; - int is_named, is_fine_locked, frequent_read; + int is_named, is_fine_locked, frequent_read, is_compressed; int cret; DeclareTmpHeap(meta_tuple,3,BIF_P); DbTableMethod* meth; @@ -1296,6 +1297,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) frequent_read = 0; heir = am_none; heir_data = (UWord) am_undefined; + is_compressed = erts_ets_always_compress; list = BIF_ARG_2; while(is_list(list)) { @@ -1358,6 +1360,9 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) else if (val == am_named_table) { is_named = 1; } + else if (val == am_compressed) { + is_compressed = 1; + } else if (val == am_set || val == am_protected) ; else break; @@ -1418,6 +1423,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2) erts_smp_atomic_init(&tb->common.nitems, 0); tb->common.fixations = NULL; + tb->common.compress = is_compressed; cret = meth->db_create(BIF_P, tb); ASSERT(cret == DB_ERROR_NONE); @@ -2572,7 +2578,7 @@ BIF_RETTYPE ets_match_object_3(BIF_ALIST_3) BIF_RETTYPE ets_info_1(BIF_ALIST_1) { static Eterm fields[] = {am_protection, am_keypos, am_type, am_named_table, - am_node, am_size, am_name, am_heir, am_owner, am_memory}; + am_node, am_size, am_name, am_heir, am_owner, am_memory, am_compressed}; Eterm results[sizeof(fields)/sizeof(Eterm)]; DbTable* tb; Eterm res; @@ -2754,13 +2760,13 @@ void init_db(void) (sizeof(erts_meta_main_tab_lock_t) * (ERTS_META_MAIN_TAB_LOCK_TAB_SIZE+1))); - if ((((Uint) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) != 0) + if ((((UWord) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) != 0) meta_main_tab_locks = ((erts_meta_main_tab_lock_t *) - ((((Uint) meta_main_tab_locks) + ((((UWord) meta_main_tab_locks) & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE)); - ASSERT((((Uint) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) == 0); + ASSERT((((UWord) meta_main_tab_locks) & ERTS_CACHE_LINE_MASK) == 0); for (i = 0; i < ERTS_META_MAIN_TAB_LOCK_TAB_SIZE; i++) { erts_smp_rwmtx_init_opt_x(&meta_main_tab_locks[i].rwmtx, &rwmtx_opt, @@ -2837,6 +2843,7 @@ void init_db(void) erts_smp_atomic_init(&meta_pid_to_tab->common.nitems, 0); meta_pid_to_tab->common.slot = -1; meta_pid_to_tab->common.meth = &db_hash; + meta_pid_to_tab->common.compress = 0; erts_refc_init(&meta_pid_to_tab->common.ref, 1); erts_refc_init(&meta_pid_to_tab->common.fixref, 0); @@ -2869,6 +2876,7 @@ void init_db(void) erts_smp_atomic_init(&meta_pid_to_fixed_tab->common.nitems, 0); meta_pid_to_fixed_tab->common.slot = -1; meta_pid_to_fixed_tab->common.meth = &db_hash; + meta_pid_to_fixed_tab->common.compress = 0; erts_refc_init(&meta_pid_to_fixed_tab->common.ref, 1); erts_refc_init(&meta_pid_to_fixed_tab->common.fixref, 0); @@ -3077,7 +3085,7 @@ retry: db_unlock(tb,LCK_WRITE); heir_data = tb->common.heir_data; if (!is_immed(heir_data)) { - Eterm* tpv = DBTERM_BUF((DbTerm*)heir_data); /* tuple_val */ + Eterm* tpv = ((DbTerm*)heir_data)->tpl; /* tuple_val */ ASSERT(arityval(*tpv) == 1); heir_data = tpv[1]; } @@ -3251,7 +3259,8 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) pp = &(*pp)->next) { if ((*pp)->pid == pid) { DbFixation* fix = *pp; - erts_refc_add(&tb->common.fixref,-fix->counter,0); + long diff = -(long)fix->counter; + erts_refc_add(&tb->common.fixref,diff,0); *pp = fix->next; erts_db_free(ERTS_ALC_T_DB_FIXATION, tb, fix, sizeof(DbFixation)); @@ -3469,8 +3478,8 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data) UseTmpHeap(2,me); /* Make a dummy 1-tuple around data to use db_get_term() */ - heir_data = (UWord) db_get_term(&tb->common, NULL, 0, - TUPLE1(tmp,heir_data)); + heir_data = (UWord) db_store_term(&tb->common, NULL, 0, + TUPLE1(tmp,heir_data)); UnUseTmpHeap(2,me); ASSERT(!is_immed(heir_data)); } @@ -3481,7 +3490,7 @@ static void free_heir_data(DbTable* tb) { if (tb->common.heir != am_none && !is_immed(tb->common.heir_data)) { DbTerm* p = (DbTerm*) tb->common.heir_data; - db_free_term_data(p); + db_cleanup_offheap_comp(p); erts_db_free(ERTS_ALC_T_DB_TERM, tb, (void *)p, sizeof(DbTerm) + (p->size-1)*sizeof(Eterm)); } @@ -3618,10 +3627,13 @@ static Eterm table_info(Process* p, DbTable* tb, Eterm What) ret = erts_this_dist_entry->sysname; } else if (What == am_named_table) { ret = is_atom(tb->common.id) ? am_true : am_false; + } else if (What == am_compressed) { + ret = tb->common.compress ? am_true : am_false; + } /* * For debugging purposes */ - } else if (What == am_data) { + else if (What == am_data) { print_table(ERTS_PRINT_STDOUT, NULL, 1, tb); ret = am_true; } else if (What == am_atom_put("fixed",5)) { diff --git a/erts/emulator/beam/erl_db.h b/erts/emulator/beam/erl_db.h index 7da28fad29..cb2da603f0 100644 --- a/erts/emulator/beam/erl_db.h +++ b/erts/emulator/beam/erl_db.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * Copyright Ericsson AB 1996-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 @@ -61,6 +61,7 @@ void erts_db_foreach_offheap(DbTable *, extern int user_requested_db_max_tabs; /* set in erl_init */ extern int erts_ets_realloc_always_moves; /* set in erl_init */ +extern int erts_ets_always_compress; /* set in erl_init */ extern Export ets_select_delete_continue_exp; extern Export ets_select_count_continue_exp; extern Export ets_select_continue_exp; diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index fa707f4eed..14ee63100a 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -267,11 +267,11 @@ static ERTS_INLINE Sint next_slot_w(DbTableHash* tb, Uint ix, */ #define BIN_FLAG_ALL_OBJECTS BIN_FLAG_USR1 -/* - * Size calculations - */ -#define SIZ_OVERHEAD ((sizeof(HashDbTerm)/sizeof(Eterm)) - 1) -#define SIZ_DBTERM(HDT) (SIZ_OVERHEAD + (HDT)->dbterm.size) + +static ERTS_INLINE void free_term(DbTableHash *tb, HashDbTerm* p) +{ + db_free_term((DbTable*)tb, p, offsetof(HashDbTerm, dbterm)); +} /* * Local types @@ -358,10 +358,8 @@ static HashDbTerm* search_list(DbTableHash* tb, Eterm key, HashValue hval, HashDbTerm *list); static void shrink(DbTableHash* tb, int nactive); static void grow(DbTableHash* tb, int nactive); -static void free_term(DbTableHash *tb, HashDbTerm* p); -static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2); -static HashDbTerm* get_term(DbTableHash* tb, HashDbTerm* old, - Eterm obj, HashValue hval); +static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2, + DbTableHash*); static int analyze_pattern(DbTableHash *tb, Eterm pattern, struct mp_info *mpi); @@ -442,6 +440,7 @@ static ERTS_INLINE int has_live_key(DbTableHash* tb, HashDbTerm* b, if (b->hvalue != hval) return 0; else { Eterm itemKey = GETKEY(tb, b->dbterm.tpl); + ASSERT(!is_header(itemKey)); return EQ(key,itemKey); } } @@ -454,10 +453,38 @@ static ERTS_INLINE int has_key(DbTableHash* tb, HashDbTerm* b, if (b->hvalue != hval && b->hvalue != INVALID_HASH) return 0; else { Eterm itemKey = GETKEY(tb, b->dbterm.tpl); + ASSERT(!is_header(itemKey)); return EQ(key,itemKey); } } +static ERTS_INLINE HashDbTerm* new_dbterm(DbTableHash* tb, Eterm obj) +{ + HashDbTerm* p; + if (tb->common.compress) { + p = db_store_term_comp(&tb->common, NULL, offsetof(HashDbTerm,dbterm), obj); + } + else { + p = db_store_term(&tb->common, NULL, offsetof(HashDbTerm,dbterm), obj); + } + return p; +} + +static ERTS_INLINE HashDbTerm* replace_dbterm(DbTableHash* tb, HashDbTerm* old, + Eterm obj) +{ + HashDbTerm* ret; + ASSERT(old != NULL); + if (tb->common.compress) { + ret = db_store_term_comp(&tb->common, &(old->dbterm), offsetof(HashDbTerm,dbterm), obj); + } + else { + ret = db_store_term(&tb->common, &(old->dbterm), offsetof(HashDbTerm,dbterm), obj); + } + return ret; +} + + /* ** External interface @@ -764,7 +791,7 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail) ret = DB_ERROR_BADKEY; goto Ldone; } - q = get_term(tb, b, obj, hval); + q = replace_dbterm(tb, b, obj); q->next = bnext; q->hvalue = hval; /* In case of INVALID_HASH */ *bp = q; @@ -784,7 +811,7 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail) HashDbTerm** qp = bp; q = b; do { - if (eq(make_tuple(q->dbterm.tpl), obj)) { + if (db_eq(&tb->common,obj,&q->dbterm)) { if (q->hvalue == INVALID_HASH) { erts_smp_atomic_inc(&tb->common.nitems); q->hvalue = hval; @@ -803,7 +830,8 @@ int db_put_hash(DbTable *tbl, Eterm obj, int key_clash_fail) /*else DB_DUPLICATE_BAG */ Lnew: - q = get_term(tb, NULL, obj, hval); + q = new_dbterm(tb, obj); + q->hvalue = hval; q->next = b; *bp = q; nitems = erts_smp_atomic_inctest(&tb->common.nitems); @@ -844,7 +872,7 @@ int db_get_hash(Process *p, DbTable *tbl, Eterm key, Eterm *ret) while(b2 != NULL && has_key(tb,b2,key,hval)) b2 = b2->next; } - copy = put_term_list(p, b1, b2); + copy = build_term_list(p, b1, b2, tb); CHECK_TABLES(); *ret = copy; goto done; @@ -967,13 +995,10 @@ static int db_get_element_hash(Process *p, DbTable *tbl, while(b1 != 0) { if (has_live_key(tb,b1,key,hval)) { - Eterm copy; - if (ndex > arityval(b1->dbterm.tpl[0])) { retval = DB_ERROR_BADITEM; goto done; } - if (tb->common.status & (DB_BAG | DB_DUPLICATE_BAG)) { HashDbTerm* b; HashDbTerm* b2 = b1->next; @@ -987,15 +1012,12 @@ static int db_get_element_hash(Process *p, DbTable *tbl, } b2 = b2->next; } - b = b1; while(b != b2) { if (b->hvalue != INVALID_HASH) { Eterm *hp; - Uint sz = size_object(b->dbterm.tpl[ndex])+2; - - hp = HAlloc(p, sz); - copy = copy_struct(b->dbterm.tpl[ndex], sz-2, &hp, &MSO(p)); + Eterm copy = db_copy_element_from_ets(&tb->common, p, + &b->dbterm, ndex, &hp, 2); elem_list = CONS(hp, copy, elem_list); hp += 2; } @@ -1004,8 +1026,8 @@ static int db_get_element_hash(Process *p, DbTable *tbl, *ret = elem_list; } else { - COPY_OBJECT(b1->dbterm.tpl[ndex], p, ©); - *ret = copy; + Eterm* hp; + *ret = db_copy_element_from_ets(&tb->common, p, &b1->dbterm, ndex, &hp, 0); } retval = DB_ERROR_NONE; goto done; @@ -1040,6 +1062,7 @@ int db_erase_bag_exact2(DbTable *tbl, Eterm key, Eterm value) ASSERT(!IS_FIXED(tb)); ASSERT((tb->common.status & DB_BAG)); + ASSERT(!tb->common.compress); while(b != 0) { if (has_live_key(tb,b,key,hval)) { @@ -1139,7 +1162,7 @@ static int db_erase_object_hash(DbTable *tbl, Eterm object, Eterm *ret) while(b != 0) { if (has_live_key(tb,b,key,hval)) { ++nkeys; - if (eq(object, make_tuple(b->dbterm.tpl))) { + if (db_eq(&tb->common,object, &b->dbterm)) { --nitems_diff; if (nkeys==1 && IS_FIXED(tb)) { /* Pseudo remove */ add_fixed_deletion(tb,ix); @@ -1188,7 +1211,7 @@ static int db_slot_hash(Process *p, DbTable *tbl, Eterm slot_term, Eterm *ret) lck = RLOCK_HASH(tb, slot); nactive = NACTIVE(tb); if (slot < nactive) { - *ret = put_term_list(p, BUCKET(tb, slot), 0); + *ret = build_term_list(p, BUCKET(tb, slot), 0, tb); retval = DB_ERROR_NONE; } else if (slot == nactive) { @@ -1232,8 +1255,6 @@ static int db_select_continue_hash(Process *p, int num_left = 1000; HashDbTerm *current = 0; Eterm match_list; - Uint32 dummy; - unsigned sz; Eterm *hp; Eterm match_res; Sint got; @@ -1285,26 +1306,14 @@ static int db_select_continue_hash(Process *p, } for(;;) { if (current->hvalue != INVALID_HASH && - (match_res = - db_prog_match(p,mp, - make_tuple(current->dbterm.tpl), - NULL,0,&dummy), + (match_res = db_prog_match_and_copy(&tb->common, p, mp, all_objects, + ¤t->dbterm, &hp, 2), is_value(match_res))) { - if (all_objects) { - hp = HAlloc(p, current->dbterm.size + 2); - match_res = copy_shallow(DBTERM_BUF(¤t->dbterm), - current->dbterm.size, - &hp, - &MSO(p)); - } else { - sz = size_object(match_res); - - hp = HAlloc(p, sz + 2); - match_res = copy_struct(match_res, sz, &hp, &MSO(p)); - } - match_list = CONS(hp, match_res, match_list); + + match_list = CONS(hp, match_res, match_list); ++got; } + --num_left; save_slot_ix = slot_ix; if ((current = next(tb, (Uint*)&slot_ix, &lck, current)) == NULL) { @@ -1395,9 +1404,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, HashDbTerm *current = 0; unsigned current_list_pos = 0; Eterm match_list; - Uint32 dummy; Eterm match_res; - unsigned sz; Eterm *hp; int num_left = 1000; Uint got = 0; @@ -1464,22 +1471,9 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl, for(;;) { if (current != NULL) { if (current->hvalue != INVALID_HASH) { - match_res = db_prog_match(p,mpi.mp, - make_tuple(current->dbterm.tpl), - NULL,0,&dummy); + match_res = db_prog_match_and_copy(&tb->common, p, mpi.mp, 0, + ¤t->dbterm, &hp, 2); if (is_value(match_res)) { - if (mpi.all_objects) { - hp = HAlloc(p, current->dbterm.size + 2); - match_res = copy_shallow(DBTERM_BUF(¤t->dbterm), - current->dbterm.size, - &hp, - &MSO(p)); - } else { - sz = size_object(match_res); - - hp = HAlloc(p, sz + 2); - match_res = copy_struct(match_res, sz, &hp, &MSO(p)); - } match_list = CONS(hp, match_res, match_list); ++got; } @@ -1594,7 +1588,6 @@ static int db_select_count_hash(Process *p, Uint slot_ix = 0; HashDbTerm* current = NULL; unsigned current_list_pos = 0; - Uint32 dummy; Eterm *hp; int num_left = 1000; Uint got = 0; @@ -1644,8 +1637,8 @@ static int db_select_count_hash(Process *p, for(;;) { if (current != NULL) { if (current->hvalue != INVALID_HASH) { - if (db_prog_match(p, mpi.mp, make_tuple(current->dbterm.tpl), - NULL,0, &dummy) == am_true) { + if (db_prog_match_and_copy(&tb->common, p, mpi.mp, 0, + ¤t->dbterm, NULL,0) == am_true) { ++got; } --num_left; @@ -1713,7 +1706,6 @@ static int db_select_delete_hash(Process *p, Uint slot_ix = 0; HashDbTerm **current = NULL; unsigned current_list_pos = 0; - Uint32 dummy; Eterm *hp; int num_left = 1000; Uint got = 0; @@ -1794,9 +1786,8 @@ static int db_select_delete_hash(Process *p, } else { int did_erase = 0; - if ((db_prog_match(p,mpi.mp, - make_tuple((*current)->dbterm.tpl), - NULL,0,&dummy)) == am_true) { + if (db_prog_match_and_copy(&tb->common, p, mpi.mp, 0, + &(*current)->dbterm, NULL, 0) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -1859,7 +1850,6 @@ static int db_select_delete_continue_hash(Process *p, Uint slot_ix; Uint last_pseudo_delete = (Uint)-1; HashDbTerm **current = NULL; - Uint32 dummy; Eterm *hp; int num_left = 1000; Uint got; @@ -1907,8 +1897,8 @@ static int db_select_delete_continue_hash(Process *p, } else { int did_erase = 0; - if ((db_prog_match(p,mp,make_tuple((*current)->dbterm.tpl), - NULL,0,&dummy)) == am_true) { + if (db_prog_match_and_copy(&tb->common, p, mp, 0, + &(*current)->dbterm, NULL, 0) == am_true) { if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */ if (slot_ix != last_pseudo_delete) { add_fixed_deletion(tb, slot_ix); @@ -1970,7 +1960,6 @@ static int db_select_count_continue_hash(Process *p, DbTableHash *tb = &tbl->hash; Uint slot_ix; HashDbTerm* current; - Uint32 dummy; Eterm *hp; int num_left = 1000; Uint got; @@ -2008,8 +1997,8 @@ static int db_select_count_continue_hash(Process *p, current = current->next; continue; } - if (db_prog_match(p, mp, make_tuple(current->dbterm.tpl), - NULL,0,&dummy) == am_true) { + if (db_prog_match_and_copy(&tb->common, p, mp, 0, ¤t->dbterm, + NULL, 0) == am_true) { ++got; } --num_left; @@ -2454,31 +2443,19 @@ static int free_seg(DbTableHash *tb, int free_records) } -static HashDbTerm* get_term(DbTableHash* tb, HashDbTerm* old, - Eterm obj, HashValue hval) -{ - HashDbTerm* p = db_get_term((DbTableCommon *) tb, - (old != NULL) ? &(old->dbterm) : NULL, - ((char *) &(old->dbterm)) - ((char *) old), - obj); - p->hvalue = hval; - /*p->next = NULL;*/ /*No Need */ - return p; -} - - /* ** Copy terms from ptr1 until ptr2 ** works for ptr1 == ptr2 == 0 => [] ** or ptr2 == 0 */ -static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2) +static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2, + DbTableHash* tb) { int sz = 0; HashDbTerm* ptr; Eterm list = NIL; Eterm copy; - Eterm *hp; + Eterm *hp, *hend; ptr = ptr1; while(ptr != ptr2) { @@ -2490,26 +2467,20 @@ static Eterm put_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2) } hp = HAlloc(p, sz); + hend = hp + sz; ptr = ptr1; while(ptr != ptr2) { if (ptr->hvalue != INVALID_HASH) { - copy = copy_shallow(DBTERM_BUF(&ptr->dbterm), ptr->dbterm.size, &hp, &MSO(p)); + copy = db_copy_object_from_ets(&tb->common, &ptr->dbterm, &hp, &MSO(p)); list = CONS(hp, copy, list); hp += 2; } ptr = ptr->next; } - return list; -} + HRelease(p,hend,hp); -static void free_term(DbTableHash *tb, HashDbTerm* p) -{ - db_free_term_data(&(p->dbterm)); - erts_db_free(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - (void *) p, - SIZ_DBTERM(p)*sizeof(Eterm)); + return list; } /* Grow table with one new bucket. @@ -2720,8 +2691,8 @@ static int db_lookup_dbterm_hash(DbTable *tbl, Eterm key, DbUpdateHandle* handle handle->tb = tbl; handle->bp = (void**) prevp; handle->dbterm = &b->dbterm; - handle->new_size = b->dbterm.size; handle->mustResize = 0; + handle->new_size = b->dbterm.size; handle->lck = lck; /* KEEP hval WLOCKED, db_finalize_dbterm_hash will WUNLOCK */ return 1; @@ -2742,37 +2713,14 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle) erts_smp_rwmtx_t* lck = (erts_smp_rwmtx_t*) handle->lck; ERTS_SMP_LC_ASSERT(IS_HASH_WLOCKED(&tbl->hash,lck)); /* locked by db_lookup_dbterm_hash */ - ASSERT(&oldp->dbterm == handle->dbterm); - if (handle->mustResize) { - ErlOffHeap tmp_offheap; - Eterm* top; - Eterm copy; - DbTerm* newDbTerm; - HashDbTerm* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM, tbl, - sizeof(HashDbTerm)+sizeof(Eterm)*(handle->new_size-1)); - sys_memcpy(newp, oldp, sizeof(HashDbTerm)-sizeof(DbTerm)); /* copy only hashtab header */ - *(handle->bp) = newp; - newDbTerm = &newp->dbterm; - - newDbTerm->size = handle->new_size; - tmp_offheap.first = NULL; - tmp_offheap.overhead = 0; - - /* make a flat copy */ - top = DBTERM_BUF(newDbTerm); - copy = copy_struct(make_tuple(handle->dbterm->tpl), - handle->new_size, - &top, &tmp_offheap); - newDbTerm->first_oh = tmp_offheap.first; - DBTERM_SET_TPL(newDbTerm,tuple_val(copy)); + ASSERT((&oldp->dbterm == handle->dbterm) == !(tbl->common.compress && handle->mustResize)); + if (handle->mustResize) { + db_finalize_resize(handle, offsetof(HashDbTerm,dbterm)); WUNLOCK_HASH(lck); - - db_free_term_data(handle->dbterm); - erts_db_free(ERTS_ALC_T_DB_TERM, tbl, - (void *) (((char *) handle->dbterm) - (sizeof(HashDbTerm) - sizeof(DbTerm))), - sizeof(HashDbTerm) + sizeof(Eterm)*(handle->dbterm->size-1)); + + free_term(&tbl->hash, oldp); } else { WUNLOCK_HASH(lck); @@ -2781,7 +2729,7 @@ static void db_finalize_dbterm_hash(DbUpdateHandle* handle) handle->dbterm = 0; #endif return; -} +} static int db_delete_all_objects_hash(Process* p, DbTable* tbl) { diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c index 5644e85f97..8108494fc5 100644 --- a/erts/emulator/beam/erl_db_tree.c +++ b/erts/emulator/beam/erl_db_tree.c @@ -122,12 +122,41 @@ static void release_stack(DbTableTree* tb, DbTreeStack* stack) } } -static void reset_static_stack(DbTableTree* tb) +static ERTS_INLINE void reset_static_stack(DbTableTree* tb) { tb->static_stack.pos = 0; tb->static_stack.slot = 0; } +static ERTS_INLINE void free_term(DbTableTree *tb, TreeDbTerm* p) +{ + db_free_term((DbTable*)tb, p, offsetof(TreeDbTerm, dbterm)); +} + +static ERTS_INLINE TreeDbTerm* new_dbterm(DbTableTree *tb, Eterm obj) +{ + TreeDbTerm* p; + if (tb->common.compress) { + p = db_store_term_comp(&tb->common, NULL, offsetof(TreeDbTerm,dbterm), obj); + } + else { + p = db_store_term(&tb->common, NULL, offsetof(TreeDbTerm,dbterm), obj); + } + return p; +} +static ERTS_INLINE TreeDbTerm* replace_dbterm(DbTableTree *tb, TreeDbTerm* old, + Eterm obj) +{ + TreeDbTerm* p; + ASSERT(old != NULL); + if (tb->common.compress) { + p = db_store_term_comp(&tb->common, &(old->dbterm), offsetof(TreeDbTerm,dbterm), obj); + } + else { + p = db_store_term(&tb->common, &(old->dbterm), offsetof(TreeDbTerm,dbterm), obj); + } + return p; +} /* ** Some macros for "direction stacks" @@ -178,12 +207,6 @@ static void do_dump_tree2(int to, void *to_arg, int show, TreeDbTerm *t, #endif /* - * Size calculations - */ -#define SIZ_OVERHEAD ((sizeof(TreeDbTerm)/sizeof(Eterm)) - 1) -#define SIZ_DBTERM(TDT) (SIZ_OVERHEAD + (TDT)->dbterm.size) - -/* ** Datatypes */ @@ -263,9 +286,6 @@ static TreeDbTerm *linkout_tree(DbTableTree *tb, Eterm key); static TreeDbTerm *linkout_object_tree(DbTableTree *tb, Eterm object); static int do_free_tree_cont(DbTableTree *tb, int num_left); -static TreeDbTerm* get_term(DbTableTree *tb, - TreeDbTerm* old, - Eterm obj); static void free_term(DbTableTree *tb, TreeDbTerm* p); static int balance_left(TreeDbTerm **this); static int balance_right(TreeDbTerm **this); @@ -622,7 +642,7 @@ static int db_put_tree(DbTable *tbl, Eterm obj, int key_clash_fail) erts_smp_atomic_dec(&tb->common.nitems); return DB_ERROR_SYSRES; } - *this = get_term(tb, NULL, obj); + *this = new_dbterm(tb, obj); (*this)->balance = 0; (*this)->left = (*this)->right = NULL; break; @@ -636,7 +656,7 @@ static int db_put_tree(DbTable *tbl, Eterm obj, int key_clash_fail) tstack[tpos++] = this; this = &((*this)->right); } else if (!key_clash_fail) { /* Equal key and this is a set, replace. */ - *this = get_term(tb, *this, obj); + *this = replace_dbterm(tb, *this, obj); break; } else { return DB_ERROR_BADKEY; /* key already exists */ @@ -714,7 +734,7 @@ static int db_get_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret) { DbTableTree *tb = &tbl->tree; Eterm copy; - Eterm *hp; + Eterm *hp, *hend; TreeDbTerm *this; /* @@ -728,11 +748,11 @@ static int db_get_tree(Process *p, DbTable *tbl, Eterm key, Eterm *ret) *ret = NIL; } else { hp = HAlloc(p, this->dbterm.size + 2); - copy = copy_shallow(DBTERM_BUF(&this->dbterm), - this->dbterm.size, - &hp, - &MSO(p)); + hend = hp + this->dbterm.size + 2; + copy = db_copy_object_from_ets(&tb->common, &this->dbterm, &hp, &MSO(p)); *ret = CONS(hp, copy, NIL); + hp += 2; + HRelease(p,hend,hp); } return DB_ERROR_NONE; } @@ -766,18 +786,10 @@ static int db_get_element_tree(Process *p, DbTable *tbl, if (this == NULL) { return DB_ERROR_BADKEY; } else { - Eterm element; - Uint sz; if (ndex > arityval(this->dbterm.tpl[0])) { return DB_ERROR_BADPARAM; } - element = this->dbterm.tpl[ndex]; - sz = size_object(element); - hp = HAlloc(p, sz); - *ret = copy_struct(element, - sz, - &hp, - &MSO(p)); + *ret = db_copy_element_from_ets(&tb->common, p, &this->dbterm, ndex, &hp, 0); } return DB_ERROR_NONE; } @@ -815,7 +827,7 @@ static int db_slot_tree(Process *p, DbTable *tbl, DbTableTree *tb = &tbl->tree; Sint slot; TreeDbTerm *st; - Eterm *hp; + Eterm *hp, *hend; Eterm copy; /* @@ -847,11 +859,11 @@ static int db_slot_tree(Process *p, DbTable *tbl, return DB_ERROR_UNSPEC; } hp = HAlloc(p, st->dbterm.size + 2); - copy = copy_shallow(DBTERM_BUF(&st->dbterm), - st->dbterm.size, - &hp, - &MSO(p)); + hend = hp + st->dbterm.size + 2; + copy = db_copy_object_from_ets(&tb->common, &st->dbterm, &hp, &MSO(p)); *ret = CONS(hp, copy, NIL); + hp += 2; + HRelease(p,hend,hp); return DB_ERROR_NONE; } @@ -1738,7 +1750,7 @@ static int db_select_delete_tree(Process *p, DbTable *tbl, ** Other interface routines (not directly coupled to one bif) */ -/* Display hash table contents (for dump) */ +/* Display tree contents (for dump) */ static void db_print_tree(int to, void *to_arg, int show, DbTable *tbl) @@ -1926,7 +1938,7 @@ static TreeDbTerm *linkout_object_tree(DbTableTree *tb, tstack[tpos++] = this; this = &((*this)->right); } else { /* Equal key, found the only possible matching object*/ - if (!eq(object,make_tuple((*this)->dbterm.tpl))) { + if (!db_eq(&tb->common,object,&(*this)->dbterm)) { return NULL; } q = (*this); @@ -2079,15 +2091,6 @@ static void do_dump_tree(int to, void *to_arg, TreeDbTerm *t) } } -static void free_term(DbTableTree *tb, TreeDbTerm* p) -{ - db_free_term_data(&(p->dbterm)); - erts_db_free(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - (void *) p, - SIZ_DBTERM(p)*sizeof(Uint)); -} - static int do_free_tree_cont(DbTableTree *tb, int num_left) { TreeDbTerm *root; @@ -2118,17 +2121,6 @@ static int do_free_tree_cont(DbTableTree *tb, int num_left) return 1; } -static TreeDbTerm* get_term(DbTableTree *tb, - TreeDbTerm* old, - Eterm obj) -{ - TreeDbTerm* p = db_get_term((DbTableCommon *) tb, - (old != NULL) ? &(old->dbterm) : NULL, - ((char *) &(old->dbterm)) - ((char *) old), - obj); - return p; -} - /* * Deletion helpers */ @@ -2570,46 +2562,21 @@ static int db_lookup_dbterm_tree(DbTable *tbl, Eterm key, DbUpdateHandle* handle handle->tb = tbl; handle->dbterm = &(*pp)->dbterm; + handle->mustResize = 0; handle->bp = (void**) pp; handle->new_size = (*pp)->dbterm.size; - handle->mustResize = 0; return 1; } static void db_finalize_dbterm_tree(DbUpdateHandle* handle) { if (handle->mustResize) { - ErlOffHeap tmp_offheap; - Eterm* top; - Eterm copy; - DbTerm* newDbTerm; - DbTableTree *tb = &handle->tb->tree; TreeDbTerm* oldp = (TreeDbTerm*) *handle->bp; - TreeDbTerm* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM, - handle->tb, - sizeof(TreeDbTerm)+sizeof(Eterm)*(handle->new_size-1)); - memcpy(newp, oldp, sizeof(TreeDbTerm)-sizeof(DbTerm)); /* copy only tree header */ - *(handle->bp) = newp; - reset_static_stack(tb); - newDbTerm = &newp->dbterm; - - newDbTerm->size = handle->new_size; - tmp_offheap.first = NULL; - tmp_offheap.overhead = 0; - - /* make a flat copy */ - top = DBTERM_BUF(newDbTerm); - copy = copy_struct(make_tuple(handle->dbterm->tpl), - handle->new_size, - &top, &tmp_offheap); - newDbTerm->first_oh = tmp_offheap.first; - DBTERM_SET_TPL(newDbTerm,tuple_val(copy)); - - db_free_term_data(handle->dbterm); - erts_db_free(ERTS_ALC_T_DB_TERM, - handle->tb, - (void *) (((char *) handle->dbterm) - (sizeof(TreeDbTerm) - sizeof(DbTerm))), - sizeof(TreeDbTerm) + sizeof(Eterm)*(handle->dbterm->size-1)); + + db_finalize_resize(handle, offsetof(TreeDbTerm,dbterm)); + reset_static_stack(&handle->tb->tree); + + free_term(&handle->tb->tree, oldp); } #ifdef DEBUG handle->dbterm = 0; @@ -3009,7 +2976,7 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr, { struct select_context *sc = (struct select_context *) ptr; Eterm ret; - Uint32 dummy; + Eterm* hp; sc->lastobj = this->dbterm.tpl; @@ -3024,24 +2991,9 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr, this->dbterm.tpl)) > 0))) { return 0; } - ret = db_prog_match(sc->p, sc->mp, - make_tuple(this->dbterm.tpl), - NULL,0, &dummy); + ret = db_prog_match_and_copy(&tb->common,sc->p,sc->mp,sc->all_objects, + &this->dbterm, &hp, 2); if (is_value(ret)) { - Uint sz; - Eterm *hp; - if (sc->all_objects) { - hp = HAlloc(sc->p, this->dbterm.size + 2); - ret = copy_shallow(DBTERM_BUF(&this->dbterm), - this->dbterm.size, - &hp, - &MSO(sc->p)); - } else { - sz = size_object(ret); - hp = HAlloc(sc->p, sz + 2); - ret = copy_struct(ret, sz, - &hp, &MSO(sc->p)); - } sc->accum = CONS(hp, ret, sc->accum); } if (MBUF(sc->p)) { @@ -3062,7 +3014,6 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr, { struct select_count_context *sc = (struct select_count_context *) ptr; Eterm ret; - Uint32 dummy; sc->lastobj = this->dbterm.tpl; @@ -3073,9 +3024,8 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr, this->dbterm.tpl)) > 0)) { return 0; } - ret = db_prog_match(sc->p, sc->mp, - make_tuple(this->dbterm.tpl), - NULL,0, &dummy); + ret = db_prog_match_and_copy(&tb->common, sc->p, sc->mp, 0, + &this->dbterm, NULL, 0); if (ret == am_true) { ++(sc->got); } @@ -3090,7 +3040,7 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr, { struct select_context *sc = (struct select_context *) ptr; Eterm ret; - Uint32 dummy; + Eterm* hp; sc->lastobj = this->dbterm.tpl; @@ -3106,25 +3056,10 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr, return 0; } - ret = db_prog_match(sc->p, sc->mp, - make_tuple(this->dbterm.tpl), - NULL,0, &dummy); + ret = db_prog_match_and_copy(&tb->common, sc->p, sc->mp, sc->all_objects, + &this->dbterm, &hp, 2); if (is_value(ret)) { - Uint sz; - Eterm *hp; - ++(sc->got); - if (sc->all_objects) { - hp = HAlloc(sc->p, this->dbterm.size + 2); - ret = copy_shallow(DBTERM_BUF(&this->dbterm), - this->dbterm.size, - &hp, - &MSO(sc->p)); - } else { - sz = size_object(ret); - hp = HAlloc(sc->p, sz + 2); - ret = copy_struct(ret, sz, &hp, &MSO(sc->p)); - } sc->accum = CONS(hp, ret, sc->accum); } if (MBUF(sc->p)) { @@ -3146,7 +3081,6 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr, { struct select_delete_context *sc = (struct select_delete_context *) ptr; Eterm ret; - Uint32 dummy; Eterm key; if (sc->erase_lastterm) @@ -3159,9 +3093,8 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr, GETKEY_WITH_POS(sc->keypos, this->dbterm.tpl)) > 0) return 0; - ret = db_prog_match(sc->p, sc->mp, - make_tuple(this->dbterm.tpl), - NULL,0, &dummy); + ret = db_prog_match_and_copy(&tb->common, sc->p, sc->mp, 0, + &this->dbterm, NULL, 0); if (ret == am_true) { key = GETKEY(sc->tb, this->dbterm.tpl); linkout_tree(sc->tb, key); diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 2f34561234..e773361619 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -25,7 +25,6 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif - #include "sys.h" #include "erl_vm.h" #include "global.h" @@ -890,6 +889,8 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace); static Eterm seq_trace_fake(Process *p, Eterm arg1); +static void db_free_tmp_uncompressed(DbTerm* obj); + /* ** Interface routines. @@ -1604,6 +1605,7 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity) } return ret; } + /* ** Execution of the match program, this is Pam. ** May return THE_NON_VALUE, which is a bailout. @@ -2391,33 +2393,46 @@ void db_do_update_element(DbUpdateHandle* handle, if (is_both_immed(newval,oldval)) { handle->dbterm->tpl[position] = newval; +#ifdef DEBUG_CLONE + if (handle->dbterm->debug_clone) { + handle->dbterm->debug_clone[position] = newval; + } +#endif return; } - else if (!handle->mustResize && is_boxed(newval)) { - newp = boxed_val(newval); - switch (*newp & _TAG_HEADER_MASK) { - case _TAG_HEADER_POS_BIG: - case _TAG_HEADER_NEG_BIG: - case _TAG_HEADER_FLOAT: - case _TAG_HEADER_HEAP_BIN: - newval_sz = header_arity(*newp) + 1; - if (is_boxed(oldval)) { - oldp = boxed_val(oldval); - switch (*oldp & _TAG_HEADER_MASK) { - case _TAG_HEADER_POS_BIG: - case _TAG_HEADER_NEG_BIG: - case _TAG_HEADER_FLOAT: - case _TAG_HEADER_HEAP_BIN: - oldval_sz = header_arity(*oldp) + 1; - if (oldval_sz == newval_sz) { - /* "self contained" terms of same size, do memcpy */ - sys_memcpy(oldp, newp, newval_sz*sizeof(Eterm)); - return; + if (!handle->mustResize) { + if (handle->tb->common.compress) { + handle->dbterm = db_alloc_tmp_uncompressed(&handle->tb->common, + handle->dbterm); + handle->mustResize = 1; + oldval = handle->dbterm->tpl[position]; + } + else if (is_boxed(newval)) { + newp = boxed_val(newval); + switch (*newp & _TAG_HEADER_MASK) { + case _TAG_HEADER_POS_BIG: + case _TAG_HEADER_NEG_BIG: + case _TAG_HEADER_FLOAT: + case _TAG_HEADER_HEAP_BIN: + newval_sz = header_arity(*newp) + 1; + if (is_boxed(oldval)) { + oldp = boxed_val(oldval); + switch (*oldp & _TAG_HEADER_MASK) { + case _TAG_HEADER_POS_BIG: + case _TAG_HEADER_NEG_BIG: + case _TAG_HEADER_FLOAT: + case _TAG_HEADER_HEAP_BIN: + oldval_sz = header_arity(*oldp) + 1; + if (oldval_sz == newval_sz) { + /* "self contained" terms of same size, do memcpy */ + sys_memcpy(oldp, newp, newval_sz*sizeof(Eterm)); + return; + } + goto both_size_set; } - goto both_size_set; } + goto new_size_set; } - goto new_size_set; } } /* Not possible for simple memcpy or dbterm is already non-contiguous, */ @@ -2436,84 +2451,372 @@ both_size_set: handle->mustResize = 1; } +static ERTS_INLINE byte* db_realloc_term(DbTableCommon* tb, void* old, + Uint old_sz, Uint new_sz, Uint offset) +{ + byte* ret; + if (erts_ets_realloc_always_moves) { + ret = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb, new_sz); + sys_memcpy(ret, old, offset); + erts_db_free(ERTS_ALC_T_DB_TERM, (DbTable*)tb, old, old_sz); + } else { + ret = erts_db_realloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb, + old, old_sz, new_sz); + } + return ret; +} + +/* Allocated size of a compressed dbterm +*/ +static ERTS_INLINE Uint db_alloced_size_comp(DbTerm* obj) +{ + return obj->tpl[arityval(*obj->tpl) + 1]; +} + +void db_free_term(DbTable *tb, void* basep, Uint offset) +{ + DbTerm* db = (DbTerm*) ((byte*)basep + offset); + Uint size; + if (tb->common.compress) { + db_cleanup_offheap_comp(db); + size = db_alloced_size_comp(db); + } + else { + ErlOffHeap tmp_oh; + tmp_oh.first = db->first_oh; + erts_cleanup_offheap(&tmp_oh); + size = offset + offsetof(DbTerm,tpl) + db->size*sizeof(Eterm); + } + erts_db_free(ERTS_ALC_T_DB_TERM, tb, basep, size); +} + +static ERTS_INLINE Uint align_up(Uint value, Uint pow2) +{ + ASSERT((pow2 & (pow2-1)) == 0); + return (value + (pow2-1)) & ~(pow2-1); +} + +/* Compressed size of an uncompressed term +*/ +static Uint db_size_dbterm_comp(DbTableCommon* tb, Eterm obj) +{ + Eterm* tpl = tuple_val(obj); + int i; + Uint size = sizeof(DbTerm) + + arityval(*tpl) * sizeof(Eterm) + + sizeof(Uint); /* "alloc_size" */ + + for (i = arityval(*tpl); i>0; i--) { + if (i != tb->keypos && is_not_immed(tpl[i])) { + size += erts_encode_ext_size_ets(tpl[i]); + } + } + size += size_object(tpl[tb->keypos]) * sizeof(Eterm); + return align_up(size, sizeof(Uint)); +} + +/* Conversion between top tuple element and pointer to compressed data +*/ +static ERTS_INLINE Eterm ext2elem(Eterm* tpl, byte* ext) +{ + return (((Uint)(ext - (byte*)tpl)) << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER; +} +static ERTS_INLINE byte* elem2ext(Eterm* tpl, Uint ix) +{ + ASSERT(is_header(tpl[ix])); + return (byte*)tpl + (tpl[ix] >> _TAG_PRIMARY_SIZE); +} + +static void* copy_to_comp(DbTableCommon* tb, Eterm obj, DbTerm* dest, + Uint alloc_size) +{ + ErlOffHeap tmp_offheap; + Eterm* src = tuple_val(obj); + Eterm* tpl = dest->tpl; + Eterm key = src[tb->keypos]; + int arity = arityval(src[0]); + union { + Eterm* ep; + byte* cp; + UWord ui; + }top; + int i; + + top.ep = tpl+ 1 + arity + 1; + tpl[0] = src[0]; + tpl[arity + 1] = alloc_size; + + tmp_offheap.first = NULL; + tpl[tb->keypos] = copy_struct(key, size_object(key), &top.ep, &tmp_offheap); + dest->first_oh = tmp_offheap.first; + for (i=1; i<=arity; i++) { + if (i != tb->keypos) { + if (is_immed(src[i])) { + tpl[i] = src[i]; + } + else { + tpl[i] = ext2elem(tpl, top.cp); + top.cp = erts_encode_ext_ets(src[i], top.cp, &dest->first_oh); + } + } + } + +#ifdef DEBUG_CLONE + { + Eterm* dbg_top = erts_alloc(ERTS_ALC_T_DB_TERM, dest->size * sizeof(Eterm)); + dest->debug_clone = dbg_top; + tmp_offheap.first = dest->first_oh; + copy_struct(obj, dest->size, &dbg_top, &tmp_offheap); + dest->first_oh = tmp_offheap.first; + ASSERT(dbg_top == dest->debug_clone + dest->size); + } +#endif + return top.cp; +} /* ** Copy the object into a possibly new DbTerm, ** offset is the offset of the DbTerm from the start -** of the sysAllocaed structure, The possibly realloced and copied +** of the allocated structure, The possibly realloced and copied ** structure is returned. Make sure (((char *) old) - offset) is a ** pointer to a ERTS_ALC_T_DB_TERM allocated data area. */ -void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) +void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) { + byte* basep; + DbTerm* newp; + Eterm* top; int size = size_object(obj); - void *structp = ((char*) old) - offset; - DbTerm* p; - Eterm copy; - Eterm *top; ErlOffHeap tmp_offheap; if (old != 0) { + basep = ((byte*) old) - offset; tmp_offheap.first = old->first_oh; - tmp_offheap.overhead = 0; erts_cleanup_offheap(&tmp_offheap); old->first_oh = tmp_offheap.first; if (size == old->size) { - p = old; - } else { + newp = old; + } + else { Uint new_sz = offset + sizeof(DbTerm) + sizeof(Eterm)*(size-1); Uint old_sz = offset + sizeof(DbTerm) + sizeof(Eterm)*(old->size-1); - if (erts_ets_realloc_always_moves) { - void *nstructp = erts_db_alloc(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - new_sz); - memcpy(nstructp,structp,offset); - erts_db_free(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - structp, - old_sz); - structp = nstructp; - } else { - structp = erts_db_realloc(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - structp, - old_sz, - new_sz); - } - p = (DbTerm*) ((void *)(((char *) structp) + offset)); + basep = db_realloc_term(tb, basep, old_sz, new_sz, offset); + newp = (DbTerm*) (basep + offset); } } else { - structp = erts_db_alloc(ERTS_ALC_T_DB_TERM, - (DbTable *) tb, - (offset - + sizeof(DbTerm) - + sizeof(Eterm)*(size-1))); - p = (DbTerm*) ((void *)(((char *) structp) + offset)); - } - p->size = size; + basep = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable *)tb, + (offset + sizeof(DbTerm) + sizeof(Eterm)*(size-1))); + newp = (DbTerm*) (basep + offset); + } + newp->size = size; + top = newp->tpl; tmp_offheap.first = NULL; - tmp_offheap.overhead = 0; + copy_struct(obj, size, &top, &tmp_offheap); + newp->first_oh = tmp_offheap.first; +#ifdef DEBUG_CLONE + newp->debug_clone = NULL; +#endif + return basep; +} + + +void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj) +{ + Uint new_sz = offset + db_size_dbterm_comp(tb, obj); + byte* basep; + DbTerm* newp; + byte* top; + + ASSERT(tb->compress); + if (old != 0) { + Uint old_sz = db_alloced_size_comp(old); + db_cleanup_offheap_comp(old); + + basep = ((byte*) old) - offset; + if (new_sz == old_sz) { + newp = old; + } + else { + basep = db_realloc_term(tb, basep, old_sz, new_sz, offset); + newp = (DbTerm*) (basep + offset); + } + } + else { + basep = erts_db_alloc(ERTS_ALC_T_DB_TERM, (DbTable*)tb, new_sz); + newp = (DbTerm*) (basep + offset); + } + + newp->size = size_object(obj); + top = copy_to_comp(tb, obj, newp, new_sz); + ASSERT(top <= basep + new_sz); + + // SVERK: realloc? + + return basep; +} + + +void db_finalize_resize(DbUpdateHandle* handle, Uint offset) +{ + DbTable* tbl = handle->tb; + DbTerm* newDbTerm; + Uint alloc_sz = offset + + (tbl->common.compress ? + db_size_dbterm_comp(&tbl->common, make_tuple(handle->dbterm->tpl)) : + sizeof(DbTerm)+sizeof(Eterm)*(handle->new_size-1)); + byte* newp = erts_db_alloc(ERTS_ALC_T_DB_TERM, tbl, alloc_sz); + byte* oldp = *(handle->bp); + + sys_memcpy(newp, oldp, offset); /* copy only hash/tree header */ + *(handle->bp) = newp; + newDbTerm = (DbTerm*) (newp + offset); + newDbTerm->size = handle->new_size; + + /* make a flat copy */ + + if (tbl->common.compress) { + copy_to_comp(&tbl->common, make_tuple(handle->dbterm->tpl), + newDbTerm, alloc_sz); + db_free_tmp_uncompressed(handle->dbterm); + } + else { + Eterm* top; + ErlOffHeap tmp_offheap; + tmp_offheap.first = NULL; + top = newDbTerm->tpl; + copy_struct(make_tuple(handle->dbterm->tpl), handle->new_size, + &top, &tmp_offheap); + newDbTerm->first_oh = tmp_offheap.first; +#ifdef DEBUG_CLONE + newDbTerm->debug_clone = NULL; +#endif + ASSERT((byte*)top <= (newp + alloc_sz)); + } +} - top = DBTERM_BUF(p); - copy = copy_struct(obj, size, &top, &tmp_offheap); - p->first_oh = tmp_offheap.first; - DBTERM_SET_TPL(p,tuple_val(copy)); +Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp, + ErlOffHeap* off_heap) +{ + Eterm* hp = *hpp; + int i, arity = arityval(bp->tpl[0]); + + hp[0] = bp->tpl[0]; + *hpp += arity + 1; + + hp[tb->keypos] = copy_struct(bp->tpl[tb->keypos], + size_object(bp->tpl[tb->keypos]), + hpp, off_heap); + for (i=arity; i>0; i--) { + if (i != tb->keypos) { + if (is_immed(bp->tpl[i])) { + hp[i] = bp->tpl[i]; + } + else { + hp[i] = erts_decode_ext_ets(hpp, off_heap, + elem2ext(bp->tpl, i)); + } + } + } + ASSERT((*hpp - hp) <= bp->size); +#ifdef DEBUG_CLONE + ASSERT(eq(make_tuple(hp),make_tuple(bp->debug_clone))); +#endif + return make_tuple(hp); +} - return structp; +Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, + DbTerm* obj, Uint pos, + Eterm** hpp, Uint extra) +{ + if (is_immed(obj->tpl[pos])) { + *hpp = HAlloc(p, extra); + return obj->tpl[pos]; + } + if (tb->compress && pos != tb->keypos) { + byte* ext = elem2ext(obj->tpl, pos); + Sint sz = erts_decode_ext_size_ets(ext, db_alloced_size_comp(obj)) + extra; + Eterm* hp = HAlloc(p, sz); + Eterm* endp = hp + sz; + Eterm copy = erts_decode_ext_ets(&hp, &MSO(p), ext); + *hpp = hp; + hp += extra; + HRelease(p, endp, hp); +#ifdef DEBUG_CLONE + ASSERT(eq(copy,obj->debug_clone[pos])); +#endif + return copy; + } + else { + Uint sz = size_object(obj->tpl[pos]); + *hpp = HAlloc(p, sz + extra); + return copy_struct(obj->tpl[pos], sz, hpp, &MSO(p)); + } } -void db_free_term_data(DbTerm* p) +/* Our own "cleanup_offheap" + * as refc-binaries may be unaligned in compressed terms +*/ +void db_cleanup_offheap_comp(DbTerm* obj) +{ + union erl_off_heap_ptr u; + ProcBin tmp; + + for (u.hdr = obj->first_oh; u.hdr; u.hdr = u.hdr->next) { + if ((UWord)u.voidp % sizeof(UWord) != 0) { /* unaligned ptr */ + sys_memcpy(&tmp, u.voidp, sizeof(tmp)); + /* Warning, must pass (void*)-variable to memcpy. Otherwise it will + cause Bus error on Sparc due to false compile time assumptions + about word aligned memory (type cast is not enough) */ + u.pb = &tmp; + } + switch (thing_subtag(u.hdr->thing_word)) { + case REFC_BINARY_SUBTAG: + if (erts_refc_dectest(&u.pb->val->refc, 0) == 0) { + erts_bin_free(u.pb->val); + } + break; + case FUN_SUBTAG: + ASSERT(u.pb != &tmp); + if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) { + erts_erase_fun_entry(u.fun->fe); + } + break; + default: + ASSERT(is_external_header(u.hdr->thing_word)); + ASSERT(u.pb != &tmp); + erts_deref_node_entry(u.ext->node); + break; + } + } +#ifdef DEBUG_CLONE + if (obj->debug_clone != NULL) { + erts_free(ERTS_ALC_T_DB_TERM, obj->debug_clone); + obj->debug_clone = NULL; + } +#endif +} + +int db_eq_comp(DbTableCommon* tb, Eterm a, DbTerm* b) { ErlOffHeap tmp_offheap; - tmp_offheap.first = p->first_oh; - tmp_offheap.overhead = 0; + Eterm* allocp; + Eterm* hp; + Eterm tmp_b; + int is_eq; + + ASSERT(tb->compress); + hp = allocp = erts_alloc(ERTS_ALC_T_TMP, b->size*sizeof(Eterm)); + tmp_offheap.first = NULL; + tmp_b = db_copy_from_comp(tb, b, &hp, &tmp_offheap); + is_eq = eq(a,tmp_b); erts_cleanup_offheap(&tmp_offheap); + erts_free(ERTS_ALC_T_TMP, allocp); + return is_eq; } - /* ** Check if object represents a "match" variable ** i.e and atom $N where N is an integer @@ -4404,7 +4707,65 @@ static Eterm seq_trace_fake(Process *p, Eterm arg1) } return result; } - + +DbTerm* db_alloc_tmp_uncompressed(DbTableCommon* tb, DbTerm* org) +{ + ErlOffHeap tmp_offheap; + DbTerm* res = erts_alloc(ERTS_ALC_T_TMP, + sizeof(DbTerm) + org->size*sizeof(Eterm)); + Eterm* hp = res->tpl; + tmp_offheap.first = NULL; + db_copy_from_comp(tb, org, &hp, &tmp_offheap); + res->first_oh = tmp_offheap.first; + res->size = org->size; +#ifdef DEBUG_CLONE + res->debug_clone = NULL; +#endif + return res; +} + +void db_free_tmp_uncompressed(DbTerm* obj) +{ + ErlOffHeap off_heap; + off_heap.first = obj->first_oh; + erts_cleanup_offheap(&off_heap); +#ifdef DEBUG_CLONE + ASSERT(obj->debug_clone == NULL); +#endif + erts_free(ERTS_ALC_T_TMP, obj); +} + +Eterm db_prog_match_and_copy(DbTableCommon* tb, Process* c_p, Binary* bprog, + int all, DbTerm* obj, Eterm** hpp, Uint extra) +{ + Uint32 dummy; + Eterm res; + + if (tb->compress) { + obj = db_alloc_tmp_uncompressed(tb, obj); + } + + res = db_prog_match(c_p, bprog, make_tuple(obj->tpl), NULL, 0, &dummy); + + if (is_value(res) && hpp!=NULL) { + if (all) { + *hpp = HAlloc(c_p, obj->size + extra); + res = copy_shallow(obj->tpl, obj->size, hpp, &MSO(c_p)); + } + else { + Uint sz = size_object(res); + *hpp = HAlloc(c_p, sz + extra); + res = copy_struct(res, sz, hpp, &MSO(c_p)); + } + } + + if (tb->compress) { + db_free_tmp_uncompressed(obj); + } + return res; +} + + #ifdef DMC_DEBUG /* ** Disassemble match program diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 0f333e8b34..10ba755e80 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -52,22 +52,27 @@ is broken.*/ #define DB_ERROR_UNSPEC -10 /* Unspecified error */ +/*#define DEBUG_CLONE*/ /* * A datatype for a database entry stored out of a process heap */ typedef struct db_term { struct erl_off_heap_header* first_oh; /* Off heap data for term. */ - Uint size; /* Size of term in "words" */ - Eterm tpl[1]; /* Untagged "constant pointer" to top tuple */ - /* (assumed to be first in buffer) */ + Uint size; /* Heap size of term in "words" */ +#ifdef DEBUG_CLONE + Eterm* debug_clone; /* An uncompressed copy */ +#endif + Eterm tpl[1]; /* Term data. Top tuple always first */ + + /* Compression: is_immed and key element are uncompressed. + Compressed elements are stored in external format after each other + last in dbterm. The top tuple elements contains byte offsets, to + the start of the data, tagged as headers. + The allocated size of the dbterm in bytes is stored at tpl[arity+1]. + */ } DbTerm; -/* "Assign" a value to DbTerm.tpl */ -#define DBTERM_SET_TPL(dbtermPtr,tplPtr) ASSERT((tplPtr)==(dbtermPtr->tpl)) -/* Get start of term buffer */ -#define DBTERM_BUF(dbtermPtr) ((dbtermPtr)->tpl) - union db_table; typedef union db_table DbTable; @@ -186,6 +191,12 @@ typedef struct db_table_method } DbTableMethod; +typedef struct db_fixation { + Eterm pid; + Uint counter; + struct db_fixation *next; +} DbFixation; + /* * This structure contains data for all different types of database * tables. Note that these fields must match the same fields @@ -194,13 +205,6 @@ typedef struct db_table_method * operations may be the same on different types of tables. */ -typedef struct db_fixation { - Eterm pid; - Uint counter; - struct db_fixation *next; -} DbFixation; - - typedef struct db_table_common { erts_refc_t ref; erts_refc_t fixref; /* fixation counter */ @@ -226,6 +230,7 @@ typedef struct db_table_common { Uint32 status; /* bit masks defined below */ int slot; /* slot index in meta_main_tab */ int keypos; /* defaults to 1 */ + int compress; } DbTableCommon; /* These are status bit patterns */ @@ -252,6 +257,54 @@ typedef struct db_table_common { #define IS_FIXED(T) (NFIXED(T) != 0) Eterm erts_ets_copy_object(Eterm, Process*); +Eterm db_copy_from_comp(DbTableCommon* tb, DbTerm* bp, Eterm** hpp, + ErlOffHeap* off_heap); +int db_eq_comp(DbTableCommon* tb, Eterm a, DbTerm* b); +DbTerm* db_alloc_tmp_uncompressed(DbTableCommon* tb, DbTerm* org); + +ERTS_GLB_INLINE Eterm db_copy_object_from_ets(DbTableCommon* tb, DbTerm* bp, + Eterm** hpp, ErlOffHeap* off_heap); +ERTS_GLB_INLINE int db_eq(DbTableCommon* tb, Eterm a, DbTerm* b); +ERTS_GLB_INLINE Eterm db_do_read_element(DbUpdateHandle* handle, Sint position); + +#if ERTS_GLB_INLINE_INCL_FUNC_DEF +ERTS_GLB_INLINE Eterm db_copy_object_from_ets(DbTableCommon* tb, DbTerm* bp, + Eterm** hpp, ErlOffHeap* off_heap) +{ + if (tb->compress) { + return db_copy_from_comp(tb, bp, hpp, off_heap); + } + else { + return copy_shallow(bp->tpl, bp->size, hpp, off_heap); + } +} + +ERTS_GLB_INLINE int db_eq(DbTableCommon* tb, Eterm a, DbTerm* b) +{ + if (!tb->compress) { + return eq(a, make_tuple(b->tpl)); + } + else { + return db_eq_comp(tb, a, b); + } +} + +/* Must be called to read elements after db_lookup_dbterm. +** Will decompress if needed. */ +ERTS_GLB_INLINE Eterm db_do_read_element(DbUpdateHandle* handle, Sint position) +{ + Eterm elem = handle->dbterm->tpl[position]; + if (!is_header(elem)) { + return elem; + } + ASSERT(((DbTableCommon*)handle->tb)->compress); + ASSERT(!handle->mustResize); + handle->dbterm = db_alloc_tmp_uncompressed((DbTableCommon*)handle->tb, handle->dbterm); + handle->mustResize = 1; + return handle->dbterm->tpl[position]; +} + +#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */ /* optimised version of copy_object (normal case? atomic object) */ #define COPY_OBJECT(obj, p, objp) \ @@ -277,14 +330,19 @@ Eterm db_set_trace_control_word_1(Process *p, Eterm val); void db_initialize_util(void); Eterm db_getkey(int keypos, Eterm obj); -void db_free_term_data(DbTerm* p); -void* db_get_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj); +void db_cleanup_offheap_comp(DbTerm* p); +void db_free_term(DbTable *tb, void* basep, Uint offset); +void* db_store_term(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj); +void* db_store_term_comp(DbTableCommon *tb, DbTerm* old, Uint offset, Eterm obj); +Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, DbTerm* obj, + Uint pos, Eterm** hpp, Uint extra); int db_has_variable(Eterm obj); int db_is_variable(Eterm obj); +Eterm db_do_read_element(DbUpdateHandle* handle, Sint position); void db_do_update_element(DbUpdateHandle* handle, Sint position, Eterm newval); -void db_finalize_update_element(DbUpdateHandle* handle); +void db_finalize_resize(DbUpdateHandle* handle, Uint offset); Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr); Eterm db_match_set_lint(Process *p, Eterm matchexpr, Uint flags); Binary *db_match_set_compile(Process *p, Eterm matchexpr, @@ -366,6 +424,8 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards, Eterm *body, int num_matches, Uint flags, DMCErrInfo *err_info); +Eterm db_prog_match_and_copy(DbTableCommon* tb, Process* c_p, Binary* bprog, + int all, DbTerm* obj, Eterm** hpp, Uint extra); /* Returns newly allocated MatchProg binary with refc == 0*/ Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm *termp, int arity, Uint32 *return_flags /* Zeroed on enter */); diff --git a/erts/emulator/beam/erl_drv_thread.c b/erts/emulator/beam/erl_drv_thread.c index d42820ddf3..17b08a71d4 100644 --- a/erts/emulator/beam/erl_drv_thread.c +++ b/erts/emulator/beam/erl_drv_thread.c @@ -528,7 +528,7 @@ erl_drv_tsd_get(ErlDrvTSDKey key) if (!dtid) return NULL; #endif - if (ERL_DRV_TSD_LEN__ < key) + if (ERL_DRV_TSD_LEN__ <= key) return NULL; return ERL_DRV_TSD__[key]; } diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index e2f2cccb7e..464ee750f7 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -41,6 +41,7 @@ #include "erl_printf_term.h" #include "erl_misc_utils.h" #include "packet_parser.h" +#include "erl_cpu_topology.h" #ifdef HIPE #include "hipe_mode_switch.h" /* for hipe_mode_switch_init() */ @@ -63,6 +64,8 @@ extern void ConNormalExit(void); extern void ConWaitForExit(void); #endif +static void erl_init(int ncpu); + #define ERTS_MIN_COMPAT_REL 7 #ifdef ERTS_SMP @@ -76,9 +79,6 @@ int erts_initialized = 0; static erts_tid_t main_thread; #endif -erts_cpu_info_t *erts_cpuinfo; - -int erts_reader_groups; int erts_use_sender_punish; /* @@ -111,7 +111,6 @@ int erts_compat_rel; static int use_multi_run_queue; static int no_schedulers; static int no_schedulers_online; -static int max_reader_groups; #ifdef DEBUG Uint32 verbose; /* See erl_debug.h for information about verbose */ @@ -230,18 +229,18 @@ void erl_error(char *fmt, va_list args) erts_vfprintf(stderr, fmt, args); } -static void early_init(int *argc, char **argv); +static int early_init(int *argc, char **argv); void erts_short_init(void) { - early_init(NULL, NULL); - erl_init(); + int ncpu = early_init(NULL, NULL); + erl_init(ncpu); erts_initialized = 1; } -void -erl_init(void) +static void +erl_init(int ncpu) { init_benchmarking(); @@ -252,11 +251,12 @@ erl_init(void) erts_init_monitors(); erts_init_gc(); init_time(); - erts_init_process(); + erts_init_sys_common_misc(); + erts_init_process(ncpu); erts_init_scheduling(use_multi_run_queue, no_schedulers, no_schedulers_online); - + erts_init_cpu_topology(); /* Must be after init_scheduling */ H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0); BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0); @@ -535,7 +535,8 @@ void erts_usage(void) erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n"); erts_fprintf(stderr, " see error_logger documentation for details\n"); - + erts_fprintf(stderr, "-zdbbl size set the distribution buffer busy limit in kilobytes\n"); + erts_fprintf(stderr, " valid range is [1-%d]\n", INT_MAX/1024); erts_fprintf(stderr, "\n"); erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n"); erts_fprintf(stderr, "from the erl script), these flags should be specified with +.\n"); @@ -587,7 +588,7 @@ static void ethr_ll_free(void *ptr) #endif -static void +static int early_init(int *argc, char **argv) /* * Only put things here which are * really important initialize @@ -600,6 +601,10 @@ early_init(int *argc, char **argv) /* int ncpuavail; int schdlrs; int schdlrs_onln; + int max_main_threads; + int max_reader_groups; + int reader_groups; + use_multi_run_queue = 1; erts_printf_eterm_func = erts_printf_term; erts_disable_tolerant_timeofday = 0; @@ -615,13 +620,11 @@ early_init(int *argc, char **argv) /* erts_use_sender_punish = 1; - erts_cpuinfo = erts_cpu_info_create(); - -#ifdef ERTS_SMP - ncpu = erts_get_cpu_configured(erts_cpuinfo); - ncpuonln = erts_get_cpu_online(erts_cpuinfo); - ncpuavail = erts_get_cpu_available(erts_cpuinfo); -#else + erts_pre_early_init_cpu_topology(&max_reader_groups, + &ncpu, + &ncpuonln, + &ncpuavail); +#ifndef ERTS_SMP ncpu = 1; ncpuonln = 1; ncpuavail = 1; @@ -664,15 +667,9 @@ early_init(int *argc, char **argv) /* ? ncpuavail : (ncpuonln > 0 ? ncpuonln : no_schedulers)); -#ifdef ERTS_SMP - erts_max_main_threads = no_schedulers_online; -#endif - schdlrs = no_schedulers; schdlrs_onln = no_schedulers_online; - max_reader_groups = ERTS_MAX_READER_GROUPS; - if (argc && argv) { int i = 1; while (i < *argc) { @@ -768,9 +765,13 @@ early_init(int *argc, char **argv) /* erts_alloc_init(argc, argv, &alloc_opts); /* Handles (and removes) -M flags. */ - - erts_early_init_scheduling(); /* Require allocators */ - erts_init_utils(); /* Require allocators */ + /* Require allocators */ + erts_early_init_scheduling(); + erts_init_utils(); + erts_early_init_cpu_topology(no_schedulers, + &max_main_threads, + max_reader_groups, + &reader_groups); #ifdef USE_THREADS { @@ -784,26 +785,13 @@ early_init(int *argc, char **argv) /* elid.mem.ll.alloc = ethr_ll_alloc; elid.mem.ll.realloc = ethr_ll_realloc; elid.mem.ll.free = ethr_ll_free; - -#ifdef ERTS_SMP - if (erts_max_main_threads > no_schedulers) - erts_max_main_threads = no_schedulers; - elid.main_threads = erts_max_main_threads; -#else - elid.main_threads = 1; -#endif - elid.reader_groups = (elid.main_threads > 1 - ? elid.main_threads - : 0); - if (max_reader_groups <= 1) - elid.reader_groups = 0; - if (elid.reader_groups > max_reader_groups) - elid.reader_groups = max_reader_groups; - erts_reader_groups = elid.reader_groups; + elid.main_threads = max_main_threads; + elid.reader_groups = reader_groups; erts_thr_late_init(&elid); } #endif + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_late_init(); #endif @@ -820,7 +808,10 @@ early_init(int *argc, char **argv) /* erl_sys_args(argc, argv); erts_ets_realloc_always_moves = 0; + erts_ets_always_compress = 0; + erts_dist_buf_busy_limit = ERTS_DE_BUSY_LIMIT; + return ncpu; } #ifndef ERTS_SMP @@ -854,8 +845,7 @@ erl_start(int argc, char **argv) char envbuf[21]; /* enough for any 64-bit integer */ size_t envbufsz; int async_max_threads = erts_async_max_threads; - - early_init(&argc, argv); + int ncpu = early_init(&argc, argv); envbufsz = sizeof(envbuf); if (erts_sys_getenv(ERL_MAX_ETS_TABLES_ENV, envbuf, &envbufsz) == 0) @@ -918,7 +908,27 @@ erl_start(int argc, char **argv) VERBOSE(DEBUG_SYSTEM, ("using display items %d\n",display_items)); break; - + case 'f': + if (!strncmp(argv[i],"-fn",3)) { + arg = get_arg(argv[i]+3, argv[i+1], &i); + switch (*arg) { + case 'u': + erts_set_user_requested_filename_encoding(ERL_FILENAME_UTF8); + break; + case 'l': + erts_set_user_requested_filename_encoding(ERL_FILENAME_LATIN1); + break; + case 'a': + erts_set_user_requested_filename_encoding(ERL_FILENAME_UNKNOWN); + default: + erts_fprintf(stderr, "bad filename encoding %s, can be (l,u or a)\n", arg); + erts_usage(); + } + break; + } else { + erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]); + erts_usage(); + } case 'l': display_loads++; break; @@ -1040,15 +1050,20 @@ erl_start(int argc, char **argv) break; case 'e': - /* set maximum number of ets tables */ - arg = get_arg(argv[i]+2, argv[i+1], &i); - if (( user_requested_db_max_tabs = atoi(arg) ) < 0) { - erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg); - erts_usage(); + if (sys_strcmp("c", argv[i]+2) == 0) { + erts_ets_always_compress = 1; + } + else { + /* set maximum number of ets tables */ + arg = get_arg(argv[i]+2, argv[i+1], &i); + if (( user_requested_db_max_tabs = atoi(arg) ) < 0) { + erts_fprintf(stderr, "bad maximum number of ets tables %s\n", arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, + ("using maximum number of ets tables %d\n", + user_requested_db_max_tabs)); } - VERBOSE(DEBUG_SYSTEM, - ("using maximum number of ets tables %d\n", - user_requested_db_max_tabs)); break; case 'i': @@ -1112,7 +1127,7 @@ erl_start(int argc, char **argv) char *sub_param = argv[i]+2; if (has_prefix("bt", sub_param)) { arg = get_arg(sub_param+2, argv[i+1], &i); - res = erts_init_scheduler_bind_type(arg); + res = erts_init_scheduler_bind_type_string(arg); if (res != ERTS_INIT_SCHED_BIND_TYPE_SUCCESS) { switch (res) { case ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED: @@ -1137,7 +1152,7 @@ erl_start(int argc, char **argv) } else if (has_prefix("ct", sub_param)) { arg = get_arg(sub_param+2, argv[i+1], &i); - res = erts_init_cpu_topology(arg); + res = erts_init_cpu_topology_string(arg); if (res != ERTS_INIT_CPU_TOPOLOGY_OK) { switch (res) { case ERTS_INIT_CPU_TOPOLOGY_INVALID_ID: @@ -1348,6 +1363,26 @@ erl_start(int argc, char **argv) } break; + case 'z': { + char *sub_param = argv[i]+2; + int new_limit; + + if (has_prefix("dbbl", sub_param)) { + arg = get_arg(sub_param+4, argv[i+1], &i); + new_limit = atoi(arg); + if (new_limit < 1 || INT_MAX/1024 < new_limit) { + erts_fprintf(stderr, "Invalid dbbl limit: %d\n", new_limit); + erts_usage(); + } else { + erts_dist_buf_busy_limit = new_limit*1024; + } + } else { + erts_fprintf(stderr, "bad -z option %s\n", argv[i]); + erts_usage(); + } + break; + } + default: erts_fprintf(stderr, "%s unknown flag %s\n", argv[0], argv[i]); erts_usage(); @@ -1388,7 +1423,7 @@ erl_start(int argc, char **argv) boot_argc = argc - i; /* Number of arguments to init */ boot_argv = &argv[i]; - erl_init(); + erl_init(ncpu); init_shared_memory(boot_argc, boot_argv); load_preloaded(); diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index d6138fa4e4..04c7dbd2ec 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -128,8 +128,8 @@ static erts_lc_lock_order_t erts_lock_order[] = { { "removed_fd_pre_alloc_lock", NULL }, { "state_prealloc", NULL }, { "schdlr_sspnd", NULL }, - { "cpu_bind", NULL }, { "run_queue", "address" }, + { "cpu_info", NULL }, { "pollset", "address" }, #ifdef __WIN32__ { "pollwaiter", "address" }, diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 1dd9c8bd4a..a680097c2d 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -99,6 +99,16 @@ static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp) return hp; } +#if SIZEOF_LONG != ERTS_SIZEOF_ETERM +static ERTS_INLINE void ensure_heap(ErlNifEnv* env, unsigned may_need) +{ + if (env->hp + may_need > env->hp_end) { + alloc_heap_heavy(env, may_need, env->hp); + env->hp -= may_need; + } +} +#endif + void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif) { env->mod_nif = mod_nif; @@ -730,9 +740,8 @@ int enif_get_long(ErlNifEnv* env, Eterm term, long* ip) { #if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Sint(term, ip); -#elif SIZEOF_INT == ERTS_SIZEOF_ETERM - Sint i; - return term_to_Sint(term, &i) ? (*ip = (long) i, 1) : 0; +#elif SIZEOF_LONG == 8 + return term_to_Sint64(term, ip); #else # error Unknown long word size #endif @@ -742,9 +751,8 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip) { #if SIZEOF_LONG == ERTS_SIZEOF_ETERM return term_to_Uint(term, ip); -#elif SIZEOF_INT == ERTS_SIZEOF_ETERM - Uint u; - return term_to_Uint(term, &u) ? (*ip = (unsigned long) u, 1) : 0; +#elif SIZEOF_LONG == 8 + return term_to_Uint64(term, ip); #else # error Unknown long word size #endif @@ -821,12 +829,22 @@ ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i) ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i) { +#if SIZEOF_LONG == ERTS_SIZEOF_ETERM return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2)); +#elif SIZEOF_LONG == 8 + ensure_heap(env,3); + return erts_sint64_to_big(i, &env->hp); +#endif } ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i) { +#if SIZEOF_LONG == ERTS_SIZEOF_ETERM return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2)); +#elif SIZEOF_LONG == 8 + ensure_heap(env,3); + return erts_uint64_to_big(i, &env->hp); +#endif } #if HAVE_INT64 && SIZEOF_LONG != 8 diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index d0b08bf72e..8cdda395df 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -107,7 +107,7 @@ dist_table_alloc(void *dep_tmpl) dep->nlinks = NULL; dep->monitors = NULL; - erts_smp_spinlock_init_x(&dep->qlock, "dist_entry_out_queue", chnl_nr); + erts_smp_mtx_init_x(&dep->qlock, "dist_entry_out_queue", chnl_nr); dep->qflgs = 0; dep->qsize = 0; dep->out_queue.first = NULL; @@ -172,7 +172,7 @@ dist_table_free(void *vdep) ASSERT(!dep->cache); erts_smp_rwmtx_destroy(&dep->rwmtx); erts_smp_mtx_destroy(&dep->lnk_mtx); - erts_smp_spinlock_destroy(&dep->qlock); + erts_smp_mtx_destroy(&dep->qlock); #ifdef DEBUG sys_memset(vdep, 0x77, sizeof(DistEntry)); @@ -755,9 +755,9 @@ void erts_init_node_tables(void) erts_this_dist_entry->nlinks = NULL; erts_this_dist_entry->monitors = NULL; - erts_smp_spinlock_init_x(&erts_this_dist_entry->qlock, - "dist_entry_out_queue", - make_small(ERST_INTERNAL_CHANNEL_NO)); + erts_smp_mtx_init_x(&erts_this_dist_entry->qlock, + "dist_entry_out_queue", + make_small(ERST_INTERNAL_CHANNEL_NO)); erts_this_dist_entry->qflgs = 0; erts_this_dist_entry->qsize = 0; erts_this_dist_entry->out_queue.first = NULL; diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h index eb759b87e9..b0a63ae035 100644 --- a/erts/emulator/beam/erl_node_tables.h +++ b/erts/emulator/beam/erl_node_tables.h @@ -131,7 +131,7 @@ typedef struct dist_entry_ { ErtsLink *nlinks; /* Link tree with subtrees */ ErtsMonitor *monitors; /* Monitor tree */ - erts_smp_spinlock_t qlock; /* Protects qflgs and out_queue */ + erts_smp_mtx_t qlock; /* Protects qflgs and out_queue */ Uint32 qflgs; Sint qsize; ErtsDistOutputQueue out_queue; diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 901167a315..fc950af8ce 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -24,7 +24,6 @@ #endif #include <stddef.h> /* offsetof() */ -#include <ctype.h> #include "sys.h" #include "erl_vm.h" #include "global.h" @@ -39,6 +38,7 @@ #include "erl_threads.h" #include "erl_binary.h" #include "beam_bp.h" +#include "erl_cpu_topology.h" #define ERTS_RUNQ_CHECK_BALANCE_REDS_PER_SCHED (2000*CONTEXT_REDS) #define ERTS_RUNQ_CALL_CHECK_BALANCE_REDS \ @@ -63,8 +63,6 @@ #define ERTS_WAKEUP_OTHER_DEC 10 #define ERTS_WAKEUP_OTHER_FIXED_INC (CONTEXT_REDS/10) -#define ERTS_MAX_CPU_TOPOLOGY_ID ((int) 0xffff) - #if 0 || defined(DEBUG) #define ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA #endif @@ -119,10 +117,6 @@ Uint erts_process_tab_index_mask; static int wakeup_other_limit; -#ifdef ERTS_SMP -Uint erts_max_main_threads; -#endif - int erts_sched_thread_suggested_stack_size = -1; #ifdef ERTS_ENABLE_LOCK_CHECK @@ -195,48 +189,6 @@ do { \ #endif -/* - * Cpu topology hierarchy. - */ -#define ERTS_TOPOLOGY_NODE 0 -#define ERTS_TOPOLOGY_PROCESSOR 1 -#define ERTS_TOPOLOGY_PROCESSOR_NODE 2 -#define ERTS_TOPOLOGY_CORE 3 -#define ERTS_TOPOLOGY_THREAD 4 -#define ERTS_TOPOLOGY_LOGICAL 5 - -#define ERTS_TOPOLOGY_MAX_DEPTH 6 - -typedef struct { - int bind_id; - int bound_id; -} ErtsCpuBindData; - -static ErtsCpuBindData *scheduler2cpu_map; -erts_smp_rwmtx_t erts_cpu_bind_rwmtx; - -typedef enum { - ERTS_CPU_BIND_UNDEFINED, - ERTS_CPU_BIND_SPREAD, - ERTS_CPU_BIND_PROCESSOR_SPREAD, - ERTS_CPU_BIND_THREAD_SPREAD, - ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD, - ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD, - ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD, - ERTS_CPU_BIND_NO_SPREAD, - ERTS_CPU_BIND_NONE -} ErtsCpuBindOrder; - -#define ERTS_CPU_BIND_DEFAULT_BIND \ - ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD - -ErtsCpuBindOrder cpu_bind_order; - -static erts_cpu_topology_t *user_cpudata; -static int user_cpudata_size; -static erts_cpu_topology_t *system_cpudata; -static int system_cpudata_size; - erts_sched_stat_t erts_sched_stat; ErtsRunQueue *erts_common_run_queue; @@ -259,11 +211,6 @@ ErtsSchedulerData *erts_scheduler_data; ErtsAlignedRunQueue *erts_aligned_run_queues; Uint erts_no_run_queues; -typedef union { - ErtsSchedulerData esd; - char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))]; -} ErtsAlignedSchedulerData; - ErtsAlignedSchedulerData *erts_aligned_scheduler_data; #ifdef ERTS_SMP @@ -334,12 +281,6 @@ ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(proclist, 200, ERTS_ALC_T_PROC_LIST) -#define ERTS_RUNQ_IX(IX) \ - (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues), \ - &erts_aligned_run_queues[(IX)].runq) -#define ERTS_SCHEDULER_IX(IX) \ - (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \ - &erts_aligned_scheduler_data[(IX)].esd) #define ERTS_SCHED_SLEEP_INFO_IX(IX) \ (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \ &aligned_sched_sleep_info[(IX)].ssi) @@ -398,22 +339,8 @@ static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, #ifdef ERTS_SMP static void handle_pending_exiters(ErtsProcList *); -static void cpu_bind_order_sort(erts_cpu_topology_t *cpudata, - int size, - ErtsCpuBindOrder bind_order, - int mk_seq); -static void signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size); - #endif -static int reader_group_lookup(int logical); -static void create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, - int *cpudata_size); -static void destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata); - -static void early_cpu_bind_init(void); -static void late_cpu_bind_init(void); - #if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK) int erts_smp_lc_runq_is_locked(ErtsRunQueue *runq) @@ -469,13 +396,13 @@ erts_pre_init_process(void) /* initialize the scheduler */ void -erts_init_process(void) +erts_init_process(int ncpu) { Uint proc_bits = ERTS_PROC_BITS; #ifdef ERTS_SMP erts_disable_proc_not_running_opt = 0; - erts_init_proc_lock(); + erts_init_proc_lock(ncpu); #endif init_proclist_alloc(); @@ -1060,6 +987,8 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) sys_poll_aux_work: + ASSERT(!erts_port_task_have_outstanding_io_tasks()); + erl_sys_schedule(1); /* Might give us something to do */ dt = do_time_read_and_reset(); @@ -1155,6 +1084,8 @@ scheduler_wait(long *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) erts_smp_runq_unlock(rq); + ASSERT(!erts_port_task_have_outstanding_io_tasks()); + erl_sys_schedule(0); dt = do_time_read_and_reset(); @@ -1242,7 +1173,7 @@ wake_scheduler(ErtsRunQueue *rq, int incq, int one) do { ErtsSchedulerSleepInfo *wake_ssi = ssi; ssi = ssi->next; - erts_sched_finish_poke(ssi, ssi_flags_set_wake(wake_ssi)); + erts_sched_finish_poke(wake_ssi, ssi_flags_set_wake(wake_ssi)); } while (ssi); } } @@ -1335,6 +1266,31 @@ erts_smp_notify_inc_runq(ErtsRunQueue *runq) smp_notify_inc_runq(runq); } +void +erts_sched_notify_check_cpu_bind(void) +{ +#ifdef ERTS_SMP + int ix; + if (erts_common_run_queue) { + for (ix = 0; ix < erts_no_schedulers; ix++) + erts_smp_atomic_set(&ERTS_SCHEDULER_IX(ix)->chk_cpu_bind, 1); + wake_all_schedulers(); + } + else { + for (ix = 0; ix < erts_no_run_queues; ix++) { + ErtsRunQueue *rq = ERTS_RUNQ_IX(ix); + erts_smp_runq_lock(rq); + rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND; + erts_smp_runq_unlock(rq); + wake_scheduler(rq, 0, 1); + }; + } +#else + erts_sched_check_cpu_bind(erts_get_scheduler_data()); +#endif +} + + #ifdef ERTS_SMP ErtsRunQueue * @@ -1886,6 +1842,9 @@ do { \ static void check_balance(ErtsRunQueue *c_rq) { +#if ERTS_MAX_PROCESSES >= (1 << 27) +# error check_balance() assumes ERTS_MAX_PROCESS < (1 << 27) +#endif ErtsRunQueueBalance avg = {0}; Sint64 scheds_reds, full_scheds_reds; int forced, active, current_active, oowc, half_full_scheds, full_scheds, @@ -2009,12 +1968,14 @@ check_balance(ErtsRunQueue *c_rq) run_queue_info[qix].prio[pix].avail = 0; } else { - int xreds = 0; - int procreds = treds; - procreds -= run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].reds; + Sint64 xreds = 0; + Sint64 procreds = treds; + procreds -= + ((Sint64) + run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].reds); for (pix = 0; pix < ERTS_NO_PROC_PRIO_LEVELS; pix++) { - int av; + Sint64 av; if (xreds == 0) av = 100; @@ -2025,9 +1986,10 @@ check_balance(ErtsRunQueue *c_rq) if (av == 0) av = 1; } - run_queue_info[qix].prio[pix].avail = av; + run_queue_info[qix].prio[pix].avail = (int) av; + ASSERT(run_queue_info[qix].prio[pix].avail >= 0); if (pix < PRIORITY_NORMAL) /* ie., max or high */ - xreds += run_queue_info[qix].prio[pix].reds; + xreds += (Sint64) run_queue_info[qix].prio[pix].reds; } run_queue_info[qix].prio[ERTS_PORT_PRIO_LEVEL].avail = 100; } @@ -2132,7 +2094,8 @@ check_balance(ErtsRunQueue *c_rq) if (max_len != 0) { int avail = avg.prio[pix].avail; if (avail != 0) { - max_len = ((100*max_len - 1) / avail) + 1; + max_len = (int) ((100*((Sint64) max_len) - 1) + / ((Sint64) avail)) + 1; avg.prio[pix].max_len = max_len; ASSERT(max_len >= 0); } @@ -2149,9 +2112,10 @@ check_balance(ErtsRunQueue *c_rq) || run_queue_info[qix].prio[pix].avail == 0) limit = 0; else - limit = (((avg.prio[pix].max_len - * run_queue_info[qix].prio[pix].avail) - 1) - / 100 + 1); + limit = (int) (((((Sint64) avg.prio[pix].max_len) + * ((Sint64) run_queue_info[qix].prio[pix].avail)) + - 1) + / 100 + 1); run_queue_info[qix].prio[pix].migration_limit = limit; } } @@ -2379,7 +2343,6 @@ erts_debug_nbalance(void) void erts_early_init_scheduling(void) { - early_cpu_bind_init(); wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM; } @@ -2528,9 +2491,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) aligned_sched_sleep_info = erts_alloc(ERTS_ALC_T_SCHDLR_SLP_INFO, (sizeof(ErtsAlignedSchedulerSleepInfo) *(n+1))); - if ((((Uint) aligned_sched_sleep_info) & ERTS_CACHE_LINE_MASK) == 0) + if ((((UWord) aligned_sched_sleep_info) & ERTS_CACHE_LINE_MASK) == 0) aligned_sched_sleep_info = ((ErtsAlignedSchedulerSleepInfo *) - ((((Uint) aligned_sched_sleep_info) + ((((UWord) aligned_sched_sleep_info) & ~ERTS_CACHE_LINE_MASK) + ERTS_CACHE_LINE_SIZE)); for (ix = 0; ix < n; ix++) { @@ -2656,8 +2619,6 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) /* init port tasks */ erts_port_task_init(); - - late_cpu_bind_init(); } ErtsRunQueue * @@ -2883,12 +2844,10 @@ suspend_scheduler(ErtsSchedulerData *esdp) long flgs; int changing; long no = (long) esdp->no; - ErtsRunQueue *rq = esdp->run_queue; ErtsSchedulerSleepInfo *ssi = esdp->ssi; long active_schedulers; int curr_online = 1; int wake = 0; - int reset_read_group = 0; #if defined(ERTS_SCHED_NEED_NONBLOCKABLE_AUX_WORK) \ || defined(ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK) long aux_work; @@ -2909,20 +2868,7 @@ suspend_scheduler(ErtsSchedulerData *esdp) erts_smp_runq_unlock(esdp->run_queue); - /* Unbind from cpu */ - erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); - if (scheduler2cpu_map[esdp->no].bound_id >= 0 - && erts_unbind_from_cpu(erts_cpuinfo) == 0) { - esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1; - reset_read_group = 1; - } - erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); - - if (reset_read_group) - erts_smp_rwmtx_set_reader_group(0); - - if (esdp->no <= erts_max_main_threads) - erts_thr_set_main_status(0, 0); + erts_sched_check_cpu_bind_prep_suspend(esdp); if (erts_system_profile_flags.scheduler) profile_scheduler(make_small(esdp->no), am_inactive); @@ -3056,17 +3002,10 @@ suspend_scheduler(ErtsSchedulerData *esdp) if (erts_system_profile_flags.scheduler) profile_scheduler(make_small(esdp->no), am_active); - if (esdp->no <= erts_max_main_threads) - erts_thr_set_main_status(1, (int) esdp->no); - erts_smp_runq_lock(esdp->run_queue); non_empty_runq(esdp->run_queue); - /* Make sure we check if we should bind to a cpu or not... */ - if (rq->flags & ERTS_RUNQ_FLG_SHARED_RUNQ) - erts_smp_atomic_set(&esdp->chk_cpu_bind, 1); - else - rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND; + erts_sched_check_cpu_bind_post_suspend(esdp); } #define ERTS_RUNQ_RESET_SUSPEND_INFO(RQ, DBG_ID) \ @@ -3583,15 +3522,7 @@ sched_thread_func(void *vesdp) erts_tsd_set(sched_data_key, vesdp); #ifdef ERTS_SMP - if (no <= erts_max_main_threads) { - erts_thr_set_main_status(1, (int) no); - if (erts_reader_groups) { - int rg = (int) no; - if (rg > erts_reader_groups) - rg = (((int) no) - 1) % erts_reader_groups + 1; - erts_smp_rwmtx_set_reader_group(rg); - } - } + erts_sched_init_check_cpu_bind((ErtsSchedulerData *) vesdp); erts_proc_lock_prepare_proc_lock_waiter(); ERTS_SCHED_SLEEP_INFO_IX(no - 1)->event = erts_tse_fetch(); @@ -3693,1907 +3624,6 @@ erts_start_schedulers(void) #endif /* ERTS_SMP */ -static int -int_cmp(const void *vx, const void *vy) -{ - return *((int *) vx) - *((int *) vy); -} - -static int -cpu_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->core != y->core) - return x->core - y->core; - if (x->processor_node != y->processor_node) - return x->processor_node - y->processor_node; - if (x->processor != y->processor) - return x->processor - y->processor; - if (x->node != y->node) - return x->node - y->node; - return 0; -} - -static int -cpu_processor_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->processor_node != y->processor_node) - return x->processor_node - y->processor_node; - if (x->core != y->core) - return x->core - y->core; - if (x->node != y->node) - return x->node - y->node; - if (x->processor != y->processor) - return x->processor - y->processor; - return 0; -} - -static int -cpu_thread_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->node != y->node) - return x->node - y->node; - if (x->processor != y->processor) - return x->processor - y->processor; - if (x->processor_node != y->processor_node) - return x->processor_node - y->processor_node; - if (x->core != y->core) - return x->core - y->core; - return 0; -} - -static int -cpu_thread_no_node_processor_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->node != y->node) - return x->node - y->node; - if (x->core != y->core) - return x->core - y->core; - if (x->processor != y->processor) - return x->processor - y->processor; - return 0; -} - -static int -cpu_no_node_processor_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->node != y->node) - return x->node - y->node; - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->core != y->core) - return x->core - y->core; - if (x->processor != y->processor) - return x->processor - y->processor; - return 0; -} - -static int -cpu_no_node_thread_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->node != y->node) - return x->node - y->node; - if (x->thread != y->thread) - return x->thread - y->thread; - if (x->processor != y->processor) - return x->processor - y->processor; - if (x->core != y->core) - return x->core - y->core; - return 0; -} - -static int -cpu_no_spread_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->node != y->node) - return x->node - y->node; - if (x->processor != y->processor) - return x->processor - y->processor; - if (x->processor_node != y->processor_node) - return x->processor_node - y->processor_node; - if (x->core != y->core) - return x->core - y->core; - if (x->thread != y->thread) - return x->thread - y->thread; - return 0; -} - -static ERTS_INLINE void -make_cpudata_id_seq(erts_cpu_topology_t *cpudata, int size, int no_node) -{ - int ix; - int node = -1; - int processor = -1; - int processor_node = -1; - int processor_node_node = -1; - int core = -1; - int thread = -1; - int old_node = -1; - int old_processor = -1; - int old_processor_node = -1; - int old_core = -1; - int old_thread = -1; - - for (ix = 0; ix < size; ix++) { - if (!no_node || cpudata[ix].node >= 0) { - if (old_node == cpudata[ix].node) - cpudata[ix].node = node; - else { - old_node = cpudata[ix].node; - old_processor = processor = -1; - if (!no_node) - old_processor_node = processor_node = -1; - old_core = core = -1; - old_thread = thread = -1; - if (no_node || cpudata[ix].node >= 0) - cpudata[ix].node = ++node; - } - } - if (old_processor == cpudata[ix].processor) - cpudata[ix].processor = processor; - else { - old_processor = cpudata[ix].processor; - if (!no_node) - processor_node_node = old_processor_node = processor_node = -1; - old_core = core = -1; - old_thread = thread = -1; - cpudata[ix].processor = ++processor; - } - if (no_node && cpudata[ix].processor_node < 0) - old_processor_node = -1; - else { - if (old_processor_node == cpudata[ix].processor_node) { - if (no_node) - cpudata[ix].node = cpudata[ix].processor_node = node; - else { - if (processor_node_node >= 0) - cpudata[ix].node = processor_node_node; - cpudata[ix].processor_node = processor_node; - } - } - else { - old_processor_node = cpudata[ix].processor_node; - old_core = core = -1; - old_thread = thread = -1; - if (no_node) - cpudata[ix].node = cpudata[ix].processor_node = ++node; - else { - cpudata[ix].node = processor_node_node = ++node; - cpudata[ix].processor_node = ++processor_node; - } - } - } - if (!no_node && cpudata[ix].processor_node < 0) - cpudata[ix].processor_node = 0; - if (old_core == cpudata[ix].core) - cpudata[ix].core = core; - else { - old_core = cpudata[ix].core; - old_thread = thread = -1; - cpudata[ix].core = ++core; - } - if (old_thread == cpudata[ix].thread) - cpudata[ix].thread = thread; - else - old_thread = cpudata[ix].thread = ++thread; - } -} - -static void -cpu_bind_order_sort(erts_cpu_topology_t *cpudata, - int size, - ErtsCpuBindOrder bind_order, - int mk_seq) -{ - if (size > 1) { - int no_node = 0; - int (*cmp_func)(const void *, const void *); - switch (bind_order) { - case ERTS_CPU_BIND_SPREAD: - cmp_func = cpu_spread_order_cmp; - break; - case ERTS_CPU_BIND_PROCESSOR_SPREAD: - cmp_func = cpu_processor_spread_order_cmp; - break; - case ERTS_CPU_BIND_THREAD_SPREAD: - cmp_func = cpu_thread_spread_order_cmp; - break; - case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: - no_node = 1; - cmp_func = cpu_thread_no_node_processor_spread_order_cmp; - break; - case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: - no_node = 1; - cmp_func = cpu_no_node_processor_spread_order_cmp; - break; - case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: - no_node = 1; - cmp_func = cpu_no_node_thread_spread_order_cmp; - break; - case ERTS_CPU_BIND_NO_SPREAD: - cmp_func = cpu_no_spread_order_cmp; - break; - default: - cmp_func = NULL; - erl_exit(ERTS_ABORT_EXIT, - "Bad cpu bind type: %d\n", - (int) cpu_bind_order); - break; - } - - if (mk_seq) - make_cpudata_id_seq(cpudata, size, no_node); - - qsort(cpudata, size, sizeof(erts_cpu_topology_t), cmp_func); - } -} - -static int -processor_order_cmp(const void *vx, const void *vy) -{ - erts_cpu_topology_t *x = (erts_cpu_topology_t *) vx; - erts_cpu_topology_t *y = (erts_cpu_topology_t *) vy; - - if (x->processor != y->processor) - return x->processor - y->processor; - if (x->node != y->node) - return x->node - y->node; - if (x->processor_node != y->processor_node) - return x->processor_node - y->processor_node; - if (x->core != y->core) - return x->core - y->core; - if (x->thread != y->thread) - return x->thread - y->thread; - return 0; -} - -static void -check_cpu_bind(ErtsSchedulerData *esdp) -{ - int rg = 0; - int res; - int cpu_id; - erts_smp_runq_unlock(esdp->run_queue); - erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); - cpu_id = scheduler2cpu_map[esdp->no].bind_id; - if (cpu_id >= 0 && cpu_id != scheduler2cpu_map[esdp->no].bound_id) { - res = erts_bind_to_cpu(erts_cpuinfo, cpu_id); - if (res == 0) - esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = cpu_id; - else { - erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); - erts_dsprintf(dsbufp, "Scheduler %d failed to bind to cpu %d: %s\n", - (int) esdp->no, cpu_id, erl_errno_id(-res)); - erts_send_error_to_logger_nogl(dsbufp); - if (scheduler2cpu_map[esdp->no].bound_id >= 0) - goto unbind; - } - } - else if (cpu_id < 0) { - unbind: - /* Get rid of old binding */ - res = erts_unbind_from_cpu(erts_cpuinfo); - if (res == 0) - esdp->cpu_id = scheduler2cpu_map[esdp->no].bound_id = -1; - else if (res != -ENOTSUP) { - erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); - erts_dsprintf(dsbufp, "Scheduler %d failed to unbind from cpu %d: %s\n", - (int) esdp->no, cpu_id, erl_errno_id(-res)); - erts_send_error_to_logger_nogl(dsbufp); - } - } - if (erts_reader_groups) { - if (esdp->cpu_id >= 0) - rg = reader_group_lookup(esdp->cpu_id); - else - rg = (((int) esdp->no) - 1) % erts_reader_groups + 1; - } - erts_smp_runq_lock(esdp->run_queue); -#ifdef ERTS_SMP - if (erts_common_run_queue) - erts_smp_atomic_set(&esdp->chk_cpu_bind, 0); - else { - esdp->run_queue->flags &= ~ERTS_RUNQ_FLG_CHK_CPU_BIND; - } -#endif - erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); - - if (erts_reader_groups) - erts_smp_rwmtx_set_reader_group(rg); -} - -static void -signal_schedulers_bind_change(erts_cpu_topology_t *cpudata, int size) -{ - int s_ix = 1; - int cpu_ix; - - if (cpu_bind_order != ERTS_CPU_BIND_NONE && size) { - - cpu_bind_order_sort(cpudata, size, cpu_bind_order, 1); - - for (cpu_ix = 0; cpu_ix < size && cpu_ix < erts_no_schedulers; cpu_ix++) - if (erts_is_cpu_available(erts_cpuinfo, cpudata[cpu_ix].logical)) - scheduler2cpu_map[s_ix++].bind_id = cpudata[cpu_ix].logical; - } - - if (s_ix <= erts_no_schedulers) - for (; s_ix <= erts_no_schedulers; s_ix++) - scheduler2cpu_map[s_ix].bind_id = -1; - -#ifdef ERTS_SMP - if (erts_common_run_queue) { - for (s_ix = 0; s_ix < erts_no_schedulers; s_ix++) - erts_smp_atomic_set(&ERTS_SCHEDULER_IX(s_ix)->chk_cpu_bind, 1); - wake_all_schedulers(); - } - else { - for (s_ix = 0; s_ix < erts_no_run_queues; s_ix++) { - ErtsRunQueue *rq = ERTS_RUNQ_IX(s_ix); - erts_smp_runq_lock(rq); - rq->flags |= ERTS_RUNQ_FLG_CHK_CPU_BIND; - erts_smp_runq_unlock(rq); - wake_scheduler(rq, 0, 1); - }; - } -#else - check_cpu_bind(erts_get_scheduler_data()); -#endif -} - -int -erts_init_scheduler_bind_type(char *how) -{ - if (erts_bind_to_cpu(erts_cpuinfo, -1) == -ENOTSUP) - return ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED; - - if (!system_cpudata && !user_cpudata) - return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY; - - if (sys_strcmp(how, "db") == 0) - cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; - else if (sys_strcmp(how, "s") == 0) - cpu_bind_order = ERTS_CPU_BIND_SPREAD; - else if (sys_strcmp(how, "ps") == 0) - cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; - else if (sys_strcmp(how, "ts") == 0) - cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; - else if (sys_strcmp(how, "tnnps") == 0) - cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; - else if (sys_strcmp(how, "nnps") == 0) - cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; - else if (sys_strcmp(how, "nnts") == 0) - cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; - else if (sys_strcmp(how, "ns") == 0) - cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; - else if (sys_strcmp(how, "u") == 0) - cpu_bind_order = ERTS_CPU_BIND_NONE; - else - return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE; - - return ERTS_INIT_SCHED_BIND_TYPE_SUCCESS; -} - -/* - * reader groups map - */ - -typedef struct { - int level[ERTS_TOPOLOGY_MAX_DEPTH+1]; -} erts_avail_cput; - -typedef struct { - int *map; - int size; - int groups; -} erts_reader_groups_map_test; - -typedef struct { - int id; - int sub_levels; - int reader_groups; -} erts_rg_count_t; - -typedef struct { - int logical; - int reader_group; -} erts_reader_groups_map_t; - -typedef struct { - erts_reader_groups_map_t *map; - int map_size; - int logical_processors; - int groups; -} erts_make_reader_groups_map_test; - -static int reader_groups_available_cpu_check; -static int reader_groups_logical_processors; -static int reader_groups_map_size; -static erts_reader_groups_map_t *reader_groups_map; - -#define ERTS_TOPOLOGY_RG ERTS_TOPOLOGY_MAX_DEPTH - -static void -make_reader_groups_map(erts_make_reader_groups_map_test *test); - -static Eterm -get_reader_groups_map(Process *c_p, - erts_reader_groups_map_t *map, - int map_size, - int logical_processors) -{ -#ifdef DEBUG - Eterm *endp; -#endif - Eterm res = NIL, tuple; - Eterm *hp; - int i; - - hp = HAlloc(c_p, logical_processors*(2+3)); -#ifdef DEBUG - endp = hp + logical_processors*(2+3); -#endif - for (i = map_size - 1; i >= 0; i--) { - if (map[i].logical >= 0) { - tuple = TUPLE2(hp, - make_small(map[i].logical), - make_small(map[i].reader_group)); - hp += 3; - res = CONS(hp, tuple, res); - hp += 2; - } - } - ASSERT(hp == endp); - return res; -} - -Eterm -erts_debug_reader_groups_map(Process *c_p, int groups) -{ - Eterm res; - erts_make_reader_groups_map_test test; - - test.groups = groups; - make_reader_groups_map(&test); - if (!test.map) - res = NIL; - else { - res = get_reader_groups_map(c_p, - test.map, - test.map_size, - test.logical_processors); - erts_free(ERTS_ALC_T_TMP, test.map); - } - return res; -} - - -Eterm -erts_get_reader_groups_map(Process *c_p) -{ - Eterm res; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - res = get_reader_groups_map(c_p, - reader_groups_map, - reader_groups_map_size, - reader_groups_logical_processors); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - return res; -} - -static void -make_available_cpu_topology(erts_avail_cput *no, - erts_avail_cput *avail, - erts_cpu_topology_t *cpudata, - int *size, - int test) -{ - int len = *size; - erts_cpu_topology_t last; - int a, i, j; - - no->level[ERTS_TOPOLOGY_NODE] = -1; - no->level[ERTS_TOPOLOGY_PROCESSOR] = -1; - no->level[ERTS_TOPOLOGY_PROCESSOR_NODE] = -1; - no->level[ERTS_TOPOLOGY_CORE] = -1; - no->level[ERTS_TOPOLOGY_THREAD] = -1; - no->level[ERTS_TOPOLOGY_LOGICAL] = -1; - - last.node = INT_MIN; - last.processor = INT_MIN; - last.processor_node = INT_MIN; - last.core = INT_MIN; - last.thread = INT_MIN; - last.logical = INT_MIN; - - a = 0; - - for (i = 0; i < len; i++) { - - if (!test && !erts_is_cpu_available(erts_cpuinfo, cpudata[i].logical)) - continue; - - if (last.node != cpudata[i].node) - goto node; - if (last.processor != cpudata[i].processor) - goto processor; - if (last.processor_node != cpudata[i].processor_node) - goto processor_node; - if (last.core != cpudata[i].core) - goto core; - ASSERT(last.thread != cpudata[i].thread); - goto thread; - - node: - no->level[ERTS_TOPOLOGY_NODE]++; - processor: - no->level[ERTS_TOPOLOGY_PROCESSOR]++; - processor_node: - no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++; - core: - no->level[ERTS_TOPOLOGY_CORE]++; - thread: - no->level[ERTS_TOPOLOGY_THREAD]++; - - no->level[ERTS_TOPOLOGY_LOGICAL]++; - - for (j = 0; j < ERTS_TOPOLOGY_LOGICAL; j++) - avail[a].level[j] = no->level[j]; - - avail[a].level[ERTS_TOPOLOGY_LOGICAL] = cpudata[i].logical; - avail[a].level[ERTS_TOPOLOGY_RG] = 0; - - ASSERT(last.logical != cpudata[a].logical); - - last = cpudata[i]; - a++; - } - - no->level[ERTS_TOPOLOGY_NODE]++; - no->level[ERTS_TOPOLOGY_PROCESSOR]++; - no->level[ERTS_TOPOLOGY_PROCESSOR_NODE]++; - no->level[ERTS_TOPOLOGY_CORE]++; - no->level[ERTS_TOPOLOGY_THREAD]++; - no->level[ERTS_TOPOLOGY_LOGICAL]++; - - *size = a; -} - -static int -reader_group_lookup(int logical) -{ - int start = logical % reader_groups_map_size; - int ix = start; - - do { - if (reader_groups_map[ix].logical == logical) { - ASSERT(reader_groups_map[ix].reader_group > 0); - return reader_groups_map[ix].reader_group; - } - ix++; - if (ix == reader_groups_map_size) - ix = 0; - } while (ix != start); - - erl_exit(ERTS_ABORT_EXIT, "Logical cpu id %d not found\n", logical); -} - -static void -reader_group_insert(erts_reader_groups_map_t *map, int map_size, - int logical, int reader_group) -{ - int start = logical % map_size; - int ix = start; - - do { - if (map[ix].logical < 0) { - map[ix].logical = logical; - map[ix].reader_group = reader_group; - return; - } - ix++; - if (ix == map_size) - ix = 0; - } while (ix != start); - - erl_exit(ERTS_ABORT_EXIT, "Reader groups map full\n"); -} - - -static int -sub_levels(erts_rg_count_t *rgc, int level, int aix, int avail_sz, erts_avail_cput *avail) -{ - int sub_level = level+1; - int last = -1; - rgc->sub_levels = 0; - - do { - if (last != avail[aix].level[sub_level]) { - rgc->sub_levels++; - last = avail[aix].level[sub_level]; - } - aix++; - } - while (aix < avail_sz && rgc->id == avail[aix].level[level]); - rgc->reader_groups = 0; - return aix; -} - -static int -write_reader_groups(int *rgp, erts_rg_count_t *rgcp, - int level, int a, - int avail_sz, erts_avail_cput *avail) -{ - int rg = *rgp; - int sub_level = level+1; - int sl_per_gr = rgcp->sub_levels / rgcp->reader_groups; - int xsl = rgcp->sub_levels % rgcp->reader_groups; - int sls = 0; - int last = -1; - int xsl_rg_lim = (rgcp->reader_groups - xsl) + rg + 1; - - ASSERT(level < 0 || avail[a].level[level] == rgcp->id) - - do { - if (last != avail[a].level[sub_level]) { - if (!sls) { - sls = sl_per_gr; - rg++; - if (rg >= xsl_rg_lim) - sls++; - } - last = avail[a].level[sub_level]; - sls--; - } - avail[a].level[ERTS_TOPOLOGY_RG] = rg; - a++; - } while (a < avail_sz && (level < 0 - || avail[a].level[level] == rgcp->id)); - - ASSERT(rgcp->reader_groups == rg - *rgp); - - *rgp = rg; - - return a; -} - -static int -rg_count_sub_levels_compare(const void *vx, const void *vy) -{ - erts_rg_count_t *x = (erts_rg_count_t *) vx; - erts_rg_count_t *y = (erts_rg_count_t *) vy; - if (x->sub_levels != y->sub_levels) - return y->sub_levels - x->sub_levels; - return x->id - y->id; -} - -static int -rg_count_id_compare(const void *vx, const void *vy) -{ - erts_rg_count_t *x = (erts_rg_count_t *) vx; - erts_rg_count_t *y = (erts_rg_count_t *) vy; - return x->id - y->id; -} - -static void -make_reader_groups_map(erts_make_reader_groups_map_test *test) -{ - int i, spread_level, avail_sz; - erts_avail_cput no, *avail; - erts_cpu_topology_t *cpudata; - erts_reader_groups_map_t *map; - int map_sz; - int groups = erts_reader_groups; - - if (test) { - test->map = NULL; - test->map_size = 0; - groups = test->groups; - } - - if (!groups) - return; - - if (!test) { - if (reader_groups_map) - erts_free(ERTS_ALC_T_RDR_GRPS_MAP, reader_groups_map); - - reader_groups_logical_processors = 0; - reader_groups_map_size = 0; - reader_groups_map = NULL; - } - - create_tmp_cpu_topology_copy(&cpudata, &avail_sz); - - if (!cpudata) - return; - - cpu_bind_order_sort(cpudata, - avail_sz, - ERTS_CPU_BIND_NO_SPREAD, - 1); - - avail = erts_alloc(ERTS_ALC_T_TMP, - sizeof(erts_avail_cput)*avail_sz); - - make_available_cpu_topology(&no, avail, cpudata, - &avail_sz, test != NULL); - - destroy_tmp_cpu_topology_copy(cpudata); - - map_sz = avail_sz*2+1; - - if (test) { - map = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_reader_groups_map_t) - * map_sz)); - test->map = map; - test->map_size = map_sz; - test->logical_processors = avail_sz; - } - else { - map = erts_alloc(ERTS_ALC_T_RDR_GRPS_MAP, - (sizeof(erts_reader_groups_map_t) - * map_sz)); - reader_groups_map = map; - reader_groups_logical_processors = avail_sz; - reader_groups_map_size = map_sz; - - } - - for (i = 0; i < map_sz; i++) { - map[i].logical = -1; - map[i].reader_group = 0; - } - - spread_level = ERTS_TOPOLOGY_CORE; - for (i = ERTS_TOPOLOGY_NODE; i < ERTS_TOPOLOGY_THREAD; i++) { - if (no.level[i] > groups) { - spread_level = i; - break; - } - } - - if (no.level[spread_level] <= groups) { - int a, rg, last = -1; - rg = 0; - ASSERT(spread_level == ERTS_TOPOLOGY_CORE); - for (a = 0; a < avail_sz; a++) { - if (last != avail[a].level[spread_level]) { - rg++; - last = avail[a].level[spread_level]; - } - reader_group_insert(map, - map_sz, - avail[a].level[ERTS_TOPOLOGY_LOGICAL], - rg); - } - } - else { /* groups < no.level[spread_level] */ - erts_rg_count_t *rg_count; - int a, rg, tl, toplevels; - - tl = spread_level-1; - - if (spread_level == ERTS_TOPOLOGY_NODE) - toplevels = 1; - else - toplevels = no.level[tl]; - - rg_count = erts_alloc(ERTS_ALC_T_TMP, - toplevels*sizeof(erts_rg_count_t)); - - if (toplevels == 1) { - rg_count[0].id = 0; - rg_count[0].sub_levels = no.level[spread_level]; - rg_count[0].reader_groups = groups; - } - else { - int rgs_per_tl, rgs; - rgs = groups; - rgs_per_tl = rgs / toplevels; - - a = 0; - for (i = 0; i < toplevels; i++) { - rg_count[i].id = avail[a].level[tl]; - a = sub_levels(&rg_count[i], tl, a, avail_sz, avail); - } - - qsort(rg_count, - toplevels, - sizeof(erts_rg_count_t), - rg_count_sub_levels_compare); - - for (i = 0; i < toplevels; i++) { - if (rg_count[i].sub_levels < rgs_per_tl) { - rg_count[i].reader_groups = rg_count[i].sub_levels; - rgs -= rg_count[i].sub_levels; - } - else { - rg_count[i].reader_groups = rgs_per_tl; - rgs -= rgs_per_tl; - } - } - - while (rgs > 0) { - for (i = 0; i < toplevels; i++) { - if (rg_count[i].sub_levels == rg_count[i].reader_groups) - break; - else { - rg_count[i].reader_groups++; - if (--rgs == 0) - break; - } - } - } - - qsort(rg_count, - toplevels, - sizeof(erts_rg_count_t), - rg_count_id_compare); - } - - a = i = rg = 0; - while (a < avail_sz) { - a = write_reader_groups(&rg, &rg_count[i], tl, - a, avail_sz, avail); - i++; - } - - ASSERT(groups == rg); - - for (a = 0; a < avail_sz; a++) - reader_group_insert(map, - map_sz, - avail[a].level[ERTS_TOPOLOGY_LOGICAL], - avail[a].level[ERTS_TOPOLOGY_RG]); - - erts_free(ERTS_ALC_T_TMP, rg_count); - } - - erts_free(ERTS_ALC_T_TMP, avail); -} - -/* - * CPU topology - */ - -typedef struct { - int *id; - int used; - int size; -} ErtsCpuTopIdSeq; - -typedef struct { - ErtsCpuTopIdSeq logical; - ErtsCpuTopIdSeq thread; - ErtsCpuTopIdSeq core; - ErtsCpuTopIdSeq processor_node; - ErtsCpuTopIdSeq processor; - ErtsCpuTopIdSeq node; -} ErtsCpuTopEntry; - -static void -init_cpu_top_entry(ErtsCpuTopEntry *cte) -{ - int size = 10; - cte->logical.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->logical.size = size; - cte->thread.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->thread.size = size; - cte->core.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->core.size = size; - cte->processor_node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->processor_node.size = size; - cte->processor.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->processor.size = size; - cte->node.id = erts_alloc(ERTS_ALC_T_TMP_CPU_IDS, - sizeof(int)*size); - cte->node.size = size; -} - -static void -destroy_cpu_top_entry(ErtsCpuTopEntry *cte) -{ - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->logical.id); - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->thread.id); - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->core.id); - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor_node.id); - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->processor.id); - erts_free(ERTS_ALC_T_TMP_CPU_IDS, cte->node.id); -} - -static int -get_cput_value_or_range(int *v, int *vr, char **str) -{ - long l; - char *c = *str; - errno = 0; - if (!isdigit((unsigned char)*c)) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID; - l = strtol(c, &c, 10); - if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID; - *v = (int) l; - if (*c == '-') { - c++; - if (!isdigit((unsigned char)*c)) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - l = strtol(c, &c, 10); - if (errno != 0 || l < 0 || ERTS_MAX_CPU_TOPOLOGY_ID < l) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - *vr = (int) l; - } - *str = c; - return ERTS_INIT_CPU_TOPOLOGY_OK; -} - -static int -get_cput_id_seq(ErtsCpuTopIdSeq *idseq, char **str) -{ - int ix = 0; - int need_size = 0; - char *c = *str; - - while (1) { - int res; - int val; - int nids; - int val_range = -1; - res = get_cput_value_or_range(&val, &val_range, &c); - if (res != ERTS_INIT_CPU_TOPOLOGY_OK) - return res; - if (val_range < 0 || val_range == val) - nids = 1; - else { - if (val_range > val) - nids = val_range - val + 1; - else - nids = val - val_range + 1; - } - need_size += nids; - if (need_size > idseq->size) { - idseq->size = need_size + 10; - idseq->id = erts_realloc(ERTS_ALC_T_TMP_CPU_IDS, - idseq->id, - sizeof(int)*idseq->size); - } - if (nids == 1) - idseq->id[ix++] = val; - else if (val_range > val) { - for (; val <= val_range; val++) - idseq->id[ix++] = val; - } - else { - for (; val >= val_range; val--) - idseq->id[ix++] = val; - } - if (*c != ',') - break; - c++; - } - *str = c; - idseq->used = ix; - return ERTS_INIT_CPU_TOPOLOGY_OK; -} - -static int -get_cput_entry(ErtsCpuTopEntry *cput, char **str) -{ - int h; - char *c = *str; - - cput->logical.used = 0; - cput->thread.id[0] = 0; - cput->thread.used = 1; - cput->core.id[0] = 0; - cput->core.used = 1; - cput->processor_node.id[0] = -1; - cput->processor_node.used = 1; - cput->processor.id[0] = 0; - cput->processor.used = 1; - cput->node.id[0] = -1; - cput->node.used = 1; - - h = ERTS_TOPOLOGY_MAX_DEPTH; - while (*c != ':' && *c != '\0') { - int res; - ErtsCpuTopIdSeq *idseqp; - switch (*c++) { - case 'L': - if (h <= ERTS_TOPOLOGY_LOGICAL) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->logical; - h = ERTS_TOPOLOGY_LOGICAL; - break; - case 't': - case 'T': - if (h <= ERTS_TOPOLOGY_THREAD) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->thread; - h = ERTS_TOPOLOGY_THREAD; - break; - case 'c': - case 'C': - if (h <= ERTS_TOPOLOGY_CORE) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->core; - h = ERTS_TOPOLOGY_CORE; - break; - case 'p': - case 'P': - if (h <= ERTS_TOPOLOGY_PROCESSOR) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->processor; - h = ERTS_TOPOLOGY_PROCESSOR; - break; - case 'n': - case 'N': - if (h <= ERTS_TOPOLOGY_PROCESSOR) { - do_node: - if (h <= ERTS_TOPOLOGY_NODE) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->node; - h = ERTS_TOPOLOGY_NODE; - } - else { - int p_node = 0; - char *p_chk = c; - while (*p_chk != '\0' && *p_chk != ':') { - if (*p_chk == 'p' || *p_chk == 'P') { - p_node = 1; - break; - } - p_chk++; - } - if (!p_node) - goto do_node; - if (h <= ERTS_TOPOLOGY_PROCESSOR_NODE) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY; - idseqp = &cput->processor_node; - h = ERTS_TOPOLOGY_PROCESSOR_NODE; - } - break; - default: - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE; - } - res = get_cput_id_seq(idseqp, &c); - if (res != ERTS_INIT_CPU_TOPOLOGY_OK) - return res; - } - - if (cput->logical.used < 1) - return ERTS_INIT_CPU_TOPOLOGY_MISSING_LID; - - if (*c == ':') { - c++; - } - - if (cput->thread.used != 1 - && cput->thread.used != cput->logical.used) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - if (cput->core.used != 1 - && cput->core.used != cput->logical.used) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - if (cput->processor_node.used != 1 - && cput->processor_node.used != cput->logical.used) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - if (cput->processor.used != 1 - && cput->processor.used != cput->logical.used) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - if (cput->node.used != 1 - && cput->node.used != cput->logical.used) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE; - - *str = c; - return ERTS_INIT_CPU_TOPOLOGY_OK; -} - -static int -verify_topology(erts_cpu_topology_t *cpudata, int size) -{ - if (size > 0) { - int *logical; - int node, processor, no_nodes, i; - - /* Verify logical ids */ - logical = erts_alloc(ERTS_ALC_T_TMP, sizeof(int)*size); - - for (i = 0; i < size; i++) - logical[i] = cpudata[i].logical; - - qsort(logical, size, sizeof(int), int_cmp); - for (i = 0; i < size-1; i++) { - if (logical[i] == logical[i+1]) { - erts_free(ERTS_ALC_T_TMP, logical); - return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS; - } - } - - erts_free(ERTS_ALC_T_TMP, logical); - - qsort(cpudata, size, sizeof(erts_cpu_topology_t), processor_order_cmp); - - /* Verify unique entities */ - - for (i = 1; i < size; i++) { - if (cpudata[i-1].processor == cpudata[i].processor - && cpudata[i-1].node == cpudata[i].node - && (cpudata[i-1].processor_node - == cpudata[i].processor_node) - && cpudata[i-1].core == cpudata[i].core - && cpudata[i-1].thread == cpudata[i].thread) { - return ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES; - } - } - - /* Verify numa nodes */ - node = cpudata[0].node; - processor = cpudata[0].processor; - no_nodes = cpudata[0].node < 0 && cpudata[0].processor_node < 0; - for (i = 1; i < size; i++) { - if (no_nodes) { - if (cpudata[i].node >= 0 || cpudata[i].processor_node >= 0) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; - } - else { - if (cpudata[i].processor == processor && cpudata[i].node != node) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; - node = cpudata[i].node; - processor = cpudata[i].processor; - if (node >= 0 && cpudata[i].processor_node >= 0) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; - if (node < 0 && cpudata[i].processor_node < 0) - return ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES; - } - } - } - - return ERTS_INIT_CPU_TOPOLOGY_OK; -} - -int -erts_init_cpu_topology(char *topology_str) -{ - ErtsCpuTopEntry cput; - int need_size; - char *c; - int ix; - int error = ERTS_INIT_CPU_TOPOLOGY_OK; - - if (user_cpudata) - erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); - user_cpudata_size = 10; - - user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, - (sizeof(erts_cpu_topology_t) - * user_cpudata_size)); - - init_cpu_top_entry(&cput); - - ix = 0; - need_size = 0; - - c = topology_str; - if (*c == '\0') { - error = ERTS_INIT_CPU_TOPOLOGY_MISSING; - goto fail; - } - do { - int r; - error = get_cput_entry(&cput, &c); - if (error != ERTS_INIT_CPU_TOPOLOGY_OK) - goto fail; - need_size += cput.logical.used; - if (user_cpudata_size < need_size) { - user_cpudata_size = need_size + 10; - user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA, - user_cpudata, - (sizeof(erts_cpu_topology_t) - * user_cpudata_size)); - } - - ASSERT(cput.thread.used == 1 - || cput.thread.used == cput.logical.used); - ASSERT(cput.core.used == 1 - || cput.core.used == cput.logical.used); - ASSERT(cput.processor_node.used == 1 - || cput.processor_node.used == cput.logical.used); - ASSERT(cput.processor.used == 1 - || cput.processor.used == cput.logical.used); - ASSERT(cput.node.used == 1 - || cput.node.used == cput.logical.used); - - for (r = 0; r < cput.logical.used; r++) { - user_cpudata[ix].logical = cput.logical.id[r]; - user_cpudata[ix].thread = - cput.thread.id[cput.thread.used == 1 ? 0 : r]; - user_cpudata[ix].core = - cput.core.id[cput.core.used == 1 ? 0 : r]; - user_cpudata[ix].processor_node = - cput.processor_node.id[cput.processor_node.used == 1 ? 0 : r]; - user_cpudata[ix].processor = - cput.processor.id[cput.processor.used == 1 ? 0 : r]; - user_cpudata[ix].node = - cput.node.id[cput.node.used == 1 ? 0 : r]; - ix++; - } - } while (*c != '\0'); - - if (user_cpudata_size != ix) { - user_cpudata_size = ix; - user_cpudata = erts_realloc(ERTS_ALC_T_CPUDATA, - user_cpudata, - (sizeof(erts_cpu_topology_t) - * user_cpudata_size)); - } - - error = verify_topology(user_cpudata, user_cpudata_size); - if (error == ERTS_INIT_CPU_TOPOLOGY_OK) { - destroy_cpu_top_entry(&cput); - return ERTS_INIT_CPU_TOPOLOGY_OK; - } - - fail: - if (user_cpudata) - erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); - user_cpudata_size = 0; - destroy_cpu_top_entry(&cput); - return error; -} - -#define ERTS_GET_CPU_TOPOLOGY_ERROR -1 -#define ERTS_GET_USED_CPU_TOPOLOGY 0 -#define ERTS_GET_DETECTED_CPU_TOPOLOGY 1 -#define ERTS_GET_DEFINED_CPU_TOPOLOGY 2 - -static Eterm get_cpu_topology_term(Process *c_p, int type); - -Eterm -erts_set_cpu_topology(Process *c_p, Eterm term) -{ - erts_cpu_topology_t *cpudata = NULL; - int cpudata_size = 0; - Eterm res; - - erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); - res = get_cpu_topology_term(c_p, ERTS_GET_USED_CPU_TOPOLOGY); - if (term == am_undefined) { - if (user_cpudata) - erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); - user_cpudata = NULL; - user_cpudata_size = 0; - - if (cpu_bind_order != ERTS_CPU_BIND_NONE && system_cpudata) { - cpudata_size = system_cpudata_size; - cpudata = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_cpu_topology_t) - * cpudata_size)); - - sys_memcpy((void *) cpudata, - (void *) system_cpudata, - sizeof(erts_cpu_topology_t)*cpudata_size); - } - } - else if (is_not_list(term)) { - error: - res = THE_NON_VALUE; - goto done; - } - else { - Eterm list = term; - int ix = 0; - - cpudata_size = 100; - cpudata = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_cpu_topology_t) - * cpudata_size)); - - while (is_list(list)) { - Eterm *lp = list_val(list); - Eterm cpu = CAR(lp); - Eterm* tp; - Sint id; - - if (is_not_tuple(cpu)) - goto error; - - tp = tuple_val(cpu); - - if (arityval(tp[0]) != 7 || tp[1] != am_cpu) - goto error; - - if (ix >= cpudata_size) { - cpudata_size += 100; - cpudata = erts_realloc(ERTS_ALC_T_TMP, - cpudata, - (sizeof(erts_cpu_topology_t) - * cpudata_size)); - } - - id = signed_val(tp[2]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].node = (int) id; - - id = signed_val(tp[3]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].processor = (int) id; - - id = signed_val(tp[4]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].processor_node = (int) id; - - id = signed_val(tp[5]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].core = (int) id; - - id = signed_val(tp[6]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].thread = (int) id; - - id = signed_val(tp[7]); - if (id < -1 || ERTS_MAX_CPU_TOPOLOGY_ID < id) - goto error; - cpudata[ix].logical = (int) id; - - list = CDR(lp); - ix++; - } - - if (is_not_nil(list)) - goto error; - - cpudata_size = ix; - - if (ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(cpudata, cpudata_size)) - goto error; - - if (user_cpudata_size != cpudata_size) { - if (user_cpudata) - erts_free(ERTS_ALC_T_CPUDATA, user_cpudata); - user_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, - sizeof(erts_cpu_topology_t)*cpudata_size); - user_cpudata_size = cpudata_size; - } - - sys_memcpy((void *) user_cpudata, - (void *) cpudata, - sizeof(erts_cpu_topology_t)*cpudata_size); - } - - make_reader_groups_map(NULL); - - signal_schedulers_bind_change(cpudata, cpudata_size); - - done: - erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); - - if (cpudata) - erts_free(ERTS_ALC_T_TMP, cpudata); - - return res; -} - -static Eterm -bound_schedulers_term(ErtsCpuBindOrder order) -{ - switch (order) { - case ERTS_CPU_BIND_SPREAD: { - ERTS_DECL_AM(spread); - return AM_spread; - } - case ERTS_CPU_BIND_PROCESSOR_SPREAD: { - ERTS_DECL_AM(processor_spread); - return AM_processor_spread; - } - case ERTS_CPU_BIND_THREAD_SPREAD: { - ERTS_DECL_AM(thread_spread); - return AM_thread_spread; - } - case ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD: { - ERTS_DECL_AM(thread_no_node_processor_spread); - return AM_thread_no_node_processor_spread; - } - case ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD: { - ERTS_DECL_AM(no_node_processor_spread); - return AM_no_node_processor_spread; - } - case ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD: { - ERTS_DECL_AM(no_node_thread_spread); - return AM_no_node_thread_spread; - } - case ERTS_CPU_BIND_NO_SPREAD: { - ERTS_DECL_AM(no_spread); - return AM_no_spread; - } - case ERTS_CPU_BIND_NONE: { - ERTS_DECL_AM(unbound); - return AM_unbound; - } - default: - ASSERT(0); - return THE_NON_VALUE; - } -} - -Eterm -erts_bound_schedulers_term(Process *c_p) -{ - ErtsCpuBindOrder order; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - order = cpu_bind_order; - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - return bound_schedulers_term(order); -} - -static void -create_tmp_cpu_topology_copy(erts_cpu_topology_t **cpudata, int *cpudata_size) -{ - if (user_cpudata) { - *cpudata_size = user_cpudata_size; - *cpudata = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_cpu_topology_t) - * (*cpudata_size))); - sys_memcpy((void *) *cpudata, - (void *) user_cpudata, - sizeof(erts_cpu_topology_t)*(*cpudata_size)); - } - else if (system_cpudata) { - *cpudata_size = system_cpudata_size; - *cpudata = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_cpu_topology_t) - * (*cpudata_size))); - sys_memcpy((void *) *cpudata, - (void *) system_cpudata, - sizeof(erts_cpu_topology_t)*(*cpudata_size)); - } - else { - *cpudata = NULL; - *cpudata_size = 0; - } -} - -static void -destroy_tmp_cpu_topology_copy(erts_cpu_topology_t *cpudata) -{ - if (cpudata) - erts_free(ERTS_ALC_T_TMP, cpudata); -} - -Eterm -erts_bind_schedulers(Process *c_p, Eterm how) -{ - Eterm res; - erts_cpu_topology_t *cpudata; - int cpudata_size; - ErtsCpuBindOrder old_cpu_bind_order; - - erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); - - if (erts_bind_to_cpu(erts_cpuinfo, -1) == -ENOTSUP) { - ERTS_BIF_PREP_ERROR(res, c_p, EXC_NOTSUP); - } - else { - - old_cpu_bind_order = cpu_bind_order; - - if (ERTS_IS_ATOM_STR("default_bind", how)) - cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; - else if (ERTS_IS_ATOM_STR("spread", how)) - cpu_bind_order = ERTS_CPU_BIND_SPREAD; - else if (ERTS_IS_ATOM_STR("processor_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("thread_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; - else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; - else if (ERTS_IS_ATOM_STR("no_spread", how)) - cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; - else if (ERTS_IS_ATOM_STR("unbound", how)) - cpu_bind_order = ERTS_CPU_BIND_NONE; - else { - cpu_bind_order = old_cpu_bind_order; - ERTS_BIF_PREP_ERROR(res, c_p, BADARG); - goto done; - } - - create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - - if (!cpudata) { - cpu_bind_order = old_cpu_bind_order; - ERTS_BIF_PREP_ERROR(res, c_p, BADARG); - goto done; - } - - signal_schedulers_bind_change(cpudata, cpudata_size); - - destroy_tmp_cpu_topology_copy(cpudata); - - res = bound_schedulers_term(old_cpu_bind_order); - } - - done: - - erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); - - return res; -} - -Eterm -erts_fake_scheduler_bindings(Process *p, Eterm how) -{ - ErtsCpuBindOrder fake_cpu_bind_order; - erts_cpu_topology_t *cpudata; - int cpudata_size; - Eterm res; - - if (ERTS_IS_ATOM_STR("default_bind", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND; - else if (ERTS_IS_ATOM_STR("spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_SPREAD; - else if (ERTS_IS_ATOM_STR("processor_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("thread_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD; - else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD; - else if (ERTS_IS_ATOM_STR("no_node_thread_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD; - else if (ERTS_IS_ATOM_STR("no_spread", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_NO_SPREAD; - else if (ERTS_IS_ATOM_STR("unbound", how)) - fake_cpu_bind_order = ERTS_CPU_BIND_NONE; - else { - ERTS_BIF_PREP_ERROR(res, p, BADARG); - return res; - } - - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - - if (!cpudata || fake_cpu_bind_order == ERTS_CPU_BIND_NONE) - ERTS_BIF_PREP_RET(res, am_false); - else { - int i; - Eterm *hp; - - cpu_bind_order_sort(cpudata, cpudata_size, fake_cpu_bind_order, 1); - -#ifdef ERTS_FAKE_SCHED_BIND_PRINT_SORTED_CPU_DATA - - erts_fprintf(stderr, "node: "); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].node); - erts_fprintf(stderr, "\n"); - erts_fprintf(stderr, "processor: "); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].processor); - erts_fprintf(stderr, "\n"); - if (fake_cpu_bind_order != ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD - && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD - && fake_cpu_bind_order != ERTS_CPU_BIND_NO_NODE_THREAD_SPREAD) { - erts_fprintf(stderr, "processor_node:"); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].processor_node); - erts_fprintf(stderr, "\n"); - } - erts_fprintf(stderr, "core: "); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].core); - erts_fprintf(stderr, "\n"); - erts_fprintf(stderr, "thread: "); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].thread); - erts_fprintf(stderr, "\n"); - erts_fprintf(stderr, "logical: "); - for (i = 0; i < cpudata_size; i++) - erts_fprintf(stderr, " %2d", cpudata[i].logical); - erts_fprintf(stderr, "\n"); -#endif - - hp = HAlloc(p, cpudata_size+1); - ERTS_BIF_PREP_RET(res, make_tuple(hp)); - *hp++ = make_arityval((Uint) cpudata_size); - for (i = 0; i < cpudata_size; i++) - *hp++ = make_small((Uint) cpudata[i].logical); - } - - destroy_tmp_cpu_topology_copy(cpudata); - - return res; -} - -Eterm -erts_get_schedulers_binds(Process *c_p) -{ - int ix; - ERTS_DECL_AM(unbound); - Eterm *hp = HAlloc(c_p, erts_no_schedulers+1); - Eterm res = make_tuple(hp); - - *(hp++) = make_arityval(erts_no_schedulers); - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - for (ix = 1; ix <= erts_no_schedulers; ix++) - *(hp++) = (scheduler2cpu_map[ix].bound_id >= 0 - ? make_small(scheduler2cpu_map[ix].bound_id) - : AM_unbound); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - return res; -} - -static Eterm -bld_topology_term(Eterm **hpp, - Uint *hszp, - erts_cpu_topology_t *cpudata, - int size) -{ - Eterm res = NIL; - int i; - - if (size == 0) - return am_undefined; - - for (i = size-1; i >= 0; i--) { - res = erts_bld_cons(hpp, - hszp, - erts_bld_tuple(hpp, - hszp, - 7, - am_cpu, - make_small(cpudata[i].node), - make_small(cpudata[i].processor), - make_small(cpudata[i].processor_node), - make_small(cpudata[i].core), - make_small(cpudata[i].thread), - make_small(cpudata[i].logical)), - res); - } - return res; -} - -static Eterm -get_cpu_topology_term(Process *c_p, int type) -{ -#ifdef DEBUG - Eterm *hp_end; -#endif - Eterm *hp; - Uint hsz; - Eterm res = THE_NON_VALUE; - erts_cpu_topology_t *cpudata = NULL; - int size = 0; - - switch (type) { - case ERTS_GET_USED_CPU_TOPOLOGY: - if (user_cpudata) - goto defined; - else - goto detected; - case ERTS_GET_DETECTED_CPU_TOPOLOGY: - detected: - if (!system_cpudata) - res = am_undefined; - else { - size = system_cpudata_size; - cpudata = erts_alloc(ERTS_ALC_T_TMP, - (sizeof(erts_cpu_topology_t) - * size)); - sys_memcpy((void *) cpudata, - (void *) system_cpudata, - sizeof(erts_cpu_topology_t)*size); - } - break; - case ERTS_GET_DEFINED_CPU_TOPOLOGY: - defined: - if (!user_cpudata) - res = am_undefined; - else { - size = user_cpudata_size; - cpudata = user_cpudata; - } - break; - default: - erl_exit(ERTS_ABORT_EXIT, "Bad cpu topology type: %d\n", type); - break; - } - - if (res == am_undefined) { - ASSERT(!cpudata); - return res; - } - - hsz = 0; - - bld_topology_term(NULL, &hsz, - cpudata, size); - - hp = HAlloc(c_p, hsz); - -#ifdef DEBUG - hp_end = hp + hsz; -#endif - - res = bld_topology_term(&hp, NULL, - cpudata, size); - - ASSERT(hp_end == hp); - - if (cpudata && cpudata != system_cpudata && cpudata != user_cpudata) - erts_free(ERTS_ALC_T_TMP, cpudata); - - return res; -} - -Eterm -erts_get_cpu_topology_term(Process *c_p, Eterm which) -{ - Eterm res; - int type; - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - if (ERTS_IS_ATOM_STR("used", which)) - type = ERTS_GET_USED_CPU_TOPOLOGY; - else if (ERTS_IS_ATOM_STR("detected", which)) - type = ERTS_GET_DETECTED_CPU_TOPOLOGY; - else if (ERTS_IS_ATOM_STR("defined", which)) - type = ERTS_GET_DEFINED_CPU_TOPOLOGY; - else - type = ERTS_GET_CPU_TOPOLOGY_ERROR; - if (type == ERTS_GET_CPU_TOPOLOGY_ERROR) - res = THE_NON_VALUE; - else - res = get_cpu_topology_term(c_p, type); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - return res; -} - -static void -early_cpu_bind_init(void) -{ - user_cpudata = NULL; - user_cpudata_size = 0; - - system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo); - system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, - (sizeof(erts_cpu_topology_t) - * system_cpudata_size)); - - cpu_bind_order = ERTS_CPU_BIND_UNDEFINED; - - reader_groups_available_cpu_check = 1; - reader_groups_logical_processors = 0; - reader_groups_map_size = 0; - reader_groups_map = NULL; - - if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata) - || ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata, - system_cpudata_size)) { - erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); - system_cpudata = NULL; - system_cpudata_size = 0; - } -} - -static void -late_cpu_bind_init(void) -{ - int ix; - - erts_smp_rwmtx_init(&erts_cpu_bind_rwmtx, "cpu_bind"); - - scheduler2cpu_map = erts_alloc(ERTS_ALC_T_CPUDATA, - (sizeof(ErtsCpuBindData) - * (erts_no_schedulers+1))); - for (ix = 1; ix <= erts_no_schedulers; ix++) { - scheduler2cpu_map[ix].bind_id = -1; - scheduler2cpu_map[ix].bound_id = -1; - } - - if (cpu_bind_order == ERTS_CPU_BIND_UNDEFINED) { - int ncpus = erts_get_cpu_configured(erts_cpuinfo); - if (ncpus < 1 || erts_no_schedulers < ncpus) - cpu_bind_order = ERTS_CPU_BIND_NONE; - else - cpu_bind_order = ((system_cpudata || user_cpudata) - && (erts_bind_to_cpu(erts_cpuinfo, -1) != -ENOTSUP) - ? ERTS_CPU_BIND_DEFAULT_BIND - : ERTS_CPU_BIND_NONE); - } - - make_reader_groups_map(NULL); - - if (cpu_bind_order != ERTS_CPU_BIND_NONE) { - erts_cpu_topology_t *cpudata; - int cpudata_size; - create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - signal_schedulers_bind_change(cpudata, cpudata_size); - destroy_tmp_cpu_topology_copy(cpudata); - } -} - -int -erts_update_cpu_info(void) -{ - int changed; - erts_smp_rwmtx_rwlock(&erts_cpu_bind_rwmtx); - changed = erts_cpu_info_update(erts_cpuinfo); - if (changed) { - erts_cpu_topology_t *cpudata; - int cpudata_size; - - if (system_cpudata) - erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); - - system_cpudata_size = erts_get_cpu_topology_size(erts_cpuinfo); - if (!system_cpudata_size) - system_cpudata = NULL; - else { - system_cpudata = erts_alloc(ERTS_ALC_T_CPUDATA, - (sizeof(erts_cpu_topology_t) - * system_cpudata_size)); - - if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata) - || (ERTS_INIT_CPU_TOPOLOGY_OK - != verify_topology(system_cpudata, - system_cpudata_size))) { - erts_free(ERTS_ALC_T_CPUDATA, system_cpudata); - system_cpudata = NULL; - system_cpudata_size = 0; - } - } - - create_tmp_cpu_topology_copy(&cpudata, &cpudata_size); - signal_schedulers_bind_change(cpudata, cpudata_size); - destroy_tmp_cpu_topology_copy(cpudata); - } - erts_smp_rwmtx_rwunlock(&erts_cpu_bind_rwmtx); - return changed; -} - #ifdef ERTS_SMP static void @@ -7069,7 +5099,7 @@ Process *schedule(Process *p, int calls) } if ((rq->flags & ERTS_RUNQ_FLG_CHK_CPU_BIND) || erts_smp_atomic_read(&esdp->chk_cpu_bind)) { - check_cpu_bind(esdp); + erts_sched_check_cpu_bind(esdp); } } @@ -7165,7 +5195,9 @@ Process *schedule(Process *p, int calls) erts_smp_atomic_set(&function_calls, 0); fcalls = 0; + ASSERT(!erts_port_task_have_outstanding_io_tasks()); + #ifdef ERTS_SMP /* erts_sys_schedule_interrupt(0); */ #endif @@ -7497,6 +5529,15 @@ erts_schedule_misc_op(void (*func)(void *), void *arg) ErtsRunQueue *rq = erts_get_runq_current(NULL); ErtsMiscOpList *molp = misc_op_list_alloc(); + if (!rq) { + /* + * This can only happen when the sys msg dispatcher + * thread schedules misc ops (this happens *very* + * seldom; only when trace drivers are unloaded). + */ + rq = ERTS_RUNQ_IX(0); + } + erts_smp_runq_lock(rq); while (rq->misc.evac_runq) { diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 4365e409e5..c038e57b65 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -89,7 +89,6 @@ extern int erts_sched_thread_suggested_stack_size; #define ERTS_SCHED_THREAD_MAX_STACK_SIZE 8192 /* Kilo words */ #ifdef ERTS_SMP -extern Uint erts_max_main_threads; #include "erl_bits.h" #endif @@ -426,6 +425,13 @@ struct ErtsSchedulerData_ { #endif }; +typedef union { + ErtsSchedulerData esd; + char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))]; +} ErtsAlignedSchedulerData; + +extern ErtsAlignedSchedulerData *erts_aligned_scheduler_data; + #ifndef ERTS_SMP extern ErtsSchedulerData *erts_scheduler_data; #endif @@ -1007,27 +1013,12 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags; (p)->flags &= ~F_TIMO; \ } while (0) - -#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS 0 -#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED 1 -#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY 2 -#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE 3 - -int erts_init_scheduler_bind_type(char *how); - -#define ERTS_INIT_CPU_TOPOLOGY_OK 0 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID 1 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE 2 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY 3 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE 4 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES 5 -#define ERTS_INIT_CPU_TOPOLOGY_MISSING_LID 6 -#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS 7 -#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES 8 -#define ERTS_INIT_CPU_TOPOLOGY_MISSING 9 - -int erts_init_cpu_topology(char *topology_str); -int erts_update_cpu_info(void); +#define ERTS_RUNQ_IX(IX) \ + (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues), \ + &erts_aligned_run_queues[(IX)].runq) +#define ERTS_SCHEDULER_IX(IX) \ + (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers), \ + &erts_aligned_scheduler_data[(IX)].esd) void erts_pre_init_process(void); void erts_late_init_process(void); @@ -1058,8 +1049,9 @@ Eterm erts_multi_scheduling_blockers(Process *); void erts_start_schedulers(void); void erts_smp_notify_check_children_needed(void); #endif +void erts_sched_notify_check_cpu_bind(void); Uint erts_active_schedulers(void); -void erts_init_process(void); +void erts_init_process(int); Eterm erts_process_status(Process *, ErtsProcLocks, Process *, Eterm); Uint erts_run_queues_len(Uint *); void erts_add_to_runq(Process *); diff --git a/erts/emulator/beam/erl_process_lock.c b/erts/emulator/beam/erl_process_lock.c index a4d12139e9..1bebcdb911 100644 --- a/erts/emulator/beam/erl_process_lock.c +++ b/erts/emulator/beam/erl_process_lock.c @@ -117,10 +117,9 @@ static int aux_thr_proc_lock_spin_count; static void cleanup_tse(void); void -erts_init_proc_lock(void) +erts_init_proc_lock(int cpus) { int i; - int cpus; erts_smp_spinlock_init(&qs_lock, "proc_lck_qs_alloc"); for (i = 0; i < ERTS_NO_OF_PIX_LOCKS; i++) { #ifdef ERTS_ENABLE_LOCK_COUNT @@ -138,7 +137,6 @@ erts_init_proc_lock(void) lc_id.proc_lock_msgq = erts_lc_get_lock_order_id("proc_msgq"); lc_id.proc_lock_status = erts_lc_get_lock_order_id("proc_status"); #endif - cpus = erts_get_cpu_configured(erts_cpuinfo); if (cpus > 1) { proc_lock_spin_count = ERTS_PROC_LOCK_SPIN_COUNT_BASE; proc_lock_spin_count += (ERTS_PROC_LOCK_SPIN_COUNT_SCHED_INC diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h index 7cfc9893fa..4fe30c7209 100644 --- a/erts/emulator/beam/erl_process_lock.h +++ b/erts/emulator/beam/erl_process_lock.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2007-2009. All Rights Reserved. + * Copyright Ericsson AB 2007-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 @@ -334,7 +334,7 @@ erts_proc_lock_flags_cmpxchg(erts_proc_lock_t *lck, ErtsProcLocks new, extern erts_pix_lock_t erts_pix_locks[ERTS_NO_OF_PIX_LOCKS]; -void erts_init_proc_lock(void); +void erts_init_proc_lock(int cpus); void erts_proc_lock_prepare_proc_lock_waiter(void); void erts_proc_lock_failed(Process *, erts_pix_lock_t *, diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h index 0b7269262e..a74cf79b8c 100644 --- a/erts/emulator/beam/erl_threads.h +++ b/erts/emulator/beam/erl_threads.h @@ -27,9 +27,6 @@ #define ERTS_SPIN_BODY ETHR_SPIN_BODY -#define ERTS_MAX_READER_GROUPS 8 -extern int erts_reader_groups; - #include "sys.h" #ifdef USE_THREADS diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c index d01a3661f9..72207df621 100644 --- a/erts/emulator/beam/erl_unicode.c +++ b/erts/emulator/beam/erl_unicode.c @@ -30,6 +30,8 @@ #include "big.h" #include "erl_unicode.h" +#include "erl_unicode_normalize.h" + typedef struct _restart_context { byte *bytes; @@ -54,13 +56,6 @@ static BIF_RETTYPE finalize_list_to_list(Process *p, Uint num_resulting_chars, int state, int left, Eterm tail); -static int analyze_utf8(byte *source, Uint size, - byte **err_pos, Uint *num_chars, int *left); -#define UTF8_OK 0 -#define UTF8_INCOMPLETE 1 -#define UTF8_ERROR 2 -#define UTF8_ANALYZE_MORE 3 - static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3); static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3); static BIF_RETTYPE characters_to_list_trap_2(BIF_ALIST_3); @@ -463,7 +458,7 @@ L_Again: /* Restart with sublist, old listend was pushed on stack */ } objp = list_val(ioterm); obj = CAR(objp); - if (!is_byte(obj)) + if (!is_small(obj)) break; } } else if (is_nil(obj)) { @@ -970,11 +965,11 @@ static int is_valid_utf8(Eterm orig_bin) bytes = erts_get_aligned_binary_bytes(orig_bin, &temp_alloc); } size = binary_size(orig_bin); - ret = analyze_utf8(bytes, + ret = erts_analyze_utf8(bytes, size, &endpos,&numchar,NULL); erts_free_aligned_binary_bytes(temp_alloc); - return (ret == UTF8_OK); + return (ret == ERTS_UTF8_OK); } BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2) @@ -1084,14 +1079,14 @@ static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint char hp += 2; rest_term = CONS(hp,leftover_bin,rest_term); } - BIF_RET(finalize_list_to_list(p, bytes, rest_term, 0U, pos, characters, UTF8_ERROR, left, NIL)); + BIF_RET(finalize_list_to_list(p, bytes, rest_term, 0U, pos, characters, ERTS_UTF8_ERROR, left, NIL)); } else if (rest_term == NIL && num_leftovers != 0) { Eterm leftover_bin = new_binary(p, leftover, num_leftovers); if (check_leftovers(leftover,num_leftovers) != 0) { - BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, UTF8_ERROR, + BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, ERTS_UTF8_ERROR, left, NIL)); } else { - BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, UTF8_INCOMPLETE, + BIF_RET(finalize_list_to_list(p, bytes, leftover_bin, 0U, pos, characters, ERTS_UTF8_INCOMPLETE, left, NIL)); } } else { /* All OK */ @@ -1107,11 +1102,11 @@ static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint char rc.num_processed_bytes = 0; /* not used */ rc.num_bytes_to_process = pos; rc.num_resulting_chars = characters; - rc.state = UTF8_OK; /* not used */ + rc.state = ERTS_UTF8_OK; /* not used */ BIF_TRAP3(&characters_to_list_trap_1_exp, p, make_magic_bin_for_restart(p,&rc), rest_term, latin1); } else { /* Success */ - BIF_RET(finalize_list_to_list(p, bytes, NIL, 0U, pos, characters, UTF8_OK, left, NIL)); + BIF_RET(finalize_list_to_list(p, bytes, NIL, 0U, pos, characters, ERTS_UTF8_OK, left, NIL)); } } } @@ -1205,7 +1200,7 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2) * When input to characters_to_list is a plain binary and the format is 'unicode', we do * a faster analyze and size count with this function. */ -static int analyze_utf8(byte *source, Uint size, +int erts_analyze_utf8(byte *source, Uint size, byte **err_pos, Uint *num_chars, int *left) { *err_pos = source; @@ -1216,60 +1211,60 @@ static int analyze_utf8(byte *source, Uint size, --size; } else if (((*source) & ((byte) 0xE0)) == 0xC0) { if (size < 2) { - return UTF8_INCOMPLETE; + return ERTS_UTF8_INCOMPLETE; } if (((source[1] & ((byte) 0xC0)) != 0x80) || ((*source) < 0xC2) /* overlong */) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } source += 2; size -= 2; } else if (((*source) & ((byte) 0xF0)) == 0xE0) { if (size < 3) { - return UTF8_INCOMPLETE; + return ERTS_UTF8_INCOMPLETE; } if (((source[1] & ((byte) 0xC0)) != 0x80) || ((source[2] & ((byte) 0xC0)) != 0x80) || (((*source) == 0xE0) && (source[1] < 0xA0)) /* overlong */ ) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } if ((((*source) & ((byte) 0xF)) == 0xD) && ((source[1] & 0x20) != 0)) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } if (((*source) == 0xEF) && (source[1] == 0xBF) && ((source[2] == 0xBE) || (source[2] == 0xBF))) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } source += 3; size -= 3; } else if (((*source) & ((byte) 0xF8)) == 0xF0) { if (size < 4) { - return UTF8_INCOMPLETE; + return ERTS_UTF8_INCOMPLETE; } if (((source[1] & ((byte) 0xC0)) != 0x80) || ((source[2] & ((byte) 0xC0)) != 0x80) || ((source[3] & ((byte) 0xC0)) != 0x80) || (((*source) == 0xF0) && (source[1] < 0x90)) /* overlong */) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } if ((((*source) & ((byte)0x7)) > 0x4U) || ((((*source) & ((byte)0x7)) == 0x4U) && ((source[1] & ((byte)0x3F)) > 0xFU))) { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } source += 4; size -= 4; } else { - return UTF8_ERROR; + return ERTS_UTF8_ERROR; } ++(*num_chars); *err_pos = source; if (left && --(*left) <= 0) { - return UTF8_ANALYZE_MORE; + return ERTS_UTF8_ANALYZE_MORE; } } - return UTF8_OK; + return ERTS_UTF8_OK; } /* @@ -1304,7 +1299,7 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, } else if (((*source) & ((byte) 0xE0)) == 0xC0) { unipoint = (((Uint) ((*source) & ((byte) 0x1F))) << 6) | - ((Uint) (source[1] & ((byte) 0x3F))); + ((Uint) (source[1] & ((byte) 0x3F))); } else if (((*source) & ((byte) 0xF0)) == 0xE0) { unipoint = (((Uint) ((*source) & ((byte) 0xF))) << 12) | @@ -1330,6 +1325,216 @@ static Eterm do_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, return ret; } +static int is_candidate(Uint cp) +{ + int index,pos; + if (cp < 768) return 0; + if (cp > 4023) { + if (cp == 12441 || cp == 12442) return 1; + return 0; + } + index = cp / 32 - COMP_CANDIDATE_MAP_OFFSET; + pos = cp % 32; + return !!(comp_candidate_map[index] & (1UL << pos)); +} + +static int hashsearch(int *htab, int htab_size, CompEntry *cv, Uint16 c) +{ + int bucket = c % htab_size; + while (htab[bucket] != -1 && cv[htab[bucket]].c != c) + bucket = (bucket + 1) % htab_size; + return htab[bucket]; +} + +#define TRANSLATE_NO 0 +#define TRANSLATE_MAYBE -1 + +/* The s array is reversed */ +static int translate(Uint16 *s, int slen, Uint16 *res) +{ + /* Go backwards through buffer and match against tree */ + int pos = 0; + CompEntry *cv = compose_tab; + int *hc = hash_compose_tab; + int cvs = compose_tab_size; + int x; + while (pos < slen) { + x = hashsearch(hc,cvs*HASH_SIZE_FACTOR,cv,s[pos]); + if (x < 0) { + return TRANSLATE_NO; + } + if (cv[x].res) { + *res = cv[x].res; + return pos; + } + cvs = cv[x].num_subs; + hc = cv[x].hash; + cv = cv[x].subs; + ++pos; + } + return TRANSLATE_MAYBE; +} + +static void handle_first_norm(Uint16 *savepoints, int *numpointsp, Uint unipoint) +{ + /*erts_fprintf(stderr,"CP = %d, numpoints = %d\n",(int) unipoint,(int) *numpointsp);*/ + *numpointsp = 1; + savepoints[0] = (Uint16) unipoint; +} + +static void cleanup_norm(Eterm **hpp, Uint16 *savepoints, int numpoints, Eterm *retp) +{ + Eterm *hp = *hpp; + int res,i; + Uint16 newpoint; + Eterm ret = *retp; + + ret = CONS(hp,make_small((Uint) savepoints[0]),ret); + hp += 2; + + for (i = 1;i < numpoints;) { + if(!is_candidate(savepoints[i]) || + ((res = translate(savepoints+i,numpoints - i, &newpoint)) <= 0)) { + ret = CONS(hp,make_small((Uint) savepoints[i]),ret); + hp += 2; + ++i; + } else { + ret = CONS(hp,make_small((Uint) newpoint),ret); + hp += 2; + i += res; + } + } + *retp = ret; +} + +static void handle_potential_norm(Eterm **hpp, Uint16 *savepoints, int *numpointsp, Uint unipoint, Eterm *retp) +{ + Eterm *hp = *hpp; + int numpoints = *numpointsp; + int res,i; + Uint16 newpoint; + Eterm ret = *retp; + + /* erts_fprintf(stderr,"CP = %d, numpoints = %d\n",(int) unipoint,(int) numpoints);*/ + if ((unipoint >> 16) == 0) { /* otherwise we're done here */ + savepoints[numpoints++] = (Uint16) unipoint; + res = translate(savepoints,numpoints,&newpoint); + if (res == TRANSLATE_NO) { + ret = CONS(hp,make_small((Uint) savepoints[0]),ret); + hp += 2; + for (i = 1;i < numpoints;) { + if(!is_candidate(savepoints[i]) || + ((res = translate(savepoints+i,numpoints - i, &newpoint)) == 0)) { + ret = CONS(hp,make_small((Uint) savepoints[i]),ret); + hp += 2; + ++i; + } else if (res > 0) { + ret = CONS(hp,make_small((Uint) newpoint),ret); + hp += 2; + i += res; + } else { /* res < 0 */ + /* A "maybe", means we are not done yet */ + int j = 0; + while (i < numpoints) { + savepoints[j++] = savepoints[i++]; + } + numpoints = j; + goto breakaway; + } + } + numpoints = 0; + breakaway: + ; + } else if (res > 0) { + numpoints = 0; + ret = CONS(hp,make_small((Uint) newpoint),ret); + hp += 2; + } /* < 0 means go on */ + } else { + /* Unconditional rollup, this character is larger than 16 bit */ + ret = CONS(hp,make_small((Uint) savepoints[0]),ret); + hp += 2; + + for (i = 1;i < numpoints;) { + if(!is_candidate(savepoints[i]) || + ((res = translate(savepoints+i,numpoints - i, &newpoint)) <= 0)) { + ret = CONS(hp,make_small((Uint) savepoints[i]),ret); + hp += 2; + ++i; + } else { + ret = CONS(hp,make_small((Uint) newpoint),ret); + hp += 2; + i += res; + } + } + ret = CONS(hp,make_small(unipoint),ret); + hp += 2; + numpoints = 0; + } + *hpp = hp; + *numpointsp = numpoints; + *retp = ret; +} + +static Eterm do_utf8_to_list_normalize(Process *p, Uint num, byte *bytes, Uint sz) +{ + Eterm *hp,*hp_end; + Eterm ret; + byte *source; + Uint unipoint; + Uint16 savepoints[4]; + int numpoints = 0; + + ASSERT(num > 0); + + hp = HAlloc(p,num * 2); /* May be to much */ + hp_end = hp + num * 2; + ret = NIL; + source = bytes + sz; + while(--source >= bytes) { + if (((*source) & ((byte) 0x80)) == 0) { + unipoint = (Uint) *source; + } else if (((*source) & ((byte) 0xE0)) == 0xC0) { + unipoint = + (((Uint) ((*source) & ((byte) 0x1F))) << 6) | + ((Uint) (source[1] & ((byte) 0x3F))); + } else if (((*source) & ((byte) 0xF0)) == 0xE0) { + unipoint = + (((Uint) ((*source) & ((byte) 0xF))) << 12) | + (((Uint) (source[1] & ((byte) 0x3F))) << 6) | + ((Uint) (source[2] & ((byte) 0x3F))); + } else if (((*source) & ((byte) 0xF8)) == 0xF0) { + unipoint = + (((Uint) ((*source) & ((byte) 0x7))) << 18) | + (((Uint) (source[1] & ((byte) 0x3F))) << 12) | + (((Uint) (source[2] & ((byte) 0x3F))) << 6) | + ((Uint) (source[3] & ((byte) 0x3F))); + } else { + /* ignore 2#10XXXXXX */ + continue; + } + if (numpoints) { + handle_potential_norm(&hp,savepoints,&numpoints,unipoint,&ret); + continue; + } + /* We are not building up any normalizations yet, look that we shouldn't start... */ + if (is_candidate(unipoint)) { + handle_first_norm(savepoints,&numpoints,unipoint); + continue; + } + ret = CONS(hp,make_small(unipoint),ret); + hp += 2; + } + /* so, we'we looped to the beginning, do we have anything saved? */ + if (numpoints) { + cleanup_norm(&hp,savepoints,numpoints,&ret); + } + if (hp_end != hp) { + HRelease(p,hp_end,hp); + } + return ret; +} + /* * The last step of characters_to_list, build a list from the buffer 'bytes' (created in the same way * as for characters_to_utf8). All sizes are known in advance and most data will be held in a @@ -1378,10 +1583,10 @@ static BIF_RETTYPE finalize_list_to_list(Process *p, */ free_restart(bytes); - if (state == UTF8_INCOMPLETE) { + if (state == ERTS_UTF8_INCOMPLETE) { hp = HAlloc(p,4); ret = TUPLE3(hp,am_incomplete,converted,rest); - } else if (state == UTF8_ERROR) { + } else if (state == ERTS_UTF8_ERROR) { hp = HAlloc(p,4); ret = TUPLE3(hp,am_error,converted,rest); } else { @@ -1408,7 +1613,7 @@ static BIF_RETTYPE characters_to_list_trap_2(BIF_ALIST_3) /* * Hooks into the process of decoding a binary depending on state. - * If last_state is UTF8_ANALYZE_MORE, num_bytes_to_process + * If last_state is ERTS_UTF8_ANALYZE_MORE, num_bytes_to_process * and num_resulting_chars will grow * until we're done analyzing the binary. Then we'll eat * the bytes to process, lowering num_bytes_to_process and num_resulting_chars, @@ -1465,14 +1670,14 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p, left = allowed_iterations(p); - if (state == UTF8_ANALYZE_MORE) { - state = analyze_utf8(bytes + num_bytes_to_process, + if (state == ERTS_UTF8_ANALYZE_MORE) { + state = erts_analyze_utf8(bytes + num_bytes_to_process, size - num_bytes_to_process, &endpos,&numchar,&left); cost_to_proc(p,numchar); num_resulting_chars += numchar; num_bytes_to_process = endpos - bytes; - if (state == UTF8_ANALYZE_MORE) { + if (state == ERTS_UTF8_ANALYZE_MORE) { Eterm epos = erts_make_integer(num_bytes_to_process,p); Eterm enumchar = erts_make_integer(num_resulting_chars,p); erts_free_aligned_binary_bytes(temp_alloc); @@ -1528,7 +1733,7 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p, ErlSubBin *sb; Eterm orig; Uint offset; - ASSERT(state != UTF8_OK); + ASSERT(state != ERTS_UTF8_OK); hp = HAlloc(p, ERL_SUB_BIN_SIZE); sb = (ErlSubBin *) hp; ERTS_GET_REAL_BIN(orig_bin, orig, offset, bitoffs, bitsize); @@ -1544,14 +1749,14 @@ static BIF_RETTYPE do_bif_utf8_to_list(Process *p, /* Done */ - if (state == UTF8_INCOMPLETE) { + if (state == ERTS_UTF8_INCOMPLETE) { if (check_leftovers(bytes + num_bytes_to_process + num_processed_bytes, b_sz) != 0) { goto error_return; } hp = HAlloc(p,4); ret = TUPLE3(hp,am_incomplete,converted,rest); - } else if (state == UTF8_ERROR) { + } else if (state == ERTS_UTF8_ERROR) { error_return: hp = HAlloc(p,4); ret = TUPLE3(hp,am_error,converted,rest); @@ -1589,7 +1794,7 @@ static BIF_RETTYPE characters_to_list_trap_3(BIF_ALIST_3) 0U, /* nothing processed yet */ num_bytes_to_process, num_resulting_chars, - UTF8_ANALYZE_MORE, /* always this state here */ + ERTS_UTF8_ANALYZE_MORE, /* always this state here */ NIL); /* Nothing built -> no tail yet */ } @@ -1642,7 +1847,7 @@ static BIF_RETTYPE utf8_to_list(BIF_ALIST_1) BIF_ERROR(BIF_P,BADARG); } return do_bif_utf8_to_list(BIF_P, BIF_ARG_1, 0U, 0U, 0U, - UTF8_ANALYZE_MORE,NIL); + ERTS_UTF8_ANALYZE_MORE,NIL); } @@ -1728,8 +1933,8 @@ binary_to_atom(Process* p, Eterm bin, Eterm enc, int must_exist) Uint n; int reds_left = bin_size+1; /* Number of reductions left. */ - if (analyze_utf8(bytes, bin_size, &err_pos, - &n, &reds_left) == UTF8_OK) { + if (erts_analyze_utf8(bytes, bin_size, &err_pos, + &n, &reds_left) == ERTS_UTF8_OK) { /* * Correct UTF-8 encoding, but too many characters to * fit in an atom. @@ -1813,3 +2018,616 @@ BIF_RETTYPE binary_to_existing_atom_2(BIF_ALIST_2) { return binary_to_atom(BIF_P, BIF_ARG_1, BIF_ARG_2, 1); } + +/********************************************************** + * Simpler non-interruptable routines for UTF-8 and + * Windowish UTF-16 (restricted) + **********************************************************/ +/* + * This function is the heart of the Unicode support for + * open_port - spawn_executable. It converts both the name + * of the executable and the arguments according to the same rules + * as for filename conversion. That means as if your arguments are + * to be raw, you supply binaries, else unicode characters are allowed up to + * the encoding maximum (256 of the unicode max). + * Depending on the filename encoding standard, the vector is then + * converted to whatever is used, which might mean win_utf16 if on windows. + * Do not peek into the argument vector or filenam with ordinary + * string routines, that will certainly fail on some OS. + */ + +char *erts_convert_filename_to_native(Eterm name, ErtsAlcType_t alloc_type, int allow_empty) +{ + int encoding = erts_get_native_filename_encoding(); + char* name_buf = NULL; + + if (is_atom(name) || is_list(name) || (allow_empty && is_nil(name))) { + Sint need; + if ((need = erts_native_filename_need(name,encoding)) < 0) { + return NULL; + } + if (encoding == ERL_FILENAME_WIN_WCHAR) { + need += 2; + } else { + ++need; + } + name_buf = (char *) erts_alloc(alloc_type, need); + erts_native_filename_put(name,encoding,(byte *)name_buf); + name_buf[need-1] = 0; + if (encoding == ERL_FILENAME_WIN_WCHAR) { + name_buf[need-2] = 0; + } + } else if (is_binary(name)) { + byte *temp_alloc = NULL; + byte *bytes; + byte *err_pos; + Uint size,num_chars; + + size = binary_size(name); + bytes = erts_get_aligned_binary_bytes(name, &temp_alloc); + if (encoding != ERL_FILENAME_WIN_WCHAR) { + /*Add 0 termination only*/ + name_buf = (char *) erts_alloc(alloc_type, size+1); + memcpy(name_buf,bytes,size); + name_buf[size]=0; + } else if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK || + erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) { + byte *p; + /* What to do now? Maybe latin1, so just take byte for byte instead */ + name_buf = (char *) erts_alloc(alloc_type, (size+1)*2); + p = (byte *) name_buf; + while (size--) { + *p++ = *bytes++; + *p++ = 0; + } + *p++ = 0; + *p++ = 0; + } else { /* WIN_WCHAR and valid UTF8 */ + name_buf = (char *) erts_alloc(alloc_type, (num_chars+1)*2); + erts_copy_utf8_to_utf16_little((byte *) name_buf, bytes, num_chars); + name_buf[num_chars*2] = 0; + name_buf[num_chars*2+1] = 0; + } + erts_free_aligned_binary_bytes(temp_alloc); + } else { + return NULL; + } + return name_buf; +} + + +Sint erts_native_filename_need(Eterm ioterm, int encoding) +{ + Eterm *objp; + Eterm obj; + DECLARE_ESTACK(stack); + Sint need = 0; + + if (is_atom(ioterm)) { + Atom* ap; + int i; + ap = atom_tab(atom_val(ioterm)); + switch (encoding) { + case ERL_FILENAME_LATIN1: + need = ap->len; + break; + case ERL_FILENAME_UTF8_MAC: + case ERL_FILENAME_UTF8: + for (i = 0; i < ap->len; i++) { + need += (ap->name[i] >= 0x80) ? 2 : 1; + } + break; + case ERL_FILENAME_WIN_WCHAR: + need = 2*(ap->len); + break; + default: + need = -1; + } + DESTROY_ESTACK(stack); + return need; + } + + if (is_nil(ioterm)) { + DESTROY_ESTACK(stack); + return need; + } + if (!is_list(ioterm)) { + DESTROY_ESTACK(stack); + return (Sint) -1; + } + /* OK a list, needs to be processed in order, handling each flat list-level + as they occur, just like io_list_to_binary would */ + ESTACK_PUSH(stack,ioterm); + while (!ESTACK_ISEMPTY(stack)) { + ioterm = ESTACK_POP(stack); + if (is_nil(ioterm)) { + /* ignore empty lists */ + continue; + } + if(is_list(ioterm)) { +L_Again: /* Restart with sublist, old listend was pushed on stack */ + objp = list_val(ioterm); + obj = CAR(objp); + for(;;) { /* loop over one flat list of bytes and binaries + until sublist or list end is encountered */ + if (is_small(obj)) { /* Always small */ + for(;;) { + Uint x = unsigned_val(obj); + switch (encoding) { + case ERL_FILENAME_LATIN1: + if (x > 255) { + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + need += 1; + break; + case ERL_FILENAME_UTF8_MAC: + case ERL_FILENAME_UTF8: + if (x < 0x80) { + need +=1; + } else if (x < 0x800) { + need += 2; + } else if (x < 0x10000) { + if ((x >= 0xD800 && x <= 0xDFFF) || + (x == 0xFFFE) || + (x == 0xFFFF)) { /* Invalid unicode range */ + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + need += 3; + } else if (x < 0x110000) { + need += 4; + } else { + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + break; + case ERL_FILENAME_WIN_WCHAR: + if (x <= 0xffff) { + need += 2; + break; + } /* else fall throug to error */ + default: + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + + /* everything else will give badarg later + in the process, so we dont check */ + ioterm = CDR(objp); + if (!is_list(ioterm)) { + break; + } + objp = list_val(ioterm); + obj = CAR(objp); + if (!is_small(obj)) + break; + } + } else if (is_nil(obj)) { + ioterm = CDR(objp); + if (!is_list(ioterm)) { + break; + } + objp = list_val(ioterm); + obj = CAR(objp); + } else if (is_list(obj)) { + /* push rest of list for later processing, start + again with sublist */ + ESTACK_PUSH(stack,CDR(objp)); + ioterm = obj; + goto L_Again; + } else { + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + if (is_nil(ioterm) || !is_list(ioterm)) { + break; + } + } /* for(;;) */ + } /* is_list(ioterm) */ + + if (!is_list(ioterm) && !is_nil(ioterm)) { + /* inproper list end */ + DESTROY_ESTACK(stack); + return ((Sint) -1); + } + } /* while not estack empty */ + DESTROY_ESTACK(stack); + return need; +} + +void erts_native_filename_put(Eterm ioterm, int encoding, byte *p) +{ + Eterm *objp; + Eterm obj; + DECLARE_ESTACK(stack); + + if (is_atom(ioterm)) { + Atom* ap; + int i; + ap = atom_tab(atom_val(ioterm)); + switch (encoding) { + case ERL_FILENAME_LATIN1: + for (i = 0; i < ap->len; i++) { + *p++ = ap->name[i]; + } + break; + case ERL_FILENAME_UTF8_MAC: + case ERL_FILENAME_UTF8: + for (i = 0; i < ap->len; i++) { + if(ap->name[i] < 0x80) { + *p++ = ap->name[i]; + } else { + *p++ = (((ap->name[i]) >> 6) | ((byte) 0xC0)); + *p++ = (((ap->name[i]) & 0x3F) | ((byte) 0x80)); + } + } + break; + case ERL_FILENAME_WIN_WCHAR: + for (i = 0; i < ap->len; i++) { + /* Little endian */ + *p++ = ap->name[i]; + *p++ = 0; + } + break; + default: + ASSERT(0); + } + DESTROY_ESTACK(stack); + return; + } + + if (is_nil(ioterm)) { + DESTROY_ESTACK(stack); + return; + } + ASSERT(is_list(ioterm)); + /* OK a list, needs to be processed in order, handling each flat list-level + as they occur, just like io_list_to_binary would */ + ESTACK_PUSH(stack,ioterm); + while (!ESTACK_ISEMPTY(stack)) { + ioterm = ESTACK_POP(stack); + if (is_nil(ioterm)) { + /* ignore empty lists */ + continue; + } + if(is_list(ioterm)) { +L_Again: /* Restart with sublist, old listend was pushed on stack */ + objp = list_val(ioterm); + obj = CAR(objp); + for(;;) { /* loop over one flat list of bytes and binaries + until sublist or list end is encountered */ + if (is_small(obj)) { /* Always small */ + for(;;) { + Uint x = unsigned_val(obj); + switch (encoding) { + case ERL_FILENAME_LATIN1: + ASSERT( x < 256); + *p++ = (byte) x; + break; + case ERL_FILENAME_UTF8_MAC: + case ERL_FILENAME_UTF8: + if (x < 0x80) { + *p++ = (byte) x; + } + else if (x < 0x800) { + *p++ = (((byte) (x >> 6)) | + ((byte) 0xC0)); + *p++ = (((byte) (x & 0x3F)) | + ((byte) 0x80)); + } else if (x < 0x10000) { + ASSERT(!((x >= 0xD800 && x <= 0xDFFF) || + (x == 0xFFFE) || + (x == 0xFFFF))); + *p++ = (((byte) (x >> 12)) | + ((byte) 0xE0)); + *p++ = ((((byte) (x >> 6)) & 0x3F) | + ((byte) 0x80)); + *p++ = (((byte) (x & 0x3F)) | + ((byte) 0x80)); + } else { + ASSERT(x < 0x110000); + *p++ = (((byte) (x >> 18)) | + ((byte) 0xF0)); + *p++ = ((((byte) (x >> 12)) & 0x3F) | + ((byte) 0x80)); + *p++ = ((((byte) (x >> 6)) & 0x3F) | + ((byte) 0x80)); + *p++ = (((byte) (x & 0x3F)) | + ((byte) 0x80)); + } + break; + case ERL_FILENAME_WIN_WCHAR: + ASSERT(x <= 0xFFFF); + *p++ = (byte) (x & 0xFFU); + *p++ = (byte) ((x >> 8) & 0xFFU); + break; + default: + ASSERT(0); + } + + /* everything else will give badarg later + in the process, so we dont check */ + ioterm = CDR(objp); + if (!is_list(ioterm)) { + break; + } + objp = list_val(ioterm); + obj = CAR(objp); + if (!is_small(obj)) + break; + } + } else if (is_nil(obj)) { + ioterm = CDR(objp); + if (!is_list(ioterm)) { + break; + } + objp = list_val(ioterm); + obj = CAR(objp); + } else if (is_list(obj)) { + /* push rest of list for later processing, start + again with sublist */ + ESTACK_PUSH(stack,CDR(objp)); + ioterm = obj; + goto L_Again; + } else { + ASSERT(0); + } + if (is_nil(ioterm) || !is_list(ioterm)) { + break; + } + } /* for(;;) */ + } /* is_list(ioterm) */ + + ASSERT(is_list(ioterm) || is_nil(ioterm)); + } /* while not estack empty */ + DESTROY_ESTACK(stack); + return; +} +void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars) +{ + Uint unipoint; + + while (num_chars--) { + if (((*bytes) & ((byte) 0x80)) == 0) { + unipoint = (Uint) *bytes; + ++bytes; + } else if (((*bytes) & ((byte) 0xE0)) == 0xC0) { + unipoint = + (((Uint) ((*bytes) & ((byte) 0x1F))) << 6) | + ((Uint) (bytes[1] & ((byte) 0x3F))); + bytes += 2; + } else if (((*bytes) & ((byte) 0xF0)) == 0xE0) { + unipoint = + (((Uint) ((*bytes) & ((byte) 0xF))) << 12) | + (((Uint) (bytes[1] & ((byte) 0x3F))) << 6) | + ((Uint) (bytes[2] & ((byte) 0x3F))); + bytes +=3; + } else if (((*bytes) & ((byte) 0xF8)) == 0xF0) { + unipoint = + (((Uint) ((*bytes) & ((byte) 0x7))) << 18) | + (((Uint) (bytes[1] & ((byte) 0x3F))) << 12) | + (((Uint) (bytes[2] & ((byte) 0x3F))) << 6) | + ((Uint) (bytes[3] & ((byte) 0x3F))); + bytes += 4; + } else { + erl_exit(1,"Internal unicode error in prim_file:internal_name2native/1"); + } + *target++ = (byte) (unipoint & 0xFF); + *target++ = (byte) ((unipoint >> 8) & 0xFF); + } +} + +/* + * This internal bif converts a filename to whatever format is suitable for the file driver + * It also adds zero termination so that prim_file neednt bother with the character encoding + * of the file driver + */ +BIF_RETTYPE prim_file_internal_name2native_1(BIF_ALIST_1) +{ + int encoding = erts_get_native_filename_encoding(); + Sint need; + Eterm bin_term; + byte* bin_p; + /* Prim file explicitly does not allow atoms, although we could + very well cope with it. Instead of letting 'file' handle them, + it would probably be more efficient to handle them here. Subject to + change in R15. */ + if (is_atom(BIF_ARG_1)) { + BIF_ERROR(BIF_P,BADARG); + } + if (is_binary(BIF_ARG_1)) { + byte *temp_alloc = NULL; + byte *bytes; + byte *err_pos; + Uint size,num_chars; + /* Uninterpreted encoding except if windows widechar, in case we convert from + utf8 to win_wchar */ + size = binary_size(BIF_ARG_1); + bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); + if (encoding != ERL_FILENAME_WIN_WCHAR) { + /*Add 0 termination only*/ + bin_term = new_binary(BIF_P, NULL, size+1); + bin_p = binary_bytes(bin_term); + memcpy(bin_p,bytes,size); + bin_p[size]=0; + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(bin_term); + } + /* In a wchar world, the emulator flags only affect how + binaries are interpreted when sent from the user. */ + /* Determine real length and create a new binary */ + if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK || + erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) { + /* What to do now? Maybe latin1, so just take byte for byte instead */ + bin_term = new_binary(BIF_P, 0, (size+1)*2); + bin_p = binary_bytes(bin_term); + while (size--) { + *bin_p++ = *bytes++; + *bin_p++ = 0; + } + *bin_p++ = 0; + *bin_p++ = 0; + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(bin_term); + } + /* OK, UTF8 ok, number of characters is in num_chars */ + bin_term = new_binary(BIF_P, 0, (num_chars+1)*2); + bin_p = binary_bytes(bin_term); + erts_copy_utf8_to_utf16_little(bin_p, bytes, num_chars); + /* zero termination */ + bin_p[num_chars*2] = 0; + bin_p[num_chars*2+1] = 0; + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(bin_term); + } /* binary */ + + + if ((need = erts_native_filename_need(BIF_ARG_1,encoding)) < 0) { + BIF_ERROR(BIF_P,BADARG); + } + if (encoding == ERL_FILENAME_WIN_WCHAR) { + need += 2; + } else { + ++need; + } + + bin_term = new_binary(BIF_P, 0, need); + bin_p = binary_bytes(bin_term); + erts_native_filename_put(BIF_ARG_1,encoding,bin_p); + bin_p[need-1] = 0; + if (encoding == ERL_FILENAME_WIN_WCHAR) { + bin_p[need-2] = 0; + } + BIF_RET(bin_term); +} + +BIF_RETTYPE prim_file_internal_native2name_1(BIF_ALIST_1) +{ + Eterm real_bin; + Uint offset; + Uint size,num_chars; + Uint bitsize; + Uint bitoffs; + Eterm *hp; + byte *temp_alloc = NULL; + byte *bytes; + byte *err_pos; + Uint num_built; /* characters */ + Uint num_eaten; /* bytes */ + Eterm ret; + int mac = 0; + + if (is_not_binary(BIF_ARG_1)) { + BIF_ERROR(BIF_P,BADARG); + } + size = binary_size(BIF_ARG_1); + ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, offset, bitoffs, bitsize); + if (bitsize != 0) { + BIF_ERROR(BIF_P,BADARG); + } + if (size == 0) { + BIF_RET(NIL); + } + switch (erts_get_native_filename_encoding()) { + case ERL_FILENAME_LATIN1: + hp = HAlloc(BIF_P, 2 * size); + bytes = binary_bytes(real_bin)+offset; + + BIF_RET(erts_bin_bytes_to_list(NIL, hp, bytes, size, bitoffs)); + case ERL_FILENAME_UTF8_MAC: + mac = 1; + case ERL_FILENAME_UTF8: + bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); + if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) { + erts_free_aligned_binary_bytes(temp_alloc); + goto noconvert; + } + num_built = 0; + num_eaten = 0; + if (mac) { + ret = do_utf8_to_list_normalize(BIF_P, num_chars, bytes, size); + } else { + ret = do_utf8_to_list(BIF_P, num_chars, bytes, size, num_chars, &num_built, &num_eaten, NIL); + } + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(ret); + case ERL_FILENAME_WIN_WCHAR: + bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); + if ((size % 2) != 0) { /* Panic fixup to avoid crashing the emulator */ + size--; + hp = HAlloc(BIF_P, size+2); + ret = CONS(hp,make_small((Uint) bytes[size]),NIL); + hp += 2; + } else { + hp = HAlloc(BIF_P, size); + ret = NIL; + } + bytes += size-1; + while (size > 0) { + Uint x = ((Uint) *bytes--) << 8; + x |= ((Uint) *bytes--); + size -= 2; + ret = CONS(hp,make_small(x),ret); + hp += 2; + } + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(ret); + default: + goto noconvert; + } + noconvert: + BIF_RET(BIF_ARG_1); +} + +BIF_RETTYPE prim_file_internal_normalize_utf8_1(BIF_ALIST_1) +{ + Eterm real_bin; + Uint offset; + Uint size,num_chars; + Uint bitsize; + Uint bitoffs; + Eterm ret; + byte *temp_alloc = NULL; + byte *bytes; + byte *err_pos; + + if (is_not_binary(BIF_ARG_1)) { + BIF_ERROR(BIF_P,BADARG); + } + size = binary_size(BIF_ARG_1); + ERTS_GET_REAL_BIN(BIF_ARG_1, real_bin, offset, bitoffs, bitsize); + if (bitsize != 0) { + BIF_ERROR(BIF_P,BADARG); + } + if (size == 0) { + BIF_RET(NIL); + } + bytes = erts_get_aligned_binary_bytes(BIF_ARG_1, &temp_alloc); + if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK) { + erts_free_aligned_binary_bytes(temp_alloc); + BIF_ERROR(BIF_P,BADARG); + } + ret = do_utf8_to_list_normalize(BIF_P, num_chars, bytes, size); + erts_free_aligned_binary_bytes(temp_alloc); + BIF_RET(ret); +} + +BIF_RETTYPE file_native_name_encoding_0(BIF_ALIST_0) +{ + switch (erts_get_native_filename_encoding()) { + case ERL_FILENAME_LATIN1: + BIF_RET(am_latin1); + case ERL_FILENAME_UTF8_MAC: + case ERL_FILENAME_UTF8: + BIF_RET(am_utf8); + case ERL_FILENAME_WIN_WCHAR: + if (erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) { + BIF_RET(am_latin1); + } else { + BIF_RET(am_utf8); + } + default: + BIF_RET(am_undefined); + } +} diff --git a/erts/emulator/beam/erl_unicode_normalize.h b/erts/emulator/beam/erl_unicode_normalize.h new file mode 100644 index 0000000000..fb0a111ca2 --- /dev/null +++ b/erts/emulator/beam/erl_unicode_normalize.h @@ -0,0 +1,1687 @@ +/* +* %CopyrightBegin% +* +* Copyright Ericsson AB 1999-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 is automatically generated by dec.erl, do not edit manually +*/ +#define HASH_SIZE_FACTOR 2 +typedef struct _compose_entry { + Uint16 c; + Uint16 res; + Uint16 num_subs; + struct _compose_entry *subs; + int *hash; +} CompEntry; + +static int compose_tab_size = 61; +static int hash_compose_tab_0_15[12] = +{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_0_15 */ +static CompEntry compose_tab_0_15[] = { +{65, 7846, 0, NULL, NULL}, +{69, 7872, 0, NULL, NULL}, +{79, 7890, 0, NULL, NULL}, +{97, 7847, 0, NULL, NULL}, +{101, 7873, 0, NULL, NULL}, +{111, 7891, 0, NULL, NULL} +}; /* compose_tab_0_15 */ +static int hash_compose_tab_0_16[8] = +{3,-1,-1,-1,-1,0,2,1}; /* hash_compose_tab_0_16 */ +static CompEntry compose_tab_0_16[] = { +{69, 7700, 0, NULL, NULL}, +{79, 7760, 0, NULL, NULL}, +{101, 7701, 0, NULL, NULL}, +{111, 7761, 0, NULL, NULL} +}; /* compose_tab_0_16 */ +static int hash_compose_tab_0_17[4] = +{-1,0,1,-1}; /* hash_compose_tab_0_17 */ +static CompEntry compose_tab_0_17[] = { +{65, 7856, 0, NULL, NULL}, +{97, 7857, 0, NULL, NULL} +}; /* compose_tab_0_17 */ +static int hash_compose_tab_0_18[8] = +{-1,2,-1,-1,-1,0,1,3}; /* hash_compose_tab_0_18 */ +static CompEntry compose_tab_0_18[] = { +{85, 475, 0, NULL, NULL}, +{117, 476, 0, NULL, NULL}, +{953, 8146, 0, NULL, NULL}, +{965, 8162, 0, NULL, NULL} +}; /* compose_tab_0_18 */ +static int hash_compose_tab_0_19_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_0_19_0 */ +static CompEntry compose_tab_0_19_0[] = { +{913, 8074, 0, NULL, NULL}, +{919, 8090, 0, NULL, NULL}, +{937, 8106, 0, NULL, NULL}, +{945, 8066, 0, NULL, NULL}, +{951, 8082, 0, NULL, NULL}, +{969, 8098, 0, NULL, NULL} +}; /* compose_tab_0_19_0 */ +static int hash_compose_tab_0_19[28] = +{9,10,-1,5,-1,-1,-1,11,-1,-1,-1,-1,-1,6,12,-1,-1,1,13,-1,-1,2,7,3,-1,0,4,8}; /* hash_compose_tab_0_19 */ +static CompEntry compose_tab_0_19[] = { +{837, 0, 6, compose_tab_0_19_0, hash_compose_tab_0_19_0}, +{913, 7946, 0, NULL, NULL}, +{917, 7962, 0, NULL, NULL}, +{919, 7978, 0, NULL, NULL}, +{921, 7994, 0, NULL, NULL}, +{927, 8010, 0, NULL, NULL}, +{937, 8042, 0, NULL, NULL}, +{945, 7938, 0, NULL, NULL}, +{949, 7954, 0, NULL, NULL}, +{951, 7970, 0, NULL, NULL}, +{953, 7986, 0, NULL, NULL}, +{959, 8002, 0, NULL, NULL}, +{965, 8018, 0, NULL, NULL}, +{969, 8034, 0, NULL, NULL} +}; /* compose_tab_0_19 */ +static int hash_compose_tab_0_20_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_0_20_0 */ +static CompEntry compose_tab_0_20_0[] = { +{913, 8075, 0, NULL, NULL}, +{919, 8091, 0, NULL, NULL}, +{937, 8107, 0, NULL, NULL}, +{945, 8067, 0, NULL, NULL}, +{951, 8083, 0, NULL, NULL}, +{969, 8099, 0, NULL, NULL} +}; /* compose_tab_0_20_0 */ +static int hash_compose_tab_0_20[30] = +{-1,-1,-1,6,-1,13,-1,7,-1,14,-1,-1,-1,1,-1,8,-1,2,-1,3,9,4,10,11,-1,-1,-1,0,5, + 12}; /* hash_compose_tab_0_20 */ +static CompEntry compose_tab_0_20[] = { +{837, 0, 6, compose_tab_0_20_0, hash_compose_tab_0_20_0}, +{913, 7947, 0, NULL, NULL}, +{917, 7963, 0, NULL, NULL}, +{919, 7979, 0, NULL, NULL}, +{921, 7995, 0, NULL, NULL}, +{927, 8011, 0, NULL, NULL}, +{933, 8027, 0, NULL, NULL}, +{937, 8043, 0, NULL, NULL}, +{945, 7939, 0, NULL, NULL}, +{949, 7955, 0, NULL, NULL}, +{951, 7971, 0, NULL, NULL}, +{953, 7987, 0, NULL, NULL}, +{959, 8003, 0, NULL, NULL}, +{965, 8019, 0, NULL, NULL}, +{969, 8035, 0, NULL, NULL} +}; /* compose_tab_0_20 */ +static int hash_compose_tab_0_21[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_0_21 */ +static CompEntry compose_tab_0_21[] = { +{79, 7900, 0, NULL, NULL}, +{85, 7914, 0, NULL, NULL}, +{111, 7901, 0, NULL, NULL}, +{117, 7915, 0, NULL, NULL} +}; /* compose_tab_0_21 */ +static int hash_compose_tab_0_22[6] = +{-1,-1,-1,0,1,2}; /* hash_compose_tab_0_22 */ +static CompEntry compose_tab_0_22[] = { +{945, 8114, 0, NULL, NULL}, +{951, 8130, 0, NULL, NULL}, +{969, 8178, 0, NULL, NULL} +}; /* compose_tab_0_22 */ +static int hash_compose_tab_0[78] = +{38,3,29,-1,-1,-1,-1,4,19,5,20,6,14,30,31,21,32,33,37,7,-1,-1,-1,8,34,-1,-1,9, + -1,35,-1,-1,-1,10,36,-1,-1,-1,-1,11,-1,12,-1,13,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,23,-1,22,-1,24,-1,25,-1,26,-1,0,-1,-1,15,1,16,27,17,2,18,28,-1,-1}; /* hash_compose_tab_0 */ +static CompEntry compose_tab_0[] = { +{65, 192, 0, NULL, NULL}, +{69, 200, 0, NULL, NULL}, +{73, 204, 0, NULL, NULL}, +{79, 210, 0, NULL, NULL}, +{85, 217, 0, NULL, NULL}, +{87, 7808, 0, NULL, NULL}, +{89, 7922, 0, NULL, NULL}, +{97, 224, 0, NULL, NULL}, +{101, 232, 0, NULL, NULL}, +{105, 236, 0, NULL, NULL}, +{111, 242, 0, NULL, NULL}, +{117, 249, 0, NULL, NULL}, +{119, 7809, 0, NULL, NULL}, +{121, 7923, 0, NULL, NULL}, +{168, 8173, 0, NULL, NULL}, +{770, 0, 6, compose_tab_0_15, hash_compose_tab_0_15}, +{772, 0, 4, compose_tab_0_16, hash_compose_tab_0_16}, +{774, 0, 2, compose_tab_0_17, hash_compose_tab_0_17}, +{776, 0, 4, compose_tab_0_18, hash_compose_tab_0_18}, +{787, 0, 14, compose_tab_0_19, hash_compose_tab_0_19}, +{788, 0, 15, compose_tab_0_20, hash_compose_tab_0_20}, +{795, 0, 4, compose_tab_0_21, hash_compose_tab_0_21}, +{837, 0, 3, compose_tab_0_22, hash_compose_tab_0_22}, +{913, 8122, 0, NULL, NULL}, +{917, 8136, 0, NULL, NULL}, +{919, 8138, 0, NULL, NULL}, +{921, 8154, 0, NULL, NULL}, +{927, 8184, 0, NULL, NULL}, +{933, 8170, 0, NULL, NULL}, +{937, 8186, 0, NULL, NULL}, +{945, 8048, 0, NULL, NULL}, +{949, 8050, 0, NULL, NULL}, +{951, 8052, 0, NULL, NULL}, +{953, 8054, 0, NULL, NULL}, +{959, 8056, 0, NULL, NULL}, +{965, 8058, 0, NULL, NULL}, +{969, 8060, 0, NULL, NULL}, +{8127, 8141, 0, NULL, NULL}, +{8190, 8157, 0, NULL, NULL} +}; /* compose_tab_0 */ +static int hash_compose_tab_1_39[12] = +{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_1_39 */ +static CompEntry compose_tab_1_39[] = { +{65, 7844, 0, NULL, NULL}, +{69, 7870, 0, NULL, NULL}, +{79, 7888, 0, NULL, NULL}, +{97, 7845, 0, NULL, NULL}, +{101, 7871, 0, NULL, NULL}, +{111, 7889, 0, NULL, NULL} +}; /* compose_tab_1_39 */ +static int hash_compose_tab_1_40[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_1_40 */ +static CompEntry compose_tab_1_40[] = { +{79, 7756, 0, NULL, NULL}, +{85, 7800, 0, NULL, NULL}, +{111, 7757, 0, NULL, NULL}, +{117, 7801, 0, NULL, NULL} +}; /* compose_tab_1_40 */ +static int hash_compose_tab_1_41[8] = +{3,-1,-1,-1,-1,0,2,1}; /* hash_compose_tab_1_41 */ +static CompEntry compose_tab_1_41[] = { +{69, 7702, 0, NULL, NULL}, +{79, 7762, 0, NULL, NULL}, +{101, 7703, 0, NULL, NULL}, +{111, 7763, 0, NULL, NULL} +}; /* compose_tab_1_41 */ +static int hash_compose_tab_1_42[4] = +{-1,0,1,-1}; /* hash_compose_tab_1_42 */ +static CompEntry compose_tab_1_42[] = { +{65, 7854, 0, NULL, NULL}, +{97, 7855, 0, NULL, NULL} +}; /* compose_tab_1_42 */ +static int hash_compose_tab_1_43[12] = +{-1,0,1,-1,-1,4,5,-1,-1,2,3,-1}; /* hash_compose_tab_1_43 */ +static CompEntry compose_tab_1_43[] = { +{73, 7726, 0, NULL, NULL}, +{85, 471, 0, NULL, NULL}, +{105, 7727, 0, NULL, NULL}, +{117, 472, 0, NULL, NULL}, +{953, 8147, 0, NULL, NULL}, +{965, 8163, 0, NULL, NULL} +}; /* compose_tab_1_43 */ +static int hash_compose_tab_1_44[4] = +{-1,0,1,-1}; /* hash_compose_tab_1_44 */ +static CompEntry compose_tab_1_44[] = { +{65, 506, 0, NULL, NULL}, +{97, 507, 0, NULL, NULL} +}; /* compose_tab_1_44 */ +static int hash_compose_tab_1_45_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_1_45_0 */ +static CompEntry compose_tab_1_45_0[] = { +{913, 8076, 0, NULL, NULL}, +{919, 8092, 0, NULL, NULL}, +{937, 8108, 0, NULL, NULL}, +{945, 8068, 0, NULL, NULL}, +{951, 8084, 0, NULL, NULL}, +{969, 8100, 0, NULL, NULL} +}; /* compose_tab_1_45_0 */ +static int hash_compose_tab_1_45[28] = +{9,10,-1,5,-1,-1,-1,11,-1,-1,-1,-1,-1,6,12,-1,-1,1,13,-1,-1,2,7,3,-1,0,4,8}; /* hash_compose_tab_1_45 */ +static CompEntry compose_tab_1_45[] = { +{837, 0, 6, compose_tab_1_45_0, hash_compose_tab_1_45_0}, +{913, 7948, 0, NULL, NULL}, +{917, 7964, 0, NULL, NULL}, +{919, 7980, 0, NULL, NULL}, +{921, 7996, 0, NULL, NULL}, +{927, 8012, 0, NULL, NULL}, +{937, 8044, 0, NULL, NULL}, +{945, 7940, 0, NULL, NULL}, +{949, 7956, 0, NULL, NULL}, +{951, 7972, 0, NULL, NULL}, +{953, 7988, 0, NULL, NULL}, +{959, 8004, 0, NULL, NULL}, +{965, 8020, 0, NULL, NULL}, +{969, 8036, 0, NULL, NULL} +}; /* compose_tab_1_45 */ +static int hash_compose_tab_1_46_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_1_46_0 */ +static CompEntry compose_tab_1_46_0[] = { +{913, 8077, 0, NULL, NULL}, +{919, 8093, 0, NULL, NULL}, +{937, 8109, 0, NULL, NULL}, +{945, 8069, 0, NULL, NULL}, +{951, 8085, 0, NULL, NULL}, +{969, 8101, 0, NULL, NULL} +}; /* compose_tab_1_46_0 */ +static int hash_compose_tab_1_46[30] = +{-1,-1,-1,6,-1,13,-1,7,-1,14,-1,-1,-1,1,-1,8,-1,2,-1,3,9,4,10,11,-1,-1,-1,0,5, + 12}; /* hash_compose_tab_1_46 */ +static CompEntry compose_tab_1_46[] = { +{837, 0, 6, compose_tab_1_46_0, hash_compose_tab_1_46_0}, +{913, 7949, 0, NULL, NULL}, +{917, 7965, 0, NULL, NULL}, +{919, 7981, 0, NULL, NULL}, +{921, 7997, 0, NULL, NULL}, +{927, 8013, 0, NULL, NULL}, +{933, 8029, 0, NULL, NULL}, +{937, 8045, 0, NULL, NULL}, +{945, 7941, 0, NULL, NULL}, +{949, 7957, 0, NULL, NULL}, +{951, 7973, 0, NULL, NULL}, +{953, 7989, 0, NULL, NULL}, +{959, 8005, 0, NULL, NULL}, +{965, 8021, 0, NULL, NULL}, +{969, 8037, 0, NULL, NULL} +}; /* compose_tab_1_46 */ +static int hash_compose_tab_1_47[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_1_47 */ +static CompEntry compose_tab_1_47[] = { +{79, 7898, 0, NULL, NULL}, +{85, 7912, 0, NULL, NULL}, +{111, 7899, 0, NULL, NULL}, +{117, 7913, 0, NULL, NULL} +}; /* compose_tab_1_47 */ +static int hash_compose_tab_1_48[4] = +{1,-1,-1,0}; /* hash_compose_tab_1_48 */ +static CompEntry compose_tab_1_48[] = { +{67, 7688, 0, NULL, NULL}, +{99, 7689, 0, NULL, NULL} +}; /* compose_tab_1_48 */ +static int hash_compose_tab_1_49[6] = +{-1,-1,-1,0,1,2}; /* hash_compose_tab_1_49 */ +static CompEntry compose_tab_1_49[] = { +{945, 8116, 0, NULL, NULL}, +{951, 8132, 0, NULL, NULL}, +{959, 8180, 0, NULL, NULL} +}; /* compose_tab_1_49 */ +static int hash_compose_tab_1[140] = +{-1,-1,-1,-1,-1,-1,-1,68,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,34,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,35,-1,-1,-1,-1,64,-1,0,-1,1,-1,2,39,3,40,4,41,5,6,7, + 8,9,10,36,11,12,42,13,43,14,44,15,16,37,45,46,50,47,51,17,52,18,53,19,54,20, + 55,21,56,22,23,24,25,26,27,38,28,29,48,30,57,31,58,32,33,59,60,61,62,65,66, + 63,67,69,-1,-1,-1,-1,-1,49,-1,-1}; /* hash_compose_tab_1 */ +static CompEntry compose_tab_1[] = { +{65, 193, 0, NULL, NULL}, +{67, 262, 0, NULL, NULL}, +{69, 201, 0, NULL, NULL}, +{71, 500, 0, NULL, NULL}, +{73, 205, 0, NULL, NULL}, +{75, 7728, 0, NULL, NULL}, +{76, 313, 0, NULL, NULL}, +{77, 7742, 0, NULL, NULL}, +{78, 323, 0, NULL, NULL}, +{79, 211, 0, NULL, NULL}, +{80, 7764, 0, NULL, NULL}, +{82, 340, 0, NULL, NULL}, +{83, 346, 0, NULL, NULL}, +{85, 218, 0, NULL, NULL}, +{87, 7810, 0, NULL, NULL}, +{89, 221, 0, NULL, NULL}, +{90, 377, 0, NULL, NULL}, +{97, 225, 0, NULL, NULL}, +{99, 263, 0, NULL, NULL}, +{101, 233, 0, NULL, NULL}, +{103, 501, 0, NULL, NULL}, +{105, 237, 0, NULL, NULL}, +{107, 7729, 0, NULL, NULL}, +{108, 314, 0, NULL, NULL}, +{109, 7743, 0, NULL, NULL}, +{110, 324, 0, NULL, NULL}, +{111, 243, 0, NULL, NULL}, +{112, 7765, 0, NULL, NULL}, +{114, 341, 0, NULL, NULL}, +{115, 347, 0, NULL, NULL}, +{117, 250, 0, NULL, NULL}, +{119, 7811, 0, NULL, NULL}, +{121, 253, 0, NULL, NULL}, +{122, 378, 0, NULL, NULL}, +{168, 8174, 0, NULL, NULL}, +{198, 508, 0, NULL, NULL}, +{216, 510, 0, NULL, NULL}, +{230, 509, 0, NULL, NULL}, +{248, 511, 0, NULL, NULL}, +{770, 0, 6, compose_tab_1_39, hash_compose_tab_1_39}, +{771, 0, 4, compose_tab_1_40, hash_compose_tab_1_40}, +{772, 0, 4, compose_tab_1_41, hash_compose_tab_1_41}, +{774, 0, 2, compose_tab_1_42, hash_compose_tab_1_42}, +{776, 0, 6, compose_tab_1_43, hash_compose_tab_1_43}, +{778, 0, 2, compose_tab_1_44, hash_compose_tab_1_44}, +{787, 0, 14, compose_tab_1_45, hash_compose_tab_1_45}, +{788, 0, 15, compose_tab_1_46, hash_compose_tab_1_46}, +{795, 0, 4, compose_tab_1_47, hash_compose_tab_1_47}, +{807, 0, 2, compose_tab_1_48, hash_compose_tab_1_48}, +{837, 0, 3, compose_tab_1_49, hash_compose_tab_1_49}, +{913, 8123, 0, NULL, NULL}, +{917, 8137, 0, NULL, NULL}, +{919, 8139, 0, NULL, NULL}, +{921, 8155, 0, NULL, NULL}, +{927, 8185, 0, NULL, NULL}, +{933, 8171, 0, NULL, NULL}, +{937, 8187, 0, NULL, NULL}, +{945, 8049, 0, NULL, NULL}, +{949, 8051, 0, NULL, NULL}, +{951, 8053, 0, NULL, NULL}, +{953, 8055, 0, NULL, NULL}, +{959, 8057, 0, NULL, NULL}, +{965, 8059, 0, NULL, NULL}, +{969, 8061, 0, NULL, NULL}, +{1043, 1027, 0, NULL, NULL}, +{1050, 1036, 0, NULL, NULL}, +{1075, 1107, 0, NULL, NULL}, +{1082, 1116, 0, NULL, NULL}, +{8127, 8142, 0, NULL, NULL}, +{8190, 8158, 0, NULL, NULL} +}; /* compose_tab_1 */ +static int hash_compose_tab_2_26[12] = +{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_2_26 */ +static CompEntry compose_tab_2_26[] = { +{65, 7852, 0, NULL, NULL}, +{69, 7878, 0, NULL, NULL}, +{79, 7896, 0, NULL, NULL}, +{97, 7853, 0, NULL, NULL}, +{101, 7879, 0, NULL, NULL}, +{111, 7897, 0, NULL, NULL} +}; /* compose_tab_2_26 */ +static int hash_compose_tab_2[54] = +{-1,-1,-1,20,-1,-1,-1,21,-1,22,-1,0,23,1,24,2,25,3,4,5,6,-1,-1,-1,-1,7,-1,-1, + -1,8,-1,9,-1,10,-1,11,12,-1,-1,-1,-1,-1,-1,13,-1,14,-1,15,26,16,17,18,19,-1}; /* hash_compose_tab_2 */ +static CompEntry compose_tab_2[] = { +{65, 194, 0, NULL, NULL}, +{67, 264, 0, NULL, NULL}, +{69, 202, 0, NULL, NULL}, +{71, 284, 0, NULL, NULL}, +{72, 292, 0, NULL, NULL}, +{73, 206, 0, NULL, NULL}, +{74, 308, 0, NULL, NULL}, +{79, 212, 0, NULL, NULL}, +{83, 348, 0, NULL, NULL}, +{85, 219, 0, NULL, NULL}, +{87, 372, 0, NULL, NULL}, +{89, 374, 0, NULL, NULL}, +{90, 7824, 0, NULL, NULL}, +{97, 226, 0, NULL, NULL}, +{99, 265, 0, NULL, NULL}, +{101, 234, 0, NULL, NULL}, +{103, 285, 0, NULL, NULL}, +{104, 293, 0, NULL, NULL}, +{105, 238, 0, NULL, NULL}, +{106, 309, 0, NULL, NULL}, +{111, 244, 0, NULL, NULL}, +{115, 349, 0, NULL, NULL}, +{117, 251, 0, NULL, NULL}, +{119, 373, 0, NULL, NULL}, +{121, 375, 0, NULL, NULL}, +{122, 7825, 0, NULL, NULL}, +{803, 0, 6, compose_tab_2_26, hash_compose_tab_2_26} +}; /* compose_tab_2 */ +static int hash_compose_tab_3_16[12] = +{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_3_16 */ +static CompEntry compose_tab_3_16[] = { +{65, 7850, 0, NULL, NULL}, +{69, 7876, 0, NULL, NULL}, +{79, 7894, 0, NULL, NULL}, +{97, 7851, 0, NULL, NULL}, +{101, 7877, 0, NULL, NULL}, +{111, 7895, 0, NULL, NULL} +}; /* compose_tab_3_16 */ +static int hash_compose_tab_3_17[4] = +{-1,0,1,-1}; /* hash_compose_tab_3_17 */ +static CompEntry compose_tab_3_17[] = { +{65, 7860, 0, NULL, NULL}, +{97, 7861, 0, NULL, NULL} +}; /* compose_tab_3_17 */ +static int hash_compose_tab_3_18[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_3_18 */ +static CompEntry compose_tab_3_18[] = { +{79, 7904, 0, NULL, NULL}, +{85, 7918, 0, NULL, NULL}, +{111, 7905, 0, NULL, NULL}, +{117, 7919, 0, NULL, NULL} +}; /* compose_tab_3_18 */ +static int hash_compose_tab_3[38] = +{-1,-1,3,4,13,14,-1,15,-1,5,6,16,-1,7,17,-1,-1,-1,-1,-1,-1,8,-1,-1,-1,9,-1,0, + -1,10,-1,1,-1,-1,11,2,12,18}; /* hash_compose_tab_3 */ +static CompEntry compose_tab_3[] = { +{65, 195, 0, NULL, NULL}, +{69, 7868, 0, NULL, NULL}, +{73, 296, 0, NULL, NULL}, +{78, 209, 0, NULL, NULL}, +{79, 213, 0, NULL, NULL}, +{85, 360, 0, NULL, NULL}, +{86, 7804, 0, NULL, NULL}, +{89, 7928, 0, NULL, NULL}, +{97, 227, 0, NULL, NULL}, +{101, 7869, 0, NULL, NULL}, +{105, 297, 0, NULL, NULL}, +{110, 241, 0, NULL, NULL}, +{111, 245, 0, NULL, NULL}, +{117, 361, 0, NULL, NULL}, +{118, 7805, 0, NULL, NULL}, +{121, 7929, 0, NULL, NULL}, +{770, 0, 6, compose_tab_3_16, hash_compose_tab_3_16}, +{774, 0, 2, compose_tab_3_17, hash_compose_tab_3_17}, +{795, 0, 4, compose_tab_3_18, hash_compose_tab_3_18} +}; /* compose_tab_3 */ +static int hash_compose_tab_4_14[4] = +{-1,0,1,-1}; /* hash_compose_tab_4_14 */ +static CompEntry compose_tab_4_14[] = { +{65, 480, 0, NULL, NULL}, +{97, 481, 0, NULL, NULL} +}; /* compose_tab_4_14 */ +static int hash_compose_tab_4_15[8] = +{-1,0,2,-1,-1,1,3,-1}; /* hash_compose_tab_4_15 */ +static CompEntry compose_tab_4_15[] = { +{65, 478, 0, NULL, NULL}, +{85, 469, 0, NULL, NULL}, +{97, 479, 0, NULL, NULL}, +{117, 470, 0, NULL, NULL} +}; /* compose_tab_4_15 */ +static int hash_compose_tab_4_16[8] = +{-1,-1,1,3,0,2,-1,-1}; /* hash_compose_tab_4_16 */ +static CompEntry compose_tab_4_16[] = { +{76, 7736, 0, NULL, NULL}, +{82, 7772, 0, NULL, NULL}, +{108, 7737, 0, NULL, NULL}, +{114, 7773, 0, NULL, NULL} +}; /* compose_tab_4_16 */ +static int hash_compose_tab_4_17[4] = +{1,-1,-1,0}; /* hash_compose_tab_4_17 */ +static CompEntry compose_tab_4_17[] = { +{79, 492, 0, NULL, NULL}, +{111, 493, 0, NULL, NULL} +}; /* compose_tab_4_17 */ +static int hash_compose_tab_4[56] = +{-1,22,-1,-1,-1,11,13,-1,-1,0,-1,-1,-1,1,23,2,26,3,18,16,-1,-1,-1,4,17,19,-1, + 27,-1,5,12,-1,-1,-1,-1,-1,-1,20,-1,-1,24,6,-1,-1,-1,7,-1,8,14,9,15,21,25,-1, + -1,10}; /* hash_compose_tab_4 */ +static CompEntry compose_tab_4[] = { +{65, 256, 0, NULL, NULL}, +{69, 274, 0, NULL, NULL}, +{71, 7712, 0, NULL, NULL}, +{73, 298, 0, NULL, NULL}, +{79, 332, 0, NULL, NULL}, +{85, 362, 0, NULL, NULL}, +{97, 257, 0, NULL, NULL}, +{101, 275, 0, NULL, NULL}, +{103, 7713, 0, NULL, NULL}, +{105, 299, 0, NULL, NULL}, +{111, 333, 0, NULL, NULL}, +{117, 363, 0, NULL, NULL}, +{198, 482, 0, NULL, NULL}, +{230, 483, 0, NULL, NULL}, +{775, 0, 2, compose_tab_4_14, hash_compose_tab_4_14}, +{776, 0, 4, compose_tab_4_15, hash_compose_tab_4_15}, +{803, 0, 4, compose_tab_4_16, hash_compose_tab_4_16}, +{808, 0, 2, compose_tab_4_17, hash_compose_tab_4_17}, +{913, 8121, 0, NULL, NULL}, +{921, 8153, 0, NULL, NULL}, +{933, 8169, 0, NULL, NULL}, +{945, 8113, 0, NULL, NULL}, +{953, 8145, 0, NULL, NULL}, +{965, 8161, 0, NULL, NULL}, +{1048, 1250, 0, NULL, NULL}, +{1059, 1262, 0, NULL, NULL}, +{1080, 1251, 0, NULL, NULL}, +{1091, 1263, 0, NULL, NULL} +}; /* compose_tab_4 */ +static int hash_compose_tab_5_12[4] = +{-1,0,1,-1}; /* hash_compose_tab_5_12 */ +static CompEntry compose_tab_5_12[] = { +{65, 7862, 0, NULL, NULL}, +{97, 7863, 0, NULL, NULL} +}; /* compose_tab_5_12 */ +static int hash_compose_tab_5_13[4] = +{-1,0,1,-1}; /* hash_compose_tab_5_13 */ +static CompEntry compose_tab_5_13[] = { +{69, 7708, 0, NULL, NULL}, +{101, 7709, 0, NULL, NULL} +}; /* compose_tab_5_13 */ +static int hash_compose_tab_5[60] = +{28,-1,-1,-1,-1,0,19,-1,-1,1,-1,2,29,3,14,-1,-1,-1,-1,4,20,15,-1,12,-1,5,21, + 13,22,23,-1,-1,-1,16,-1,-1,-1,6,-1,24,-1,7,-1,8,-1,9,17,-1,-1,-1,-1,10,25,18, + -1,-1,-1,11,26,27}; /* hash_compose_tab_5 */ +static CompEntry compose_tab_5[] = { +{65, 258, 0, NULL, NULL}, +{69, 276, 0, NULL, NULL}, +{71, 286, 0, NULL, NULL}, +{73, 300, 0, NULL, NULL}, +{79, 334, 0, NULL, NULL}, +{85, 364, 0, NULL, NULL}, +{97, 259, 0, NULL, NULL}, +{101, 277, 0, NULL, NULL}, +{103, 287, 0, NULL, NULL}, +{105, 301, 0, NULL, NULL}, +{111, 335, 0, NULL, NULL}, +{117, 365, 0, NULL, NULL}, +{803, 0, 2, compose_tab_5_12, hash_compose_tab_5_12}, +{807, 0, 2, compose_tab_5_13, hash_compose_tab_5_13}, +{913, 8120, 0, NULL, NULL}, +{921, 8152, 0, NULL, NULL}, +{933, 8168, 0, NULL, NULL}, +{945, 8112, 0, NULL, NULL}, +{953, 8144, 0, NULL, NULL}, +{965, 8160, 0, NULL, NULL}, +{1040, 1232, 0, NULL, NULL}, +{1045, 1238, 0, NULL, NULL}, +{1046, 1217, 0, NULL, NULL}, +{1048, 1049, 0, NULL, NULL}, +{1059, 1038, 0, NULL, NULL}, +{1072, 1233, 0, NULL, NULL}, +{1077, 1239, 0, NULL, NULL}, +{1078, 1218, 0, NULL, NULL}, +{1080, 1081, 0, NULL, NULL}, +{1091, 1118, 0, NULL, NULL} +}; /* compose_tab_5 */ +static int hash_compose_tab_6_36[4] = +{1,-1,-1,0}; /* hash_compose_tab_6_36 */ +static CompEntry compose_tab_6_36[] = { +{83, 7780, 0, NULL, NULL}, +{115, 7781, 0, NULL, NULL} +}; /* compose_tab_6_36 */ +static int hash_compose_tab_6_38[4] = +{1,-1,-1,0}; /* hash_compose_tab_6_38 */ +static CompEntry compose_tab_6_38[] = { +{83, 7782, 0, NULL, NULL}, +{115, 7783, 0, NULL, NULL} +}; /* compose_tab_6_38 */ +static int hash_compose_tab_6_39[4] = +{1,-1,-1,0}; /* hash_compose_tab_6_39 */ +static CompEntry compose_tab_6_39[] = { +{83, 7784, 0, NULL, NULL}, +{115, 7785, 0, NULL, NULL} +}; /* compose_tab_6_39 */ +static int hash_compose_tab_6[80] = +{10,-1,11,12,13,39,-1,14,15,16,17,-1,-1,-1,-1,-1,-1,-1,18,19,20,21,22,23,24, + -1,-1,-1,-1,25,26,-1,27,-1,28,29,30,-1,-1,31,32,33,34,-1,-1,-1,-1,-1,-1,36, + -1,-1,-1,-1,37,-1,-1,-1,-1,-1,38,-1,-1,35,-1,-1,0,1,2,3,4,5,6,7,-1,-1,-1,8,9, + -1}; /* hash_compose_tab_6 */ +static CompEntry compose_tab_6[] = { +{66, 7682, 0, NULL, NULL}, +{67, 266, 0, NULL, NULL}, +{68, 7690, 0, NULL, NULL}, +{69, 278, 0, NULL, NULL}, +{70, 7710, 0, NULL, NULL}, +{71, 288, 0, NULL, NULL}, +{72, 7714, 0, NULL, NULL}, +{73, 304, 0, NULL, NULL}, +{77, 7744, 0, NULL, NULL}, +{78, 7748, 0, NULL, NULL}, +{80, 7766, 0, NULL, NULL}, +{82, 7768, 0, NULL, NULL}, +{83, 7776, 0, NULL, NULL}, +{84, 7786, 0, NULL, NULL}, +{87, 7814, 0, NULL, NULL}, +{88, 7818, 0, NULL, NULL}, +{89, 7822, 0, NULL, NULL}, +{90, 379, 0, NULL, NULL}, +{98, 7683, 0, NULL, NULL}, +{99, 267, 0, NULL, NULL}, +{100, 7691, 0, NULL, NULL}, +{101, 279, 0, NULL, NULL}, +{102, 7711, 0, NULL, NULL}, +{103, 289, 0, NULL, NULL}, +{104, 7715, 0, NULL, NULL}, +{109, 7745, 0, NULL, NULL}, +{110, 7749, 0, NULL, NULL}, +{112, 7767, 0, NULL, NULL}, +{114, 7769, 0, NULL, NULL}, +{115, 7777, 0, NULL, NULL}, +{116, 7787, 0, NULL, NULL}, +{119, 7815, 0, NULL, NULL}, +{120, 7819, 0, NULL, NULL}, +{121, 7823, 0, NULL, NULL}, +{122, 380, 0, NULL, NULL}, +{383, 7835, 0, NULL, NULL}, +{769, 0, 2, compose_tab_6_36, hash_compose_tab_6_36}, +{774, 784, 0, NULL, NULL}, +{780, 0, 2, compose_tab_6_38, hash_compose_tab_6_38}, +{803, 0, 2, compose_tab_6_39, hash_compose_tab_6_39} +}; /* compose_tab_6 */ +static int hash_compose_tab_7_23[4] = +{1,-1,-1,0}; /* hash_compose_tab_7_23 */ +static CompEntry compose_tab_7_23[] = { +{79, 7758, 0, NULL, NULL}, +{111, 7759, 0, NULL, NULL} +}; /* compose_tab_7_23 */ +static int hash_compose_tab_7_24[4] = +{-1,0,1,-1}; /* hash_compose_tab_7_24 */ +static CompEntry compose_tab_7_24[] = { +{85, 7802, 0, NULL, NULL}, +{117, 7803, 0, NULL, NULL} +}; /* compose_tab_7_24 */ +static int hash_compose_tab_7[100] = +{48,10,21,-1,11,12,-1,-1,-1,-1,49,13,-1,-1,-1,20,14,15,-1,16,17,18,25,-1,-1, + -1,-1,-1,-1,22,30,-1,-1,26,-1,-1,-1,-1,-1,-1,31,-1,-1,-1,-1,32,33,34,35,-1, + -1,-1,-1,27,36,-1,-1,-1,-1,37,-1,-1,-1,38,-1,0,28,39,-1,1,-1,23,2,3,24,40,-1, + 41,29,4,42,43,44,-1,-1,5,45,6,7,8,-1,46,-1,-1,-1,47,-1,9,-1,19}; /* hash_compose_tab_7 */ +static CompEntry compose_tab_7[] = { +{65, 196, 0, NULL, NULL}, +{69, 203, 0, NULL, NULL}, +{72, 7718, 0, NULL, NULL}, +{73, 207, 0, NULL, NULL}, +{79, 214, 0, NULL, NULL}, +{85, 220, 0, NULL, NULL}, +{87, 7812, 0, NULL, NULL}, +{88, 7820, 0, NULL, NULL}, +{89, 376, 0, NULL, NULL}, +{97, 228, 0, NULL, NULL}, +{101, 235, 0, NULL, NULL}, +{104, 7719, 0, NULL, NULL}, +{105, 239, 0, NULL, NULL}, +{111, 246, 0, NULL, NULL}, +{116, 7831, 0, NULL, NULL}, +{117, 252, 0, NULL, NULL}, +{119, 7813, 0, NULL, NULL}, +{120, 7821, 0, NULL, NULL}, +{121, 255, 0, NULL, NULL}, +{399, 1242, 0, NULL, NULL}, +{415, 1258, 0, NULL, NULL}, +{601, 1243, 0, NULL, NULL}, +{629, 1259, 0, NULL, NULL}, +{771, 0, 2, compose_tab_7_23, hash_compose_tab_7_23}, +{772, 0, 2, compose_tab_7_24, hash_compose_tab_7_24}, +{921, 938, 0, NULL, NULL}, +{933, 939, 0, NULL, NULL}, +{953, 970, 0, NULL, NULL}, +{965, 971, 0, NULL, NULL}, +{978, 980, 0, NULL, NULL}, +{1030, 1031, 0, NULL, NULL}, +{1040, 1234, 0, NULL, NULL}, +{1045, 1025, 0, NULL, NULL}, +{1046, 1244, 0, NULL, NULL}, +{1047, 1246, 0, NULL, NULL}, +{1048, 1252, 0, NULL, NULL}, +{1054, 1254, 0, NULL, NULL}, +{1059, 1264, 0, NULL, NULL}, +{1063, 1268, 0, NULL, NULL}, +{1067, 1272, 0, NULL, NULL}, +{1072, 1235, 0, NULL, NULL}, +{1077, 1105, 0, NULL, NULL}, +{1078, 1245, 0, NULL, NULL}, +{1079, 1247, 0, NULL, NULL}, +{1080, 1253, 0, NULL, NULL}, +{1086, 1255, 0, NULL, NULL}, +{1091, 1265, 0, NULL, NULL}, +{1095, 1269, 0, NULL, NULL}, +{1099, 1273, 0, NULL, NULL}, +{1110, 1111, 0, NULL, NULL} +}; /* compose_tab_7 */ +static int hash_compose_tab_8_12[12] = +{-1,3,-1,5,-1,0,4,2,-1,1,-1,-1}; /* hash_compose_tab_8_12 */ +static CompEntry compose_tab_8_12[] = { +{65, 7848, 0, NULL, NULL}, +{69, 7874, 0, NULL, NULL}, +{79, 7892, 0, NULL, NULL}, +{97, 7849, 0, NULL, NULL}, +{101, 7875, 0, NULL, NULL}, +{111, 7893, 0, NULL, NULL} +}; /* compose_tab_8_12 */ +static int hash_compose_tab_8_13[4] = +{-1,0,1,-1}; /* hash_compose_tab_8_13 */ +static CompEntry compose_tab_8_13[] = { +{65, 7858, 0, NULL, NULL}, +{97, 7859, 0, NULL, NULL} +}; /* compose_tab_8_13 */ +static int hash_compose_tab_8_14[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_8_14 */ +static CompEntry compose_tab_8_14[] = { +{79, 7902, 0, NULL, NULL}, +{85, 7916, 0, NULL, NULL}, +{111, 7903, 0, NULL, NULL}, +{117, 7917, 0, NULL, NULL} +}; /* compose_tab_8_14 */ +static int hash_compose_tab_8[30] = +{-1,11,-1,-1,-1,0,-1,6,-1,1,-1,7,-1,2,-1,8,14,-1,-1,3,12,9,-1,-1,13,4,-1,10, + -1,5}; /* hash_compose_tab_8 */ +static CompEntry compose_tab_8[] = { +{65, 7842, 0, NULL, NULL}, +{69, 7866, 0, NULL, NULL}, +{73, 7880, 0, NULL, NULL}, +{79, 7886, 0, NULL, NULL}, +{85, 7910, 0, NULL, NULL}, +{89, 7926, 0, NULL, NULL}, +{97, 7843, 0, NULL, NULL}, +{101, 7867, 0, NULL, NULL}, +{105, 7881, 0, NULL, NULL}, +{111, 7887, 0, NULL, NULL}, +{117, 7911, 0, NULL, NULL}, +{121, 7927, 0, NULL, NULL}, +{770, 0, 6, compose_tab_8_12, hash_compose_tab_8_12}, +{774, 0, 2, compose_tab_8_13, hash_compose_tab_8_13}, +{795, 0, 4, compose_tab_8_14, hash_compose_tab_8_14} +}; /* compose_tab_8 */ +static int hash_compose_tab_9[12] = +{-1,1,2,5,-1,0,-1,-1,-1,3,-1,4}; /* hash_compose_tab_9 */ +static CompEntry compose_tab_9[] = { +{65, 197, 0, NULL, NULL}, +{85, 366, 0, NULL, NULL}, +{97, 229, 0, NULL, NULL}, +{117, 367, 0, NULL, NULL}, +{119, 7832, 0, NULL, NULL}, +{121, 7833, 0, NULL, NULL} +}; /* compose_tab_9 */ +static int hash_compose_tab_10[12] = +{-1,1,-1,2,4,-1,-1,0,-1,3,-1,5}; /* hash_compose_tab_10 */ +static CompEntry compose_tab_10[] = { +{79, 336, 0, NULL, NULL}, +{85, 368, 0, NULL, NULL}, +{111, 337, 0, NULL, NULL}, +{117, 369, 0, NULL, NULL}, +{1059, 1266, 0, NULL, NULL}, +{1091, 1267, 0, NULL, NULL} +}; /* compose_tab_10 */ +static int hash_compose_tab_11_33[4] = +{-1,0,1,-1}; /* hash_compose_tab_11_33 */ +static CompEntry compose_tab_11_33[] = { +{85, 473, 0, NULL, NULL}, +{117, 474, 0, NULL, NULL} +}; /* compose_tab_11_33 */ +static int hash_compose_tab_11[68] = +{2,3,-1,4,-1,5,-1,6,7,-1,8,9,-1,-1,10,11,12,13,-1,-1,-1,-1,14,-1,-1,-1,-1,-1, + 33,15,-1,16,17,18,31,19,-1,20,21,22,23,-1,24,25,-1,-1,26,27,28,29,32,-1,-1, + -1,30,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,1}; /* hash_compose_tab_11 */ +static CompEntry compose_tab_11[] = { +{65, 461, 0, NULL, NULL}, +{67, 268, 0, NULL, NULL}, +{68, 270, 0, NULL, NULL}, +{69, 282, 0, NULL, NULL}, +{71, 486, 0, NULL, NULL}, +{73, 463, 0, NULL, NULL}, +{75, 488, 0, NULL, NULL}, +{76, 317, 0, NULL, NULL}, +{78, 327, 0, NULL, NULL}, +{79, 465, 0, NULL, NULL}, +{82, 344, 0, NULL, NULL}, +{83, 352, 0, NULL, NULL}, +{84, 356, 0, NULL, NULL}, +{85, 467, 0, NULL, NULL}, +{90, 381, 0, NULL, NULL}, +{97, 462, 0, NULL, NULL}, +{99, 269, 0, NULL, NULL}, +{100, 271, 0, NULL, NULL}, +{101, 283, 0, NULL, NULL}, +{103, 487, 0, NULL, NULL}, +{105, 464, 0, NULL, NULL}, +{106, 496, 0, NULL, NULL}, +{107, 489, 0, NULL, NULL}, +{108, 318, 0, NULL, NULL}, +{110, 328, 0, NULL, NULL}, +{111, 466, 0, NULL, NULL}, +{114, 345, 0, NULL, NULL}, +{115, 353, 0, NULL, NULL}, +{116, 357, 0, NULL, NULL}, +{117, 468, 0, NULL, NULL}, +{122, 382, 0, NULL, NULL}, +{439, 494, 0, NULL, NULL}, +{658, 495, 0, NULL, NULL}, +{776, 0, 2, compose_tab_11_33, hash_compose_tab_11_33} +}; /* compose_tab_11 */ +static int hash_compose_tab_12_1[4] = +{-1,0,1,-1}; /* hash_compose_tab_12_1 */ +static CompEntry compose_tab_12_1[] = { +{953, 912, 0, NULL, NULL}, +{965, 944, 0, NULL, NULL} +}; /* compose_tab_12_1 */ +static int hash_compose_tab_12[34] = +{11,4,12,5,-1,-1,-1,13,-1,6,-1,-1,-1,14,-1,7,-1,15,-1,8,-1,-1,-1,-1,-1,-1,16, + 9,1,2,-1,10,0,3}; /* hash_compose_tab_12 */ +static CompEntry compose_tab_12[] = { +{168, 901, 0, NULL, NULL}, +{776, 0, 2, compose_tab_12_1, hash_compose_tab_12_1}, +{913, 902, 0, NULL, NULL}, +{917, 904, 0, NULL, NULL}, +{919, 905, 0, NULL, NULL}, +{921, 906, 0, NULL, NULL}, +{927, 908, 0, NULL, NULL}, +{933, 910, 0, NULL, NULL}, +{937, 911, 0, NULL, NULL}, +{945, 940, 0, NULL, NULL}, +{949, 941, 0, NULL, NULL}, +{951, 942, 0, NULL, NULL}, +{953, 943, 0, NULL, NULL}, +{959, 972, 0, NULL, NULL}, +{965, 973, 0, NULL, NULL}, +{969, 974, 0, NULL, NULL}, +{978, 979, 0, NULL, NULL} +}; /* compose_tab_12 */ +static int hash_compose_tab_13[28] = +{-1,5,10,-1,-1,11,-1,-1,-1,0,-1,-1,-1,1,6,-1,-1,2,7,-1,12,8,13,3,-1,-1,4,9}; /* hash_compose_tab_13 */ +static CompEntry compose_tab_13[] = { +{65, 512, 0, NULL, NULL}, +{69, 516, 0, NULL, NULL}, +{73, 520, 0, NULL, NULL}, +{79, 524, 0, NULL, NULL}, +{82, 528, 0, NULL, NULL}, +{85, 532, 0, NULL, NULL}, +{97, 513, 0, NULL, NULL}, +{101, 517, 0, NULL, NULL}, +{105, 521, 0, NULL, NULL}, +{111, 525, 0, NULL, NULL}, +{114, 529, 0, NULL, NULL}, +{117, 533, 0, NULL, NULL}, +{1140, 1142, 0, NULL, NULL}, +{1141, 1143, 0, NULL, NULL} +}; /* compose_tab_13 */ +static int hash_compose_tab_14[24] = +{-1,2,6,-1,-1,7,-1,3,-1,8,4,-1,-1,5,-1,9,-1,0,10,-1,-1,1,11,-1}; /* hash_compose_tab_14 */ +static CompEntry compose_tab_14[] = { +{65, 514, 0, NULL, NULL}, +{69, 518, 0, NULL, NULL}, +{73, 522, 0, NULL, NULL}, +{79, 526, 0, NULL, NULL}, +{82, 530, 0, NULL, NULL}, +{85, 534, 0, NULL, NULL}, +{97, 515, 0, NULL, NULL}, +{101, 519, 0, NULL, NULL}, +{105, 523, 0, NULL, NULL}, +{111, 527, 0, NULL, NULL}, +{114, 531, 0, NULL, NULL}, +{117, 535, 0, NULL, NULL} +}; /* compose_tab_14 */ +static int hash_compose_tab_15_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_15_0 */ +static CompEntry compose_tab_15_0[] = { +{913, 8072, 0, NULL, NULL}, +{919, 8088, 0, NULL, NULL}, +{937, 8104, 0, NULL, NULL}, +{945, 8064, 0, NULL, NULL}, +{951, 8080, 0, NULL, NULL}, +{969, 8096, 0, NULL, NULL} +}; /* compose_tab_15_0 */ +static int hash_compose_tab_15[30] = +{-1,12,-1,-1,-1,13,-1,6,-1,14,-1,-1,-1,1,-1,7,-1,2,-1,3,8,4,9,10,-1,-1,-1,0,5, + 11}; /* hash_compose_tab_15 */ +static CompEntry compose_tab_15[] = { +{837, 0, 6, compose_tab_15_0, hash_compose_tab_15_0}, +{913, 7944, 0, NULL, NULL}, +{917, 7960, 0, NULL, NULL}, +{919, 7976, 0, NULL, NULL}, +{921, 7992, 0, NULL, NULL}, +{927, 8008, 0, NULL, NULL}, +{937, 8040, 0, NULL, NULL}, +{945, 7936, 0, NULL, NULL}, +{949, 7952, 0, NULL, NULL}, +{951, 7968, 0, NULL, NULL}, +{953, 7984, 0, NULL, NULL}, +{959, 8000, 0, NULL, NULL}, +{961, 8164, 0, NULL, NULL}, +{965, 8016, 0, NULL, NULL}, +{969, 8032, 0, NULL, NULL} +}; /* compose_tab_15 */ +static int hash_compose_tab_16_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_16_0 */ +static CompEntry compose_tab_16_0[] = { +{913, 8073, 0, NULL, NULL}, +{919, 8089, 0, NULL, NULL}, +{937, 8105, 0, NULL, NULL}, +{945, 8065, 0, NULL, NULL}, +{951, 8081, 0, NULL, NULL}, +{969, 8097, 0, NULL, NULL} +}; /* compose_tab_16_0 */ +static int hash_compose_tab_16[34] = +{11,3,12,4,-1,-1,-1,13,-1,5,14,6,-1,15,-1,7,-1,16,-1,8,-1,0,-1,-1,-1,-1,-1,9, + -1,1,-1,10,-1,2}; /* hash_compose_tab_16 */ +static CompEntry compose_tab_16[] = { +{837, 0, 6, compose_tab_16_0, hash_compose_tab_16_0}, +{913, 7945, 0, NULL, NULL}, +{917, 7961, 0, NULL, NULL}, +{919, 7977, 0, NULL, NULL}, +{921, 7993, 0, NULL, NULL}, +{927, 8009, 0, NULL, NULL}, +{929, 8172, 0, NULL, NULL}, +{933, 8025, 0, NULL, NULL}, +{937, 8041, 0, NULL, NULL}, +{945, 7937, 0, NULL, NULL}, +{949, 7953, 0, NULL, NULL}, +{951, 7969, 0, NULL, NULL}, +{953, 7985, 0, NULL, NULL}, +{959, 8001, 0, NULL, NULL}, +{961, 8165, 0, NULL, NULL}, +{965, 8017, 0, NULL, NULL}, +{969, 8033, 0, NULL, NULL} +}; /* compose_tab_16 */ +static int hash_compose_tab_17[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_17 */ +static CompEntry compose_tab_17[] = { +{79, 416, 0, NULL, NULL}, +{85, 431, 0, NULL, NULL}, +{111, 417, 0, NULL, NULL}, +{117, 432, 0, NULL, NULL} +}; /* compose_tab_17 */ +static int hash_compose_tab_18_38[8] = +{2,-1,-1,-1,-1,1,3,0}; /* hash_compose_tab_18_38 */ +static CompEntry compose_tab_18_38[] = { +{79, 7906, 0, NULL, NULL}, +{85, 7920, 0, NULL, NULL}, +{111, 7907, 0, NULL, NULL}, +{117, 7921, 0, NULL, NULL} +}; /* compose_tab_18_38 */ +static int hash_compose_tab_18[78] = +{9,10,-1,-1,11,12,13,14,15,16,-1,17,18,-1,-1,38,-1,-1,-1,19,20,-1,21,22,-1,-1, + 23,24,-1,25,26,27,28,29,-1,-1,30,31,32,33,34,35,-1,36,37,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,-1,2,3,-1,-1,4,5,-1,6,7,8}; /* hash_compose_tab_18 */ +static CompEntry compose_tab_18[] = { +{65, 7840, 0, NULL, NULL}, +{66, 7684, 0, NULL, NULL}, +{68, 7692, 0, NULL, NULL}, +{69, 7864, 0, NULL, NULL}, +{72, 7716, 0, NULL, NULL}, +{73, 7882, 0, NULL, NULL}, +{75, 7730, 0, NULL, NULL}, +{76, 7734, 0, NULL, NULL}, +{77, 7746, 0, NULL, NULL}, +{78, 7750, 0, NULL, NULL}, +{79, 7884, 0, NULL, NULL}, +{82, 7770, 0, NULL, NULL}, +{83, 7778, 0, NULL, NULL}, +{84, 7788, 0, NULL, NULL}, +{85, 7908, 0, NULL, NULL}, +{86, 7806, 0, NULL, NULL}, +{87, 7816, 0, NULL, NULL}, +{89, 7924, 0, NULL, NULL}, +{90, 7826, 0, NULL, NULL}, +{97, 7841, 0, NULL, NULL}, +{98, 7685, 0, NULL, NULL}, +{100, 7693, 0, NULL, NULL}, +{101, 7865, 0, NULL, NULL}, +{104, 7717, 0, NULL, NULL}, +{105, 7883, 0, NULL, NULL}, +{107, 7731, 0, NULL, NULL}, +{108, 7735, 0, NULL, NULL}, +{109, 7747, 0, NULL, NULL}, +{110, 7751, 0, NULL, NULL}, +{111, 7885, 0, NULL, NULL}, +{114, 7771, 0, NULL, NULL}, +{115, 7779, 0, NULL, NULL}, +{116, 7789, 0, NULL, NULL}, +{117, 7909, 0, NULL, NULL}, +{118, 7807, 0, NULL, NULL}, +{119, 7817, 0, NULL, NULL}, +{121, 7925, 0, NULL, NULL}, +{122, 7827, 0, NULL, NULL}, +{795, 0, 4, compose_tab_18_38, hash_compose_tab_18_38} +}; /* compose_tab_18 */ +static int hash_compose_tab_19[4] = +{-1,0,1,-1}; /* hash_compose_tab_19 */ +static CompEntry compose_tab_19[] = { +{85, 7794, 0, NULL, NULL}, +{117, 7795, 0, NULL, NULL} +}; /* compose_tab_19 */ +static int hash_compose_tab_20[4] = +{-1,0,1,-1}; /* hash_compose_tab_20 */ +static CompEntry compose_tab_20[] = { +{65, 7680, 0, NULL, NULL}, +{97, 7681, 0, NULL, NULL} +}; /* compose_tab_20 */ +static int hash_compose_tab_21[40] = +{-1,-1,7,8,9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,-1,-1,12,13,-1, + -1,0,1,14,15,2,3,16,17,4,5,18,6,19}; /* hash_compose_tab_21 */ +static CompEntry compose_tab_21[] = { +{67, 199, 0, NULL, NULL}, +{68, 7696, 0, NULL, NULL}, +{71, 290, 0, NULL, NULL}, +{72, 7720, 0, NULL, NULL}, +{75, 310, 0, NULL, NULL}, +{76, 315, 0, NULL, NULL}, +{78, 325, 0, NULL, NULL}, +{82, 342, 0, NULL, NULL}, +{83, 350, 0, NULL, NULL}, +{84, 354, 0, NULL, NULL}, +{99, 231, 0, NULL, NULL}, +{100, 7697, 0, NULL, NULL}, +{103, 291, 0, NULL, NULL}, +{104, 7721, 0, NULL, NULL}, +{107, 311, 0, NULL, NULL}, +{108, 316, 0, NULL, NULL}, +{110, 326, 0, NULL, NULL}, +{114, 343, 0, NULL, NULL}, +{115, 351, 0, NULL, NULL}, +{116, 355, 0, NULL, NULL} +}; /* compose_tab_21 */ +static int hash_compose_tab_22[20] = +{-1,6,-1,-1,-1,0,4,7,-1,1,-1,8,-1,2,-1,-1,-1,5,9,3}; /* hash_compose_tab_22 */ +static CompEntry compose_tab_22[] = { +{65, 260, 0, NULL, NULL}, +{69, 280, 0, NULL, NULL}, +{73, 302, 0, NULL, NULL}, +{79, 490, 0, NULL, NULL}, +{85, 370, 0, NULL, NULL}, +{97, 261, 0, NULL, NULL}, +{101, 281, 0, NULL, NULL}, +{105, 303, 0, NULL, NULL}, +{111, 491, 0, NULL, NULL}, +{117, 371, 0, NULL, NULL} +}; /* compose_tab_22 */ +static int hash_compose_tab_23[24] = +{-1,-1,-1,-1,2,6,3,7,-1,-1,-1,-1,4,5,8,9,-1,-1,-1,-1,0,1,10,11}; /* hash_compose_tab_23 */ +static CompEntry compose_tab_23[] = { +{68, 7698, 0, NULL, NULL}, +{69, 7704, 0, NULL, NULL}, +{76, 7740, 0, NULL, NULL}, +{78, 7754, 0, NULL, NULL}, +{84, 7792, 0, NULL, NULL}, +{85, 7798, 0, NULL, NULL}, +{100, 7699, 0, NULL, NULL}, +{101, 7705, 0, NULL, NULL}, +{108, 7741, 0, NULL, NULL}, +{110, 7755, 0, NULL, NULL}, +{116, 7793, 0, NULL, NULL}, +{117, 7799, 0, NULL, NULL} +}; /* compose_tab_23 */ +static int hash_compose_tab_24[4] = +{0,1,-1,-1}; /* hash_compose_tab_24 */ +static CompEntry compose_tab_24[] = { +{72, 7722, 0, NULL, NULL}, +{104, 7723, 0, NULL, NULL} +}; /* compose_tab_24 */ +static int hash_compose_tab_25[12] = +{-1,1,2,-1,-1,3,-1,-1,-1,0,4,5}; /* hash_compose_tab_25 */ +static CompEntry compose_tab_25[] = { +{69, 7706, 0, NULL, NULL}, +{73, 7724, 0, NULL, NULL}, +{85, 7796, 0, NULL, NULL}, +{101, 7707, 0, NULL, NULL}, +{105, 7725, 0, NULL, NULL}, +{117, 7797, 0, NULL, NULL} +}; /* compose_tab_25 */ +static int hash_compose_tab_26[34] = +{1,-1,10,-1,-1,11,12,2,3,13,4,-1,14,-1,5,15,6,-1,-1,-1,16,-1,7,-1,-1,-1,-1,-1, + -1,-1,8,-1,0,9}; /* hash_compose_tab_26 */ +static CompEntry compose_tab_26[] = { +{66, 7686, 0, NULL, NULL}, +{68, 7694, 0, NULL, NULL}, +{75, 7732, 0, NULL, NULL}, +{76, 7738, 0, NULL, NULL}, +{78, 7752, 0, NULL, NULL}, +{82, 7774, 0, NULL, NULL}, +{84, 7790, 0, NULL, NULL}, +{90, 7828, 0, NULL, NULL}, +{98, 7687, 0, NULL, NULL}, +{100, 7695, 0, NULL, NULL}, +{104, 7830, 0, NULL, NULL}, +{107, 7733, 0, NULL, NULL}, +{108, 7739, 0, NULL, NULL}, +{110, 7753, 0, NULL, NULL}, +{114, 7775, 0, NULL, NULL}, +{116, 7791, 0, NULL, NULL}, +{122, 7829, 0, NULL, NULL} +}; /* compose_tab_26 */ +static int hash_compose_tab_27_1[4] = +{-1,0,1,-1}; /* hash_compose_tab_27_1 */ +static CompEntry compose_tab_27_1[] = { +{953, 8151, 0, NULL, NULL}, +{965, 8167, 0, NULL, NULL} +}; /* compose_tab_27_1 */ +static int hash_compose_tab_27_2_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_27_2_0 */ +static CompEntry compose_tab_27_2_0[] = { +{913, 8078, 0, NULL, NULL}, +{919, 8094, 0, NULL, NULL}, +{937, 8110, 0, NULL, NULL}, +{945, 8070, 0, NULL, NULL}, +{951, 8086, 0, NULL, NULL}, +{969, 8102, 0, NULL, NULL} +}; /* compose_tab_27_2_0 */ +static int hash_compose_tab_27_2[20] = +{-1,3,-1,-1,-1,5,8,-1,-1,9,-1,6,-1,1,7,-1,-1,0,4,2}; /* hash_compose_tab_27_2 */ +static CompEntry compose_tab_27_2[] = { +{837, 0, 6, compose_tab_27_2_0, hash_compose_tab_27_2_0}, +{913, 7950, 0, NULL, NULL}, +{919, 7982, 0, NULL, NULL}, +{921, 7998, 0, NULL, NULL}, +{937, 8046, 0, NULL, NULL}, +{945, 7942, 0, NULL, NULL}, +{951, 7974, 0, NULL, NULL}, +{953, 7990, 0, NULL, NULL}, +{965, 8022, 0, NULL, NULL}, +{969, 8038, 0, NULL, NULL} +}; /* compose_tab_27_2 */ +static int hash_compose_tab_27_3_0[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_27_3_0 */ +static CompEntry compose_tab_27_3_0[] = { +{913, 8079, 0, NULL, NULL}, +{919, 8095, 0, NULL, NULL}, +{937, 8111, 0, NULL, NULL}, +{945, 8071, 0, NULL, NULL}, +{951, 8087, 0, NULL, NULL}, +{969, 8103, 0, NULL, NULL} +}; /* compose_tab_27_3_0 */ +static int hash_compose_tab_27_3[22] = +{-1,0,10,-1,-1,7,-1,8,-1,4,-1,1,-1,5,-1,-1,-1,2,-1,3,9,6}; /* hash_compose_tab_27_3 */ +static CompEntry compose_tab_27_3[] = { +{837, 0, 6, compose_tab_27_3_0, hash_compose_tab_27_3_0}, +{913, 7951, 0, NULL, NULL}, +{919, 7983, 0, NULL, NULL}, +{921, 7999, 0, NULL, NULL}, +{933, 8031, 0, NULL, NULL}, +{937, 8047, 0, NULL, NULL}, +{945, 7943, 0, NULL, NULL}, +{951, 7975, 0, NULL, NULL}, +{953, 7991, 0, NULL, NULL}, +{965, 8023, 0, NULL, NULL}, +{969, 8039, 0, NULL, NULL} +}; /* compose_tab_27_3 */ +static int hash_compose_tab_27_4[6] = +{-1,-1,-1,0,1,2}; /* hash_compose_tab_27_4 */ +static CompEntry compose_tab_27_4[] = { +{945, 8119, 0, NULL, NULL}, +{951, 8135, 0, NULL, NULL}, +{969, 8183, 0, NULL, NULL} +}; /* compose_tab_27_4 */ +static int hash_compose_tab_27[24] = +{0,-1,-1,-1,-1,8,11,-1,1,5,9,-1,-1,-1,-1,6,10,7,-1,2,3,4,-1,-1}; /* hash_compose_tab_27 */ +static CompEntry compose_tab_27[] = { +{168, 8129, 0, NULL, NULL}, +{776, 0, 2, compose_tab_27_1, hash_compose_tab_27_1}, +{787, 0, 10, compose_tab_27_2, hash_compose_tab_27_2}, +{788, 0, 11, compose_tab_27_3, hash_compose_tab_27_3}, +{837, 0, 3, compose_tab_27_4, hash_compose_tab_27_4}, +{945, 8118, 0, NULL, NULL}, +{951, 8134, 0, NULL, NULL}, +{953, 8150, 0, NULL, NULL}, +{965, 8166, 0, NULL, NULL}, +{969, 8182, 0, NULL, NULL}, +{8127, 8143, 0, NULL, NULL}, +{8190, 8159, 0, NULL, NULL} +}; /* compose_tab_27 */ +static int hash_compose_tab_28[12] = +{-1,0,2,4,-1,-1,-1,1,-1,3,5,-1}; /* hash_compose_tab_28 */ +static CompEntry compose_tab_28[] = { +{913, 8124, 0, NULL, NULL}, +{919, 8140, 0, NULL, NULL}, +{937, 8188, 0, NULL, NULL}, +{945, 8115, 0, NULL, NULL}, +{951, 8131, 0, NULL, NULL}, +{969, 8179, 0, NULL, NULL} +}; /* compose_tab_28 */ +static int hash_compose_tab_29[4] = +{0,-1,1,-1}; /* hash_compose_tab_29 */ +static CompEntry compose_tab_29[] = { +{1488, 64302, 0, NULL, NULL}, +{1522, 64287, 0, NULL, NULL} +}; /* compose_tab_29 */ +static int hash_compose_tab_30[2] = +{0,-1}; /* hash_compose_tab_30 */ +static CompEntry compose_tab_30[] = { +{1488, 64303, 0, NULL, NULL} +}; /* compose_tab_30 */ +static int hash_compose_tab_31[2] = +{-1,0}; /* hash_compose_tab_31 */ +static CompEntry compose_tab_31[] = { +{1493, 64331, 0, NULL, NULL} +}; /* compose_tab_31 */ +static int hash_compose_tab_32[44] = +{7,8,9,10,11,-1,12,-1,13,14,-1,15,16,-1,17,18,19,20,21,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,-1}; /* hash_compose_tab_32 */ +static CompEntry compose_tab_32[] = { +{1488, 64304, 0, NULL, NULL}, +{1489, 64305, 0, NULL, NULL}, +{1490, 64306, 0, NULL, NULL}, +{1491, 64307, 0, NULL, NULL}, +{1492, 64308, 0, NULL, NULL}, +{1493, 64309, 0, NULL, NULL}, +{1494, 64310, 0, NULL, NULL}, +{1496, 64312, 0, NULL, NULL}, +{1497, 64313, 0, NULL, NULL}, +{1498, 64314, 0, NULL, NULL}, +{1499, 64315, 0, NULL, NULL}, +{1500, 64316, 0, NULL, NULL}, +{1502, 64318, 0, NULL, NULL}, +{1504, 64320, 0, NULL, NULL}, +{1505, 64321, 0, NULL, NULL}, +{1507, 64323, 0, NULL, NULL}, +{1508, 64324, 0, NULL, NULL}, +{1510, 64326, 0, NULL, NULL}, +{1511, 64327, 0, NULL, NULL}, +{1512, 64328, 0, NULL, NULL}, +{1513, 64329, 0, NULL, NULL}, +{1514, 64330, 0, NULL, NULL} +}; /* compose_tab_32 */ +static int hash_compose_tab_33[6] = +{-1,0,2,-1,-1,1}; /* hash_compose_tab_33 */ +static CompEntry compose_tab_33[] = { +{1489, 64332, 0, NULL, NULL}, +{1499, 64333, 0, NULL, NULL}, +{1508, 64334, 0, NULL, NULL} +}; /* compose_tab_33 */ +static int hash_compose_tab_34_0[2] = +{-1,0}; /* hash_compose_tab_34_0 */ +static CompEntry compose_tab_34_0[] = { +{1513, 64300, 0, NULL, NULL} +}; /* compose_tab_34_0 */ +static int hash_compose_tab_34[4] = +{0,1,-1,-1}; /* hash_compose_tab_34 */ +static CompEntry compose_tab_34[] = { +{1468, 0, 1, compose_tab_34_0, hash_compose_tab_34_0}, +{1513, 64298, 0, NULL, NULL} +}; /* compose_tab_34 */ +static int hash_compose_tab_35_0[2] = +{-1,0}; /* hash_compose_tab_35_0 */ +static CompEntry compose_tab_35_0[] = { +{1513, 64301, 0, NULL, NULL} +}; /* compose_tab_35_0 */ +static int hash_compose_tab_35[4] = +{0,1,-1,-1}; /* hash_compose_tab_35 */ +static CompEntry compose_tab_35[] = { +{1468, 0, 1, compose_tab_35_0, hash_compose_tab_35_0}, +{1513, 64299, 0, NULL, NULL} +}; /* compose_tab_35 */ +static int hash_compose_tab_36[22] = +{3,10,-1,-1,-1,4,5,-1,-1,-1,-1,-1,6,-1,-1,0,1,2,7,8,9,-1}; /* hash_compose_tab_36 */ +static CompEntry compose_tab_36[] = { +{2325, 2392, 0, NULL, NULL}, +{2326, 2393, 0, NULL, NULL}, +{2327, 2394, 0, NULL, NULL}, +{2332, 2395, 0, NULL, NULL}, +{2337, 2396, 0, NULL, NULL}, +{2338, 2397, 0, NULL, NULL}, +{2344, 2345, 0, NULL, NULL}, +{2347, 2398, 0, NULL, NULL}, +{2351, 2399, 0, NULL, NULL}, +{2352, 2353, 0, NULL, NULL}, +{2355, 2356, 0, NULL, NULL} +}; /* compose_tab_36 */ +static int hash_compose_tab_37[8] = +{-1,0,1,-1,2,-1,-1,3}; /* hash_compose_tab_37 */ +static CompEntry compose_tab_37[] = { +{2465, 2524, 0, NULL, NULL}, +{2466, 2525, 0, NULL, NULL}, +{2476, 2480, 0, NULL, NULL}, +{2479, 2527, 0, NULL, NULL} +}; /* compose_tab_37 */ +static int hash_compose_tab_38[2] = +{-1,0}; /* hash_compose_tab_38 */ +static CompEntry compose_tab_38[] = { +{2503, 2507, 0, NULL, NULL} +}; /* compose_tab_38 */ +static int hash_compose_tab_39[2] = +{-1,0}; /* hash_compose_tab_39 */ +static CompEntry compose_tab_39[] = { +{2503, 2508, 0, NULL, NULL} +}; /* compose_tab_39 */ +static int hash_compose_tab_40[10] = +{-1,-1,0,1,3,4,-1,-1,2,-1}; /* hash_compose_tab_40 */ +static CompEntry compose_tab_40[] = { +{2582, 2649, 0, NULL, NULL}, +{2583, 2650, 0, NULL, NULL}, +{2588, 2651, 0, NULL, NULL}, +{2593, 2652, 0, NULL, NULL}, +{2603, 2654, 0, NULL, NULL} +}; /* compose_tab_40 */ +static int hash_compose_tab_41[6] = +{1,2,-1,-1,-1,0}; /* hash_compose_tab_41 */ +static CompEntry compose_tab_41[] = { +{2849, 2908, 0, NULL, NULL}, +{2850, 2909, 0, NULL, NULL}, +{2863, 2911, 0, NULL, NULL} +}; /* compose_tab_41 */ +static int hash_compose_tab_42[2] = +{-1,0}; /* hash_compose_tab_42 */ +static CompEntry compose_tab_42[] = { +{2887, 2891, 0, NULL, NULL} +}; /* compose_tab_42 */ +static int hash_compose_tab_43[2] = +{-1,0}; /* hash_compose_tab_43 */ +static CompEntry compose_tab_43[] = { +{2887, 2888, 0, NULL, NULL} +}; /* compose_tab_43 */ +static int hash_compose_tab_44[2] = +{-1,0}; /* hash_compose_tab_44 */ +static CompEntry compose_tab_44[] = { +{2887, 2892, 0, NULL, NULL} +}; /* compose_tab_44 */ +static int hash_compose_tab_45[4] = +{-1,-1,0,1}; /* hash_compose_tab_45 */ +static CompEntry compose_tab_45[] = { +{3014, 3018, 0, NULL, NULL}, +{3015, 3019, 0, NULL, NULL} +}; /* compose_tab_45 */ +static int hash_compose_tab_46[4] = +{-1,-1,0,1}; /* hash_compose_tab_46 */ +static CompEntry compose_tab_46[] = { +{2962, 2964, 0, NULL, NULL}, +{3014, 3020, 0, NULL, NULL} +}; /* compose_tab_46 */ +static int hash_compose_tab_47[2] = +{0,-1}; /* hash_compose_tab_47 */ +static CompEntry compose_tab_47[] = { +{3142, 3144, 0, NULL, NULL} +}; /* compose_tab_47 */ +static int hash_compose_tab_48[2] = +{0,-1}; /* hash_compose_tab_48 */ +static CompEntry compose_tab_48[] = { +{3270, 3274, 0, NULL, NULL} +}; /* compose_tab_48 */ +static int hash_compose_tab_49_1[2] = +{0,-1}; /* hash_compose_tab_49_1 */ +static CompEntry compose_tab_49_1[] = { +{3270, 3275, 0, NULL, NULL} +}; /* compose_tab_49_1 */ +static int hash_compose_tab_49[6] = +{2,-1,1,-1,-1,0}; /* hash_compose_tab_49 */ +static CompEntry compose_tab_49[] = { +{3263, 3264, 0, NULL, NULL}, +{3266, 0, 1, compose_tab_49_1, hash_compose_tab_49_1}, +{3270, 3271, 0, NULL, NULL} +}; /* compose_tab_49 */ +static int hash_compose_tab_50[2] = +{0,-1}; /* hash_compose_tab_50 */ +static CompEntry compose_tab_50[] = { +{3270, 3272, 0, NULL, NULL} +}; /* compose_tab_50 */ +static int hash_compose_tab_51[4] = +{-1,-1,0,1}; /* hash_compose_tab_51 */ +static CompEntry compose_tab_51[] = { +{3398, 3402, 0, NULL, NULL}, +{3399, 3403, 0, NULL, NULL} +}; /* compose_tab_51 */ +static int hash_compose_tab_52[2] = +{0,-1}; /* hash_compose_tab_52 */ +static CompEntry compose_tab_52[] = { +{3398, 3404, 0, NULL, NULL} +}; /* compose_tab_52 */ +static int hash_compose_tab_53[2] = +{-1,0}; /* hash_compose_tab_53 */ +static CompEntry compose_tab_53[] = { +{3661, 3635, 0, NULL, NULL} +}; /* compose_tab_53 */ +static int hash_compose_tab_54[2] = +{-1,0}; /* hash_compose_tab_54 */ +static CompEntry compose_tab_54[] = { +{3789, 3763, 0, NULL, NULL} +}; /* compose_tab_54 */ +static int hash_compose_tab_55_2[4] = +{-1,-1,0,1}; /* hash_compose_tab_55_2 */ +static CompEntry compose_tab_55_2[] = { +{4018, 3959, 0, NULL, NULL}, +{4019, 3961, 0, NULL, NULL} +}; /* compose_tab_55_2 */ +static int hash_compose_tab_55[6] = +{0,-1,1,2,-1,-1}; /* hash_compose_tab_55 */ +static CompEntry compose_tab_55[] = { +{3954, 3955, 0, NULL, NULL}, +{3956, 3957, 0, NULL, NULL}, +{3968, 0, 2, compose_tab_55_2, hash_compose_tab_55_2} +}; /* compose_tab_55 */ +static int hash_compose_tab_56[4] = +{-1,-1,0,1}; /* hash_compose_tab_56 */ +static CompEntry compose_tab_56[] = { +{4018, 3958, 0, NULL, NULL}, +{4019, 3960, 0, NULL, NULL} +}; /* compose_tab_56 */ +static int hash_compose_tab_57[4] = +{0,1,-1,-1}; /* hash_compose_tab_57 */ +static CompEntry compose_tab_57[] = { +{3904, 3945, 0, NULL, NULL}, +{3984, 4025, 0, NULL, NULL} +}; /* compose_tab_57 */ +static int hash_compose_tab_58[20] = +{-1,2,7,-1,-1,-1,0,3,5,8,-1,4,9,-1,-1,-1,1,6,-1,-1}; /* hash_compose_tab_58 */ +static CompEntry compose_tab_58[] = { +{3906, 3907, 0, NULL, NULL}, +{3916, 3917, 0, NULL, NULL}, +{3921, 3922, 0, NULL, NULL}, +{3926, 3927, 0, NULL, NULL}, +{3931, 3932, 0, NULL, NULL}, +{3986, 3987, 0, NULL, NULL}, +{3996, 3997, 0, NULL, NULL}, +{4001, 4002, 0, NULL, NULL}, +{4006, 4007, 0, NULL, NULL}, +{4011, 4012, 0, NULL, NULL} +}; /* compose_tab_58 */ +static int hash_compose_tab_59[96] = +{33,12,34,-1,13,35,14,36,15,37,-1,-1,-1,-1,-1,16,38,-1,17,39,-1,18,40,-1,19, + 41,-1,20,42,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,43,44,45, + 46,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,47,-1,-1,-1,-1,-1,-1,-1,0,22,-1,-1,-1,1, + 23,2,24,3,25,4,26,5,27,6,28,7,29,8,30,9,31,10,32,11}; /* hash_compose_tab_59 */ +static CompEntry compose_tab_59[] = { +{12358, 12436, 0, NULL, NULL}, +{12363, 12364, 0, NULL, NULL}, +{12365, 12366, 0, NULL, NULL}, +{12367, 12368, 0, NULL, NULL}, +{12369, 12370, 0, NULL, NULL}, +{12371, 12372, 0, NULL, NULL}, +{12373, 12374, 0, NULL, NULL}, +{12375, 12376, 0, NULL, NULL}, +{12377, 12378, 0, NULL, NULL}, +{12379, 12380, 0, NULL, NULL}, +{12381, 12382, 0, NULL, NULL}, +{12383, 12384, 0, NULL, NULL}, +{12385, 12386, 0, NULL, NULL}, +{12388, 12389, 0, NULL, NULL}, +{12390, 12391, 0, NULL, NULL}, +{12392, 12393, 0, NULL, NULL}, +{12399, 12400, 0, NULL, NULL}, +{12402, 12403, 0, NULL, NULL}, +{12405, 12406, 0, NULL, NULL}, +{12408, 12409, 0, NULL, NULL}, +{12411, 12412, 0, NULL, NULL}, +{12445, 12446, 0, NULL, NULL}, +{12454, 12532, 0, NULL, NULL}, +{12459, 12460, 0, NULL, NULL}, +{12461, 12462, 0, NULL, NULL}, +{12463, 12464, 0, NULL, NULL}, +{12465, 12466, 0, NULL, NULL}, +{12467, 12468, 0, NULL, NULL}, +{12469, 12470, 0, NULL, NULL}, +{12471, 12472, 0, NULL, NULL}, +{12473, 12474, 0, NULL, NULL}, +{12475, 12476, 0, NULL, NULL}, +{12477, 12478, 0, NULL, NULL}, +{12479, 12480, 0, NULL, NULL}, +{12481, 12482, 0, NULL, NULL}, +{12484, 12485, 0, NULL, NULL}, +{12486, 12487, 0, NULL, NULL}, +{12488, 12489, 0, NULL, NULL}, +{12495, 12496, 0, NULL, NULL}, +{12498, 12499, 0, NULL, NULL}, +{12501, 12502, 0, NULL, NULL}, +{12504, 12505, 0, NULL, NULL}, +{12507, 12508, 0, NULL, NULL}, +{12527, 12535, 0, NULL, NULL}, +{12528, 12536, 0, NULL, NULL}, +{12529, 12537, 0, NULL, NULL}, +{12530, 12538, 0, NULL, NULL}, +{12541, 12542, 0, NULL, NULL} +}; /* compose_tab_59 */ +static int hash_compose_tab_60[20] = +{-1,7,1,-1,8,2,-1,9,3,-1,-1,4,-1,-1,-1,5,-1,-1,6,0}; /* hash_compose_tab_60 */ +static CompEntry compose_tab_60[] = { +{12399, 12401, 0, NULL, NULL}, +{12402, 12404, 0, NULL, NULL}, +{12405, 12407, 0, NULL, NULL}, +{12408, 12410, 0, NULL, NULL}, +{12411, 12413, 0, NULL, NULL}, +{12495, 12497, 0, NULL, NULL}, +{12498, 12500, 0, NULL, NULL}, +{12501, 12503, 0, NULL, NULL}, +{12504, 12506, 0, NULL, NULL}, +{12507, 12509, 0, NULL, NULL} +}; /* compose_tab_60 */ +static int hash_compose_tab[122] = +{30,31,52,60,32,-1,-1,33,-1,34,35,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,-1,5,6,7,8,9,10,11,12,36,13,37,14, + 38,15,16,55,40,-1,-1,-1,-1,17,56,-1,-1,-1,-1,-1,41,18,19,20,42,21,22,-1,45, + 39,-1,23,24,-1,25,26,-1,-1,-1,-1,-1,-1,-1,-1,48,-1,43,44,51,53,-1,-1,27,46, + 54,28,-1,-1,47,-1,-1,-1,-1,49,50,-1,-1,57,-1,58,59,29}; /* hash_compose_tab */ +static CompEntry compose_tab[] = { +{768, 0, 39, compose_tab_0, hash_compose_tab_0}, +{769, 0, 70, compose_tab_1, hash_compose_tab_1}, +{770, 0, 27, compose_tab_2, hash_compose_tab_2}, +{771, 0, 19, compose_tab_3, hash_compose_tab_3}, +{772, 0, 28, compose_tab_4, hash_compose_tab_4}, +{774, 0, 30, compose_tab_5, hash_compose_tab_5}, +{775, 0, 40, compose_tab_6, hash_compose_tab_6}, +{776, 0, 50, compose_tab_7, hash_compose_tab_7}, +{777, 0, 15, compose_tab_8, hash_compose_tab_8}, +{778, 0, 6, compose_tab_9, hash_compose_tab_9}, +{779, 0, 6, compose_tab_10, hash_compose_tab_10}, +{780, 0, 34, compose_tab_11, hash_compose_tab_11}, +{781, 0, 17, compose_tab_12, hash_compose_tab_12}, +{783, 0, 14, compose_tab_13, hash_compose_tab_13}, +{785, 0, 12, compose_tab_14, hash_compose_tab_14}, +{787, 0, 15, compose_tab_15, hash_compose_tab_15}, +{788, 0, 17, compose_tab_16, hash_compose_tab_16}, +{795, 0, 4, compose_tab_17, hash_compose_tab_17}, +{803, 0, 39, compose_tab_18, hash_compose_tab_18}, +{804, 0, 2, compose_tab_19, hash_compose_tab_19}, +{805, 0, 2, compose_tab_20, hash_compose_tab_20}, +{807, 0, 20, compose_tab_21, hash_compose_tab_21}, +{808, 0, 10, compose_tab_22, hash_compose_tab_22}, +{813, 0, 12, compose_tab_23, hash_compose_tab_23}, +{814, 0, 2, compose_tab_24, hash_compose_tab_24}, +{816, 0, 6, compose_tab_25, hash_compose_tab_25}, +{817, 0, 17, compose_tab_26, hash_compose_tab_26}, +{834, 0, 12, compose_tab_27, hash_compose_tab_27}, +{837, 0, 6, compose_tab_28, hash_compose_tab_28}, +{1463, 0, 2, compose_tab_29, hash_compose_tab_29}, +{1464, 0, 1, compose_tab_30, hash_compose_tab_30}, +{1465, 0, 1, compose_tab_31, hash_compose_tab_31}, +{1468, 0, 22, compose_tab_32, hash_compose_tab_32}, +{1471, 0, 3, compose_tab_33, hash_compose_tab_33}, +{1473, 0, 2, compose_tab_34, hash_compose_tab_34}, +{1474, 0, 2, compose_tab_35, hash_compose_tab_35}, +{2364, 0, 11, compose_tab_36, hash_compose_tab_36}, +{2492, 0, 4, compose_tab_37, hash_compose_tab_37}, +{2494, 0, 1, compose_tab_38, hash_compose_tab_38}, +{2519, 0, 1, compose_tab_39, hash_compose_tab_39}, +{2620, 0, 5, compose_tab_40, hash_compose_tab_40}, +{2876, 0, 3, compose_tab_41, hash_compose_tab_41}, +{2878, 0, 1, compose_tab_42, hash_compose_tab_42}, +{2902, 0, 1, compose_tab_43, hash_compose_tab_43}, +{2903, 0, 1, compose_tab_44, hash_compose_tab_44}, +{3006, 0, 2, compose_tab_45, hash_compose_tab_45}, +{3031, 0, 2, compose_tab_46, hash_compose_tab_46}, +{3158, 0, 1, compose_tab_47, hash_compose_tab_47}, +{3266, 0, 1, compose_tab_48, hash_compose_tab_48}, +{3285, 0, 3, compose_tab_49, hash_compose_tab_49}, +{3286, 0, 1, compose_tab_50, hash_compose_tab_50}, +{3390, 0, 2, compose_tab_51, hash_compose_tab_51}, +{3415, 0, 1, compose_tab_52, hash_compose_tab_52}, +{3634, 0, 1, compose_tab_53, hash_compose_tab_53}, +{3762, 0, 1, compose_tab_54, hash_compose_tab_54}, +{3953, 0, 3, compose_tab_55, hash_compose_tab_55}, +{3968, 0, 2, compose_tab_56, hash_compose_tab_56}, +{4021, 0, 2, compose_tab_57, hash_compose_tab_57}, +{4023, 0, 10, compose_tab_58, hash_compose_tab_58}, +{12441, 0, 48, compose_tab_59, hash_compose_tab_59}, +{12442, 0, 10, compose_tab_60, hash_compose_tab_60} +}; /* compose_tab */ +#define COMP_CANDIDATE_MAP_OFFSET 24 +static Uint32 comp_candidate_map[] = { + 0x081ABFDFU, + 0x000361B8U, + 0x00000024U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x93800000U, + 0x00000006U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x10000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x50000000U, + 0x00800000U, + 0x00000000U, + 0x00000000U, + 0x10000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x50000000U, + 0x00C00000U, + 0x00000000U, + 0x00000000U, + 0x40000000U, + 0x00800000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00400000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00600004U, + 0x00000000U, + 0x00000000U, + 0x40000000U, + 0x00800000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00040000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00040000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00000000U, + 0x00020000U, + 0x00000001U, + 0x00A00000U +}; diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index cd63401581..48fa99934e 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -199,6 +199,7 @@ extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */ extern int erts_atom_table_size;/* Atom table size */ #define ORIG_CREATION 0 +#define INTERNAL_CREATION 255 /* macros for extracting bytes from uint16's */ diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index d7c8aa84e9..328aa2be6a 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -49,10 +49,8 @@ #define in_area(ptr,start,nbytes) ((Uint)((char*)(ptr) - (char*)(start)) < (nbytes)) #define MAX_STRING_LEN 0xffff -#define dec_set_creation(nodename,creat) \ - (((nodename) == erts_this_node->sysname && (creat) == ORIG_CREATION) \ - ? erts_this_node->creation \ - : (creat)) + +#define is_valid_creation(Cre) ((unsigned)(Cre) < MAX_CREATION || (Cre) == INTERNAL_CREATION) #undef ERTS_DEBUG_USE_DIST_SEP #ifdef DEBUG @@ -83,14 +81,14 @@ * */ -static byte* enc_term(ErtsAtomCacheMap *, Eterm, byte*, Uint32); +static byte* enc_term(ErtsAtomCacheMap *, Eterm, byte*, Uint32, struct erl_off_heap_header** off_heap); static Uint is_external_string(Eterm obj, int* p_is_string); static byte* enc_atom(ErtsAtomCacheMap *, Eterm, byte*, Uint32); static byte* enc_pid(ErtsAtomCacheMap *, Eterm, byte*, Uint32); static byte* dec_term(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*); static byte* dec_atom(ErtsDistExternal *, byte*, Eterm*); static byte* dec_pid(ErtsDistExternal *, Eterm**, byte*, ErlOffHeap*, Eterm*); -static Sint decoded_size(byte *ep, byte* endp, int only_heap_bins); +static Sint decoded_size(byte *ep, byte* endp, int only_heap_bins, int internal_tags); static Uint encode_size_struct2(ErtsAtomCacheMap *, Eterm, unsigned); @@ -461,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term) + 1 /* VERSION_MAGIC */; } +Uint erts_encode_ext_size_ets(Eterm term) +{ + return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS); +} + + void erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap *acmp) { byte *ep = *ext; @@ -468,7 +472,7 @@ void erts_encode_dist_ext(Eterm term, byte **ext, Uint32 flags, ErtsAtomCacheMap if (!(flags & DFLAG_DIST_HDR_ATOM_CACHE)) #endif *ep++ = VERSION_MAGIC; - ep = enc_term(acmp, term, ep, flags); + ep = enc_term(acmp, term, ep, flags, NULL); if (!ep) erl_exit(ERTS_ABORT_EXIT, "%s:%d:erts_encode_dist_ext(): Internal data structure error\n", @@ -480,7 +484,7 @@ void erts_encode_ext(Eterm term, byte **ext) { byte *ep = *ext; *ep++ = VERSION_MAGIC; - ep = enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS); + ep = enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS, NULL); if (!ep) erl_exit(ERTS_ABORT_EXIT, "%s:%d:erts_encode_ext(): Internal data structure error\n", @@ -488,6 +492,12 @@ void erts_encode_ext(Eterm term, byte **ext) *ext = ep; } +byte* erts_encode_ext_ets(Eterm term, byte *ep, struct erl_off_heap_header** off_heap) +{ + return enc_term(NULL, term, ep, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS, + off_heap); +} + ErtsDistExternal * erts_make_dist_ext_copy(ErtsDistExternal *edep, Uint xsize) { @@ -813,7 +823,7 @@ erts_decode_dist_ext_size(ErtsDistExternal *edep, int no_refc_bins) goto fail; ep = edep->extp+1; } - res = decoded_size(ep, edep->ext_endp, no_refc_bins); + res = decoded_size(ep, edep->ext_endp, no_refc_bins, 0); if (res >= 0) return res; fail: @@ -825,9 +835,17 @@ Sint erts_decode_ext_size(byte *ext, Uint size, int no_refc_bins) { if (size == 0 || *ext != VERSION_MAGIC) return -1; - return decoded_size(ext+1, ext+size, no_refc_bins); + return decoded_size(ext+1, ext+size, no_refc_bins, 0); } +Sint erts_decode_ext_size_ets(byte *ext, Uint size) +{ + Sint sz = decoded_size(ext, ext+size, 0, 1); + ASSERT(sz >= 0); + return sz; +} + + /* ** hpp is set to either a &p->htop or ** a pointer to a memory pointer (form message buffers) @@ -887,7 +905,13 @@ Eterm erts_decode_ext(Eterm **hpp, ErlOffHeap *off_heap, byte **ext) return obj; } - +Eterm erts_decode_ext_ets(Eterm **hpp, ErlOffHeap *off_heap, byte *ext) +{ + Eterm obj; + ext = dec_term(NULL, hpp, ext, off_heap, &obj); + ASSERT(ext); + return obj; +} /**********************************************************************/ @@ -964,6 +988,7 @@ term_to_binary_1(Process* p, Eterm Term) return erts_term_to_binary(p, Term, 0, TERM_TO_BINARY_DFLAGS); } + Eterm term_to_binary_2(Process* p, Eterm Term, Eterm Flags) { @@ -1075,7 +1100,7 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size) goto error; size = (Sint) dest_len; } - res = decoded_size(state->extp, state->extp + size, 0); + res = decoded_size(state->extp, state->extp + size, 0, 0); if (res < 0) goto error; return res; @@ -1183,7 +1208,8 @@ BIF_RETTYPE binary_to_term_2(BIF_ALIST_2) opt = CAR(list_val(opts)); if (opt == am_safe) { fakedep.flags |= ERTS_DIST_EXT_BTT_SAFE; - } else { + } + else { goto error; } opts = CDR(list_val(opts)); @@ -1255,7 +1281,7 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) bytes = erts_alloc(ERTS_ALC_T_TMP, size); } - if ((endp = enc_term(NULL, Term, bytes, flags)) + if ((endp = enc_term(NULL, Term, bytes, flags, NULL)) == NULL) { erl_exit(1, "%s, line %d: bad term: %x\n", __FILE__, __LINE__, Term); @@ -1300,7 +1326,7 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) bin = new_binary(p, (byte *)NULL, size); bytes = binary_bytes(bin); bytes[0] = VERSION_MAGIC; - if ((endp = enc_term(NULL, Term, bytes+1, flags)) + if ((endp = enc_term(NULL, Term, bytes+1, flags, NULL)) == NULL) { erl_exit(1, "%s, line %d: bad term: %x\n", __FILE__, __LINE__, Term); @@ -1330,6 +1356,21 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags) ASSERT(is_atom(atom)); + if (dflags & DFLAGS_INTERNAL_TAGS) { + Uint aval = atom_val(atom); + ASSERT(aval < (1<<24)); + if (aval >= (1 << 16)) { + *ep++ = ATOM_INTERNAL_REF3; + put_int24(aval, ep); + ep += 3; + } + else { + *ep++ = ATOM_INTERNAL_REF2; + put_int16(aval, ep); + ep += 2; + } + return ep; + } /* * term_to_binary/1,2 and the initial distribution message * don't use the cache. @@ -1379,7 +1420,8 @@ enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags) ep += 4; put_int32(os, ep); ep += 4; - *ep++ = pid_creation(pid); + *ep++ = (is_internal_pid(pid) && (dflags & DFLAGS_INTERNAL_TAGS)) ? + INTERNAL_CREATION : pid_creation(pid); return ep; } @@ -1418,6 +1460,23 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp) } ep += len; break; + case ATOM_INTERNAL_REF2: + n = get_int16(ep); + ep += 2; + if (n >= atom_table_size()) { + goto error; + } + *objp = make_atom(n); + break; + case ATOM_INTERNAL_REF3: + n = get_int24(ep); + ep += 3; + if (n >= atom_table_size()) { + goto error; + } + *objp = make_atom(n); + break; + default: error: *objp = NIL; /* Don't leave a hole in the heap */ @@ -1426,6 +1485,19 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp) return ep; } +static ERTS_INLINE ErlNode* dec_get_node(Eterm sysname, Uint creation) +{ + switch (creation) { + case INTERNAL_CREATION: + return erts_this_node; + case ORIG_CREATION: + if (sysname == erts_this_node->sysname) { + creation = erts_this_node->creation; + } + } + return erts_find_or_insert_node(sysname,creation); +} + static byte* dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Eterm* objp) { @@ -1449,18 +1521,20 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete ep += 4; if (ser > ERTS_MAX_PID_SERIAL) return NULL; - if ((cre = get_int8(ep)) >= MAX_CREATION) - return NULL; + cre = get_int8(ep); ep += 1; + if (!is_valid_creation(cre)) { + return NULL; + } + data = make_pid_data(ser, num); + /* * We are careful to create the node entry only after all * validity tests are done. */ - cre = dec_set_creation(sysname,cre); - node = erts_find_or_insert_node(sysname,cre); + node = dec_get_node(sysname, cre); - data = make_pid_data(ser, num); if(node == erts_this_node) { *objp = make_internal_pid(data); } else { @@ -1485,7 +1559,8 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete #define ENC_LAST_ARRAY_ELEMENT ((Eterm) 3) static byte* -enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) +enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags, + struct erl_off_heap_header** off_heap) { DECLARE_WSTACK(s); Uint n; @@ -1637,12 +1712,14 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) Uint32 *ref_num; ASSERT(dflags & DFLAG_EXTENDED_REFERENCES); + *ep++ = NEW_REFERENCE_EXT; i = ref_no_of_numbers(obj); put_int16(i, ep); ep += 2; ep = enc_atom(acmp,ref_node_name(obj),ep,dflags); - *ep++ = ref_creation(obj); + *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_ref(obj)) ? + INTERNAL_CREATION : ref_creation(obj); ref_num = ref_numbers(obj); for (j = 0; j < i; j++) { put_int32(ref_num[j], ep); @@ -1658,7 +1735,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) j = port_number(obj); put_int32(j, ep); ep += 4; - *ep++ = port_creation(obj); + *ep++ = ((dflags & DFLAGS_INTERNAL_TAGS) && is_internal_port(obj)) ? + INTERNAL_CREATION : port_creation(obj); break; case LIST_DEF: @@ -1738,6 +1816,41 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) byte* bytes; ERTS_GET_BINARY_BYTES(obj, bytes, bitoffs, bitsize); + if (dflags & DFLAGS_INTERNAL_TAGS) { + ProcBin* pb = (ProcBin*) binary_val(obj); + Uint bytesize = pb->size; + if (pb->thing_word == HEADER_SUB_BIN) { + ErlSubBin* sub = (ErlSubBin*)pb; + pb = (ProcBin*) binary_val(sub->orig); + ASSERT(bytesize == sub->size); + bytesize += (bitoffs + bitsize + 7) / 8; + } + if (pb->thing_word == HEADER_PROC_BIN + && heap_bin_size(bytesize) > PROC_BIN_SIZE) { + ProcBin tmp; + if (bitoffs || bitsize) { + *ep++ = BIT_BINARY_INTERNAL_REF; + *ep++ = bitoffs; + *ep++ = bitsize; + } + else { + *ep++ = BINARY_INTERNAL_REF; + } + if (pb->flags) { + erts_emasculate_writable_binary(pb); + } + erts_refc_inc(&pb->val->refc, 2); + + sys_memcpy(&tmp, pb, sizeof(ProcBin)); + tmp.next = *off_heap; + tmp.bytes = bytes; + tmp.size = bytesize; + sys_memcpy(ep, &tmp, sizeof(ProcBin)); + *off_heap = (struct erl_off_heap_header*) ep; + ep += sizeof(ProcBin); + break; + } + } if (bitsize == 0) { /* Plain old byte-sized binary. */ *ep++ = BINARY_EXT; @@ -1773,8 +1886,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) *ep++ = SMALL_INTEGER_EXT; *ep++ = bitsize; } - break; } + break; case EXPORT_DEF: { Export* exp = *((Export **) (export_val(obj) + 1)); @@ -1782,7 +1895,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) *ep++ = EXPORT_EXT; ep = enc_atom(acmp, exp->code[0], ep, dflags); ep = enc_atom(acmp, exp->code[1], ep, dflags); - ep = enc_term(acmp, make_small(exp->code[2]), ep, dflags); + ep = enc_term(acmp, make_small(exp->code[2]), ep, dflags, off_heap); } else { /* Tag, arity */ *ep++ = SMALL_TUPLE_EXT; @@ -1818,8 +1931,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) put_int32(funp->num_free, ep); ep += 4; ep = enc_atom(acmp, funp->fe->module, ep, dflags); - ep = enc_term(acmp, make_small(funp->fe->old_index), ep, dflags); - ep = enc_term(acmp, make_small(funp->fe->old_uniq), ep, dflags); + ep = enc_term(acmp, make_small(funp->fe->old_index), ep, dflags, off_heap); + ep = enc_term(acmp, make_small(funp->fe->old_uniq), ep, dflags, off_heap); ep = enc_pid(acmp, funp->creator, ep, dflags); fun_env: @@ -1872,7 +1985,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags) return ep; } -static Uint +static +Uint is_external_string(Eterm list, int* p_is_string) { Uint len = 0; @@ -2162,13 +2276,13 @@ dec_term_atom_common: goto error; } ep += 4; - if ((cre = get_int8(ep)) >= MAX_CREATION) { + cre = get_int8(ep); + ep++; + if (!is_valid_creation(cre)) { goto error; } - ep++; - cre = dec_set_creation(sysname,cre); - node = erts_find_or_insert_node(sysname, cre); + node = dec_get_node(sysname, cre); if(node == erts_this_node) { *objp = make_internal_port(num); } @@ -2205,9 +2319,11 @@ dec_term_atom_common: goto error; ep += 4; - if ((cre = get_int8(ep)) >= MAX_CREATION) - goto error; + cre = get_int8(ep); ep += 1; + if (!is_valid_creation(cre)) { + goto error; + } goto ref_ext_common; case NEW_REFERENCE_EXT: @@ -2220,10 +2336,11 @@ dec_term_atom_common: if ((ep = dec_atom(edep, ep, &sysname)) == NULL) goto error; - if ((cre = get_int8(ep)) >= MAX_CREATION) - goto error; + cre = get_int8(ep); ep += 1; - + if (!is_valid_creation(cre)) { + goto error; + } r0 = get_int32(ep); ep += 4; if (r0 >= MAX_REFERENCE) @@ -2231,8 +2348,7 @@ dec_term_atom_common: ref_ext_common: - cre = dec_set_creation(sysname, cre); - node = erts_find_or_insert_node(sysname, cre); + node = dec_get_node(sysname, cre); if(node == erts_this_node) { RefThing *rtp = (RefThing *) hp; ref_num = (Uint32 *) (hp + REF_THING_HEAD_SIZE); @@ -2560,6 +2676,66 @@ dec_term_atom_common: } break; } + case ATOM_INTERNAL_REF2: + n = get_int16(ep); + ep += 2; + if (n >= atom_table_size()) { + goto error; + } + *objp = make_atom(n); + break; + case ATOM_INTERNAL_REF3: + n = get_int24(ep); + ep += 3; + if (n >= atom_table_size()) { + goto error; + } + *objp = make_atom(n); + break; + + case BINARY_INTERNAL_REF: + { + ProcBin* pb = (ProcBin*) hp; + sys_memcpy(pb, ep, sizeof(ProcBin)); + ep += sizeof(ProcBin); + + erts_refc_inc(&pb->val->refc, 1); + hp += PROC_BIN_SIZE; + pb->next = off_heap->first; + off_heap->first = (struct erl_off_heap_header*)pb; + pb->flags = 0; + *objp = make_binary(pb); + break; + } + case BIT_BINARY_INTERNAL_REF: + { + Sint bitoffs = *ep++; + Sint bitsize = *ep++; + ProcBin* pb = (ProcBin*) hp; + ErlSubBin* sub; + sys_memcpy(pb, ep, sizeof(ProcBin)); + ep += sizeof(ProcBin); + + erts_refc_inc(&pb->val->refc, 1); + hp += PROC_BIN_SIZE; + pb->next = off_heap->first; + off_heap->first = (struct erl_off_heap_header*)pb; + pb->flags = 0; + + sub = (ErlSubBin*)hp; + sub->thing_word = HEADER_SUB_BIN; + sub->size = pb->size - (bitoffs + bitsize + 7)/8; + sub->offs = 0; + sub->bitoffs = bitoffs; + sub->bitsize = bitsize; + sub->is_writable = 0; + sub->orig = make_binary(pb); + + hp += ERL_SUB_BIN_SIZE; + *objp = make_binary(sub); + break; + } + default: error: /* UNDO: @@ -2642,20 +2818,29 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) case NIL_DEF: result++; break; - case ATOM_DEF: { - int alen = atom_tab(atom_val(obj))->len; - if ((MAX_ATOM_LENGTH <= 255 || alen <= 255) - && (dflags & DFLAG_SMALL_ATOM_TAGS)) { - /* Make sure a SMALL_ATOM_EXT fits: SMALL_ATOM_EXT l t1 t2... */ - result += 1 + 1 + alen; + case ATOM_DEF: + if (dflags & DFLAGS_INTERNAL_TAGS) { + if (atom_val(obj) >= (1<<16)) { + result += 1 + 3; + } + else { + result += 1 + 2; + } } else { - /* Make sure an ATOM_EXT fits: ATOM_EXT l1 l0 t1 t2... */ - result += 1 + 2 + alen; + int alen = atom_tab(atom_val(obj))->len; + if ((MAX_ATOM_LENGTH <= 255 || alen <= 255) + && (dflags & DFLAG_SMALL_ATOM_TAGS)) { + /* Make sure a SMALL_ATOM_EXT fits: SMALL_ATOM_EXT l t1 t2... */ + result += 1 + 1 + alen; + } + else { + /* Make sure an ATOM_EXT fits: ATOM_EXT l1 l0 t1 t2... */ + result += 1 + 2 + alen; + } + insert_acache_map(acmp, obj); } - insert_acache_map(acmp, obj); break; - } case SMALL_DEF: { Sint val = signed_val(obj); @@ -2734,8 +2919,25 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) } break; case BINARY_DEF: + if (dflags & DFLAGS_INTERNAL_TAGS) { + ProcBin* pb = (ProcBin*) binary_val(obj); + Uint sub_extra = 0; + Uint tot_bytes = pb->size; + if (pb->thing_word == HEADER_SUB_BIN) { + ErlSubBin* sub = (ErlSubBin*) pb; + pb = (ProcBin*) binary_val(sub->orig); + sub_extra = 2; /* bitoffs and bitsize */ + tot_bytes += (sub->bitoffs + sub->bitsize+ 7) / 8; + } + if (pb->thing_word == HEADER_PROC_BIN + && heap_bin_size(tot_bytes) > PROC_BIN_SIZE) { + + result += 1 + sub_extra + sizeof(ProcBin); + break; + } + } result += 1 + 4 + binary_size(obj) + - 5; /* For unaligned binary */ + 5; /* For unaligned binary */ break; case FUN_DEF: { @@ -2807,7 +3009,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags) } static Sint -decoded_size(byte *ep, byte* endp, int no_refc_bins) +decoded_size(byte *ep, byte* endp, int no_refc_bins, int internal_tags) { int heap_size = 0; int terms; @@ -3017,6 +3219,29 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins) heap_size += ERL_FUN_SIZE + num_free; break; } + case ATOM_INTERNAL_REF2: + SKIP(2+atom_extra_skip); + atom_extra_skip = 0; + break; + case ATOM_INTERNAL_REF3: + SKIP(3+atom_extra_skip); + atom_extra_skip = 0; + break; + + case BINARY_INTERNAL_REF: + if (!internal_tags) { + return -1; + } + SKIP(sizeof(ProcBin)); + heap_size += PROC_BIN_SIZE; + break; + case BIT_BINARY_INTERNAL_REF: + if (!internal_tags) { + return -1; + } + SKIP(2+sizeof(ProcBin)); + heap_size += PROC_BIN_SIZE + ERL_SUB_BIN_SIZE; + break; default: return -1; } diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h index cee48bbeb0..d8287b96a4 100644 --- a/erts/emulator/beam/external.h +++ b/erts/emulator/beam/external.h @@ -54,6 +54,10 @@ #define DIST_HEADER 'D' #define ATOM_CACHE_REF 'R' +#define ATOM_INTERNAL_REF2 'I' +#define ATOM_INTERNAL_REF3 'K' +#define BINARY_INTERNAL_REF 'J' +#define BIT_BINARY_INTERNAL_REF 'L' #define COMPRESSED 'P' #if 0 @@ -156,7 +160,9 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *); void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *); Uint erts_encode_ext_size(Eterm); +Uint erts_encode_ext_size_ets(Eterm); void erts_encode_ext(Eterm, byte **); +byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap); #ifdef ERTS_WANT_EXTERNAL_TAGS ERTS_GLB_INLINE void erts_peek_dist_header(ErtsDistHeaderPeek *, byte *, Uint); @@ -172,7 +178,9 @@ Sint erts_decode_dist_ext_size(ErtsDistExternal *, int); Eterm erts_decode_dist_ext(Eterm **, ErlOffHeap *, ErtsDistExternal *); Sint erts_decode_ext_size(byte*, Uint, int); +Sint erts_decode_ext_size_ets(byte*, Uint); Eterm erts_decode_ext(Eterm **, ErlOffHeap *, byte**); +Eterm erts_decode_ext_ets(Eterm **, ErlOffHeap *, byte*); Eterm erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 280421952e..524db2a2eb 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -522,6 +522,7 @@ union erl_off_heap_ptr { struct erl_fun_thing* fun; struct external_thing_* ext; Eterm* ep; + void* voidp; }; /* arrays that get malloced at startup */ @@ -1499,7 +1500,7 @@ erts_cmp_timeval(SysTimeval *t1p, SysTimeval *t2p) #endif #ifdef DEBUG -void p_slpq(_VOID_); +void p_slpq(void); #endif /* utils.c */ @@ -1595,6 +1596,19 @@ Sint erts_binary_set_loop_limit(Sint limit); /* erl_unicode.c */ void erts_init_unicode(void); Sint erts_unicode_set_loop_limit(Sint limit); + +void erts_native_filename_put(Eterm ioterm, int encoding, byte *p) ; +Sint erts_native_filename_need(Eterm ioterm, int encoding); +void erts_copy_utf8_to_utf16_little(byte *target, byte *bytes, int num_chars); +int erts_analyze_utf8(byte *source, Uint size, + byte **err_pos, Uint *num_chars, int *left); +char *erts_convert_filename_to_native(Eterm name, ErtsAlcType_t alloc_type, int allow_empty); + +#define ERTS_UTF8_OK 0 +#define ERTS_UTF8_INCOMPLETE 1 +#define ERTS_UTF8_ERROR 2 +#define ERTS_UTF8_ANALYZE_MORE 3 + /* erl_trace.c */ void erts_init_trace(void); void erts_trace_check_exiting(Eterm exiting); @@ -1728,11 +1742,6 @@ Uint erts_current_reductions(Process* current, Process *p); int erts_print_system_version(int to, void *arg, Process *c_p); -/* - * Interface to erl_init - */ -void erl_init(void); - #define seq_trace_output(token, msg, type, receiver, process) \ seq_trace_output_generic((token), (msg), (type), (receiver), (process), NIL) #define seq_trace_output_exit(token, msg, type, receiver, exitfrom) \ diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 79022d5dd7..9ed92bbe03 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -2802,17 +2802,25 @@ driver_deliver_term(ErlDrvPort port, break; case ERL_DRV_INT: /* signed int argument */ ERTS_DDT_CHK_ENOUGH_ARGS(1); +#if HALFWORD_HEAP + erts_bld_sint64(NULL, &need, (Sint64)ptr[0]); +#else /* check for bignum */ if (!IS_SSMALL((Sint)ptr[0])) need += BIG_UINT_HEAP_SIZE; /* use small_to_big */ +#endif ptr++; depth++; break; case ERL_DRV_UINT: /* unsigned int argument */ ERTS_DDT_CHK_ENOUGH_ARGS(1); +#if HALFWORD_HEAP + erts_bld_uint64(NULL, &need, (Uint64)ptr[0]); +#else /* check for bignum */ if (!IS_USMALL(0, (Uint)ptr[0])) need += BIG_UINT_HEAP_SIZE; /* use small_to_big */ +#endif ptr++; depth++; break; @@ -2979,22 +2987,30 @@ driver_deliver_term(ErlDrvPort port, break; case ERL_DRV_INT: /* signed int argument */ +#if HALFWORD_HEAP + mess = erts_bld_sint64(&hp, NULL, (Sint64)ptr[0]); +#else if (IS_SSMALL((Sint)ptr[0])) mess = make_small((Sint)ptr[0]); else { mess = small_to_big((Sint)ptr[0], hp); hp += BIG_UINT_HEAP_SIZE; } +#endif ptr++; break; case ERL_DRV_UINT: /* unsigned int argument */ +#if HALFWORD_HEAP + mess = erts_bld_uint64(&hp, NULL, (Uint64)ptr[0]); +#else if (IS_USMALL(0, (Uint)ptr[0])) mess = make_small((Uint)ptr[0]); else { mess = uint_to_big((Uint)ptr[0], hp); hp += BIG_UINT_HEAP_SIZE; } +#endif ptr++; break; diff --git a/erts/emulator/beam/packet_parser.c b/erts/emulator/beam/packet_parser.c index 5bcd567b5f..a66d60aa22 100644 --- a/erts/emulator/beam/packet_parser.c +++ b/erts/emulator/beam/packet_parser.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-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 @@ -47,11 +47,6 @@ (((unsigned char*) (s))[1] << 8) | \ (((unsigned char*) (s))[0])) -#define put_int24(s, x) ((((unsigned char*)(s))[0] = ((x) >> 16) & 0xff), \ - (((unsigned char*)(s))[1] = ((x) >> 8) & 0xff), \ - (((unsigned char*)(s))[2] = (x) & 0xff)) - - #if !defined(__WIN32__) && !defined(HAVE_STRNCASECMP) #define STRNCASECMP my_strncasecmp @@ -833,7 +828,7 @@ int packet_parse_ssl(const char* buf, int len, char prefix[4]; /* <<1:8,Length:24,Data/binary>> */ prefix[0] = 1; - put_int24(&prefix[1],len-3); + put_int24(len-3,&prefix[1]); return pcb->ssl_tls(arg, 22, major, minor, buf+3, len-3, prefix, sizeof(prefix)); } else { diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 0031568af6..27c5f99320 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -466,8 +466,6 @@ static const int zero_value = 0, one_value = 1; # endif /* !__WIN32__ */ #endif /* WANT_NONBLOCKING */ -extern erts_cpu_info_t *erts_cpuinfo; /* erl_init.c */ - __decl_noreturn void __noreturn erl_exit(int n, char*, ...); /* Some special erl_exit() codes: */ @@ -1168,6 +1166,15 @@ void* sys_calloc2(Uint, Uint); ((char*)(s))[3] = (char)(i) & 0xff;} \ while (0) +#define get_int24(s) ((((unsigned char*) (s))[0] << 16) | \ + (((unsigned char*) (s))[1] << 8) | \ + (((unsigned char*) (s))[2])) + +#define put_int24(i, s) do {((char*)(s))[0] = (char)((i) >> 16) & 0xff; \ + ((char*)(s))[1] = (char)((i) >> 8) & 0xff; \ + ((char*)(s))[2] = (char)(i) & 0xff;} \ + while (0) + #define get_int16(s) ((((unsigned char*) (s))[0] << 8) | \ (((unsigned char*) (s))[1])) @@ -1181,6 +1188,7 @@ void* sys_calloc2(Uint, Uint); #define put_int8(i, s) do {((unsigned char*)(s))[0] = (i) & 0xff;} while (0) + /* * Use DEBUGF as you would use printf, but use double parentheses: * @@ -1245,6 +1253,22 @@ char* win32_errorstr(int); #endif +/************************************************************************ + * Find out the native filename encoding of the process (look at locale of + * Unix processes and just do UTF16 on windows + ************************************************************************/ +#define ERL_FILENAME_UNKNOWN 0 +#define ERL_FILENAME_LATIN1 1 +#define ERL_FILENAME_UTF8 2 +#define ERL_FILENAME_UTF8_MAC 3 +#define ERL_FILENAME_WIN_WCHAR 4 + +int erts_get_native_filename_encoding(void); +/* The set function is only to be used by erl_init! */ +void erts_set_user_requested_filename_encoding(int encoding); +int erts_get_user_requested_filename_encoding(void); + +void erts_init_sys_common_misc(void); #endif diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index c450f10f48..786fa7da77 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -67,6 +67,8 @@ #define FILE_RESP_LDATA 6 #define FILE_RESP_N2DATA 7 #define FILE_RESP_EOF 8 +#define FILE_RESP_FNAME 9 +#define FILE_RESP_ALL_DATA 10 /* Options */ @@ -109,11 +111,11 @@ void erl_exit(int n, char *fmt, ...); static ErlDrvSysInfo sys_info; -/*#define TRACE 1*/ +/* #define TRACE 1 */ #ifdef TRACE -# define TRACE_C(c) (putchar(c)) -# define TRACE_S(s) (fputs((s), stdout)) -# define TRACE_F(args) (printf args) +# define TRACE_C(c) do { putchar(c); fflush(stdout); } while (0) +# define TRACE_S(s) do { fputs((s), stdout); fflush(stdout); } while (0) +# define TRACE_F(args) do { printf args ;fflush(stdout); } while (0) #else # define TRACE_C(c) ((void)(0)) # define TRACE_S(s) ((void)(0)) @@ -137,24 +139,54 @@ static ErlDrvSysInfo sys_info; #define MUTEX_UNLOCK(m) #endif - - #if 0 /* Experimental, for forcing all file operations to use the same thread. */ -static unsigned file_fixed_key = 1; -#define KEY(desc) (&file_fixed_key) + static unsigned file_fixed_key = 1; +# define KEY(desc) (&file_fixed_key) #else -#define KEY(desc) (&(desc)->key) +# define KEY(desc) (&(desc)->key) #endif +#ifdef FILENAMES_16BIT +# define FILENAME_BYTELEN(Str) filename_len_16bit(Str) +# define FILENAME_COPY(To,From) filename_cpy_16bit((To),(From)) +# define FILENAME_CHARSIZE 2 + + static int filename_len_16bit(char *str) + { + char *p = str; + while(*p != '\0' || p[1] != '\0') { + p += 2; + } + return (p - str); + } + + static void filename_cpy_16bit(char *to, char *from) + { + while(*from != '\0' || from[1] != '\0') { + *to++ = *from++; + *to++ = *from++; + } + *to++ = *from++; + *to++ = *from++; + } + +#else +# define FILENAME_BYTELEN(Str) strlen(Str) +# define FILENAME_COPY(To,From) strcpy(To,From) +# define FILENAME_CHARSIZE 1 +#endif -#if MAXPATHLEN >= BUFSIZ -#define RESBUFSIZE MAXPATHLEN+1 +#if (MAXPATHLEN+1)*FILENAME_CHARSIZE+1 > BUFSIZ +# define RESBUFSIZE ((MAXPATHLEN+1)*FILENAME_CHARSIZE+1) #else -#define RESBUFSIZE BUFSIZ +# define RESBUFSIZE BUFSIZ #endif + + + #define GET_TIME(i, b) \ (i).year = get_int32((b) + 0 * 4); \ (i).month = get_int32((b) + 1 * 4); \ @@ -286,9 +318,9 @@ struct t_preadv { }; #define READDIR_BUFSIZE (8*1024) -#if READDIR_BUFSIZE < (2*MAXPATHLEN) -#undef READDIR_BUFSIZE -#define READDIR_BUFSIZE (2*MAXPATHLEN) +#if READDIR_BUFSIZE < (FILENAME_CHARSIZE*2*(MAXPATHLEN+1)) +# undef READDIR_BUFSIZE +# define READDIR_BUFSIZE (FILENAME_CHARSIZE*2*(MAXPATHLEN+1)) #endif struct t_readdir_buf { @@ -369,6 +401,7 @@ struct t_data }; + #define EF_ALLOC(S) driver_alloc((S)) #define EF_REALLOC(P, S) driver_realloc((P), (S)) #define EF_SAFE_ALLOC(S) ef_safe_alloc((S)) @@ -1288,7 +1321,7 @@ static void invoke_writev(void *data) { p < size && iovcnt < iovlen; p += iov0[iovcnt++].iov_len) ; - iov = EF_ALLOC(sizeof(SysIOVec)*iovcnt); + iov = EF_SAFE_ALLOC(sizeof(SysIOVec)*iovcnt); memcpy(iov,iov0,iovcnt*sizeof(SysIOVec)); MUTEX_UNLOCK(d->c.writev.q_mtx); /* Let go of lock until we deque from original vector */ @@ -1368,7 +1401,7 @@ static void invoke_readlink(void *data) d->result_ok = efile_readlink(&d->errInfo, d->b, resbuf+1, RESBUFSIZE-1); if (d->result_ok != 0) - strcpy((char *) d->b + 1, resbuf+1); + FILENAME_COPY((char *) d->b + 1, resbuf+1); } static void invoke_altname(void *data) @@ -1380,7 +1413,7 @@ static void invoke_altname(void *data) d->result_ok = efile_altname(&d->errInfo, d->b, resbuf+1, RESBUFSIZE-1); if (d->result_ok != 0) - strcpy((char *) d->b + 1, resbuf+1); + FILENAME_COPY((char *) d->b + 1, resbuf+1); } static void invoke_pwritev(void *data) { @@ -1405,7 +1438,7 @@ static void invoke_pwritev(void *data) { /* Lock the queue just for a while, we don't want it locked during write */ MUTEX_LOCK(c->q_mtx); iov0 = driver_peekq(c->port, &iovlen); - iov = EF_ALLOC(sizeof(SysIOVec)*iovlen); + iov = EF_SAFE_ALLOC(sizeof(SysIOVec)*iovlen); memcpy(iov,iov0,sizeof(SysIOVec)*iovlen); MUTEX_UNLOCK(c->q_mtx); @@ -1499,7 +1532,7 @@ static void invoke_link(void *data) char *new_name; d->again = 0; - new_name = name+strlen(name)+1; + new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; d->result_ok = efile_link(&d->errInfo, name, new_name); } @@ -1510,7 +1543,7 @@ static void invoke_symlink(void *data) char *new_name; d->again = 0; - new_name = name+strlen(name)+1; + new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; d->result_ok = efile_symlink(&d->errInfo, name, new_name); } @@ -1521,7 +1554,7 @@ static void invoke_rename(void *data) char *new_name; d->again = 0; - new_name = name+strlen(name)+1; + new_name = name+FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; d->result_ok = efile_rename(&d->errInfo, name, new_name); } @@ -1569,13 +1602,15 @@ static void invoke_readdir(void *data) int s; char *p = NULL; int buf_sz = 0; + size_t tmp_bs; d->again = 0; d->errInfo.posix_errno = 0; while (1) { char *str; - if (buf_sz < (4 /* sz */ + 1 /* cmd */ + MAXPATHLEN + 1 /* '\0' */)) { + if (buf_sz < (4 /* sz */ + 1 /* cmd */ + + FILENAME_CHARSIZE*(MAXPATHLEN + 1))) { struct t_readdir_buf *b; if (p) { put_int32(0, p); /* EOB */ @@ -1591,18 +1626,18 @@ static void invoke_readdir(void *data) buf_sz = READDIR_BUFSIZE - 4/* EOB */; } - p[4] = FILE_RESP_OK; + p[4] = FILE_RESP_FNAME; buf_sz -= 4 + 1; str = p + 4 + 1; ASSERT(buf_sz >= MAXPATHLEN + 1); - s = efile_readdir(&d->errInfo, d->b, &d->dir_handle, str, buf_sz); + tmp_bs = buf_sz; + s = efile_readdir(&d->errInfo, d->b, &d->dir_handle, str, &tmp_bs); if (s) { - int str_sz = strlen(str); - int sz = str_sz + 1; - put_int32(sz, p); - p += 4 + sz; - buf_sz -= str_sz; + put_int32(tmp_bs + 1 /* 1 byte for opcode */, p); + p += 4 + tmp_bs + 1; + ASSERT(p == (str + tmp_bs)); + buf_sz -= tmp_bs; } else { put_int32(1, p); @@ -1911,7 +1946,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) if (!d->result_ok) reply_error(desc, &d->errInfo); else { - header[0] = FILE_RESP_OK; + header[0] = FILE_RESP_ALL_DATA; TRACE_C('R'); driver_output_binary(desc->port, header, 1, d->c.read_file.binp, @@ -1968,10 +2003,10 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) if (!d->result_ok) reply_error(desc, &d->errInfo); else { - resbuf[0] = FILE_RESP_OK; - length = 1+strlen((char*) resbuf+1); + resbuf[0] = FILE_RESP_FNAME; + length = 1+FILENAME_BYTELEN((char*) resbuf+1); TRACE_C('R'); - driver_output2(desc->port, resbuf, length, NULL, 0); + driver_output2(desc->port, resbuf, 1, resbuf+1, length-1); } free_data(data); break; @@ -2031,13 +2066,18 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data) int sz = get_int32(p); while (sz) { /* 0 == EOB */ p += 4; - driver_output2(desc->port, p, sz, NULL, 0); + if (sz - 1 > 0) { + driver_output2(desc->port, p, 1, p+1, sz-1); + } else { + driver_output2(desc->port, p, 1, NULL, 0); + } p += sz; sz = get_int32(p); } b1 = b1->next; EF_FREE(b2); } + d->c.read_dir.first_buf = NULL; d->c.read_dir.last_buf = NULL; } @@ -2113,9 +2153,9 @@ file_output(ErlDrvData e, char* buf, int count) case FILE_MKDIR: { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_mkdir; d->free = free_data; @@ -2124,9 +2164,9 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_RMDIR: { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_rmdir; d->free = free_data; @@ -2135,9 +2175,9 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_DELETE: { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_delete_file; d->free = free_data; @@ -2147,14 +2187,14 @@ file_output(ErlDrvData e, char* buf, int count) case FILE_RENAME: { char* new_name; - - new_name = name+strlen(name)+1; + int namelen = FILENAME_BYTELEN(name)+FILENAME_CHARSIZE; + new_name = name+namelen; d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 - + strlen(name) + 1 - + strlen(new_name) + 1); + + namelen + + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE); - strcpy(d->b, name); - strcpy(d->b + strlen(name) + 1, new_name); + FILENAME_COPY(d->b, name); + FILENAME_COPY(d->b + namelen, new_name); d->flags = desc->flags; d->fd = fd; d->command = command; @@ -2165,9 +2205,9 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_CHDIR: { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + FILENAME_CHARSIZE); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_chdir; d->free = free_data; @@ -2190,9 +2230,10 @@ file_output(ErlDrvData e, char* buf, int count) #ifdef USE_THREADS if (sys_info.async_threads > 0) { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + + FILENAME_CHARSIZE); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->dir_handle = NULL; d->command = command; d->invoke = invoke_readdir; @@ -2205,17 +2246,19 @@ file_output(ErlDrvData e, char* buf, int count) else #endif { + size_t resbufsize; char resbuf[RESBUFSIZE+1]; EFILE_DIR_HANDLE dir_handle; /* Handle to open directory. */ errInfo.posix_errno = 0; dir_handle = NULL; - resbuf[0] = FILE_RESP_OK; + resbuf[0] = FILE_RESP_FNAME; + resbufsize = RESBUFSIZE; while (efile_readdir(&errInfo, name, &dir_handle, - resbuf+1, RESBUFSIZE)) { - int length = 1 + strlen(resbuf+1); - driver_output2(desc->port, resbuf, length, NULL, 0); + resbuf+1, &resbufsize)) { + driver_output2(desc->port, resbuf, 1, resbuf+1, resbufsize); + resbufsize = RESBUFSIZE; } if (errInfo.posix_errno != 0) { reply_error(desc, &errInfo); @@ -2227,11 +2270,12 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_OPEN: { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(buf+4) + 1); + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(buf+4) + + FILENAME_CHARSIZE); d->flags = get_int32((uchar*)buf); name = buf+4; - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_open; d->free = free_data; @@ -2240,44 +2284,45 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_FDATASYNC: - { + { d = EF_SAFE_ALLOC(sizeof(struct t_data)); - + d->fd = fd; d->command = command; d->invoke = invoke_fdatasync; d->free = free_data; d->level = 2; goto done; - } + } case FILE_FSYNC: - { - d = EF_SAFE_ALLOC(sizeof(struct t_data)); - - d->fd = fd; - d->command = command; - d->invoke = invoke_fsync; - d->free = free_data; - d->level = 2; - goto done; - } + { + d = EF_SAFE_ALLOC(sizeof(struct t_data)); + + d->fd = fd; + d->command = command; + d->invoke = invoke_fsync; + d->free = free_data; + d->level = 2; + goto done; + } case FILE_FSTAT: case FILE_LSTAT: - { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + strlen(name) + 1); + { + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + FILENAME_BYTELEN(name) + + FILENAME_CHARSIZE); + + FILENAME_COPY(d->b, name); + d->fd = fd; + d->command = command; + d->invoke = invoke_flstat; + d->free = free_data; + d->level = 2; + goto done; + } - strcpy(d->b, name); - d->fd = fd; - d->command = command; - d->invoke = invoke_flstat; - d->free = free_data; - d->level = 2; - goto done; - } - case FILE_TRUNCATE: { d = EF_SAFE_ALLOC(sizeof(struct t_data)); @@ -2294,7 +2339,7 @@ file_output(ErlDrvData e, char* buf, int count) case FILE_WRITE_INFO: { d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 - + strlen(buf+21*4) + 1); + + FILENAME_BYTELEN(buf+21*4) + FILENAME_CHARSIZE); d->info.mode = get_int32(buf + 0 * 4); d->info.uid = get_int32(buf + 1 * 4); @@ -2302,7 +2347,7 @@ file_output(ErlDrvData e, char* buf, int count) GET_TIME(d->info.accessTime, buf + 3 * 4); GET_TIME(d->info.modifyTime, buf + 9 * 4); GET_TIME(d->info.cTime, buf + 15 * 4); - strcpy(d->b, buf+21*4); + FILENAME_COPY(d->b, buf+21*4); d->command = command; d->invoke = invoke_write_info; d->free = free_data; @@ -2314,7 +2359,7 @@ file_output(ErlDrvData e, char* buf, int count) { d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1); - strcpy(d->b, name); + FILENAME_COPY(d->b, name); d->command = command; d->invoke = invoke_readlink; d->free = free_data; @@ -2323,28 +2368,29 @@ file_output(ErlDrvData e, char* buf, int count) } case FILE_ALTNAME: - { - d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1); - strcpy(d->b, name); - d->command = command; - d->invoke = invoke_altname; - d->free = free_data; - d->level = 2; - goto done; - } + { + d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 + RESBUFSIZE + 1); + FILENAME_COPY(d->b, name); + d->command = command; + d->invoke = invoke_altname; + d->free = free_data; + d->level = 2; + goto done; + } case FILE_LINK: { char* new_name; + int namelen = FILENAME_BYTELEN(name) + FILENAME_CHARSIZE; - new_name = name+strlen(name)+1; + new_name = name+namelen; d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 - + strlen(name) + 1 - + strlen(new_name) + 1); + + namelen + + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE); - strcpy(d->b, name); - strcpy(d->b + strlen(name) + 1, new_name); + FILENAME_COPY(d->b, name); + FILENAME_COPY(d->b + namelen, new_name); d->flags = desc->flags; d->fd = fd; d->command = command; @@ -2357,14 +2403,15 @@ file_output(ErlDrvData e, char* buf, int count) case FILE_SYMLINK: { char* new_name; + int namelen = FILENAME_BYTELEN(name) + FILENAME_CHARSIZE; - new_name = name+strlen(name)+1; + new_name = name+namelen; d = EF_SAFE_ALLOC(sizeof(struct t_data) - 1 - + strlen(name) + 1 - + strlen(new_name) + 1); + + namelen + + FILENAME_BYTELEN(new_name) + FILENAME_CHARSIZE); - strcpy(d->b, name); - strcpy(d->b + strlen(name) + 1, new_name); + FILENAME_COPY(d->b, name); + FILENAME_COPY(d->b + namelen, new_name); d->flags = desc->flags; d->fd = fd; d->command = command; @@ -3004,6 +3051,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { case FILE_READ_FILE: { struct t_data *d; + char *filename; if (ev->size < 1+1) { /* Buffer contains empty name */ reply_posix_error(desc, ENOENT); @@ -3014,7 +3062,8 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { reply_posix_error(desc, EINVAL); goto done; } - d = EF_ALLOC(sizeof(struct t_data) + ev->size); + filename = EV_CHAR_P(ev, p, q); + d = EF_ALLOC(sizeof(struct t_data) -1 + FILENAME_BYTELEN(filename) + FILENAME_CHARSIZE); if (! d) { reply_posix_error(desc, ENOMEM); goto done; @@ -3022,8 +3071,7 @@ file_outputv(ErlDrvData e, ErlIOVec *ev) { d->command = command; d->reply = !0; /* Copy name */ - memcpy(d->c.read_file.name, EV_CHAR_P(ev, p, q), ev->size-1); - d->c.read_file.name[ev->size-1] = '\0'; + FILENAME_COPY(d->c.read_file.name, filename); d->c.read_file.binp = NULL; d->invoke = invoke_read_file; d->free = free_read_file; diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h index ac95c1f949..3097ded3f1 100644 --- a/erts/emulator/drivers/common/erl_efile.h +++ b/erts/emulator/drivers/common/erl_efile.h @@ -59,6 +59,14 @@ #define FA_WRITE 1 #define FA_READ 2 +/* Some OS'es (i.e. Windows) has filenames in wide charaqcters. That requires special handling */ +/* Note that we do *not* honor alignment in the communication to the OS specific driver, */ +/* which is not a problem on x86, but might be on other platforms. The OS specific efile */ +/* implementation is expected to align if needed */ +#ifdef __WIN32__ +#define FILENAMES_16BIT 1 +#endif + /* * An handle to an open directory. To be cast to the correct type * in the system-dependent directory functions. @@ -123,7 +131,7 @@ int efile_getdcwd(Efile_error* errInfo, int drive, char* buffer, size_t size); int efile_readdir(Efile_error* errInfo, char* name, EFILE_DIR_HANDLE* dir_handle, - char* buffer, size_t size); + char* buffer, size_t *size); int efile_openfile(Efile_error* errInfo, char* name, int flags, int* pfd, Sint64* pSize); void efile_closefile(int fd); diff --git a/erts/emulator/drivers/common/gzio.c b/erts/emulator/drivers/common/gzio.c index 801bc61d4d..5531a275ea 100644 --- a/erts/emulator/drivers/common/gzio.c +++ b/erts/emulator/drivers/common/gzio.c @@ -28,6 +28,7 @@ #ifdef __WIN32__ #define HAVE_CONFLICTING_FREAD_DECLARATION +#define FILENAMES_16BIT 1 #endif #ifdef STDC @@ -102,6 +103,40 @@ local uLong getLong OF((gz_stream *s)); # define ERTS_GZREAD(File, Buf, Count) fread((Buf), 1, (Count), (File)) #endif +/* + * Ripped from efile_drv.c + */ + +#ifdef FILENAMES_16BIT +# define FILENAME_BYTELEN(Str) filename_len_16bit(Str) +# define FILENAME_COPY(To,From) filename_cpy_16bit((To),(From)) +# define FILENAME_CHARSIZE 2 + + static int filename_len_16bit(const char *str) + { + const char *p = str; + while(*p != '\0' || p[1] != '\0') { + p += 2; + } + return (p - str); + } + + static void filename_cpy_16bit(char *to, const char *from) + { + while(*from != '\0' || from[1] != '\0') { + *to++ = *from++; + *to++ = *from++; + } + *to++ = *from++; + *to++ = *from++; + } + +#else +# define FILENAME_BYTELEN(Str) strlen(Str) +# define FILENAME_COPY(To,From) strcpy(To,From) +# define FILENAME_CHARSIZE 1 +#endif + /* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The file is given either by file descriptor @@ -144,11 +179,11 @@ local gzFile gz_open (path, mode) s->position = 0; s->destroy = destroy; - s->path = (char*)ALLOC(strlen(path)+1); + s->path = (char*)ALLOC(FILENAME_BYTELEN(path)+FILENAME_CHARSIZE); if (s->path == NULL) { return s->destroy(s), (gzFile)Z_NULL; } - strcpy(s->path, path); /* do this early for debugging */ + FILENAME_COPY(s->path, path); /* do this early for debugging */ s->mode = '\0'; do { @@ -194,7 +229,22 @@ local gzFile gz_open (path, mode) s->stream.avail_out = Z_BUFSIZE; errno = 0; -#ifdef UNIX +#if defined(FILENAMES_16BIT) + { + char wfmode[160]; + int i=0,j; + for(j=0;fmode[j] != '\0';++j) { + wfmode[i++]=fmode[j]; + wfmode[i++]='\0'; + } + wfmode[i++] = '\0'; + wfmode[i++] = '\0'; + s->file = F_OPEN(path, wfmode); + if (s->file == NULL) { + return s->destroy(s), (gzFile)Z_NULL; + } + } +#elif defined(UNIX) if (s->mode == 'r') { s->file = open(path, O_RDONLY); } else { diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 3de48194fb..1382d1dfe4 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -54,6 +54,9 @@ #ifdef HAVE_IFADDRS_H #include <ifaddrs.h> #endif +#ifdef HAVE_NETPACKET_PACKET_H +#include <netpacket/packet.h> +#endif /* All platforms fail on malloc errors. */ #define FATAL_MALLOC @@ -85,8 +88,21 @@ #include <winsock2.h> #endif #include <windows.h> +#include <Ws2tcpip.h> /* NEED VC 6.0 or higher */ + +/* Visual studio 2008+: NTDDI_VERSION needs to be set for iphlpapi.h + to define the right structures. It needs to be set to WINXP (or LONGHORN) + for IPV6 to work and it's set lower by default, so we need to change it. */ +#ifdef HAVE_SDKDDKVER_H +# include <sdkddkver.h> +# ifdef NTDDI_VERSION +# undef NTDDI_VERSION +# endif +# define NTDDI_VERSION NTDDI_WINXP +#endif + +#include <iphlpapi.h> -#include <Ws2tcpip.h> /* NEED VC 6.0 !!! */ #undef WANT_NONBLOCKING #include "sys.h" @@ -467,6 +483,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define INET_REQ_IFGET 22 #define INET_REQ_IFSET 23 #define INET_REQ_SUBSCRIBE 24 +#define INET_REQ_GETIFADDRS 25 /* TCP requests */ #define TCP_REQ_ACCEPT 40 #define TCP_REQ_LISTEN 41 @@ -632,15 +649,12 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define IS_BUSY(d) \ (((d)->state & INET_F_BUSY) == INET_F_BUSY) +#define INET_MAX_OPT_BUFFER (64*1024) + #define INET_DEF_BUFFER 1460 /* default buffer size */ #define INET_MIN_BUFFER 1 /* internal min buffer */ -#define INET_MAX_BUFFER (1024*64) /* internal max buffer */ -/* Note: INET_HIGH_WATERMARK MUST be less than 2*INET_MAX_BUFFER */ #define INET_HIGH_WATERMARK (1024*8) /* 8k pending high => busy */ -/* Note: INET_LOW_WATERMARK MUST be less than INET_MAX_BUFFER and -** less than INET_HIGH_WATERMARK -*/ #define INET_LOW_WATERMARK (1024*4) /* 4k pending => allow more */ #define INET_INFINITY 0xffffffff /* infinity value */ @@ -1251,139 +1265,136 @@ static int load_ip_and_port LOAD_ATOM((spec), (i), (flag) ? am_true : am_false); #endif /* HAVE_SCTP */ +/* Assume a cache line size of 64 bytes */ +#define INET_DRV_CACHE_LINE_SIZE ((ErlDrvUInt) 64) +#define INET_DRV_CACHE_LINE_MASK (INET_DRV_CACHE_LINE_SIZE - 1) + /* ** Binary Buffer Managment ** We keep a stack of usable buffers */ -#define BUFFER_STACK_SIZE 16 - -static erts_smp_spinlock_t inet_buffer_stack_lock; -static ErlDrvBinary* buffer_stack[BUFFER_STACK_SIZE]; -static int buffer_stack_pos = 0; +#define BUFFER_STACK_SIZE 14 +#define BUFFER_STACK_MAX_MEM_SIZE (1024*1024) +ErlDrvTSDKey buffer_stack_key; -/* - * XXX - * The erts_smp_spin_* functions should not be used by drivers (but this - * driver is special). Replace when driver locking api has been implemented. - * /rickard - */ -#define BUFSTK_LOCK erts_smp_spin_lock(&inet_buffer_stack_lock); -#define BUFSTK_UNLOCK erts_smp_spin_unlock(&inet_buffer_stack_lock); - -#ifdef DEBUG -static int tot_buf_allocated = 0; /* memory in use for i_buf */ -static int tot_buf_stacked = 0; /* memory on stack */ -static int max_buf_allocated = 0; /* max allocated */ - -#define COUNT_BUF_ALLOC(sz) do { \ - BUFSTK_LOCK; \ - tot_buf_allocated += (sz); \ - if (tot_buf_allocated > max_buf_allocated) \ - max_buf_allocated = tot_buf_allocated; \ - BUFSTK_UNLOCK; \ -} while(0) - -#define COUNT_BUF_FREE(sz) do { \ - BUFSTK_LOCK; \ - tot_buf_allocated -= (sz); \ - BUFSTK_UNLOCK; \ - } while(0) - -#define COUNT_BUF_STACK(sz) do { \ - BUFSTK_LOCK; \ - tot_buf_stacked += (sz); \ - BUFSTK_UNLOCK; \ - } while(0) +typedef struct { + int mem_size; + int pos; + ErlDrvBinary* stk[BUFFER_STACK_SIZE]; +} InetDrvBufStkBase; -#else +typedef struct { + InetDrvBufStkBase buf; + char align[(((sizeof(InetDrvBufStkBase) - 1) / INET_DRV_CACHE_LINE_SIZE) + 1) + * INET_DRV_CACHE_LINE_SIZE]; +} InetDrvBufStk; + +static InetDrvBufStk *get_bufstk(void) +{ + InetDrvBufStk *bs = erl_drv_tsd_get(buffer_stack_key); + if (bs) + return bs; + bs = driver_alloc(sizeof(InetDrvBufStk) + + INET_DRV_CACHE_LINE_SIZE - 1); + if (!bs) + return NULL; + if ((((ErlDrvUInt) bs) & INET_DRV_CACHE_LINE_MASK) != 0) + bs = ((InetDrvBufStk *) + ((((ErlDrvUInt) bs) & ~INET_DRV_CACHE_LINE_MASK) + + INET_DRV_CACHE_LINE_SIZE)); + erl_drv_tsd_set(buffer_stack_key, bs); + bs->buf.pos = 0; + bs->buf.mem_size = 0; -#define COUNT_BUF_ALLOC(sz) -#define COUNT_BUF_FREE(sz) -#define COUNT_BUF_STACK(sz) + ASSERT(bs == erl_drv_tsd_get(buffer_stack_key)); -#endif + return bs; +} static ErlDrvBinary* alloc_buffer(long minsz) { - ErlDrvBinary* buf = NULL; + InetDrvBufStk *bs = get_bufstk(); + + DEBUGF(("alloc_buffer: %ld\r\n", minsz)); + + if (bs && bs->buf.pos > 0) { + long size; + ErlDrvBinary* buf = bs->buf.stk[--bs->buf.pos]; + size = buf->orig_size; + bs->buf.mem_size -= size; + ASSERT(0 <= bs->buf.mem_size + && bs->buf.mem_size <= BUFFER_STACK_MAX_MEM_SIZE); + if (size >= minsz) + return buf; - BUFSTK_LOCK; + driver_free_binary(buf); + } - DEBUGF(("alloc_buffer: sz = %ld, tot = %d, max = %d\r\n", - minsz, tot_buf_allocated, max_buf_allocated)); + ASSERT(!bs || bs->buf.pos != 0 || bs->buf.mem_size == 0); - if (buffer_stack_pos > 0) { - int origsz; + return driver_alloc_binary(minsz); +} - buf = buffer_stack[--buffer_stack_pos]; - origsz = buf->orig_size; - BUFSTK_UNLOCK; - COUNT_BUF_STACK(-origsz); - if (origsz < minsz) { - if ((buf = driver_realloc_binary(buf, minsz)) == NULL) - return NULL; - COUNT_BUF_ALLOC(buf->orig_size - origsz); +/*#define CHECK_DOUBLE_RELEASE 1*/ +#ifdef CHECK_DOUBLE_RELEASE +static void +check_double_release(InetDrvBufStk *bs, ErlDrvBinary* buf) +{ +#ifdef __GNUC__ +#warning CHECK_DOUBLE_RELEASE is enabled, this is a custom build emulator +#endif + int i; + for (i = 0; i < bs->buf.pos; ++i) { + if (bs->buf.stk[i] == buf) { + erl_exit(ERTS_ABORT_EXIT, + "Multiple buffer release in inet_drv, this " + "is a bug, save the core and send it to " + "[email protected]!"); } } - else { - BUFSTK_UNLOCK; - if ((buf = driver_alloc_binary(minsz)) == NULL) - return NULL; - COUNT_BUF_ALLOC(buf->orig_size); - } - return buf; } +#endif -/* -** Max buffer memory "cached" BUFFER_STACK_SIZE * INET_MAX_BUFFER -** (16 * 64k ~ 1M) -*/ -/*#define CHECK_DOUBLE_RELEASE 1*/ static void release_buffer(ErlDrvBinary* buf) { + InetDrvBufStk *bs; + long size; + DEBUGF(("release_buffer: %ld\r\n", (buf==NULL) ? 0 : buf->orig_size)); - if (buf == NULL) + + if (!buf) return; - BUFSTK_LOCK; - if ((buf->orig_size > INET_MAX_BUFFER) || - (buffer_stack_pos >= BUFFER_STACK_SIZE)) { - BUFSTK_UNLOCK; - COUNT_BUF_FREE(buf->orig_size); + + size = buf->orig_size; + + if (size > BUFFER_STACK_MAX_MEM_SIZE) + goto free_binary; + + bs = get_bufstk(); + if (!bs + || (bs->buf.mem_size + size > BUFFER_STACK_MAX_MEM_SIZE) + || (bs->buf.pos >= BUFFER_STACK_SIZE)) { + free_binary: driver_free_binary(buf); } else { #ifdef CHECK_DOUBLE_RELEASE -#ifdef __GNUC__ -#warning CHECK_DOUBLE_RELEASE is enabled, this is a custom build emulator + check_double_release(bs, buf); #endif - int i; - for (i = 0; i < buffer_stack_pos; ++i) { - if (buffer_stack[i] == buf) { - erl_exit(1,"Multiple buffer release in inet_drv, this is a " - "bug, save the core and send it to " - "[email protected]!"); - } - } -#endif - buffer_stack[buffer_stack_pos++] = buf; - BUFSTK_UNLOCK; - COUNT_BUF_STACK(buf->orig_size); + ASSERT(bs->buf.pos != 0 || bs->buf.mem_size == 0); + + bs->buf.mem_size += size; + bs->buf.stk[bs->buf.pos++] = buf; + + ASSERT(0 <= bs->buf.mem_size + && bs->buf.mem_size <= BUFFER_STACK_MAX_MEM_SIZE); } } static ErlDrvBinary* realloc_buffer(ErlDrvBinary* buf, long newsz) { - ErlDrvBinary* bin; -#ifdef DEBUG - long orig_size = buf->orig_size; -#endif - - if ((bin = driver_realloc_binary(buf,newsz)) != NULL) { - COUNT_BUF_ALLOC(newsz - orig_size); - ; - } - return bin; + return driver_realloc_binary(buf, newsz); } /* use a TRICK, access the refc field to see if any one else has @@ -1397,10 +1408,8 @@ static void free_buffer(ErlDrvBinary* buf) if (buf != NULL) { if (driver_binary_get_refc(buf) == 1) release_buffer(buf); - else { - COUNT_BUF_FREE(buf->orig_size); + else driver_free_binary(buf); - } } } @@ -3404,20 +3413,14 @@ static int inet_init() if (!sock_init()) goto error; - buffer_stack_pos = 0; - - erts_smp_spinlock_init(&inet_buffer_stack_lock, "inet_buffer_stack_lock"); + if (0 != erl_drv_tsd_key_create("inet_buffer_stack_key", &buffer_stack_key)) + goto error; ASSERT(sizeof(struct in_addr) == 4); # if defined(HAVE_IN6) && defined(AF_INET6) ASSERT(sizeof(struct in6_addr) == 16); # endif -#ifdef DEBUG - tot_buf_allocated = 0; - max_buf_allocated = 0; - tot_buf_stacked = 0; -#endif INIT_ATOM(ok); INIT_ATOM(tcp); INIT_ATOM(udp); @@ -3824,39 +3827,81 @@ do { if ((end)-(ptr) < (n)) goto error; } while(0) static char* sockaddr_to_buf(struct sockaddr* addr, char* ptr, char* end) { if (addr->sa_family == AF_INET || addr->sa_family == 0) { - struct in_addr a; - buf_check(ptr,end,sizeof(struct in_addr)); - a = ((struct sockaddr_in*) addr)->sin_addr; - sys_memcpy(ptr, (char*)&a, sizeof(struct in_addr)); - return ptr + sizeof(struct in_addr); + struct in_addr *p = &(((struct sockaddr_in*) addr)->sin_addr); + buf_check(ptr, end, 1 + sizeof(struct in_addr)); + *ptr = INET_AF_INET; + sys_memcpy(ptr+1, (char*)p, sizeof(struct in_addr)); + return ptr + 1 + sizeof(struct in_addr); } #if defined(HAVE_IN6) && defined(AF_INET6) else if (addr->sa_family == AF_INET6) { - struct in6_addr a; - buf_check(ptr,end,sizeof(struct in6_addr)); - a = ((struct sockaddr_in6*) addr)->sin6_addr; - sys_memcpy(ptr, (char*)&a, sizeof(struct in6_addr)); - return ptr + sizeof(struct in6_addr); + struct in6_addr *p = &(((struct sockaddr_in6*) addr)->sin6_addr); + buf_check(ptr, end, 1 + sizeof(struct in6_addr)); + *ptr = INET_AF_INET6; + sys_memcpy(ptr+1, (char*)p, sizeof(struct in6_addr)); + return ptr + 1 + sizeof(struct in6_addr); + } +#endif +#if defined(AF_LINK) + else if (addr->sa_family == AF_LINK) { + struct sockaddr_dl *sdl_p = (struct sockaddr_dl*) addr; + buf_check(ptr, end, 2 + sdl_p->sdl_alen); + put_int16(sdl_p->sdl_alen, ptr); ptr += 2; + sys_memcpy(ptr, sdl_p->sdl_data + sdl_p->sdl_nlen, sdl_p->sdl_alen); + return ptr + sdl_p->sdl_alen; + } +#endif +#if defined(AF_PACKET) && defined(HAVE_NETPACKET_PACKET_H) + else if(addr->sa_family == AF_PACKET) { + struct sockaddr_ll *sll_p = (struct sockaddr_ll*) addr; + buf_check(ptr, end, 2 + sll_p->sll_halen); + put_int16(sll_p->sll_halen, ptr); ptr += 2; + sys_memcpy(ptr, sll_p->sll_addr, sll_p->sll_halen); + return ptr + sll_p->sll_halen; } #endif + return ptr; error: return NULL; - } static char* buf_to_sockaddr(char* ptr, char* end, struct sockaddr* addr) { - buf_check(ptr,end,sizeof(struct in_addr)); - sys_memcpy((char*) &((struct sockaddr_in*)addr)->sin_addr, ptr, - sizeof(struct in_addr)); - addr->sa_family = AF_INET; - return ptr + sizeof(struct in_addr); - + buf_check(ptr,end,1); + switch (*ptr++) { + case INET_AF_INET: { + struct in_addr *p = &((struct sockaddr_in*)addr)->sin_addr; + buf_check(ptr,end,sizeof(struct in_addr)); + sys_memcpy((char*) p, ptr, sizeof(struct in_addr)); + addr->sa_family = AF_INET; + return ptr + sizeof(struct in_addr); + } + case INET_AF_INET6: { + struct in6_addr *p = &((struct sockaddr_in6*)addr)->sin6_addr; + buf_check(ptr,end,sizeof(struct in6_addr)); + sys_memcpy((char*) p, ptr, sizeof(struct in6_addr)); + addr->sa_family = AF_INET6; + return ptr + sizeof(struct in6_addr); + } + } error: return NULL; } +#if defined (IFF_POINTOPOINT) +#define IFGET_FLAGS(cflags) IFGET_FLAGS_P2P(cflags, IFF_POINTOPOINT) +#elif defined IFF_POINTTOPOINT +#define IFGET_FLAGS(cflags) IFGET_FLAGS_P2P(cflags, IFF_POINTTOPOINT) +#endif + +#define IFGET_FLAGS_P2P(cflags, iff_ptp) \ + ((((cflags) & IFF_UP) ? INET_IFF_UP : 0) | \ + (((cflags) & IFF_BROADCAST) ? INET_IFF_BROADCAST : 0) | \ + (((cflags) & IFF_LOOPBACK) ? INET_IFF_LOOPBACK : 0) | \ + (((cflags) & iff_ptp) ? INET_IFF_POINTTOPOINT : 0) | \ + (((cflags) & IFF_UP) ? INET_IFF_RUNNING : 0) | /* emulate running ? */ \ + (((cflags) & IFF_MULTICAST) ? INET_IFF_MULTICAST : 0)) #if defined(__WIN32__) && defined(SIO_GET_INTERFACE_LIST) @@ -3894,7 +3939,6 @@ static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) return ctl_reply(INET_REP_OK, sbuf, sptr - sbuf, rbuf, rsize); } - /* input is an ip-address in string format i.e A.B.C.D ** scan the INTERFACE_LIST to get the options */ @@ -3980,27 +4024,12 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, break; case INET_IFOPT_FLAGS: { - long eflags = 0; int flags = ifp->iiFlags; /* just enumerate the interfaces (no names) */ - /* translate flags */ - if (flags & IFF_UP) - eflags |= INET_IFF_UP; - if (flags & IFF_BROADCAST) - eflags |= INET_IFF_BROADCAST; - if (flags & IFF_LOOPBACK) - eflags |= INET_IFF_LOOPBACK; - if (flags & IFF_POINTTOPOINT) - eflags |= INET_IFF_POINTTOPOINT; - if (flags & IFF_UP) /* emulate runnign ? */ - eflags |= INET_IFF_RUNNING; - if (flags & IFF_MULTICAST) - eflags |= INET_IFF_MULTICAST; - buf_check(sptr, s_end, 5); *sptr++ = INET_IFOPT_FLAGS; - put_int32(eflags, sptr); + put_int32(IFGET_FLAGS(flags), sptr); sptr += 4; break; } @@ -4021,7 +4050,6 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize); } - #elif defined(SIOCGIFCONF) && defined(SIOCSIFFLAGS) /* cygwin has SIOCGIFCONF but not SIOCSIFFLAGS (Nov 2002) */ @@ -4032,69 +4060,77 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, #define SIZEA(p) (sizeof (p)) #endif - -static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) -{ - struct ifconf ifc; - struct ifreq *ifr; - char *buf; - int buflen, ifc_len, i; - char *sbuf, *sp; - - /* Courtesy of Per Bergqvist and W. Richard Stevens */ - - ifc_len = 0; - buflen = 100 * sizeof(struct ifreq); - buf = ALLOC(buflen); +static int get_ifconf(SOCKET s, struct ifconf *ifcp) { + int ifc_len = 0; + int buflen = 100 * sizeof(struct ifreq); + char *buf = ALLOC(buflen); for (;;) { - ifc.ifc_len = buflen; - ifc.ifc_buf = buf; - if (ioctl(desc->s, SIOCGIFCONF, (char *)&ifc) < 0) { + ifcp->ifc_len = buflen; + ifcp->ifc_buf = buf; + if (ioctl(s, SIOCGIFCONF, (char *)ifcp) < 0) { int res = sock_errno(); if (res != EINVAL || ifc_len) { FREE(buf); - return ctl_error(res, rbuf, rsize); + return -1; } } else { - if (ifc.ifc_len == ifc_len) break; /* buf large enough */ - ifc_len = ifc.ifc_len; + if (ifcp->ifc_len == ifc_len) break; /* buf large enough */ + ifc_len = ifcp->ifc_len; } buflen += 10 * sizeof(struct ifreq); buf = (char *)REALLOC(buf, buflen); } - - sp = sbuf = ALLOC(ifc_len+1); + return 0; +} + +static void free_ifconf(struct ifconf *ifcp) { + FREE(ifcp->ifc_buf); +} + +static int inet_ctl_getiflist(inet_descriptor* desc, char** rbuf, int rsize) +{ + struct ifconf ifc; + struct ifreq *ifrp; + char *sbuf, *sp; + int i; + + /* Courtesy of Per Bergqvist and W. Richard Stevens */ + + if (get_ifconf(desc->s, &ifc) < 0) { + return ctl_error(sock_errno(), rbuf, rsize); + } + + sp = sbuf = ALLOC(ifc.ifc_len+1); *sp++ = INET_REP_OK; i = 0; for (;;) { int n; - - ifr = (struct ifreq *) VOIDP(buf + i); - n = sizeof(ifr->ifr_name) + SIZEA(ifr->ifr_addr); - if (n < sizeof(*ifr)) n = sizeof(*ifr); - if (i+n > ifc_len) break; + + ifrp = (struct ifreq *) VOIDP(ifc.ifc_buf + i); + n = sizeof(ifrp->ifr_name) + SIZEA(ifrp->ifr_addr); + if (n < sizeof(*ifrp)) n = sizeof(*ifrp); + if (i+n > ifc.ifc_len) break; i += n; - - switch (ifr->ifr_addr.sa_family) { + + switch (ifrp->ifr_addr.sa_family) { #if defined(HAVE_IN6) && defined(AF_INET6) case AF_INET6: #endif case AF_INET: - ASSERT(sp+IFNAMSIZ+1 < sbuf+buflen+1) - strncpy(sp, ifr->ifr_name, IFNAMSIZ); + ASSERT(sp+IFNAMSIZ+1 < sbuf+ifc.ifc_len+1) + strncpy(sp, ifrp->ifr_name, IFNAMSIZ); sp[IFNAMSIZ] = '\0'; sp += strlen(sp), ++sp; } - - if (i >= ifc_len) break; + + if (i >= ifc.ifc_len) break; } - FREE(buf); + free_ifconf(&ifc); *rbuf = sbuf; return sp - sbuf; } - /* FIXME: temporary hack */ #ifndef IFHWADDRLEN #define IFHWADDRLEN 6 @@ -4133,37 +4169,52 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, #ifdef SIOCGIFHWADDR if (ioctl(desc->s, SIOCGIFHWADDR, (char *)&ifreq) < 0) break; - buf_check(sptr, s_end, 1+IFHWADDRLEN); + buf_check(sptr, s_end, 1+2+IFHWADDRLEN); *sptr++ = INET_IFOPT_HWADDR; + put_int16(IFHWADDRLEN, sptr); sptr += 2; /* raw memcpy (fix include autoconf later) */ sys_memcpy(sptr, (char*)(&ifreq.ifr_hwaddr.sa_data), IFHWADDRLEN); sptr += IFHWADDRLEN; -#elif defined(HAVE_GETIFADDRS) - struct ifaddrs *ifa, *ifp; - int found = 0; - - if (getifaddrs(&ifa) == -1) - goto error; +#elif defined(SIOCGENADDR) + if (ioctl(desc->s, SIOCGENADDR, (char *)&ifreq) < 0) + break; + buf_check(sptr, s_end, 1+2+sizeof(ifreq.ifr_enaddr)); + *sptr++ = INET_IFOPT_HWADDR; + put_int16(sizeof(ifreq.ifr_enaddr), sptr); sptr += 2; + /* raw memcpy (fix include autoconf later) */ + sys_memcpy(sptr, (char*)(&ifreq.ifr_enaddr), + sizeof(ifreq.ifr_enaddr)); + sptr += sizeof(ifreq.ifr_enaddr); +#elif defined(HAVE_GETIFADDRS) && defined(AF_LINK) + struct ifaddrs *ifa, *ifp; + struct sockaddr_dl *sdlp; + int found = 0; + + if (getifaddrs(&ifa) == -1) + goto error; - for (ifp = ifa; ifp; ifp = ifp->ifa_next) { - if ((ifp->ifa_addr->sa_family == AF_LINK) && - (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) { - found = 1; - break; - } - } + for (ifp = ifa; ifp; ifp = ifp->ifa_next) { + if ((ifp->ifa_addr->sa_family == AF_LINK) && + (sys_strcmp(ifp->ifa_name, ifreq.ifr_name) == 0)) { + found = 1; + break; + } + } - if (found == 0) { - freeifaddrs(ifa); - break; - } + if (found == 0) { + freeifaddrs(ifa); + break; + } + sdlp = (struct sockaddr_dl *)ifp->ifa_addr; - buf_check(sptr, s_end, 1+IFHWADDRLEN); - *sptr++ = INET_IFOPT_HWADDR; - sys_memcpy(sptr, ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_data + - ((struct sockaddr_dl *)ifp->ifa_addr)->sdl_nlen, IFHWADDRLEN); - freeifaddrs(ifa); - sptr += IFHWADDRLEN; + buf_check(sptr, s_end, 1+2+sdlp->sdl_alen); + *sptr++ = INET_IFOPT_HWADDR; + put_int16(sdlp->sdl_alen, sptr); sptr += 2; + sys_memcpy(sptr, + sdlp->sdl_data + sdlp->sdl_nlen, + sdlp->sdl_alen); + freeifaddrs(ifa); + sptr += sdlp->sdl_alen; #endif break; } @@ -4240,29 +4291,15 @@ static int inet_ctl_ifget(inet_descriptor* desc, char* buf, int len, case INET_IFOPT_FLAGS: { int flags; - int eflags = 0; if (ioctl(desc->s, SIOCGIFFLAGS, (char*)&ifreq) < 0) flags = 0; else flags = ifreq.ifr_flags; - /* translate flags */ - if (flags & IFF_UP) - eflags |= INET_IFF_UP; - if (flags & IFF_BROADCAST) - eflags |= INET_IFF_BROADCAST; - if (flags & IFF_LOOPBACK) - eflags |= INET_IFF_LOOPBACK; - if (flags & IFF_POINTOPOINT) - eflags |= INET_IFF_POINTTOPOINT; - if (flags & IFF_RUNNING) - eflags |= INET_IFF_RUNNING; - if (flags & IFF_MULTICAST) - eflags |= INET_IFF_MULTICAST; buf_check(sptr, s_end, 5); *sptr++ = INET_IFOPT_FLAGS; - put_int32(eflags, sptr); + put_int32(IFGET_FLAGS(flags), sptr); sptr += 4; break; } @@ -4300,17 +4337,22 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, (void) ioctl(desc->s, SIOCSIFADDR, (char*)&ifreq); break; - case INET_IFOPT_HWADDR: - buf_check(buf, b_end, IFHWADDRLEN); + case INET_IFOPT_HWADDR: { + unsigned int len; + buf_check(buf, b_end, 2); + len = get_int16(buf); buf += 2; + buf_check(buf, b_end, len); #ifdef SIOCSIFHWADDR /* raw memcpy (fix include autoconf later) */ - sys_memcpy((char*)(&ifreq.ifr_hwaddr.sa_data), buf, IFHWADDRLEN); + sys_memset((char*)(&ifreq.ifr_hwaddr.sa_data), + '\0', sizeof(ifreq.ifr_hwaddr.sa_data)); + sys_memcpy((char*)(&ifreq.ifr_hwaddr.sa_data), buf, len); (void) ioctl(desc->s, SIOCSIFHWADDR, (char *)&ifreq); #endif - buf += IFHWADDRLEN; + buf += len; break; - + } case INET_IFOPT_BROADADDR: #ifdef SIOCSIFBRDADDR @@ -4415,6 +4457,551 @@ static int inet_ctl_ifset(inet_descriptor* desc, char* buf, int len, #endif + + +/* Latin-1 to utf8 */ + +static int utf8_len(const char *c, int m) { + int l; + for (l = 0; m; c++, l++, m--) { + if (*c == '\0') break; + if ((*c & 0x7f) != *c) l++; + } + return l; +} + +static void utf8_encode(const char *c, int m, char *p) { + for (; m; c++, m--) { + if (*c == '\0') break; + if ((*c & 0x7f) != *c) { + *p++ = (char) (0xC0 | (0x03 & (*c >> 6))); + *p++ = (char) (0x80 | (0x3F & *c)); + } else { + *p++ = (char) *c; + } + } +} + +#if defined(__WIN32__) + +static void set_netmask_bytes(char *c, int len, int pref_len) { + int i, m; + for (i = 0, m = pref_len >> 3; i < m && i < len; i++) c[i] = '\xFF'; + if (i < len) c[i++] = 0xFF << (8 - (pref_len & 7)); + for (; i < len; i++) c[i] = '\0'; +} + + +int eq_masked_bytes(char *a, char *b, int pref_len) { + int i, m; + for (i = 0, m = pref_len >> 3; i < m; i++) { + if (a[i] != b[i]) return 0; + } + m = pref_len & 7; + if (m) { + m = 0xFF & (0xFF << (8 - m)); + if ((a[i] & m) != (b[i] & m)) return 0; + } + return !0; +} + +static int inet_ctl_getifaddrs(inet_descriptor* desc_p, + char **rbuf_pp, int rsize) +{ + int i; + DWORD ret, n; + IP_INTERFACE_INFO *info_p; + MIB_IPADDRTABLE *ip_addrs_p; + IP_ADAPTER_ADDRESSES *ip_adaddrs_p, *ia_p; + + char *buf_p; + char *buf_alloc_p; + int buf_size =512; +# define BUF_ENSURE(Size) \ + do { \ + int NEED_, GOT_ = buf_p - buf_alloc_p; \ + NEED_ = GOT_ + (Size); \ + if (NEED_ > buf_size) { \ + buf_size = NEED_ + 512; \ + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ + buf_p = buf_alloc_p + GOT_; \ + } \ + } while(0) +# define SOCKADDR_TO_BUF(opt, sa) \ + do { \ + if (sa) { \ + char *P_; \ + *buf_p++ = (opt); \ + while (! (P_ = sockaddr_to_buf((sa), buf_p, \ + buf_alloc_p+buf_size))) { \ + int GOT_ = buf_p - buf_alloc_p; \ + buf_size += 512; \ + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ + buf_p = buf_alloc_p + GOT_; \ + } \ + if (P_ == buf_p) { \ + buf_p--; \ + } else { \ + buf_p = P_; \ + } \ + } \ + } while (0) + + { + /* Try GetAdaptersAddresses, if it is available */ + unsigned long ip_adaddrs_size = 16 * 1024; + ULONG family = AF_UNSPEC; + ULONG flags = + GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | + GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME | + GAA_FLAG_SKIP_MULTICAST; + ULONG (WINAPI *fpGetAdaptersAddresses) + (ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG); + HMODULE iphlpapi = GetModuleHandle("iphlpapi"); + fpGetAdaptersAddresses = (void *) + (iphlpapi ? + GetProcAddress(iphlpapi, "GetAdaptersAddresses") : + NULL); + if (fpGetAdaptersAddresses) { + ip_adaddrs_p = ALLOC(ip_adaddrs_size); + for (i = 17; i; i--) { + ret = fpGetAdaptersAddresses( + family, flags, NULL, ip_adaddrs_p, &ip_adaddrs_size); + ip_adaddrs_p = REALLOC(ip_adaddrs_p, ip_adaddrs_size); + if (ret == NO_ERROR) break; + if (ret == ERROR_BUFFER_OVERFLOW) continue; + i = 0; + } + if (! i) { + FREE(ip_adaddrs_p); + ip_adaddrs_p = NULL; + } + } else ip_adaddrs_p = NULL; + } + + { + /* Load the IP_INTERFACE_INFO table (only IPv4 interfaces), + * reliable source of interface names on XP + */ + unsigned long info_size = 4 * 1024; + info_p = ALLOC(info_size); + for (i = 17; i; i--) { + ret = GetInterfaceInfo(info_p, &info_size); + info_p = REALLOC(info_p, info_size); + if (ret == NO_ERROR) break; + if (ret == ERROR_INSUFFICIENT_BUFFER) continue; + i = 0; + } + if (! i) { + FREE(info_p); + info_p = NULL; + } + } + + if (! ip_adaddrs_p) { + /* If GetAdaptersAddresses gave nothing we fall back to + * MIB_IPADDRTABLE (only IPv4 interfaces) + */ + unsigned long ip_addrs_size = 16 * sizeof(*ip_addrs_p); + ip_addrs_p = ALLOC(ip_addrs_size); + for (i = 17; i; i--) { + ret = GetIpAddrTable(ip_addrs_p, &ip_addrs_size, FALSE); + ip_addrs_p = REALLOC(ip_addrs_p, ip_addrs_size); + if (ret == NO_ERROR) break; + if (ret == ERROR_INSUFFICIENT_BUFFER) continue; + i = 0; + } + if (! i) { + if (info_p) FREE(info_p); + FREE(ip_addrs_p); + return ctl_reply(INET_REP_OK, NULL, 0, rbuf_pp, rsize); + } + } else ip_addrs_p = NULL; + + buf_p = buf_alloc_p = ALLOC(buf_size); + *buf_p++ = INET_REP_OK; + + /* Iterate over MIB_IPADDRTABLE or IP_ADAPTER_ADDRESSES */ + for (ia_p = NULL, ip_addrs_p ? ((void *)(i = 0)) : (ia_p = ip_adaddrs_p); + ip_addrs_p ? (i < ip_addrs_p->dwNumEntries) : (ia_p != NULL); + ip_addrs_p ? ((void *)(i++)) : (ia_p = ia_p->Next)) { + MIB_IPADDRROW *ipaddrrow_p = NULL; + DWORD flags = INET_IFF_MULTICAST; + DWORD index = 0; + WCHAR *wname_p = NULL; + MIB_IFROW ifrow; + + if (ip_addrs_p) { + ipaddrrow_p = ip_addrs_p->table + i; + index = ipaddrrow_p->dwIndex; + } else { + index = ia_p->IfIndex; + if (ia_p->Flags & IP_ADAPTER_NO_MULTICAST) { + flags &= ~INET_IFF_MULTICAST; + } + } +index: + if (! index) goto done; + sys_memzero(&ifrow, sizeof(ifrow)); + ifrow.dwIndex = index; + if (GetIfEntry(&ifrow) != NO_ERROR) break; + /* Find the interface name - first try MIB_IFROW.wzname */ + if (ifrow.wszName[0] != 0) { + wname_p = ifrow.wszName; + } else { + /* Then try IP_ADAPTER_INDEX_MAP.Name (only IPv4 adapters) */ + int j; + for (j = 0; j < info_p->NumAdapters; j++) { + if (info_p->Adapter[j].Index == (ULONG) ifrow.dwIndex) { + if (info_p->Adapter[j].Name[0] != 0) { + wname_p = info_p->Adapter[j].Name; + } + break; + } + } + } + if (wname_p) { + int len; + /* Convert interface name to UTF-8 */ + len = + WideCharToMultiByte( + CP_UTF8, 0, wname_p, -1, NULL, 0, NULL, NULL); + if (! len) break; + BUF_ENSURE(len); + WideCharToMultiByte( + CP_UTF8, 0, wname_p, -1, buf_p, len, NULL, NULL); + buf_p += len; + } else { + /* Found no name - + * use "MIB_IFROW.dwIndex: MIB_IFROW.bDescr" as name instead */ + int l; + l = utf8_len(ifrow.bDescr, ifrow.dwDescrLen); + BUF_ENSURE(9 + l+1); + buf_p += + erts_sprintf( + buf_p, "%lu: ", (unsigned long) ifrow.dwIndex); + utf8_encode(ifrow.bDescr, ifrow.dwDescrLen, buf_p); + buf_p += l; + *buf_p++ = '\0'; + } + /* Interface flags, often make up broadcast and multicast flags */ + switch (ifrow.dwType) { + case IF_TYPE_ETHERNET_CSMACD: + flags |= INET_IFF_BROADCAST; + break; + case IF_TYPE_SOFTWARE_LOOPBACK: + flags |= INET_IFF_LOOPBACK; + flags &= ~INET_IFF_MULTICAST; + break; + default: + flags &= ~INET_IFF_MULTICAST; + break; + } + if (ifrow.dwAdminStatus) { + flags |= INET_IFF_UP; + switch (ifrow.dwOperStatus) { + case IF_OPER_STATUS_CONNECTING: + flags |= INET_IFF_POINTTOPOINT; + break; + case IF_OPER_STATUS_CONNECTED: + flags |= INET_IFF_RUNNING | INET_IFF_POINTTOPOINT; + break; + case IF_OPER_STATUS_OPERATIONAL: + flags |= INET_IFF_RUNNING; + break; + } + } + BUF_ENSURE(1 + 4); + *buf_p++ = INET_IFOPT_FLAGS; + put_int32(flags, buf_p); buf_p += 4; + if (ipaddrrow_p) { + /* Legacy implementation through GetIpAddrTable */ + struct sockaddr_in sin; + /* IP Address */ + sys_memzero(&sin, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = ipaddrrow_p->dwAddr; + BUF_ENSURE(1); + /* Netmask */ + SOCKADDR_TO_BUF(INET_IFOPT_ADDR, (struct sockaddr *) &sin); + sin.sin_addr.s_addr = ipaddrrow_p->dwMask; + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, (struct sockaddr *) &sin); + if (flags & INET_IFF_BROADCAST) { + /* Broadcast address - fake it*/ + sin.sin_addr.s_addr = ipaddrrow_p->dwAddr; + sin.sin_addr.s_addr |= ~ipaddrrow_p->dwMask; + BUF_ENSURE(1); + SOCKADDR_TO_BUF( + INET_IFOPT_BROADADDR, (struct sockaddr *) &sin); + } + } else { + IP_ADAPTER_UNICAST_ADDRESS *p; + /* IP Address(es) */ + for (p = ia_p->FirstUnicastAddress; + p; + p = p->Next) + { + IP_ADAPTER_PREFIX *q; + ULONG shortest_length; + struct sockaddr *shortest_p, *sa_p = p->Address.lpSockaddr; + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_ADDR, sa_p); + shortest_p = NULL; + shortest_length = 0; + for (q = ia_p->FirstPrefix; + q; + q = q->Next) { + struct sockaddr *sp_p = q->Address.lpSockaddr; + if (sa_p->sa_family != sp_p->sa_family) continue; + switch (sa_p->sa_family) { + case AF_INET: { + struct sockaddr_in sin; + DWORD sa, sp, mask; + sa = ntohl((DWORD) + ((struct sockaddr_in *) + sa_p)->sin_addr.s_addr); + sp = ntohl((DWORD) + ((struct sockaddr_in *) + sp_p)->sin_addr.s_addr); + mask = 0xFFFFFFFF << (32 - q->PrefixLength); + if ((sa & mask) != (sp & mask)) continue; + if ((! shortest_p) + || q->PrefixLength < shortest_length) { + shortest_p = sp_p; + shortest_length = q->PrefixLength; + } + } break; + case AF_INET6: { + struct sockaddr_in6 sin6; + if (!eq_masked_bytes((char *) + &((struct sockaddr_in6 *) + sa_p)->sin6_addr, + (char *) + &((struct sockaddr_in6 *) + sp_p)->sin6_addr, + q->PrefixLength)) { + continue; + } + if ((! shortest_p) + || q->PrefixLength < shortest_length) { + shortest_p = sp_p; + shortest_length = q->PrefixLength; + } + } break; + } + } + if (! shortest_p) { + /* Found no shortest prefix */ + shortest_p = sa_p; + switch (shortest_p->sa_family) { + case AF_INET: { + /* Fall back to old classfull network addresses */ + DWORD addr = ntohl(((struct sockaddr_in *)shortest_p) + ->sin_addr.s_addr); + if (! (addr & 0x800000)) { + /* Class A */ + shortest_length = 8; + } else if (! (addr & 0x400000)) { + /* Class B */ + shortest_length = 16; + } else if (! (addr & 0x200000)) { + /* Class C */ + shortest_length = 24; + } else { + shortest_length = 32; + } + } break; + case AF_INET6: { + /* Just play it safe */ + shortest_length = 128; + } break; + } + } + switch (shortest_p->sa_family) { + case AF_INET: { + struct sockaddr_in sin; + DWORD mask = 0xFFFFFFFF << (32 - shortest_length); + sys_memzero(&sin, sizeof(sin)); + sin.sin_family = shortest_p->sa_family; + sin.sin_addr.s_addr = htonl(mask); + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, + (struct sockaddr *) &sin); + if (flags & INET_IFF_BROADCAST) { + DWORD sp = + ntohl((DWORD) + ((struct sockaddr_in *)shortest_p) + -> sin_addr.s_addr); + sin.sin_addr.s_addr = htonl(sp | ~mask); + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR, + (struct sockaddr *) &sin); + } + } break; + case AF_INET6: { + struct sockaddr_in6 sin6; + sys_memzero(&sin6, sizeof(sin6)); + sin6.sin6_family = shortest_p->sa_family; + set_netmask_bytes((char *) &sin6.sin6_addr, + 16, + shortest_length); + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, + (struct sockaddr *) &sin6); + } break; + } + } + } + if (ifrow.dwPhysAddrLen) { + /* Hardware Address */ + BUF_ENSURE(1 + 2 + ifrow.dwPhysAddrLen); + *buf_p++ = INET_IFOPT_HWADDR; + put_int16(ifrow.dwPhysAddrLen, buf_p); buf_p += 2; + sys_memcpy(buf_p, ifrow.bPhysAddr, ifrow.dwPhysAddrLen); + buf_p += ifrow.dwPhysAddrLen; + } + +done: + /* That is all for this interface */ + BUF_ENSURE(1); + *buf_p++ = '\0'; + if (ia_p && + ia_p->Ipv6IfIndex && + ia_p->Ipv6IfIndex != index) + { + /* Oops, there was an other interface for IPv6. Possible? XXX */ + index = ia_p->Ipv6IfIndex; + goto index; + } + } + + if (ip_adaddrs_p) FREE(ip_adaddrs_p); + if (info_p) FREE(info_p); + if (ip_addrs_p) FREE(ip_addrs_p); + + buf_size = buf_p - buf_alloc_p; + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); + /* buf_p is now unreliable */ + *rbuf_pp = buf_alloc_p; + return buf_size; +# undef BUF_ENSURE +} + +#elif defined(HAVE_GETIFADDRS) + +static int inet_ctl_getifaddrs(inet_descriptor* desc_p, + char **rbuf_pp, int rsize) +{ + struct ifaddrs *ifa_p, *ifa_free_p; + + int buf_size; + char *buf_p; + char *buf_alloc_p; + + buf_size = 512; + buf_alloc_p = ALLOC(buf_size); + buf_p = buf_alloc_p; +# define BUF_ENSURE(Size) \ + do { \ + int NEED_, GOT_ = buf_p - buf_alloc_p; \ + NEED_ = GOT_ + (Size); \ + if (NEED_ > buf_size) { \ + buf_size = NEED_ + 512; \ + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ + buf_p = buf_alloc_p + GOT_; \ + } \ + } while (0) +# define SOCKADDR_TO_BUF(opt, sa) \ + do { \ + if (sa) { \ + char *P_; \ + *buf_p++ = (opt); \ + while (! (P_ = sockaddr_to_buf((sa), buf_p, \ + buf_alloc_p+buf_size))) { \ + int GOT_ = buf_p - buf_alloc_p; \ + buf_size += 512; \ + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); \ + buf_p = buf_alloc_p + GOT_; \ + } \ + if (P_ == buf_p) { \ + buf_p--; \ + } else { \ + buf_p = P_; \ + } \ + } \ + } while (0) + + if (getifaddrs(&ifa_p) < 0) { + return ctl_error(sock_errno(), rbuf_pp, rsize); + } + ifa_free_p = ifa_p; + *buf_p++ = INET_REP_OK; + for (; ifa_p; ifa_p = ifa_p->ifa_next) { + int len = utf8_len(ifa_p->ifa_name, -1); + BUF_ENSURE(len+1 + 1+4 + 1); + utf8_encode(ifa_p->ifa_name, -1, buf_p); + buf_p += len; + *buf_p++ = '\0'; + *buf_p++ = INET_IFOPT_FLAGS; + put_int32(IFGET_FLAGS(ifa_p->ifa_flags), buf_p); buf_p += 4; + if (ifa_p->ifa_addr->sa_family == AF_INET +#if defined(AF_INET6) + || ifa_p->ifa_addr->sa_family == AF_INET6 +#endif + ) { + SOCKADDR_TO_BUF(INET_IFOPT_ADDR, ifa_p->ifa_addr); + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_NETMASK, ifa_p->ifa_netmask); + if (ifa_p->ifa_flags & IFF_POINTOPOINT) { + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_DSTADDR, ifa_p->ifa_dstaddr); + } else if (ifa_p->ifa_flags & IFF_BROADCAST) { + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_BROADADDR, ifa_p->ifa_broadaddr); + } + } +#if defined(AF_LINK) || defined(AF_PACKET) + else if ( +#if defined(AF_LINK) + ifa_p->ifa_addr->sa_family == AF_LINK +#else + 0 +#endif +#if defined(AF_PACKET) + || ifa_p->ifa_addr->sa_family == AF_PACKET +#endif + ) { + char *bp = buf_p; + BUF_ENSURE(1); + SOCKADDR_TO_BUF(INET_IFOPT_HWADDR, ifa_p->ifa_addr); + if (buf_p - bp < 4) buf_p = bp; /* Empty hwaddr */ + } +#endif + BUF_ENSURE(1); + *buf_p++ = '\0'; + } + buf_size = buf_p - buf_alloc_p; + buf_alloc_p = REALLOC(buf_alloc_p, buf_size); + /* buf_p is now unreliable */ + freeifaddrs(ifa_free_p); + *rbuf_pp = buf_alloc_p; + return buf_size; +# undef BUF_ENSURE +} + +#else + +static int inet_ctl_getifaddrs(inet_descriptor* desc_p, + char **rbuf_pp, int rsize) +{ + return ctl_error(ENOTSUP, rbuf_pp, rsize); +} + +#endif + + + #ifdef VXWORKS /* ** THIS is a terrible creature, a bug in the TCP part @@ -4576,8 +5163,7 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) case INET_LOPT_BUFFER: DEBUGF(("inet_set_opts(%ld): s=%d, BUFFER=%d\r\n", (long)desc->port, desc->s, ival)); - if (ival > INET_MAX_BUFFER) ival = INET_MAX_BUFFER; - else if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER; + if (ival < INET_MIN_BUFFER) ival = INET_MIN_BUFFER; desc->bufsz = ival; continue; @@ -4642,7 +5228,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) if (desc->stype == SOCK_STREAM) { tcp_descriptor* tdesc = (tcp_descriptor*) desc; if (ival < 0) ival = 0; - else if (ival > INET_MAX_BUFFER*2) ival = INET_MAX_BUFFER*2; if (tdesc->low > ival) tdesc->low = ival; tdesc->high = ival; @@ -4653,7 +5238,6 @@ static int inet_set_opts(inet_descriptor* desc, char* ptr, int len) if (desc->stype == SOCK_STREAM) { tcp_descriptor* tdesc = (tcp_descriptor*) desc; if (ival < 0) ival = 0; - else if (ival > INET_MAX_BUFFER) ival = INET_MAX_BUFFER; if (tdesc->high < ival) tdesc->high = ival; tdesc->low = ival; @@ -4999,9 +5583,6 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) case INET_LOPT_BUFFER: desc->bufsz = get_int32(curr); curr += 4; - if (desc->bufsz > INET_MAX_BUFFER) - desc->bufsz = INET_MAX_BUFFER; - else if (desc->bufsz < INET_MIN_BUFFER) desc->bufsz = INET_MIN_BUFFER; res = 0; /* This does not affect the kernel buffer size */ @@ -5242,9 +5823,12 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) char *after; # ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_FLAGS int eflags, cflags, hb_enable, hb_disable, - pmtud_enable, pmtud_disable, + pmtud_enable, pmtud_disable; +# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY + int sackdelay_enable, sackdelay_disable; # endif +# endif CHKLEN(curr, ASSOC_ID_LEN); arg.pap.spp_assoc_id = GET_ASSOC_ID(curr); curr += ASSOC_ID_LEN; @@ -5293,12 +5877,15 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) if (pmtud_enable) cflags |= SPP_PMTUD_ENABLE; if (pmtud_disable) cflags |= SPP_PMTUD_DISABLE; +# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY + /* The followings are missing in FreeBSD 7.1 */ sackdelay_enable =eflags& SCTP_FLAG_SACDELAY_ENABLE; sackdelay_disable=eflags& SCTP_FLAG_SACDELAY_DISABLE; if (sackdelay_enable && sackdelay_disable) return -1; if (sackdelay_enable) cflags |= SPP_SACKDELAY_ENABLE; if (sackdelay_disable) cflags |= SPP_SACKDELAY_DISABLE; +# endif arg.pap.spp_flags = cflags; # endif @@ -5436,7 +6023,7 @@ static int inet_fill_opts(inet_descriptor* desc, #define PLACE_FOR(Size,Ptr) \ do { \ int need = dest_used + (Size); \ - if (need > INET_MAX_BUFFER) { \ + if (need > INET_MAX_OPT_BUFFER) { \ RETURN_ERROR(); \ } \ if (need > dest_allocated) { \ @@ -5660,7 +6247,7 @@ static int inet_fill_opts(inet_descriptor* desc, buf += 4; data_provided = (int) *buf++; arg_sz = get_int32(buf); - if (arg_sz > INET_MAX_BUFFER) { + if (arg_sz > INET_MAX_OPT_BUFFER) { RETURN_ERROR(); } buf += 4; @@ -5774,7 +6361,7 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, "miscalculated buffer size"); \ } \ need = (Index) + (N); \ - if (need > INET_MAX_BUFFER/sizeof(ErlDrvTermData)) { \ + if (need > INET_MAX_OPT_BUFFER/sizeof(ErlDrvTermData)) {\ RETURN_ERROR((Spec), -ENOMEM); \ } \ if (need > spec_allocated) { \ @@ -6199,13 +6786,15 @@ static int sctp_fill_opts(inet_descriptor* desc, char* buf, int buflen, if (ap.spp_flags & SPP_PMTUD_DISABLE) { i = LOAD_ATOM (spec, i, am_pmtud_disable); n++; } - +# ifdef HAVE_STRUCT_SCTP_PADDRPARAMS_SPP_SACKDELAY + /* SPP_SACKDELAY_* not in FreeBSD 7.1 */ if (ap.spp_flags & SPP_SACKDELAY_ENABLE) { i = LOAD_ATOM (spec, i, am_sackdelay_enable); n++; } if (ap.spp_flags & SPP_SACKDELAY_DISABLE) { i = LOAD_ATOM (spec, i, am_sackdelay_disable); n++; } # endif +# endif PLACE_FOR(spec, i, LOAD_NIL_CNT + LOAD_LIST_CNT + 2*LOAD_TUPLE_CNT); @@ -6625,7 +7214,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len, } } DEBUGF(("inet_ctl(%ld): GETSTAT\r\n", (long) desc->port)); - if (dstlen > INET_MAX_BUFFER) /* sanity check */ + if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */ return 0; if (dstlen > rsize) { if ((dst = (char*) ALLOC(dstlen)) == NULL) @@ -6641,7 +7230,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len, char* dst; int dstlen = 1 /* Reply code */ + len*5; DEBUGF(("inet_ctl(%ld): INET_REQ_SUBSCRIBE\r\n", (long) desc->port)); - if (dstlen > INET_MAX_BUFFER) /* sanity check */ + if (dstlen > INET_MAX_OPT_BUFFER) /* sanity check */ return 0; if (dstlen > rsize) { if ((dst = (char*) ALLOC(dstlen)) == NULL) @@ -6676,6 +7265,13 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len, return inet_ctl_getiflist(desc, rbuf, rsize); } + case INET_REQ_GETIFADDRS: { + DEBUGF(("inet_ctl(%ld): GETIFADDRS\r\n", (long)desc->port)); + if (!IS_OPEN(desc)) + return ctl_xerror(EXBADPORT, rbuf, rsize); + return inet_ctl_getifaddrs(desc, rbuf, rsize); + } + case INET_REQ_IFGET: { DEBUGF(("inet_ctl(%ld): IFGET\r\n", (long)desc->port)); if (!IS_OPEN(desc)) diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index b19f632f52..6297ccb8bc 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -587,7 +587,8 @@ efile_readdir(Efile_error* errInfo, /* Where to return error codes. */ open directory.*/ char* buffer, /* Pointer to buffer for one filename. */ - size_t size) /* Size of buffer. */ + size_t *size) /* in-out Size of buffer, length + of name. */ { DIR *dp; /* Pointer to directory structure. */ struct dirent* dirp; /* Pointer to directory entry. */ @@ -620,6 +621,7 @@ efile_readdir(Efile_error* errInfo, /* Where to return error codes. */ continue; buffer[0] = '\0'; strncat(buffer, dirp->d_name, size-1); + *size = strlen(dirp->d_name); return 1; } } diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index 04bd1139f5..4ec9579529 100644..100755 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -23,20 +23,20 @@ #include <windows.h> #include "sys.h" #include <ctype.h> - +#include <wchar.h> #include "erl_efile.h" /* * Microsoft-specific function to map a WIN32 error code to a Posix errno. */ -#define ISSLASH(a) ((a) == '\\' || (a) == '/') +#define ISSLASH(a) ((a) == L'\\' || (a) == L'/') #define ISDIR(st) (((st).st_mode&S_IFMT) == S_IFDIR) #define ISREG(st) (((st).st_mode&S_IFMT) == S_IFREG) #define IS_DOT_OR_DOTDOT(s) \ - (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0'))) + ((s)[0] == L'.' && ((s)[1] == L'\0' || ((s)[1] == L'.' && (s)[2] == L'\0'))) #ifndef INVALID_FILE_ATTRIBUTES #define INVALID_FILE_ATTRIBUTES ((DWORD) 0xFFFFFFFF) @@ -44,9 +44,9 @@ static int check_error(int result, Efile_error* errInfo); static int set_error(Efile_error* errInfo); -static int IsRootUNCName(const char* path); -static int extract_root(char* name); -static unsigned short dos_to_posix_mode(int attr, const char *name); +static int is_root_unc_name(const WCHAR *path); +static int extract_root(WCHAR *name); +static unsigned short dos_to_posix_mode(int attr, const WCHAR *name); static int errno_map(DWORD last_error) { @@ -196,27 +196,26 @@ win_writev(Efile_error* errInfo, int -efile_mkdir(errInfo, name) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of directory to create. */ +efile_mkdir(Efile_error* errInfo, /* Where to return error codes. */ + char* name) /* Name of directory to create. */ { - return check_error(mkdir(name), errInfo); + return check_error(_wmkdir((WCHAR *) name), errInfo); } int -efile_rmdir(errInfo, name) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of directory to delete. */ +efile_rmdir(Efile_error* errInfo, /* Where to return error codes. */ + char* name) /* Name of directory to delete. */ { OSVERSIONINFO os; DWORD attr; + WCHAR *wname = (WCHAR *) name; - if (RemoveDirectory(name) != FALSE) { + if (RemoveDirectoryW(wname) != FALSE) { return 1; } errno = errno_map(GetLastError()); if (errno == EACCES) { - attr = GetFileAttributes(name); + attr = GetFileAttributesW(wname); if (attr != (DWORD) -1) { if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { /* @@ -238,21 +237,21 @@ char* name; /* Name of directory to delete. */ GetVersionEx(&os); if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { HANDLE handle; - WIN32_FIND_DATA data; - char buffer[2*MAX_PATH]; + WIN32_FIND_DATAW data; + WCHAR buffer[2*MAX_PATH]; int len; - len = strlen(name); - strcpy(buffer, name); - if (buffer[0] && buffer[len-1] != '\\' && buffer[len-1] != '/') { - strcat(buffer, "\\"); + len = wcslen(wname); + wcscpy(buffer, wname); + if (buffer[0] && buffer[len-1] != L'\\' && buffer[len-1] != L'/') { + wcscat(buffer, L"\\"); } - strcat(buffer, "*.*"); - handle = FindFirstFile(buffer, &data); + wcscat(buffer, L"*.*"); + handle = FindFirstFileW(buffer, &data); if (handle != INVALID_HANDLE_VALUE) { while (1) { - if ((strcmp(data.cFileName, ".") != 0) - && (strcmp(data.cFileName, "..") != 0)) { + if ((wcscmp(data.cFileName, L".") != 0) + && (wcscmp(data.cFileName, L"..") != 0)) { /* * Found something in this directory. */ @@ -260,7 +259,7 @@ char* name; /* Name of directory to delete. */ errno = EEXIST; break; } - if (FindNextFile(handle, &data) == FALSE) { + if (FindNextFileW(handle, &data) == FALSE) { break; } } @@ -284,19 +283,19 @@ char* name; /* Name of directory to delete. */ } int -efile_delete_file(errInfo, name) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of file to delete. */ +efile_delete_file(Efile_error* errInfo, /* Where to return error codes. */ + char* name) /* Name of file to delete. */ { DWORD attr; + WCHAR *wname = (WCHAR *) name; - if (DeleteFile(name) != FALSE) { + if (DeleteFileW(wname) != FALSE) { return 1; } errno = errno_map(GetLastError()); if (errno == EACCES) { - attr = GetFileAttributes(name); + attr = GetFileAttributesW(wname); if (attr != (DWORD) -1) { if (attr & FILE_ATTRIBUTE_DIRECTORY) { /* @@ -308,7 +307,7 @@ char* name; /* Name of file to delete. */ } } } else if (errno == ENOENT) { - attr = GetFileAttributes(name); + attr = GetFileAttributesW(wname); if (attr != (DWORD) -1) { if (attr & FILE_ATTRIBUTE_DIRECTORY) { /* @@ -362,20 +361,21 @@ char* name; /* Name of file to delete. */ */ int -efile_rename(errInfo, src, dst) -Efile_error* errInfo; /* Where to return error codes. */ -char* src; /* Original name. */ -char* dst; /* New name. */ +efile_rename(Efile_error* errInfo, /* Where to return error codes. */ + char* src, /* Original name. */ + char* dst) /* New name. */ { DWORD srcAttr, dstAttr; + WCHAR *wsrc = (WCHAR *) src; + WCHAR *wdst = (WCHAR *) dst; - if (MoveFile(src, dst) != FALSE) { + if (MoveFileW(wsrc, wdst) != FALSE) { return 1; } errno = errno_map(GetLastError()); - srcAttr = GetFileAttributes(src); - dstAttr = GetFileAttributes(dst); + srcAttr = GetFileAttributesW(wsrc); + dstAttr = GetFileAttributesW(wdst); if (srcAttr == (DWORD) -1) { srcAttr = 0; } @@ -390,22 +390,22 @@ char* dst; /* New name. */ if (errno == EACCES) { decode: if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) { - char srcPath[MAX_PATH], dstPath[MAX_PATH]; - char *srcRest, *dstRest; + WCHAR srcPath[MAX_PATH], dstPath[MAX_PATH]; + WCHAR *srcRest, *dstRest; int size; - size = GetFullPathName(src, sizeof(srcPath), srcPath, &srcRest); - if ((size == 0) || (size > sizeof(srcPath))) { + size = GetFullPathNameW(wsrc, MAX_PATH, srcPath, &srcRest); + if ((size == 0) || (size > MAX_PATH)) { return check_error(-1, errInfo); } - size = GetFullPathName(dst, sizeof(dstPath), dstPath, &dstRest); - if ((size == 0) || (size > sizeof(dstPath))) { + size = GetFullPathNameW(wdst, MAX_PATH, dstPath, &dstRest); + if ((size == 0) || (size > MAX_PATH)) { return check_error(-1, errInfo); } if (srcRest == NULL) { - srcRest = srcPath + strlen(srcPath); + srcRest = srcPath + wcslen(srcPath); } - if (strnicmp(srcPath, dstPath, srcRest - srcPath) == 0) { + if (_wcsnicmp(srcPath, dstPath, srcRest - srcPath) == 0) { /* * Trying to move a directory into itself. */ @@ -420,14 +420,14 @@ char* dst; /* New name. */ } (void) extract_root(dstPath); - if (dstPath[0] == '\0') { + if (dstPath[0] == L'\0') { /* * The filename was invalid. (Don't know why, * but play it safe.) */ errno = EINVAL; } - if (stricmp(srcPath, dstPath) != 0) { + if (_wcsicmp(srcPath, dstPath) != 0) { /* * If src is a directory and dst filesystem != src * filesystem, errno should be EXDEV. It is very @@ -463,14 +463,14 @@ char* dst; /* New name. */ * fails, it's because it wasn't empty. */ - if (RemoveDirectory(dst)) { + if (RemoveDirectoryW(wdst)) { /* * Now that that empty directory is gone, we can try * renaming again. If that fails, we'll put this empty * directory back, for completeness. */ - if (MoveFile(src, dst) != FALSE) { + if (MoveFileW(wsrc, wdst) != FALSE) { return 1; } @@ -480,8 +480,8 @@ char* dst; /* New name. */ */ errno = errno_map(GetLastError()); - CreateDirectory(dst, NULL); - SetFileAttributes(dst, dstAttr); + CreateDirectoryW(wdst, NULL); + SetFileAttributesW(wdst, dstAttr); if (errno == EACCES) { /* * Decode the EACCES to a more meaningful error. @@ -506,17 +506,17 @@ char* dst; /* New name. */ * put temp file back to old name. */ - char tempName[MAX_PATH]; + WCHAR tempName[MAX_PATH]; int result, size; - char *rest; + WCHAR *rest; - size = GetFullPathName(dst, sizeof(tempName), tempName, &rest); - if ((size == 0) || (size > sizeof(tempName)) || (rest == NULL)) { + size = GetFullPathNameW(wdst, MAX_PATH, tempName, &rest); + if ((size == 0) || (size > MAX_PATH) || (rest == NULL)) { return check_error(-1, errInfo); } - *rest = '\0'; + *rest = L'\0'; result = -1; - if (GetTempFileName(tempName, "erlr", 0, tempName) != 0) { + if (GetTempFileNameW(tempName, L"erlr", 0, tempName) != 0) { /* * Strictly speaking, need the following DeleteFile and * MoveFile to be joined as an atomic operation so no @@ -524,15 +524,15 @@ char* dst; /* New name. */ * same temp file. */ - DeleteFile(tempName); - if (MoveFile(dst, tempName) != FALSE) { - if (MoveFile(src, dst) != FALSE) { - SetFileAttributes(tempName, FILE_ATTRIBUTE_NORMAL); - DeleteFile(tempName); + DeleteFileW(tempName); + if (MoveFileW(wdst, tempName) != FALSE) { + if (MoveFileW(wsrc, wdst) != FALSE) { + SetFileAttributesW(tempName, FILE_ATTRIBUTE_NORMAL); + DeleteFileW(tempName); return 1; } else { - DeleteFile(dst); - MoveFile(tempName, dst); + DeleteFileW(wdst); + MoveFileW(tempName, wdst); } } @@ -558,11 +558,10 @@ char* dst; /* New name. */ } int -efile_chdir(errInfo, name) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of directory to make current. */ +efile_chdir(Efile_error* errInfo, /* Where to return error codes. */ + char* name) /* Name of directory to make current. */ { - int success = check_error(chdir(name), errInfo); + int success = check_error(_wchdir((WCHAR *) name), errInfo); if (!success && errInfo->posix_errno == EINVAL) /* POSIXification of errno */ errInfo->posix_errno = ENOENT; @@ -570,59 +569,65 @@ char* name; /* Name of directory to make current. */ } int -efile_getdcwd(errInfo, drive, buffer, size) -Efile_error* errInfo; /* Where to return error codes. */ -int drive; /* 0 - current, 1 - A, 2 - B etc. */ -char* buffer; /* Where to return the current directory. */ -size_t size; /* Size of buffer. */ +efile_getdcwd(Efile_error* errInfo, /* Where to return error codes. */ + int drive, /* 0 - current, 1 - A, 2 - B etc. */ + char* buffer, /* Where to return the current directory. */ + size_t size) /* Size of buffer. */ { - if (_getdcwd(drive, buffer, size) == NULL) + WCHAR *wbuffer = (WCHAR *) buffer; + size_t wbuffer_size = size / 2; + if (_wgetdcwd(drive, wbuffer, wbuffer_size) == NULL) return check_error(-1, errInfo); - for ( ; *buffer; buffer++) - if (*buffer == '\\') - *buffer = '/'; + for ( ; *wbuffer; wbuffer++) + if (*wbuffer == L'\\') + *wbuffer = L'/'; return 1; } int -efile_readdir(errInfo, name, dir_handle, buffer, size) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of directory to open. */ -EFILE_DIR_HANDLE* dir_handle; /* Directory handle of open directory. */ -char* buffer; /* Pointer to buffer for one filename. */ -size_t size; /* Size of buffer. */ +efile_readdir(Efile_error* errInfo, /* Where to return error codes. */ + char* name, /* Name of directory to list */ + EFILE_DIR_HANDLE* dir_handle, /* Handle of opened directory or NULL */ + char* buffer, /* Buffer to put one filename in */ + size_t *size) /* in-out size of buffer/size of filename excluding zero + termination in bytes*/ { HANDLE dir; /* Handle to directory. */ - char wildcard[MAX_PATH]; /* Wildcard to search for. */ - WIN32_FIND_DATA findData; /* Data found by FindFirstFile() or FindNext(). */ + WCHAR wildcard[MAX_PATH]; /* Wildcard to search for. */ + WIN32_FIND_DATAW findData; /* Data found by FindFirstFile() or FindNext(). */ + /* Alignment is not honored, this works on x86 because of alignment fixup by processor. + Not perfect, but faster than alinging by hand (really) */ + WCHAR *wname = (WCHAR *) name; + WCHAR *wbuffer = (WCHAR *) buffer; /* * First time we must setup everything. */ if (*dir_handle == NULL) { - int length = strlen(name); - char* s; + int length = wcslen(wname); + WCHAR* s; if (length+3 >= MAX_PATH) { errno = ENAMETOOLONG; return check_error(-1, errInfo); } - strcpy(wildcard, name); + wcscpy(wildcard, wname); s = wildcard+length-1; - if (*s != '/' && *s != '\\') - *++s = '\\'; - *++s = '*'; - *++s = '\0'; - DEBUGF(("Reading %s\n", wildcard)); - dir = FindFirstFile(wildcard, &findData); + if (*s != L'/' && *s != L'\\') + *++s = L'\\'; + *++s = L'*'; + *++s = L'\0'; + DEBUGF(("Reading %ws\n", wildcard)); + dir = FindFirstFileW(wildcard, &findData); if (dir == INVALID_HANDLE_VALUE) return set_error(errInfo); *dir_handle = (EFILE_DIR_HANDLE) dir; if (!IS_DOT_OR_DOTDOT(findData.cFileName)) { - strcpy(buffer, findData.cFileName); + wcscpy(wbuffer, findData.cFileName); + *size = wcslen(wbuffer)*2; return 1; } } @@ -635,10 +640,11 @@ size_t size; /* Size of buffer. */ dir = (HANDLE) *dir_handle; for (;;) { - if (FindNextFile(dir, &findData)) { + if (FindNextFileW(dir, &findData)) { if (IS_DOT_OR_DOTDOT(findData.cFileName)) continue; - strcpy(buffer, findData.cFileName); + wcscpy(wbuffer, findData.cFileName); + *size = wcslen(wbuffer)*2; return 1; } @@ -655,17 +661,17 @@ size_t size; /* Size of buffer. */ } int -efile_openfile(errInfo, name, flags, pfd, pSize) -Efile_error* errInfo; /* Where to return error codes. */ -char* name; /* Name of directory to open. */ -int flags; /* Flags to use for opening. */ -int* pfd; /* Where to store the file descriptor. */ -Sint64* pSize; /* Where to store the size of the file. */ +efile_openfile(Efile_error* errInfo, /* Where to return error codes. */ + char* name, /* Name of directory to open. */ + int flags, /* Flags to use for opening. */ + int* pfd, /* Where to store the file descriptor. */ + Sint64* pSize) /* Where to store the size of the file. */ { BY_HANDLE_FILE_INFORMATION fileInfo; /* File information from a handle. */ HANDLE fd; /* Handle to open file. */ DWORD access; /* Access mode: GENERIC_READ, GENERIC_WRITE. */ DWORD crFlags; + WCHAR *wname = (WCHAR *) name; switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) { case EFILE_MODE_READ: @@ -692,7 +698,7 @@ Sint64* pSize; /* Where to store the size of the file. */ if (flags & EFILE_MODE_EXCL) { crFlags = CREATE_NEW; } - fd = CreateFile(name, access, + fd = CreateFileW(wname, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL); @@ -711,7 +717,7 @@ Sint64* pSize; /* Where to store the size of the file. */ * to EISDIR. */ if (errInfo->posix_errno && - (attr = GetFileAttributes(name)) != INVALID_FILE_ATTRIBUTES && + (attr = GetFileAttributesW(wname)) != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) { errInfo->posix_errno = EISDIR; } @@ -735,9 +741,10 @@ Sint64* pSize; /* Where to store the size of the file. */ int efile_may_openfile(Efile_error* errInfo, char *name) { + WCHAR *wname = (WCHAR *) name; DWORD attr; - if ((attr = GetFileAttributes(name)) == INVALID_FILE_ATTRIBUTES) { + if ((attr = GetFileAttributesW(wname)) == INVALID_FILE_ATTRIBUTES) { return check_error(-1, errInfo); } @@ -746,18 +753,6 @@ efile_may_openfile(Efile_error* errInfo, char *name) { return check_error(-1, errInfo); } return 1; -#if 0 - struct stat statbuf; - - if (stat(name, &statbuf)) { - return check_error(-1, errInfo); - } - if (ISDIR(statbuf)) { - errno = EISDIR; - return check_error(-1, errInfo); - } - return 1; -#endif } void @@ -792,16 +787,17 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, char* orig_name, int info_for_link) { HANDLE findhandle; /* Handle returned by FindFirstFile(). */ - WIN32_FIND_DATA findbuf; /* Data return by FindFirstFile(). */ - char name[_MAX_PATH]; + WIN32_FIND_DATAW findbuf; /* Data return by FindFirstFile(). */ + WCHAR name[_MAX_PATH]; int name_len; - char* path; - char pathbuf[_MAX_PATH]; + WCHAR *path; + WCHAR pathbuf[_MAX_PATH]; int drive; /* Drive for filename (1 = A:, 2 = B: etc). */ + WCHAR *worig_name = (WCHAR *) orig_name; /* Don't allow wildcards to be interpreted by system */ - if (strpbrk(orig_name, "?*")) { + if (wcspbrk(worig_name, L"?*")) { enoent: errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; @@ -813,25 +809,25 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, * slash, because it causes FindFirstFile() to fail on Win95. */ - if ((name_len = strlen(orig_name)) >= _MAX_PATH) { + if ((name_len = wcslen(worig_name)) >= _MAX_PATH) { goto enoent; } else { - strcpy(name, orig_name); + wcscpy(name, worig_name); if (name_len > 2 && ISSLASH(name[name_len-1]) && - name[name_len-2] != ':') { - name[name_len-1] = '\0'; + name[name_len-2] != L':') { + name[name_len-1] = L'\0'; } } /* Try to get disk from name. If none, get current disk. */ - if (name[1] != ':') { + if (name[1] != L':') { drive = 0; - if (GetCurrentDirectory(sizeof(pathbuf), pathbuf) && - pathbuf[1] == ':') { - drive = tolower(pathbuf[0]) - 'a' + 1; + if (GetCurrentDirectoryW(_MAX_PATH, pathbuf) && + pathbuf[1] == L':') { + drive = towlower(pathbuf[0]) - L'a' + 1; } - } else if (*name && name[2] == '\0') { + } else if (*name && name[2] == L'\0') { /* * X: and nothing more is an error. */ @@ -839,15 +835,15 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, errInfo->os_errno = ERROR_FILE_NOT_FOUND; return 0; } else - drive = tolower(*name) - 'a' + 1; + drive = towlower(*name) - L'a' + 1; - findhandle = FindFirstFile(name, &findbuf); + findhandle = FindFirstFileW(name, &findbuf); if (findhandle == INVALID_HANDLE_VALUE) { - if (!(strpbrk(name, "./\\") && - (path = _fullpath(pathbuf, name, _MAX_PATH)) && + if (!(wcspbrk(name, L"./\\") && + (path = _wfullpath(pathbuf, name, _MAX_PATH)) && /* root dir. ('C:\') or UNC root dir. ('\\server\share\') */ - ((strlen(path) == 3) || IsRootUNCName(path)) && - (GetDriveType(path) > 1) ) ) { + ((wcslen(path) == 3) || is_root_unc_name(path)) && + (GetDriveTypeW(path) > 1) ) ) { errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; return 0; @@ -860,8 +856,9 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, findbuf.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; findbuf.nFileSizeHigh = 0; findbuf.nFileSizeLow = 0; - findbuf.cFileName[0] = '\0'; + findbuf.cFileName[0] = L'\0'; + pInfo->links = 1; pInfo->modifyTime.year = 1980; pInfo->modifyTime.month = 1; pInfo->modifyTime.day = 1; @@ -874,6 +871,35 @@ efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, SYSTEMTIME SystemTime; FILETIME LocalFTime; + /*first check if we are a symlink */ + if (!info_for_link && (findbuf.dwFileAttributes & + FILE_ATTRIBUTE_REPARSE_POINT)){ + /* + * given that we know this is a symlink, + we should be able to find its target */ + WCHAR target_name[_MAX_PATH]; + if (efile_readlink(errInfo, (char *) name, + (char *) target_name,256) == 1) { + FindClose(findhandle); + return efile_fileinfo(errInfo, pInfo, + (char *) target_name, info_for_link); + } + } + + /* number of links: */ + { + HANDLE handle; /* Handle returned by CreateFile() */ + BY_HANDLE_FILE_INFORMATION fileInfo; /* from CreateFile() */ + if (handle = CreateFileW(name, GENERIC_READ, 0,NULL, + OPEN_EXISTING, 0, NULL)) { + GetFileInformationByHandle(handle, &fileInfo); + pInfo->links = fileInfo.nNumberOfLinks; + CloseHandle(handle); + } else { + pInfo->links = 1; + } + } + #define GET_TIME(dst, src) \ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \ !FileTimeToSystemTime(&LocalFTime, &SystemTime)) { \ @@ -908,7 +934,10 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \ pInfo->size_low = findbuf.nFileSizeLow; pInfo->size_high = findbuf.nFileSizeHigh; - if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + if (info_for_link && (findbuf.dwFileAttributes & + FILE_ATTRIBUTE_REPARSE_POINT)) + pInfo->type = FT_SYMLINK; + else if (findbuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) pInfo->type = FT_DIRECTORY; else pInfo->type = FT_REGULAR; @@ -919,7 +948,6 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \ pInfo->access = FA_READ|FA_WRITE; pInfo->mode = dos_to_posix_mode(findbuf.dwFileAttributes, name); - pInfo->links = 1; pInfo->major_device = drive; pInfo->minor_device = 0; pInfo->inode = 0; @@ -930,10 +958,9 @@ if (!FileTimeToLocalFileTime(&findbuf.src, &LocalFTime) || \ } int -efile_write_info(errInfo, pInfo, name) -Efile_error* errInfo; -Efile_info* pInfo; -char* name; +efile_write_info(Efile_error* errInfo, + Efile_info* pInfo, + char* name) { SYSTEMTIME timebuf; FILETIME LocalFileTime; @@ -947,12 +974,13 @@ char* name; DWORD attr; DWORD tempAttr; BOOL modifyTime = FALSE; + WCHAR *wname = (WCHAR *) name; /* * Get the attributes for the file. */ - tempAttr = attr = GetFileAttributes((LPTSTR)name); + tempAttr = attr = GetFileAttributesW(wname); if (attr == 0xffffffff) { return set_error(errInfo); } @@ -1006,12 +1034,12 @@ char* name; if (tempAttr & FILE_ATTRIBUTE_READONLY) { tempAttr &= ~FILE_ATTRIBUTE_READONLY; - if (!SetFileAttributes((LPTSTR) name, tempAttr)) { + if (!SetFileAttributesW(wname, tempAttr)) { return set_error(errInfo); } } - fd = CreateFile(name, GENERIC_READ|GENERIC_WRITE, + fd = CreateFileW(wname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fd != INVALID_HANDLE_VALUE) { @@ -1029,7 +1057,7 @@ char* name; */ if (tempAttr != attr) { - if (!SetFileAttributes((LPTSTR) name, attr)) { + if (!SetFileAttributesW(wname, attr)) { return set_error(errInfo); } } @@ -1082,12 +1110,17 @@ char* buf; /* Buffer to write. */ size_t count; /* Number of bytes to write. */ { DWORD written; /* Bytes written in last operation. */ + OVERLAPPED overlapped; + OVERLAPPED* pOverlapped = NULL; if (flags & EFILE_MODE_APPEND) { - (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END); + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.Offset = 0xffffffff; + overlapped.OffsetHigh = 0xffffffff; + pOverlapped = &overlapped; } while (count > 0) { - if (!WriteFile((HANDLE) fd, buf, count, &written, NULL)) + if (!WriteFile((HANDLE) fd, buf, count, &written, pOverlapped)) return set_error(errInfo); buf += written; count -= written; @@ -1107,11 +1140,16 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */ size_t size) /* Number of bytes to write */ { int cnt; /* Buffers so far written */ + OVERLAPPED overlapped; + OVERLAPPED* pOverlapped = NULL; ASSERT(iovcnt >= 0); if (flags & EFILE_MODE_APPEND) { - (void) SetFilePointer((HANDLE) fd, 0, NULL, FILE_END); + memset(&overlapped, 0, sizeof(overlapped)); + overlapped.Offset = 0xffffffff; + overlapped.OffsetHigh = 0xffffffff; + pOverlapped = &overlapped; } for (cnt = 0; cnt < iovcnt; cnt++) { if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { @@ -1123,7 +1161,7 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */ iov[cnt].iov_base + p, iov[cnt].iov_len - p, &w, - NULL)) + pOverlapped)) return set_error(errInfo); } } @@ -1195,7 +1233,7 @@ int flags; /* - * IsRootUNCName - returns TRUE if the argument is a UNC name specifying + * is_root_unc_name - returns TRUE if the argument is a UNC name specifying * a root share. That is, if it is of the form \\server\share\. * This routine will also return true if the argument is of the * form \\server\share (no trailing slash) but Win32 currently @@ -1205,16 +1243,16 @@ int flags; */ static int -IsRootUNCName(const char* path) +is_root_unc_name(const WCHAR *path) { /* * If a root UNC name, path will start with 2 (but not 3) slashes */ - if ((strlen(path) >= 5) /* minimum string is "//x/y" */ + if ((wcslen(path) >= 5) /* minimum string is "//x/y" */ && ISSLASH(path[0]) && ISSLASH(path[1])) { - const char * p = path + 2 ; + const WCHAR *p = path + 2; /* * find the slash between the server name and share name @@ -1257,19 +1295,19 @@ IsRootUNCName(const char* path) */ static int -extract_root(char* name) +extract_root(WCHAR* name) { - int len = strlen(name); + int len = wcslen(name); - if (isalpha(name[0]) && name[1] == ':' && ISSLASH(name[2])) { - int c = name[3]; - name[3] = '\0'; - return c == '\0'; + if (iswalpha(name[0]) && name[1] == L':' && ISSLASH(name[2])) { + WCHAR c = name[3]; + name[3] = L'\0'; + return c == L'\0'; } else if (len < 5 || !ISSLASH(name[0]) || !ISSLASH(name[1])) { goto error; } else { /* Try to find the end of the UNC name. */ - char* p; - int c; + WCHAR* p; + WCHAR c; /* * Find the slash between the server name and share name. @@ -1278,7 +1316,7 @@ extract_root(char* name) for (p = name + 2; *p; p++) if (ISSLASH(*p)) break; - if (*p == '\0') + if (*p == L'\0') goto error; /* @@ -1289,24 +1327,24 @@ extract_root(char* name) if (ISSLASH(*p)) break; c = *p; - *p = '\0'; - return c == '\0' || p[1] == '\0'; + *p = L'\0'; + return c == L'\0' || p[1] == L'\0'; } error: - *name = '\0'; + *name = L'\0'; return 1; } static unsigned short -dos_to_posix_mode(int attr, const char *name) +dos_to_posix_mode(int attr, const WCHAR *name) { register unsigned short uxmode; unsigned dosmode; - register const char *p; + register const WCHAR *p; dosmode = attr & 0xff; - if ((p = name)[1] == ':') + if ((p = name)[1] == L':') p += 2; /* check to see if this is a directory - note we must make a special @@ -1315,7 +1353,7 @@ dos_to_posix_mode(int attr, const char *name) uxmode = (unsigned short) (((ISSLASH(*p) && !p[1]) || (dosmode & FILE_ATTRIBUTE_DIRECTORY) || - *p == '\0') ? _S_IFDIR|_S_IEXEC : _S_IFREG); + *p == L'\0') ? _S_IFDIR|_S_IEXEC : _S_IFREG); /* If attribute byte does not have read-only bit, it is read-write */ @@ -1324,11 +1362,11 @@ dos_to_posix_mode(int attr, const char *name) /* see if file appears to be executable - check extension of name */ - if (p = strrchr(name, '.')) { - if (!stricmp(p, ".exe") || - !stricmp(p, ".cmd") || - !stricmp(p, ".bat") || - !stricmp(p, ".com")) + if (p = wcsrchr(name, L'.')) { + if (!_wcsicmp(p, L".exe") || + !_wcsicmp(p, L".cmd") || + !_wcsicmp(p, L".bat") || + !_wcsicmp(p, L".com")) uxmode |= _S_IEXEC; } @@ -1343,6 +1381,60 @@ dos_to_posix_mode(int attr, const char *name) int efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) { + /* + * load dll and see if we have CreateSymbolicLink at runtime: + * (Vista only) + */ + HINSTANCE hModule = NULL; + WCHAR *wname = (WCHAR *) name; + WCHAR *wbuffer = (WCHAR *) buffer; + if ((hModule = LoadLibrary("kernel32.dll")) != NULL) { + typedef DWORD (WINAPI * GETFINALPATHNAMEBYHANDLEPTR)( + HANDLE hFile, + LPCWSTR lpFilePath, + DWORD cchFilePath, + DWORD dwFlags); + + GETFINALPATHNAMEBYHANDLEPTR pGetFinalPathNameByHandle = + (GETFINALPATHNAMEBYHANDLEPTR)GetProcAddress(hModule, "GetFinalPathNameByHandleW"); + + if (pGetFinalPathNameByHandle == NULL) { + FreeLibrary(hModule); + } else { + /* first check if file is a symlink; {error, einval} otherwise */ + DWORD fileAttributes = GetFileAttributesW(wname); + if ((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + BOOLEAN success = 0; + HANDLE h = CreateFileW(wname, GENERIC_READ, 0,NULL, OPEN_EXISTING, 0, NULL); + int len; + if(h != INVALID_HANDLE_VALUE) { + success = pGetFinalPathNameByHandle(h, wbuffer, size,0); + /* GetFinalPathNameByHandle prepends path with "\\?\": */ + len = wcslen(wbuffer); + wmemmove(wbuffer,wbuffer+4,len-3); + if (len - 4 >= 2 && wbuffer[1] == L':' && wbuffer[0] >= L'A' && + wbuffer[0] <= L'Z') { + wbuffer[0] = wbuffer[0] + L'a' - L'A'; + } + + for ( ; *wbuffer; wbuffer++) + if (*wbuffer == L'\\') + *wbuffer = L'/'; + CloseHandle(h); + } + FreeLibrary(hModule); + if (success) { + return 1; + } else { + return set_error(errInfo); + } + } else { + FreeLibrary(hModule); + errno = EINVAL; + return check_error(-1, errInfo); + } + } + } errno = ENOTSUP; return check_error(-1, errInfo); } @@ -1351,17 +1443,20 @@ efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) int efile_altname(Efile_error* errInfo, char* orig_name, char* buffer, size_t size) { - WIN32_FIND_DATA wfd; + WIN32_FIND_DATAW wfd; HANDLE fh; - char name[_MAX_PATH]; + WCHAR name[_MAX_PATH+1]; int name_len; - char* path; - char pathbuf[_MAX_PATH]; + WCHAR* path; + WCHAR pathbuf[_MAX_PATH+1]; /* Unclear weather GetCurrentDirectory will access one char after + _MAX_PATH */ + WCHAR *worig_name = (WCHAR *) orig_name; + WCHAR *wbuffer = (WCHAR *) buffer; int drive; /* Drive for filename (1 = A:, 2 = B: etc). */ /* Don't allow wildcards to be interpreted by system */ - if (strpbrk(orig_name, "?*")) { + if (wcspbrk(worig_name, L"?*")) { enoent: errInfo->posix_errno = ENOENT; errInfo->os_errno = ERROR_FILE_NOT_FOUND; @@ -1373,67 +1468,105 @@ efile_altname(Efile_error* errInfo, char* orig_name, char* buffer, size_t size) * slash, because it causes FindFirstFile() to fail on Win95. */ - if ((name_len = strlen(orig_name)) >= _MAX_PATH) { + if ((name_len = wcslen(worig_name)) >= _MAX_PATH) { goto enoent; } else { - strcpy(name, orig_name); + wcscpy(name, worig_name); if (name_len > 2 && ISSLASH(name[name_len-1]) && - name[name_len-2] != ':') { - name[name_len-1] = '\0'; + name[name_len-2] != L':') { + name[name_len-1] = L'\0'; } } /* Try to get disk from name. If none, get current disk. */ - if (name[1] != ':') { + if (name[1] != L':') { drive = 0; - if (GetCurrentDirectory(sizeof(pathbuf), pathbuf) && - pathbuf[1] == ':') { - drive = tolower(pathbuf[0]) - 'a' + 1; + if (GetCurrentDirectoryW(_MAX_PATH, pathbuf) && + pathbuf[1] == L':') { + drive = towlower(pathbuf[0]) - L'a' + 1; } - } else if (*name && name[2] == '\0') { + } else if (*name && name[2] == L'\0') { /* * X: and nothing more is an error. */ goto enoent; } else { - drive = tolower(*name) - 'a' + 1; + drive = towlower(*name) - L'a' + 1; } - fh = FindFirstFile(name,&wfd); + fh = FindFirstFileW(name,&wfd); if (fh == INVALID_HANDLE_VALUE) { - if (!(strpbrk(name, "./\\") && - (path = _fullpath(pathbuf, name, _MAX_PATH)) && + if (!(wcspbrk(name, L"./\\") && + (path = _wfullpath(pathbuf, name, _MAX_PATH)) && /* root dir. ('C:\') or UNC root dir. ('\\server\share\') */ - ((strlen(path) == 3) || IsRootUNCName(path)) && - (GetDriveType(path) > 1) ) ) { + ((wcslen(path) == 3) || is_root_unc_name(path)) && + (GetDriveTypeW(path) > 1) ) ) { errno = errno_map(GetLastError()); return check_error(-1, errInfo); } /* * Root directories (such as C:\ or \\server\share\ are fabricated. */ - strcpy(buffer,name); + wcscpy(wbuffer,name); return 1; } - strcpy(buffer,wfd.cAlternateFileName); - if (!*buffer) { - strcpy(buffer,wfd.cFileName); + wcscpy(wbuffer,wfd.cAlternateFileName); + if (!*wbuffer) { + wcscpy(wbuffer,wfd.cFileName); } - + FindClose(fh); return 1; } + int efile_link(Efile_error* errInfo, char* old, char* new) { - errno = ENOTSUP; - return check_error(-1, errInfo); + WCHAR *wold = (WCHAR *) old; + WCHAR *wnew = (WCHAR *) new; + if(!CreateHardLinkW(wnew, wold, NULL)) { + return set_error(errInfo); + } + return 1; } int efile_symlink(Efile_error* errInfo, char* old, char* new) { + /* + * Load dll and see if we have CreateSymbolicLink at runtime: + * (Vista only) + */ + HINSTANCE hModule = NULL; + WCHAR *wold = (WCHAR *) old; + WCHAR *wnew = (WCHAR *) new; + if ((hModule = LoadLibrary("kernel32.dll")) != NULL) { + typedef BOOLEAN (WINAPI * CREATESYMBOLICLINKFUNCPTR) ( + LPCWSTR lpSymlinkFileName, + LPCWSTR lpTargetFileName, + DWORD dwFlags); + + CREATESYMBOLICLINKFUNCPTR pCreateSymbolicLink = + (CREATESYMBOLICLINKFUNCPTR) GetProcAddress(hModule, + "CreateSymbolicLinkW"); + /* A for MBCS, W for UNICODE... char* above implies 'W'! */ + if (pCreateSymbolicLink != NULL) { + DWORD attr = GetFileAttributesW(wold); + int flag = (attr != INVALID_FILE_ATTRIBUTES && + attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; + /* SYMBOLIC_LINK_FLAG_DIRECTORY = 1 */ + BOOLEAN success = pCreateSymbolicLink(wnew, wold, flag); + FreeLibrary(hModule); + + if (success) { + return 1; + } else { + return set_error(errInfo); + } + } else + FreeLibrary(hModule); + } errno = ENOTSUP; return check_error(-1, errInfo); } diff --git a/erts/emulator/hipe/hipe_amd64_glue.S b/erts/emulator/hipe/hipe_amd64_glue.S index ede762aae0..3376487292 100644 --- a/erts/emulator/hipe/hipe_amd64_glue.S +++ b/erts/emulator/hipe/hipe_amd64_glue.S @@ -402,7 +402,7 @@ nbif_3_simple_exception: * - the native heap/stack/reds registers are saved in P */ .handle_trap: - movq %rax, P_NARITY(P) + movl %eax, P_NARITY(P) # Note: narity is a 32-bit field movl $HIPE_MODE_SWITCH_RES_TRAP, %eax jmp .nosave_exit diff --git a/erts/emulator/hipe/hipe_ppc_glue.S b/erts/emulator/hipe/hipe_ppc_glue.S index 0651963294..c010f4f047 100644 --- a/erts/emulator/hipe/hipe_ppc_glue.S +++ b/erts/emulator/hipe/hipe_ppc_glue.S @@ -541,7 +541,7 @@ CSYM(nbif_3_simple_exception): .handle_trap: li r3, HIPE_MODE_SWITCH_RES_TRAP STORE NSP, P_NSP(P) - STORE r4, P_NARITY(P) + stw r4, P_NARITY(P) /* Note: narity is a 32-bit field */ STORE TEMP_LR, P_NRA(P) b .nosave_exit diff --git a/erts/emulator/internal_doc/dec.dat b/erts/emulator/internal_doc/dec.dat new file mode 100644 index 0000000000..771ef51baa --- /dev/null +++ b/erts/emulator/internal_doc/dec.dat @@ -0,0 +1,942 @@ +{[59],894}. +{[96],8175}. +{[180],8189}. +{[183],903}. +{[198],1236}. +{[230],1237}. +{[399],1240}. +{[415],1256}. +{[439],1248}. +{[601],1241}. +{[629],1257}. +{[658],1249}. +{[697],884}. +{[768],832}. +{[768,65],192}. +{[768,69],200}. +{[768,73],204}. +{[768,79],210}. +{[768,85],217}. +{[768,87],7808}. +{[768,89],7922}. +{[768,97],224}. +{[768,101],232}. +{[768,105],236}. +{[768,111],242}. +{[768,117],249}. +{[768,119],7809}. +{[768,121],7923}. +{[768,168],8173}. +{[768,770,65],7846}. +{[768,770,69],7872}. +{[768,770,79],7890}. +{[768,770,97],7847}. +{[768,770,101],7873}. +{[768,770,111],7891}. +{[768,772,69],7700}. +{[768,772,79],7760}. +{[768,772,101],7701}. +{[768,772,111],7761}. +{[768,774,65],7856}. +{[768,774,97],7857}. +{[768,776,85],475}. +{[768,776,117],476}. +{[768,776,953],8146}. +{[768,776,965],8162}. +{[768,787,837,913],8074}. +{[768,787,837,919],8090}. +{[768,787,837,937],8106}. +{[768,787,837,945],8066}. +{[768,787,837,951],8082}. +{[768,787,837,969],8098}. +{[768,787,913],7946}. +{[768,787,917],7962}. +{[768,787,919],7978}. +{[768,787,921],7994}. +{[768,787,927],8010}. +{[768,787,937],8042}. +{[768,787,945],7938}. +{[768,787,949],7954}. +{[768,787,951],7970}. +{[768,787,953],7986}. +{[768,787,959],8002}. +{[768,787,965],8018}. +{[768,787,969],8034}. +{[768,788,837,913],8075}. +{[768,788,837,919],8091}. +{[768,788,837,937],8107}. +{[768,788,837,945],8067}. +{[768,788,837,951],8083}. +{[768,788,837,969],8099}. +{[768,788,913],7947}. +{[768,788,917],7963}. +{[768,788,919],7979}. +{[768,788,921],7995}. +{[768,788,927],8011}. +{[768,788,933],8027}. +{[768,788,937],8043}. +{[768,788,945],7939}. +{[768,788,949],7955}. +{[768,788,951],7971}. +{[768,788,953],7987}. +{[768,788,959],8003}. +{[768,788,965],8019}. +{[768,788,969],8035}. +{[768,795,79],7900}. +{[768,795,85],7914}. +{[768,795,111],7901}. +{[768,795,117],7915}. +{[768,837,945],8114}. +{[768,837,951],8130}. +{[768,837,969],8178}. +{[768,913],8122}. +{[768,917],8136}. +{[768,919],8138}. +{[768,921],8154}. +{[768,927],8184}. +{[768,933],8170}. +{[768,937],8186}. +{[768,945],8048}. +{[768,949],8050}. +{[768,951],8052}. +{[768,953],8054}. +{[768,959],8056}. +{[768,965],8058}. +{[768,969],8060}. +{[768,8127],8141}. +{[768,8190],8157}. +{[769],833}. +{[769,65],193}. +{[769,67],262}. +{[769,69],201}. +{[769,71],500}. +{[769,73],205}. +{[769,75],7728}. +{[769,76],313}. +{[769,77],7742}. +{[769,78],323}. +{[769,79],211}. +{[769,80],7764}. +{[769,82],340}. +{[769,83],346}. +{[769,85],218}. +{[769,87],7810}. +{[769,89],221}. +{[769,90],377}. +{[769,97],225}. +{[769,99],263}. +{[769,101],233}. +{[769,103],501}. +{[769,105],237}. +{[769,107],7729}. +{[769,108],314}. +{[769,109],7743}. +{[769,110],324}. +{[769,111],243}. +{[769,112],7765}. +{[769,114],341}. +{[769,115],347}. +{[769,117],250}. +{[769,119],7811}. +{[769,121],253}. +{[769,122],378}. +{[769,168],8174}. +{[769,198],508}. +{[769,216],510}. +{[769,230],509}. +{[769,248],511}. +{[769,770,65],7844}. +{[769,770,69],7870}. +{[769,770,79],7888}. +{[769,770,97],7845}. +{[769,770,101],7871}. +{[769,770,111],7889}. +{[769,771,79],7756}. +{[769,771,85],7800}. +{[769,771,111],7757}. +{[769,771,117],7801}. +{[769,772,69],7702}. +{[769,772,79],7762}. +{[769,772,101],7703}. +{[769,772,111],7763}. +{[769,774,65],7854}. +{[769,774,97],7855}. +{[769,776,73],7726}. +{[769,776,85],471}. +{[769,776,105],7727}. +{[769,776,117],472}. +{[769,776,953],8147}. +{[769,776,965],8163}. +{[769,778,65],506}. +{[769,778,97],507}. +{[769,787,837,913],8076}. +{[769,787,837,919],8092}. +{[769,787,837,937],8108}. +{[769,787,837,945],8068}. +{[769,787,837,951],8084}. +{[769,787,837,969],8100}. +{[769,787,913],7948}. +{[769,787,917],7964}. +{[769,787,919],7980}. +{[769,787,921],7996}. +{[769,787,927],8012}. +{[769,787,937],8044}. +{[769,787,945],7940}. +{[769,787,949],7956}. +{[769,787,951],7972}. +{[769,787,953],7988}. +{[769,787,959],8004}. +{[769,787,965],8020}. +{[769,787,969],8036}. +{[769,788,837,913],8077}. +{[769,788,837,919],8093}. +{[769,788,837,937],8109}. +{[769,788,837,945],8069}. +{[769,788,837,951],8085}. +{[769,788,837,969],8101}. +{[769,788,913],7949}. +{[769,788,917],7965}. +{[769,788,919],7981}. +{[769,788,921],7997}. +{[769,788,927],8013}. +{[769,788,933],8029}. +{[769,788,937],8045}. +{[769,788,945],7941}. +{[769,788,949],7957}. +{[769,788,951],7973}. +{[769,788,953],7989}. +{[769,788,959],8005}. +{[769,788,965],8021}. +{[769,788,969],8037}. +{[769,795,79],7898}. +{[769,795,85],7912}. +{[769,795,111],7899}. +{[769,795,117],7913}. +{[769,807,67],7688}. +{[769,807,99],7689}. +{[769,837,945],8116}. +{[769,837,951],8132}. +{[769,837,959],8180}. +{[769,913],8123}. +{[769,917],8137}. +{[769,919],8139}. +{[769,921],8155}. +{[769,927],8185}. +{[769,933],8171}. +{[769,937],8187}. +{[769,945],8049}. +{[769,949],8051}. +{[769,951],8053}. +{[769,953],8055}. +{[769,959],8057}. +{[769,965],8059}. +{[769,969],8061}. +{[769,1043],1027}. +{[769,1050],1036}. +{[769,1075],1107}. +{[769,1082],1116}. +{[769,8127],8142}. +{[769,8190],8158}. +{[770,65],194}. +{[770,67],264}. +{[770,69],202}. +{[770,71],284}. +{[770,72],292}. +{[770,73],206}. +{[770,74],308}. +{[770,79],212}. +{[770,83],348}. +{[770,85],219}. +{[770,87],372}. +{[770,89],374}. +{[770,90],7824}. +{[770,97],226}. +{[770,99],265}. +{[770,101],234}. +{[770,103],285}. +{[770,104],293}. +{[770,105],238}. +{[770,106],309}. +{[770,111],244}. +{[770,115],349}. +{[770,117],251}. +{[770,119],373}. +{[770,121],375}. +{[770,122],7825}. +{[770,803,65],7852}. +{[770,803,69],7878}. +{[770,803,79],7896}. +{[770,803,97],7853}. +{[770,803,101],7879}. +{[770,803,111],7897}. +{[771,65],195}. +{[771,69],7868}. +{[771,73],296}. +{[771,78],209}. +{[771,79],213}. +{[771,85],360}. +{[771,86],7804}. +{[771,89],7928}. +{[771,97],227}. +{[771,101],7869}. +{[771,105],297}. +{[771,110],241}. +{[771,111],245}. +{[771,117],361}. +{[771,118],7805}. +{[771,121],7929}. +{[771,770,65],7850}. +{[771,770,69],7876}. +{[771,770,79],7894}. +{[771,770,97],7851}. +{[771,770,101],7877}. +{[771,770,111],7895}. +{[771,774,65],7860}. +{[771,774,97],7861}. +{[771,795,79],7904}. +{[771,795,85],7918}. +{[771,795,111],7905}. +{[771,795,117],7919}. +{[772,65],256}. +{[772,69],274}. +{[772,71],7712}. +{[772,73],298}. +{[772,79],332}. +{[772,85],362}. +{[772,97],257}. +{[772,101],275}. +{[772,103],7713}. +{[772,105],299}. +{[772,111],333}. +{[772,117],363}. +{[772,198],482}. +{[772,230],483}. +{[772,775,65],480}. +{[772,775,97],481}. +{[772,776,65],478}. +{[772,776,85],469}. +{[772,776,97],479}. +{[772,776,117],470}. +{[772,803,76],7736}. +{[772,803,82],7772}. +{[772,803,108],7737}. +{[772,803,114],7773}. +{[772,808,79],492}. +{[772,808,111],493}. +{[772,913],8121}. +{[772,921],8153}. +{[772,933],8169}. +{[772,945],8113}. +{[772,953],8145}. +{[772,965],8161}. +{[772,1048],1250}. +{[772,1059],1262}. +{[772,1080],1251}. +{[772,1091],1263}. +{[774,65],258}. +{[774,69],276}. +{[774,71],286}. +{[774,73],300}. +{[774,79],334}. +{[774,85],364}. +{[774,97],259}. +{[774,101],277}. +{[774,103],287}. +{[774,105],301}. +{[774,111],335}. +{[774,117],365}. +{[774,803,65],7862}. +{[774,803,97],7863}. +{[774,807,69],7708}. +{[774,807,101],7709}. +{[774,913],8120}. +{[774,921],8152}. +{[774,933],8168}. +{[774,945],8112}. +{[774,953],8144}. +{[774,965],8160}. +{[774,1040],1232}. +{[774,1045],1238}. +{[774,1046],1217}. +{[774,1048],1049}. +{[774,1059],1038}. +{[774,1072],1233}. +{[774,1077],1239}. +{[774,1078],1218}. +{[774,1080],1081}. +{[774,1091],1118}. +{[775,66],7682}. +{[775,67],266}. +{[775,68],7690}. +{[775,69],278}. +{[775,70],7710}. +{[775,71],288}. +{[775,72],7714}. +{[775,73],304}. +{[775,77],7744}. +{[775,78],7748}. +{[775,80],7766}. +{[775,82],7768}. +{[775,83],7776}. +{[775,84],7786}. +{[775,87],7814}. +{[775,88],7818}. +{[775,89],7822}. +{[775,90],379}. +{[775,98],7683}. +{[775,99],267}. +{[775,100],7691}. +{[775,101],279}. +{[775,102],7711}. +{[775,103],289}. +{[775,104],7715}. +{[775,109],7745}. +{[775,110],7749}. +{[775,112],7767}. +{[775,114],7769}. +{[775,115],7777}. +{[775,116],7787}. +{[775,119],7815}. +{[775,120],7819}. +{[775,121],7823}. +{[775,122],380}. +{[775,383],7835}. +{[775,769,83],7780}. +{[775,769,115],7781}. +{[775,774],784}. +{[775,780,83],7782}. +{[775,780,115],7783}. +{[775,803,83],7784}. +{[775,803,115],7785}. +{[776,65],196}. +{[776,69],203}. +{[776,72],7718}. +{[776,73],207}. +{[776,79],214}. +{[776,85],220}. +{[776,87],7812}. +{[776,88],7820}. +{[776,89],376}. +{[776,97],228}. +{[776,101],235}. +{[776,104],7719}. +{[776,105],239}. +{[776,111],246}. +{[776,116],7831}. +{[776,117],252}. +{[776,119],7813}. +{[776,120],7821}. +{[776,121],255}. +{[776,399],1242}. +{[776,415],1258}. +{[776,601],1243}. +{[776,629],1259}. +{[776,771,79],7758}. +{[776,771,111],7759}. +{[776,772,85],7802}. +{[776,772,117],7803}. +{[776,921],938}. +{[776,933],939}. +{[776,953],970}. +{[776,965],971}. +{[776,978],980}. +{[776,1030],1031}. +{[776,1040],1234}. +{[776,1045],1025}. +{[776,1046],1244}. +{[776,1047],1246}. +{[776,1048],1252}. +{[776,1054],1254}. +{[776,1059],1264}. +{[776,1063],1268}. +{[776,1067],1272}. +{[776,1072],1235}. +{[776,1077],1105}. +{[776,1078],1245}. +{[776,1079],1247}. +{[776,1080],1253}. +{[776,1086],1255}. +{[776,1091],1265}. +{[776,1095],1269}. +{[776,1099],1273}. +{[776,1110],1111}. +{[777,65],7842}. +{[777,69],7866}. +{[777,73],7880}. +{[777,79],7886}. +{[777,85],7910}. +{[777,89],7926}. +{[777,97],7843}. +{[777,101],7867}. +{[777,105],7881}. +{[777,111],7887}. +{[777,117],7911}. +{[777,121],7927}. +{[777,770,65],7848}. +{[777,770,69],7874}. +{[777,770,79],7892}. +{[777,770,97],7849}. +{[777,770,101],7875}. +{[777,770,111],7893}. +{[777,774,65],7858}. +{[777,774,97],7859}. +{[777,795,79],7902}. +{[777,795,85],7916}. +{[777,795,111],7903}. +{[777,795,117],7917}. +{[778,65],197}. +{[778,85],366}. +{[778,97],229}. +{[778,117],367}. +{[778,119],7832}. +{[778,121],7833}. +{[779,79],336}. +{[779,85],368}. +{[779,111],337}. +{[779,117],369}. +{[779,1059],1266}. +{[779,1091],1267}. +{[780,65],461}. +{[780,67],268}. +{[780,68],270}. +{[780,69],282}. +{[780,71],486}. +{[780,73],463}. +{[780,75],488}. +{[780,76],317}. +{[780,78],327}. +{[780,79],465}. +{[780,82],344}. +{[780,83],352}. +{[780,84],356}. +{[780,85],467}. +{[780,90],381}. +{[780,97],462}. +{[780,99],269}. +{[780,100],271}. +{[780,101],283}. +{[780,103],487}. +{[780,105],464}. +{[780,106],496}. +{[780,107],489}. +{[780,108],318}. +{[780,110],328}. +{[780,111],466}. +{[780,114],345}. +{[780,115],353}. +{[780,116],357}. +{[780,117],468}. +{[780,122],382}. +{[780,439],494}. +{[780,658],495}. +{[780,776,85],473}. +{[780,776,117],474}. +{[781,168],901}. +{[781,776],836}. +{[781,776,953],912}. +{[781,776,965],944}. +{[781,913],902}. +{[781,917],904}. +{[781,919],905}. +{[781,921],906}. +{[781,927],908}. +{[781,933],910}. +{[781,937],911}. +{[781,945],940}. +{[781,949],941}. +{[781,951],942}. +{[781,953],943}. +{[781,959],972}. +{[781,965],973}. +{[781,969],974}. +{[781,978],979}. +{[783,65],512}. +{[783,69],516}. +{[783,73],520}. +{[783,79],524}. +{[783,82],528}. +{[783,85],532}. +{[783,97],513}. +{[783,101],517}. +{[783,105],521}. +{[783,111],525}. +{[783,114],529}. +{[783,117],533}. +{[783,1140],1142}. +{[783,1141],1143}. +{[785,65],514}. +{[785,69],518}. +{[785,73],522}. +{[785,79],526}. +{[785,82],530}. +{[785,85],534}. +{[785,97],515}. +{[785,101],519}. +{[785,105],523}. +{[785,111],527}. +{[785,114],531}. +{[785,117],535}. +{[787],835}. +{[787,837,913],8072}. +{[787,837,919],8088}. +{[787,837,937],8104}. +{[787,837,945],8064}. +{[787,837,951],8080}. +{[787,837,969],8096}. +{[787,913],7944}. +{[787,917],7960}. +{[787,919],7976}. +{[787,921],7992}. +{[787,927],8008}. +{[787,937],8040}. +{[787,945],7936}. +{[787,949],7952}. +{[787,951],7968}. +{[787,953],7984}. +{[787,959],8000}. +{[787,961],8164}. +{[787,965],8016}. +{[787,969],8032}. +{[788,837,913],8073}. +{[788,837,919],8089}. +{[788,837,937],8105}. +{[788,837,945],8065}. +{[788,837,951],8081}. +{[788,837,969],8097}. +{[788,913],7945}. +{[788,917],7961}. +{[788,919],7977}. +{[788,921],7993}. +{[788,927],8009}. +{[788,929],8172}. +{[788,933],8025}. +{[788,937],8041}. +{[788,945],7937}. +{[788,949],7953}. +{[788,951],7969}. +{[788,953],7985}. +{[788,959],8001}. +{[788,961],8165}. +{[788,965],8017}. +{[788,969],8033}. +{[795,79],416}. +{[795,85],431}. +{[795,111],417}. +{[795,117],432}. +{[803,65],7840}. +{[803,66],7684}. +{[803,68],7692}. +{[803,69],7864}. +{[803,72],7716}. +{[803,73],7882}. +{[803,75],7730}. +{[803,76],7734}. +{[803,77],7746}. +{[803,78],7750}. +{[803,79],7884}. +{[803,82],7770}. +{[803,83],7778}. +{[803,84],7788}. +{[803,85],7908}. +{[803,86],7806}. +{[803,87],7816}. +{[803,89],7924}. +{[803,90],7826}. +{[803,97],7841}. +{[803,98],7685}. +{[803,100],7693}. +{[803,101],7865}. +{[803,104],7717}. +{[803,105],7883}. +{[803,107],7731}. +{[803,108],7735}. +{[803,109],7747}. +{[803,110],7751}. +{[803,111],7885}. +{[803,114],7771}. +{[803,115],7779}. +{[803,116],7789}. +{[803,117],7909}. +{[803,118],7807}. +{[803,119],7817}. +{[803,121],7925}. +{[803,122],7827}. +{[803,795,79],7906}. +{[803,795,85],7920}. +{[803,795,111],7907}. +{[803,795,117],7921}. +{[804,85],7794}. +{[804,117],7795}. +{[805,65],7680}. +{[805,97],7681}. +{[807,67],199}. +{[807,68],7696}. +{[807,71],290}. +{[807,72],7720}. +{[807,75],310}. +{[807,76],315}. +{[807,78],325}. +{[807,82],342}. +{[807,83],350}. +{[807,84],354}. +{[807,99],231}. +{[807,100],7697}. +{[807,103],291}. +{[807,104],7721}. +{[807,107],311}. +{[807,108],316}. +{[807,110],326}. +{[807,114],343}. +{[807,115],351}. +{[807,116],355}. +{[808,65],260}. +{[808,69],280}. +{[808,73],302}. +{[808,79],490}. +{[808,85],370}. +{[808,97],261}. +{[808,101],281}. +{[808,105],303}. +{[808,111],491}. +{[808,117],371}. +{[813,68],7698}. +{[813,69],7704}. +{[813,76],7740}. +{[813,78],7754}. +{[813,84],7792}. +{[813,85],7798}. +{[813,100],7699}. +{[813,101],7705}. +{[813,108],7741}. +{[813,110],7755}. +{[813,116],7793}. +{[813,117],7799}. +{[814,72],7722}. +{[814,104],7723}. +{[816,69],7706}. +{[816,73],7724}. +{[816,85],7796}. +{[816,101],7707}. +{[816,105],7725}. +{[816,117],7797}. +{[817,66],7686}. +{[817,68],7694}. +{[817,75],7732}. +{[817,76],7738}. +{[817,78],7752}. +{[817,82],7774}. +{[817,84],7790}. +{[817,90],7828}. +{[817,98],7687}. +{[817,100],7695}. +{[817,104],7830}. +{[817,107],7733}. +{[817,108],7739}. +{[817,110],7753}. +{[817,114],7775}. +{[817,116],7791}. +{[817,122],7829}. +{[834,168],8129}. +{[834,776,953],8151}. +{[834,776,965],8167}. +{[834,787,837,913],8078}. +{[834,787,837,919],8094}. +{[834,787,837,937],8110}. +{[834,787,837,945],8070}. +{[834,787,837,951],8086}. +{[834,787,837,969],8102}. +{[834,787,913],7950}. +{[834,787,919],7982}. +{[834,787,921],7998}. +{[834,787,937],8046}. +{[834,787,945],7942}. +{[834,787,951],7974}. +{[834,787,953],7990}. +{[834,787,965],8022}. +{[834,787,969],8038}. +{[834,788,837,913],8079}. +{[834,788,837,919],8095}. +{[834,788,837,937],8111}. +{[834,788,837,945],8071}. +{[834,788,837,951],8087}. +{[834,788,837,969],8103}. +{[834,788,913],7951}. +{[834,788,919],7983}. +{[834,788,921],7999}. +{[834,788,933],8031}. +{[834,788,937],8047}. +{[834,788,945],7943}. +{[834,788,951],7975}. +{[834,788,953],7991}. +{[834,788,965],8023}. +{[834,788,969],8039}. +{[834,837,945],8119}. +{[834,837,951],8135}. +{[834,837,969],8183}. +{[834,945],8118}. +{[834,951],8134}. +{[834,953],8150}. +{[834,965],8166}. +{[834,969],8182}. +{[834,8127],8143}. +{[834,8190],8159}. +{[837,913],8124}. +{[837,919],8140}. +{[837,937],8188}. +{[837,945],8115}. +{[837,951],8131}. +{[837,969],8179}. +{[953],8126}. +{[1463,1488],64302}. +{[1463,1522],64287}. +{[1464,1488],64303}. +{[1465,1493],64331}. +{[1468,1488],64304}. +{[1468,1489],64305}. +{[1468,1490],64306}. +{[1468,1491],64307}. +{[1468,1492],64308}. +{[1468,1493],64309}. +{[1468,1494],64310}. +{[1468,1496],64312}. +{[1468,1497],64313}. +{[1468,1498],64314}. +{[1468,1499],64315}. +{[1468,1500],64316}. +{[1468,1502],64318}. +{[1468,1504],64320}. +{[1468,1505],64321}. +{[1468,1507],64323}. +{[1468,1508],64324}. +{[1468,1510],64326}. +{[1468,1511],64327}. +{[1468,1512],64328}. +{[1468,1513],64329}. +{[1468,1514],64330}. +{[1471,1489],64332}. +{[1471,1499],64333}. +{[1471,1508],64334}. +{[1473,1468,1513],64300}. +{[1473,1513],64298}. +{[1474,1468,1513],64301}. +{[1474,1513],64299}. +{[2364,2325],2392}. +{[2364,2326],2393}. +{[2364,2327],2394}. +{[2364,2332],2395}. +{[2364,2337],2396}. +{[2364,2338],2397}. +{[2364,2344],2345}. +{[2364,2347],2398}. +{[2364,2351],2399}. +{[2364,2352],2353}. +{[2364,2355],2356}. +{[2492,2465],2524}. +{[2492,2466],2525}. +{[2492,2476],2480}. +{[2492,2479],2527}. +{[2494,2503],2507}. +{[2519,2503],2508}. +{[2620,2582],2649}. +{[2620,2583],2650}. +{[2620,2588],2651}. +{[2620,2593],2652}. +{[2620,2603],2654}. +{[2876,2849],2908}. +{[2876,2850],2909}. +{[2876,2863],2911}. +{[2878,2887],2891}. +{[2902,2887],2888}. +{[2903,2887],2892}. +{[3006,3014],3018}. +{[3006,3015],3019}. +{[3031,2962],2964}. +{[3031,3014],3020}. +{[3158,3142],3144}. +{[3266,3270],3274}. +{[3285,3263],3264}. +{[3285,3266,3270],3275}. +{[3285,3270],3271}. +{[3286,3270],3272}. +{[3390,3398],3402}. +{[3390,3399],3403}. +{[3415,3398],3404}. +{[3634,3661],3635}. +{[3762,3789],3763}. +{[3953,3954],3955}. +{[3953,3956],3957}. +{[3953,3968],3969}. +{[3953,3968,4018],3959}. +{[3953,3968,4019],3961}. +{[3968,4018],3958}. +{[3968,4019],3960}. +{[4021,3904],3945}. +{[4021,3984],4025}. +{[4023,3906],3907}. +{[4023,3916],3917}. +{[4023,3921],3922}. +{[4023,3926],3927}. +{[4023,3931],3932}. +{[4023,3986],3987}. +{[4023,3996],3997}. +{[4023,4001],4002}. +{[4023,4006],4007}. +{[4023,4011],4012}. +{[12441,12358],12436}. +{[12441,12363],12364}. +{[12441,12365],12366}. +{[12441,12367],12368}. +{[12441,12369],12370}. +{[12441,12371],12372}. +{[12441,12373],12374}. +{[12441,12375],12376}. +{[12441,12377],12378}. +{[12441,12379],12380}. +{[12441,12381],12382}. +{[12441,12383],12384}. +{[12441,12385],12386}. +{[12441,12388],12389}. +{[12441,12390],12391}. +{[12441,12392],12393}. +{[12441,12399],12400}. +{[12441,12402],12403}. +{[12441,12405],12406}. +{[12441,12408],12409}. +{[12441,12411],12412}. +{[12441,12445],12446}. +{[12441,12454],12532}. +{[12441,12459],12460}. +{[12441,12461],12462}. +{[12441,12463],12464}. +{[12441,12465],12466}. +{[12441,12467],12468}. +{[12441,12469],12470}. +{[12441,12471],12472}. +{[12441,12473],12474}. +{[12441,12475],12476}. +{[12441,12477],12478}. +{[12441,12479],12480}. +{[12441,12481],12482}. +{[12441,12484],12485}. +{[12441,12486],12487}. +{[12441,12488],12489}. +{[12441,12495],12496}. +{[12441,12498],12499}. +{[12441,12501],12502}. +{[12441,12504],12505}. +{[12441,12507],12508}. +{[12441,12527],12535}. +{[12441,12528],12536}. +{[12441,12529],12537}. +{[12441,12530],12538}. +{[12441,12541],12542}. +{[12442,12399],12401}. +{[12442,12402],12404}. +{[12442,12405],12407}. +{[12442,12408],12410}. +{[12442,12411],12413}. +{[12442,12495],12497}. +{[12442,12498],12500}. +{[12442,12501],12503}. +{[12442,12504],12506}. +{[12442,12507],12509}. diff --git a/erts/emulator/internal_doc/dec.erl b/erts/emulator/internal_doc/dec.erl new file mode 100644 index 0000000000..0315f2a52d --- /dev/null +++ b/erts/emulator/internal_doc/dec.erl @@ -0,0 +1,237 @@ +%% +%% %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% +%% + +%% This program is used to generate a header file with data for +%% normalizing denormalized unicode. + +%% The C header is generated from a text file containing tuples in the +%% following format: +%% {RevList,Translation} +%% Where 'RevList' is a reversed list of the denormalized repressentation of +%% the character 'Translation'. An example would be the swedish character +%% '�', which would be represented in the file as: +%% {[776,111],246}, as the denormalized representation of codepoint 246 +%% is [111,776] (i.e an 'o' followed by the "double dot accent character 776), +%% while '�' instead is represented as {[776,97],228}, as the denormalized +%% form would be [97,776] (same accent but an 'a' instead). +%% The datafile is generated from the table on Apple's developer connection +%% http://developer.apple.com/library/mac/#technotes/tn/tn1150table.html +%% The generating is done whenever new data is present (i.e. dec.dat has +%% to be changed) and not for every build. The product (the C header) is copied +%% to $ERL_TOP/erts/beam after generation and checked in. +%% The program and the data file is included for reference. + +-module(dec). + +-compile(export_all). + +-define(HASH_SIZE_FACTOR,2). +-define(BIG_PREFIX_SIZE,392). + +-define(INPUT_FILE_NAME,"dec.dat"). +-define(OUTPUT_FILE_NAME,"erl_unicode_normalize.h"). + +read(FName) -> + {ok,L} = file:consult(FName), + [{A,B} || {A,B} <- L, + length(A) > 1% , hd(A) < 769 + ]. + +dec() -> + L = read(?INPUT_FILE_NAME), + G = group(L), + {ok,Out} = file:open(?OUTPUT_FILE_NAME,[write]), + io:format + (Out, + "/*~n" + "* %CopyrightBegin%~n" + "*~n" + "* Copyright Ericsson AB 1999-2010. All Rights Reserved.~n" + "*~n" + "* The contents of this file are subject to the Erlang Public License,~n" + "* Version 1.1, (the \"License\"); you may not use this file except in~n" + "* compliance with the License. You should have received a copy of the~n" + "* Erlang Public License along with this software. If not, it can be~n" + "* retrieved online at http://www.erlang.org/.~n" + "*~n" + "* Software distributed under the License is distributed on an " + "\"AS IS\"~n" + "* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See~n" + "* the License for the specific language governing rights and " + "limitations~n" + "* under the License.~n" + "*~n" + "* %CopyrightEnd%~n" + "*/~n" + "/*~n" + "* This file is automatically generated by ~p.erl, " + "do not edit manually~n" + "*/~n", + [?MODULE]), + + io:format(Out, + "#define HASH_SIZE_FACTOR ~w~n" + "typedef struct _compose_entry {~n" + " Uint16 c;~n" + " Uint16 res;~n" + " Uint16 num_subs;~n" + " struct _compose_entry *subs;~n" + " int *hash;~n" + "} CompEntry;~n~n" + "static int compose_tab_size = ~p;~n", + [?HASH_SIZE_FACTOR,length(G)]), + d(Out,G,[],0), + PreTab = tuple_to_list(make_prefix_table(G,erlang:make_tuple(102,0))), + dump_prefixes(Out,PreTab), +%% Using this cuts down on the searching in the +%% actual implementation, but wastes memory with little real gain.. +%% LL = lists:flatten([PartList || {PartList,_} <- L]), +%% BigPreTab = tuple_to_list( +%% make_big_prefixes(LL, +%% erlang:make_tuple(?BIG_PREFIX_SIZE,0))), +%% dump_big_prefixes(Out,BigPreTab), + file:close(Out), + ok. + + + +d(Out,List,D,C) -> + d_sub(Out,List,D,C), + d_top_hash(Out,List,D,C), + d_top(Out,List,D,C). +d_sub(_Out,[],_D,_C) -> + ok; +d_sub(Out,[{_CP,[],_Res}|T],D,C) -> + d_sub(Out,T,D,C+1); +d_sub(Out,[{_CP,Subs,_Res0}|T],D,C) -> + d(Out,Subs,[C|D],0), + d_sub(Out,T,D,C+1). +d_top(Out,L,D,C) -> + io:format(Out,"static CompEntry ~s[] = {~n",[format_depth(D)]), + d_top_1(Out,L,D,C), + io:format(Out,"}; /* ~s */ ~n",[format_depth(D)]). + +d_top_1(_Out,[],_D,_C) -> + ok; +d_top_1(Out,[{CP,[],Res}|T],D,C) -> + io:format(Out, + "{~w, ~w, 0, NULL, NULL}",[CP,Res]), + if + T =:= [] -> + io:format(Out,"~n",[]); + true -> + io:format(Out,",~n",[]) + end, + d_top_1(Out,T,D,C+1); +d_top_1(Out,[{CP,Subs,_Res}|T],D,C) -> + io:format(Out, + "{~w, 0, ~w, ~s, ~s}",[CP,length(Subs), + format_depth([C|D]), + "hash_"++format_depth([C|D])]), + if + T =:= [] -> + io:format(Out,"~n",[]); + true -> + io:format(Out,",~n",[]) + end, + d_top_1(Out,T,D,C+1). + + +d_top_hash(Out,List,D,_C) -> + HSize = length(List)*?HASH_SIZE_FACTOR, + io:format(Out,"static int ~s[~p] = ~n",["hash_"++format_depth(D),HSize]), + Tup = d_top_hash_1(List,0,erlang:make_tuple(HSize,-1),HSize), + io:format(Out,"~p; /* ~s */ ~n",[Tup,"hash_"++format_depth(D)]). + +d_top_hash_1([],_,Hash,_HSize) -> + Hash; +d_top_hash_1([{CP,_,_}|T],Index,Hash,HSize) -> + Bucket = hash_search(Hash,HSize,CP rem HSize), + d_top_hash_1(T,Index+1,erlang:setelement(Bucket+1,Hash,Index),HSize). + +hash_search(Hash,_HSize,Bucket) when element(Bucket+1,Hash) =:= -1 -> + Bucket; +hash_search(Hash,HSize,Bucket) -> + hash_search(Hash,HSize,(Bucket + 1) rem HSize). + +format_depth(D) -> + lists:reverse(tl(lists:reverse(lists:flatten(["compose_tab_",[ integer_to_list(X) ++ "_" || X <- lists:reverse(D) ]])))). + + + + +make_prefix_table([],Table) -> + Table; +make_prefix_table([{C,_,_}|T],Table) when C =< 4023 -> + Index = (C div 32) + 1 - 24, + Pos = C rem 32, + X = element(Index,Table), + Y = X bor (1 bsl Pos), + NewTab = setelement(Index,Table,Y), + make_prefix_table(T,NewTab); +make_prefix_table([_|T],Tab) -> + make_prefix_table(T,Tab). + +dump_prefixes(Out,L) -> + io:format(Out,"#define COMP_CANDIDATE_MAP_OFFSET 24~n",[]), + io:format(Out,"static Uint32 comp_candidate_map[] = {~n",[]), + dump_prefixes_1(Out,L). +dump_prefixes_1(Out,[H]) -> + io:format(Out," 0x~8.16.0BU~n",[H]), + io:format(Out,"};~n",[]); +dump_prefixes_1(Out,[H|T]) -> + io:format(Out," 0x~8.16.0BU,~n",[H]), + dump_prefixes_1(Out,T). + +%% make_big_prefixes([],Table) -> +%% Table; +%% make_big_prefixes([C|T],Table) -> +%% Index = (C div 32) + 1, +%% Pos = C rem 32, +%% X = element(Index,Table), +%% Y = X bor (1 bsl Pos), +%% NewTab = setelement(Index,Table,Y), +%% make_big_prefixes(T,NewTab). + +%% dump_big_prefixes(Out,L) -> +%% io:format(Out,"#define BIG_COMP_CANDIDATE_SIZE ~w~n", [?BIG_PREFIX_SIZE]), +%% io:format(Out,"static Uint32 big_comp_candidate_map[] = {~n",[]), +%% dump_prefixes_1(Out,L). + +pick([],_,Acc) -> + {lists:reverse(Acc),[]}; +pick([{[H|TT],N}|T],H,Acc) -> + pick(T,H,[{TT,N}|Acc]); +pick([{[H|_],_}|_]=L,M,Acc) when H =/= M -> + {lists:reverse(Acc),L}. + + +group([]) -> + []; +group([{[H],N}|T]) -> + {Part,Rest} = pick(T,H,[]), + [{H,group(Part),N}| group(Rest)]; +group([{[H|_],_}|_]=L) -> + {Part,Rest} = pick(L,H,[]), + [{H,group(Part),0}| group(Rest)]. + + + + + diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c new file mode 100644 index 0000000000..461e763f03 --- /dev/null +++ b/erts/emulator/sys/common/erl_sys_common_misc.c @@ -0,0 +1,107 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2006-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% + */ + + + +/* + * Darwin needs conversion! + * http://developer.apple.com/library/mac/#qa/qa2001/qa1235.html + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "sys.h" +#include "global.h" + +#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) +#define __DARWIN__ 1 +#endif + +#if !defined(__WIN32__) +#include <locale.h> +#if !defined(HAVE_SETLOCALE) || !defined(HAVE_NL_LANGINFO) || !defined(HAVE_LANGINFO_H) +#define PRIMITIVE_UTF8_CHECK 1 +#else +#include <langinfo.h> +#endif +#endif + +/* Written once and only once */ + +static int filename_encoding = ERL_FILENAME_UNKNOWN; +#if defined(__WIN32__) || defined(__DARWIN__) +static int user_filename_encoding = ERL_FILENAME_UTF8; /* Default unicode on windows */ +#else +static int user_filename_encoding = ERL_FILENAME_LATIN1; +#endif +void erts_set_user_requested_filename_encoding(int encoding) +{ + user_filename_encoding = encoding; +} + +int erts_get_user_requested_filename_encoding(void) +{ + return user_filename_encoding; +} + +void erts_init_sys_common_misc(void) +{ +#if defined(__WIN32__) + /* win_efile will totally fail if this is not set. */ + filename_encoding = ERL_FILENAME_WIN_WCHAR; +#else + if (user_filename_encoding != ERL_FILENAME_UNKNOWN) { + filename_encoding = user_filename_encoding; + } else { + char *l; + filename_encoding = ERL_FILENAME_LATIN1; +# ifdef PRIMITIVE_UTF8_CHECK + setlocale(LC_CTYPE, ""); /* Set international environment, + ignore result */ + if (((l = getenv("LC_ALL")) && *l) || + ((l = getenv("LC_CTYPE")) && *l) || + ((l = getenv("LANG")) && *l)) { + if (strstr(l, "UTF-8")) { + filename_encoding = ERL_FILENAME_UTF8; + } + } + +# else + l = setlocale(LC_CTYPE, ""); /* Set international environment */ + if (l != NULL) { + if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) { + filename_encoding = ERL_FILENAME_UTF8; + } + } +# endif + } +# if defined(__DARWIN__) + if (filename_encoding == ERL_FILENAME_UTF8) { + filename_encoding = ERL_FILENAME_UTF8_MAC; + } +# endif +#endif +} + +int erts_get_native_filename_encoding(void) +{ + return filename_encoding; +} diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index af4ab693dc..01ba773688 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -75,6 +75,7 @@ static erts_smp_rwmtx_t environ_rwmtx; #include "erl_sys_driver.h" #include "erl_check_io.h" +#include "erl_cpu_topology.h" #ifndef DISABLE_VFORK #define DISABLE_VFORK 0 @@ -399,7 +400,7 @@ typedef struct { #ifdef ERTS_THR_HAVE_SIG_FUNCS sigset_t saved_sigmask; #endif - int unbind_child; + int sched_bind_data; } erts_thr_create_data_t; /* @@ -410,15 +411,13 @@ static void * thr_create_prepare(void) { erts_thr_create_data_t *tcdp; - ErtsSchedulerData *esdp; tcdp = erts_alloc(ERTS_ALC_T_TMP, sizeof(erts_thr_create_data_t)); #ifdef ERTS_THR_HAVE_SIG_FUNCS erts_thr_sigmask(SIG_BLOCK, &thr_create_sigmask, &tcdp->saved_sigmask); #endif - esdp = erts_get_scheduler_data(); - tcdp->unbind_child = esdp && erts_is_scheduler_bound(esdp); + tcdp->sched_bind_data = erts_sched_bind_atthrcreate_prepare(); return (void *) tcdp; } @@ -430,6 +429,8 @@ thr_create_cleanup(void *vtcdp) { erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp; + erts_sched_bind_atthrcreate_parent(tcdp->sched_bind_data); + #ifdef ERTS_THR_HAVE_SIG_FUNCS /* Restore signalmask... */ erts_thr_sigmask(SIG_SETMASK, &tcdp->saved_sigmask, NULL); @@ -456,12 +457,7 @@ thr_create_prepare_child(void *vtcdp) erts_thread_disable_fpe(); #endif - if (tcdp->unbind_child) { - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); - erts_unbind_from_cpu(erts_cpuinfo); - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); - } - + erts_sched_bind_atthrcreate_child(tcdp->sched_bind_data); } #endif /* #ifdef USE_THREADS */ @@ -1461,9 +1457,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op CHLD_STAT_LOCK; - unbind = erts_is_scheduler_bound(NULL); - if (unbind) - erts_smp_rwmtx_rlock(&erts_cpu_bind_rwmtx); + unbind = erts_sched_bind_atfork_prepare(); #if !DISABLE_VFORK /* See fork/vfork discussion before this function. */ @@ -1476,7 +1470,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op if (pid == 0) { /* The child! Setup child... */ - if (unbind && erts_unbind_from_cpu(erts_cpuinfo) != 0) + if (erts_sched_bind_atfork_child(unbind) != 0) goto child_error; /* OBSERVE! @@ -1577,8 +1571,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op cs_argv[CS_ARGV_PROGNAME_IX] = child_setup_prog; cs_argv[CS_ARGV_WD_IX] = opts->wd ? opts->wd : "."; - cs_argv[CS_ARGV_UNBIND_IX] - = (unbind ? erts_get_unbind_from_cpu_str(erts_cpuinfo) : "false"); + cs_argv[CS_ARGV_UNBIND_IX] = erts_sched_bind_atvfork_child(unbind); cs_argv[CS_ARGV_FD_CR_IX] = fd_close_range; for (i = 0; i < CS_ARGV_NO_OF_DUP2_OPS; i++) cs_argv[CS_ARGV_DUP2_OP_IX(i)] = &dup2_op[i][0]; @@ -1627,8 +1620,7 @@ static ErlDrvData spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* op } #endif - if (unbind) - erts_smp_rwmtx_runlock(&erts_cpu_bind_rwmtx); + erts_sched_bind_atfork_parent(unbind); if (pid == -1) { saved_errno = errno; diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index 15d4cd7361..37041ed987 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -31,7 +31,7 @@ #include "global.h" #include "erl_threads.h" #include "../../drivers/win32/win_con.h" - +#include "erl_cpu_topology.h" void erts_sys_init_float(void); @@ -67,14 +67,17 @@ static void async_read_file(struct async_io* aio, LPVOID buf, DWORD numToRead); static int async_write_file(struct async_io* aio, LPVOID buf, DWORD numToWrite); static int get_overlapped_result(struct async_io* aio, LPDWORD pBytesRead, BOOL wait); -static BOOL CreateChildProcess(char *, HANDLE, HANDLE, +static BOOL create_child_process(char *, HANDLE, HANDLE, HANDLE, LPHANDLE, BOOL, LPVOID, LPTSTR, unsigned, char **, int *); static int create_pipe(LPHANDLE, LPHANDLE, BOOL, BOOL); -static int ApplicationType(const char* originalName, char fullPath[MAX_PATH], +static int application_type(const char* originalName, char fullPath[MAX_PATH], BOOL search_in_path, BOOL handle_quotes, int *error_return); +static int application_type_w(const char* originalName, WCHAR fullPath[MAX_PATH], + BOOL search_in_path, BOOL handle_quotes, + int *error_return); HANDLE erts_service_event; @@ -87,7 +90,7 @@ static erts_smp_atomic_t pipe_creation_counter; static erts_smp_mtx_t sys_driver_data_lock; -/* Results from ApplicationType is one of */ +/* Results from application_type(_w) is one of */ #define APPL_NONE 0 #define APPL_DOS 1 #define APPL_WIN3X 2 @@ -97,7 +100,7 @@ static int driver_write(long, HANDLE, byte*, int); static void common_stop(int); static int create_file_thread(struct async_io* aio, int mode); #ifdef ERTS_SMP -static void close_active_handles(ErlDrvPort, const HANDLE* handles, int cnt); +static void close_active_handle(ErlDrvPort, HANDLE handle); static DWORD WINAPI threaded_handle_closer(LPVOID param); #endif static DWORD WINAPI threaded_reader(LPVOID param); @@ -137,7 +140,11 @@ static BOOL win_console = FALSE; static OSVERSIONINFO int_os_version; /* Version information for Win32. */ -#ifdef ERTS_SMP +/*#define USE_CANCELIOEX + Disabled the use of CancelIoEx as its been seen to cause problem with some + drivers. Not sure what to blame; faulty drivers or some form of invalid use. +*/ +#if defined(ERTS_SMP) && defined(USE_CANCELIOEX) static BOOL (WINAPI *fpCancelIoEx)(HANDLE,LPOVERLAPPED); #endif @@ -684,6 +691,7 @@ release_driver_data(DriverData* dp) erts_smp_mtx_lock(&sys_driver_data_lock); #ifdef ERTS_SMP +#ifdef USE_CANCELIOEX if (fpCancelIoEx != NULL) { if (dp->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) { (*fpCancelIoEx)(dp->in.fd, NULL); @@ -692,10 +700,12 @@ release_driver_data(DriverData* dp) (*fpCancelIoEx)(dp->out.fd, NULL); } } - else { + else +#endif + { /* This is a workaround for the fact that CancelIo cant cancel requests issued by another thread and that we cant use - CancelIoEx as that's only availabele in Vista etc. + CancelIoEx as that's only available in Vista etc. R14: Avoid scheduler deadlock by only wait for 10ms, and then spawn a thread that will keep waiting in in order to close handles. */ HANDLE handles[2]; @@ -706,7 +716,7 @@ release_driver_data(DriverData* dp) dp->in.fd = INVALID_HANDLE_VALUE; DEBUGF(("Waiting for the in event thingie")); if (WaitForSingleObject(dp->in.ov.hEvent,timeout) == WAIT_TIMEOUT) { - handles[i++] = dp->in.ov.hEvent; + close_active_handle(dp->port_num, dp->in.ov.hEvent); dp->in.ov.hEvent = NULL; timeout = 0; } @@ -717,14 +727,11 @@ release_driver_data(DriverData* dp) dp->out.fd = INVALID_HANDLE_VALUE; DEBUGF(("Waiting for the out event thingie")); if (WaitForSingleObject(dp->out.ov.hEvent,timeout) == WAIT_TIMEOUT) { - handles[i++] = dp->out.ov.hEvent; + close_active_handle(dp->port_num, dp->out.ov.hEvent); dp->out.ov.hEvent = NULL; } DEBUGF(("...done\n")); } - if (i > 0) { - close_active_handles(dp->port_num, handles, i); - } } #else if (dp->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) { @@ -772,42 +779,82 @@ release_driver_data(DriverData* dp) #ifdef ERTS_SMP -struct handles_to_be_closed -{ - int cnt; - HANDLE handles[2]; +struct handles_to_be_closed { + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + unsigned cnt; }; +static struct handles_to_be_closed* htbc_curr = NULL; +CRITICAL_SECTION htbc_lock; -static void close_active_handles(ErlDrvPort port_num, const HANDLE* handles, int cnt) +static void close_active_handle(ErlDrvPort port_num, HANDLE handle) { - DWORD tid; - HANDLE thread; + struct handles_to_be_closed* htbc; int i; - struct handles_to_be_closed* htbc = erts_alloc(ERTS_ALC_T_DRV_TAB, - sizeof(struct handles_to_be_closed)); - htbc->cnt = cnt; - for (i=0; i < cnt; ++i) { - htbc->handles[i] = handles[i]; - (void) driver_select(port_num, (ErlDrvEvent)handles[i], - ERL_DRV_USE_NO_CALLBACK, 0); + EnterCriticalSection(&htbc_lock); + htbc = htbc_curr; + if (htbc == NULL || htbc->cnt >= MAXIMUM_WAIT_OBJECTS) { + DWORD tid; + HANDLE thread; + + htbc = (struct handles_to_be_closed*) erts_alloc(ERTS_ALC_T_DRV_TAB, + sizeof(*htbc)); + htbc->handles[0] = CreateAutoEvent(FALSE); + htbc->cnt = 1; + thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid); + CloseHandle(thread); } - thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid); - CloseHandle(thread); + htbc->handles[htbc->cnt++] = handle; + driver_select(port_num, (ErlDrvEvent)handle, ERL_DRV_USE_NO_CALLBACK, 0); + SetEvent(htbc->handles[0]); + htbc_curr = htbc; + LeaveCriticalSection(&htbc_lock); } - static DWORD WINAPI threaded_handle_closer(LPVOID param) { struct handles_to_be_closed* htbc = (struct handles_to_be_closed*) param; - int i; - DEBUGF(("threaded_handle_closer waiting for %d handles\r\n",htbc->cnt)); - WaitForMultipleObjects(htbc->cnt, htbc->handles, TRUE, INFINITE); - for (i=0; i < htbc->cnt; ++i) { - CloseHandle(htbc->handles[i]); + unsigned ix; + DWORD res; + DEBUGF(("threaded_handle_closer %p started\r\n", htbc)); + EnterCriticalSection(&htbc_lock); + for (;;) { + { + HANDLE* handles = htbc->handles; + unsigned cnt = htbc->cnt; + DWORD timeout = (htbc == htbc_curr) ? INFINITE : 10*1000; + + LeaveCriticalSection(&htbc_lock); + DEBUGF(("threaded_handle_closer %p waiting for %d handles\r\n", htbc, cnt)); + res = WaitForMultipleObjects(cnt, handles, FALSE, timeout); + } + EnterCriticalSection(&htbc_lock); + switch (res) { + case WAIT_OBJECT_0: + case WAIT_TIMEOUT: + break; /* got some more handles to wait for maybe */ + default: + ix = res - WAIT_OBJECT_0; + if (ix > 0 && ix < htbc->cnt) { + CloseHandle(htbc->handles[ix]); + htbc->handles[ix] = htbc->handles[--htbc->cnt]; + } + } + if (htbc != htbc_curr) { + if (htbc->cnt == 1) { /* no real handles left */ + break; + } + /* The thread with most free slots will be "current" */ + if (htbc->cnt < htbc_curr->cnt) { + htbc_curr = htbc; + DEBUGF(("threaded_handle_closer %p made current\r\n", htbc)); + } + } } + LeaveCriticalSection(&htbc_lock); + CloseHandle(htbc->handles[0]); erts_free(ERTS_ALC_T_DRV_TAB, htbc); - DEBUGF(("threaded_handle_closer terminating\r\n")); + DEBUGF(("threaded_handle_closer %p terminating\r\n", htbc)); return 0; } #endif /* ERTS_SMP */ @@ -1101,11 +1148,10 @@ static int spawn_init() { int i; -#ifdef ERTS_SMP +#if defined(ERTS_SMP) && defined(USE_CANCELIOEX) HMODULE module = GetModuleHandle("kernel32"); - fpCancelIoEx = (module != NULL) ? - (BOOL (WINAPI *)(HANDLE,LPOVERLAPPED)) - GetProcAddress(module,"CancelIoEx") : NULL; + fpCancelIoEx = (BOOL (WINAPI *)(HANDLE,LPOVERLAPPED)) + ((module != NULL) ? GetProcAddress(module,"CancelIoEx") : NULL); DEBUGF(("fpCancelIoEx = %p\r\n", fpCancelIoEx)); #endif driver_data = (struct driver_data *) @@ -1192,8 +1238,10 @@ spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* opts) */ DEBUGF(("Spawning \"%s\"\n", name)); - envir = win_build_environment(envir); - ok = CreateChildProcess(name, + envir = win_build_environment(envir); /* Still an ansi environment, could be + converted to unicode for spawn_executable, but + that is not done (yet) */ + ok = create_child_process(name, hChildStdin, hChildStdout, hChildStderr, @@ -1272,7 +1320,7 @@ create_file_thread(AsyncIo* aio, int mode) } /* - * A helper function used by CreateChildProcess(). + * A helper function used by create_child_process(). * Parses a command line with arguments and returns the length of the * first part containing the program name. * Example: input = "\"Program Files\"\\erl arg1 arg2" @@ -1313,24 +1361,25 @@ int parse_command(char* cmd){ return i; } -BOOL need_quotes(char *str) +static BOOL need_quotes(WCHAR *str) { int in_quote = 0; int backslashed = 0; int naked_space = 0; - while (*str != '\0') { + + while (*str != L'\0') { switch (*str) { - case '\\' : + case L'\\' : backslashed = !backslashed; break; - case '"': + case L'"': if (backslashed) { backslashed=0; } else { in_quote = !in_quote; } break; - case ' ': + case L' ': backslashed = 0; if (!(backslashed || in_quote)) { naked_space++; @@ -1349,7 +1398,7 @@ BOOL need_quotes(char *str) /* *---------------------------------------------------------------------- * - * CreateChildProcess -- + * create_child_process -- * * Create a child process that has pipes as its * standard input, output, and error. The child process runs @@ -1374,7 +1423,7 @@ BOOL need_quotes(char *str) */ static BOOL -CreateChildProcess +create_child_process ( char *origcmd, /* Command line for child process (including * name of executable). Or whole executable if st is @@ -1393,14 +1442,12 @@ CreateChildProcess ) { PROCESS_INFORMATION piProcInfo = {0}; - STARTUPINFO siStartInfo = {0}; BOOL ok = FALSE; int applType; /* Not to be changed for different types of executables */ int staticCreateFlags = GetPriorityClass(GetCurrentProcess()); int createFlags = DETACHED_PROCESS; char *newcmdline = NULL; - char execPath[MAX_PATH]; int cmdlength; char* thecommand; LPTSTR appname = NULL; @@ -1408,14 +1455,17 @@ CreateChildProcess *errno_return = -1; - siStartInfo.cb = sizeof(STARTUPINFO); - siStartInfo.dwFlags = STARTF_USESTDHANDLES; - siStartInfo.hStdInput = hStdin; - siStartInfo.hStdOutput = hStdout; - siStartInfo.hStdError = hStderr; - if (st != ERTS_SPAWN_EXECUTABLE) { + STARTUPINFO siStartInfo = {0}; + char execPath[MAX_PATH]; + + siStartInfo.cb = sizeof(STARTUPINFO); + siStartInfo.dwFlags = STARTF_USESTDHANDLES; + siStartInfo.hStdInput = hStdin; + siStartInfo.hStdOutput = hStdout; + siStartInfo.hStdError = hStderr; + /* * Parse out the program name from the command line (it can be quoted and * contain spaces). @@ -1427,9 +1477,9 @@ CreateChildProcess thecommand[cmdlength] = '\0'; DEBUGF(("spawn command: %s\n", thecommand)); - applType = ApplicationType(thecommand, execPath, TRUE, + applType = application_type(thecommand, execPath, TRUE, TRUE, errno_return); - DEBUGF(("ApplicationType returned for (%s) is %d\n", thecommand, applType)); + DEBUGF(("application_type returned for (%s) is %d\n", thecommand, applType)); erts_free(ERTS_ALC_T_TMP, (void *) thecommand); if (applType == APPL_NONE) { erts_free(ERTS_ALC_T_TMP,newcmdline); @@ -1458,126 +1508,147 @@ CreateChildProcess strcat(newcmdline, execPath); strcat(newcmdline, origcmd+cmdlength); - } else { /* ERTS_SPAWN_EXECUTABLE */ + DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags)); + ok = CreateProcessA(appname, + newcmdline, + NULL, + NULL, + TRUE, + createFlags | staticCreateFlags, + env, + wd, + &siStartInfo, + &piProcInfo); + + } else { /* ERTS_SPAWN_EXECUTABLE, filename and args are in unicode ({utf16,little}) */ int run_cmd = 0; - applType = ApplicationType(origcmd, execPath, FALSE, FALSE, - errno_return); + STARTUPINFOW siStartInfo = {0}; + WCHAR execPath[MAX_PATH]; + + + siStartInfo.cb = sizeof(STARTUPINFOW); + siStartInfo.dwFlags = STARTF_USESTDHANDLES; + siStartInfo.hStdInput = hStdin; + siStartInfo.hStdOutput = hStdout; + siStartInfo.hStdError = hStderr; + + applType = application_type_w(origcmd, (char *) execPath, FALSE, FALSE, + errno_return); if (applType == APPL_NONE) { return FALSE; } if (applType == APPL_DOS) { - /* - * See comment above - */ + /* + * See comment above + */ - siStartInfo.wShowWindow = SW_HIDE; - siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - createFlags = CREATE_NEW_CONSOLE; - run_cmd = 1; + siStartInfo.wShowWindow = SW_HIDE; + siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; + createFlags = CREATE_NEW_CONSOLE; + run_cmd = 1; } else if (hide) { - DEBUGF(("hiding window\n")); - siStartInfo.wShowWindow = SW_HIDE; - siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; - createFlags = 0; + DEBUGF(("hiding window\n")); + siStartInfo.wShowWindow = SW_HIDE; + siStartInfo.dwFlags |= STARTF_USESHOWWINDOW; + createFlags = 0; } if (run_cmd) { - char cmdPath[MAX_PATH]; + WCHAR cmdPath[MAX_PATH]; int cmdType; - cmdType = ApplicationType("cmd.exe", cmdPath, TRUE, FALSE, errno_return); + cmdType = application_type_w((char *) L"cmd.exe", (char *) cmdPath, TRUE, FALSE, errno_return); if (cmdType == APPL_NONE || cmdType == APPL_DOS) { return FALSE; } - appname = (char *) erts_alloc(ERTS_ALC_T_TMP, strlen(cmdPath)+1); - strcpy(appname,cmdPath); + appname = (char *) erts_alloc(ERTS_ALC_T_TMP, (wcslen(cmdPath)+1)*sizeof(WCHAR)); + wcscpy((WCHAR *) appname,cmdPath); } else { - appname = (char *) erts_alloc(ERTS_ALC_T_TMP, strlen(execPath)+1); - strcpy(appname,execPath); + appname = (char *) erts_alloc(ERTS_ALC_T_TMP, (wcslen(execPath)+1)*sizeof(WCHAR)); + wcscpy((WCHAR *) appname, execPath); } - if (argv == NULL) { + if (argv == NULL) { BOOL orig_need_q = need_quotes(execPath); - char *ptr; - int ocl = strlen(execPath); + WCHAR *ptr; + int ocl = wcslen(execPath); if (run_cmd) { newcmdline = (char *) erts_alloc(ERTS_ALC_T_TMP, - ocl + ((orig_need_q) ? 3 : 1) - + 11); - memcpy(newcmdline,"cmd.exe /c ",11); - ptr = newcmdline + 11; + (ocl + ((orig_need_q) ? 3 : 1) + + 11)*sizeof(WCHAR)); + memcpy(newcmdline,L"cmd.exe /c ",11*sizeof(WCHAR)); + ptr = (WCHAR *) (newcmdline + (11*sizeof(WCHAR))); } else { newcmdline = (char *) erts_alloc(ERTS_ALC_T_TMP, - ocl + ((orig_need_q) ? 3 : 1)); - ptr = newcmdline; + (ocl + ((orig_need_q) ? 3 : 1))*sizeof(WCHAR)); + ptr = (WCHAR *) newcmdline; } if (orig_need_q) { - *ptr++ = '"'; + *ptr++ = L'"'; } - memcpy(ptr,execPath,ocl); + memcpy(ptr,execPath,ocl*sizeof(WCHAR)); ptr += ocl; if (orig_need_q) { - *ptr++ = '"'; + *ptr++ = L'"'; } - *ptr = '\0'; + *ptr = L'\0'; } else { int sum = 1; /* '\0' */ - char **ar = argv; - char *n; + WCHAR **ar = (WCHAR **) argv; + WCHAR *n; char *save_arg0 = NULL; if (argv[0] == erts_default_arg0 || run_cmd) { save_arg0 = argv[0]; - argv[0] = execPath; + argv[0] = (char *) execPath; } if (run_cmd) { sum += 11; /* cmd.exe /c */ } while (*ar != NULL) { - sum += strlen(*ar); + sum += wcslen(*ar); if (need_quotes(*ar)) { sum += 2; /* quotes */ } sum++; /* space */ ++ar; } - ar = argv; - newcmdline = erts_alloc(ERTS_ALC_T_TMP, sum); - n = newcmdline; + ar = (WCHAR **) argv; + newcmdline = erts_alloc(ERTS_ALC_T_TMP, sum*sizeof(WCHAR)); + n = (WCHAR *) newcmdline; if (run_cmd) { - memcpy(n,"cmd.exe /c ",11); + memcpy(n,L"cmd.exe /c ",11*sizeof(WCHAR)); n += 11; } while (*ar != NULL) { int q = need_quotes(*ar); - sum = strlen(*ar); + sum = wcslen(*ar); if (q) { - *n++ = '"'; + *n++ = L'"'; } - memcpy(n,*ar,sum); + memcpy(n,*ar,sum*sizeof(WCHAR)); n += sum; if (q) { - *n++ = '"'; + *n++ = L'"'; } - *n++ = ' '; + *n++ = L' '; ++ar; } - ASSERT(n > newcmdline); - *(n-1) = '\0'; + *(n-1) = L'\0'; if (save_arg0 != NULL) { argv[0] = save_arg0; } } - } - DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags)); - ok = CreateProcess(appname, - newcmdline, - NULL, - NULL, - TRUE, - createFlags | staticCreateFlags, - env, - wd, - &siStartInfo, - &piProcInfo); - + DEBUGF(("Creating child process: %s, createFlags = %d\n", newcmdline, createFlags)); + ok = CreateProcessW((WCHAR *) appname, + (WCHAR *) newcmdline, + NULL, + NULL, + TRUE, + createFlags | staticCreateFlags, + env, + (WCHAR *) wd, + &siStartInfo, + &piProcInfo); + + } /* end SPAWN_EXECUTABLE */ if (newcmdline != NULL) { erts_free(ERTS_ALC_T_TMP,newcmdline); } @@ -1696,7 +1767,7 @@ static int create_pipe(HANDLE *phRead, HANDLE *phWrite, BOOL inheritRead, BOOL o -static int ApplicationType +static int application_type ( const char *originalName, /* Name of the application to find. */ char fullPath[MAX_PATH], /* Filled with complete path to @@ -1850,6 +1921,146 @@ static int ApplicationType return applType; } +static int application_type_w (const char *originalName, /* Name of the application to find. */ + WCHAR wfullpath[MAX_PATH],/* Filled with complete path to + * application. */ + BOOL search_in_path, /* If we should search the system wide path */ + BOOL handle_quotes, /* If we should handle quotes around executable */ + int *error_return) /* A place to put an error code */ +{ + int applType, i; + HANDLE hFile; + WCHAR *ext, *rest; + char buf[2]; + DWORD read; + IMAGE_DOS_HEADER header; + static WCHAR extensions[][5] = {L"", L".com", L".exe", L".bat"}; + int is_quoted; + int len; + WCHAR *wname = (WCHAR *) originalName; + WCHAR xfullpath[MAX_PATH]; + + len = wcslen(wname); + is_quoted = handle_quotes && len > 0 && wname[0] == L'"' && + wname[len-1] == L'"'; + + applType = APPL_NONE; + *error_return = ENOENT; + for (i = 0; i < (int) (sizeof(extensions) / sizeof(extensions[0])); i++) { + if(is_quoted) { + lstrcpynW(xfullpath, wname+1, MAX_PATH - 7); /* Cannot start using StringCchCopy yet, we support + older platforms */ + len = wcslen(xfullpath); + if(len > 0) { + xfullpath[len-1] = L'\0'; + } + } else { + lstrcpynW(xfullpath, wname, MAX_PATH - 5); + } + wcscat(xfullpath, extensions[i]); + /* It seems that the Unicode version does not allow in and out parameter to overlap. */ + SearchPathW((search_in_path) ? NULL : L".", xfullpath, NULL, MAX_PATH, wfullpath, &rest); + + /* + * Ignore matches on directories or data files, return if identified + * a known type. + */ + + if (GetFileAttributesW(wfullpath) & FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + + ext = wcsrchr(wfullpath, L'.'); + if ((ext != NULL) && (_wcsicmp(ext, L".bat") == 0)) { + *error_return = EACCES; + applType = APPL_DOS; + break; + } + + hFile = CreateFileW(wfullpath, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + continue; + } + + *error_return = EACCES; /* If considered an error, + it's an access error */ + header.e_magic = 0; + ReadFile(hFile, (void *) &header, sizeof(header), &read, NULL); + if (header.e_magic != IMAGE_DOS_SIGNATURE) { + /* + * Doesn't have the magic number for relocatable executables. If + * filename ends with .com, assume it's a DOS application anyhow. + * Note that we didn't make this assumption at first, because some + * supposed .com files are really 32-bit executables with all the + * magic numbers and everything. + */ + + CloseHandle(hFile); + if ((ext != NULL) && (_wcsicmp(ext, L".com") == 0)) { + applType = APPL_DOS; + break; + } + continue; + } + if (header.e_lfarlc != sizeof(header)) { + /* + * All Windows 3.X and Win32 and some DOS programs have this value + * set here. If it doesn't, assume that since it already had the + * other magic number it was a DOS application. + */ + + CloseHandle(hFile); + applType = APPL_DOS; + break; + } + + /* + * The DWORD at header.e_lfanew points to yet another magic number. + */ + + buf[0] = '\0'; + SetFilePointer(hFile, header.e_lfanew, NULL, FILE_BEGIN); + ReadFile(hFile, (void *) buf, 2, &read, NULL); + CloseHandle(hFile); + + if ((buf[0] == 'L') && (buf[1] == 'E')) { + applType = APPL_DOS; + } else if ((buf[0] == 'N') && (buf[1] == 'E')) { + applType = APPL_WIN3X; + } else if ((buf[0] == 'P') && (buf[1] == 'E')) { + applType = APPL_WIN32; + } else { + continue; + } + break; + } + + if (applType == APPL_NONE) { + return APPL_NONE; + } + + if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) { + /* + * Replace long path name of executable with short path name for + * 16-bit applications. Otherwise the application may not be able + * to correctly parse its own command line to separate off the + * application name from the arguments. + */ + + GetShortPathNameW(wfullpath, wfullpath, MAX_PATH); + } + if (is_quoted) { + /* restore quotes on quoted program name */ + len = wcslen(wfullpath); + memmove(wfullpath+1,wfullpath,len*sizeof(WCHAR)); + wfullpath[0]=L'"'; + wfullpath[len+1]=L'"'; + wfullpath[len+2]=L'\0'; + } + return applType; +} + /* * Thread function used to emulate overlapped reading. */ @@ -2973,13 +3184,50 @@ check_supported_os_version(void) } #ifdef USE_THREADS -#ifdef ERTS_ENABLE_LOCK_COUNT + +typedef struct { + int sched_bind_data; +} erts_thr_create_data_t; + +/* + * thr_create_prepare() is called in parent thread before thread creation. + * Returned value is passed as argument to thr_create_cleanup(). + */ +static void * +thr_create_prepare(void) +{ + erts_thr_create_data_t *tcdp; + + tcdp = erts_alloc(ERTS_ALC_T_TMP, sizeof(erts_thr_create_data_t)); + tcdp->sched_bind_data = erts_sched_bind_atthrcreate_prepare(); + + return (void *) tcdp; +} + + +/* thr_create_cleanup() is called in parent thread after thread creation. */ +static void +thr_create_cleanup(void *vtcdp) +{ + erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp; + + erts_sched_bind_atthrcreate_parent(tcdp->sched_bind_data); + + erts_free(ERTS_ALC_T_TMP, tcdp); +} + static void thr_create_prepare_child(void *vtcdp) { + erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp; + +#ifdef ERTS_ENABLE_LOCK_COUNT erts_lcnt_thread_setup(); -} #endif /* ERTS_ENABLE_LOCK_COUNT */ + + erts_sched_bind_atthrcreate_child(tcdp->sched_bind_data); +} + #endif /* USE_THREADS */ void @@ -2991,9 +3239,13 @@ erts_sys_pre_init(void) #ifdef USE_THREADS { erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER; -#ifdef ERTS_ENABLE_LOCK_COUNT + eid.thread_create_child_func = thr_create_prepare_child; -#endif + /* Before creation in parent */ + eid.thread_create_prepare_func = thr_create_prepare; + /* After creation in parent */ + eid.thread_create_parent_func = thr_create_cleanup, + erts_thr_init(&eid); #ifdef ERTS_ENABLE_LOCK_COUNT erts_lcnt_init(); @@ -3027,6 +3279,7 @@ void erl_sys_init(void) #ifdef ERTS_SMP erts_smp_tsd_key_create(&win32_errstr_key); + InitializeCriticalSection(&htbc_lock); #endif erts_smp_atomic_init(&pipe_creation_counter,0); /* diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 7c19274696..79252d0593 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -27,6 +27,7 @@ -export([all/1, ping/1, bulk_send/1, bulk_send_small/1, bulk_send_big/1, + bulk_send_bigbig/1, local_send/1, local_send_small/1, local_send_big/1, local_send_legal/1, link_to_busy/1, exit_to_busy/1, lost_exit/1, link_to_dead/1, link_to_dead_new_node/1, @@ -50,7 +51,8 @@ -export([sender/3, receiver2/2, dummy_waiter/0, dead_process/0, roundtrip/1, bounce/1, do_dist_auto_connect/1, inet_rpc_server/1, dist_parallel_sender/3, dist_parallel_receiver/0, - dist_evil_parallel_receiver/0]). + dist_evil_parallel_receiver/0, + sendersender/4, sendersender2/4]). all(suite) -> [ ping, bulk_send, local_send, link_to_busy, exit_to_busy, @@ -121,7 +123,7 @@ bulk_send(doc) -> "the time. This tests that a process that is suspended on a ", "busy port will eventually be resumed."]; bulk_send(suite) -> - [bulk_send_small, bulk_send_big]. + [bulk_send_small, bulk_send_big, bulk_send_bigbig]. bulk_send_small(Config) when is_list(Config) -> ?line bulk_send(64, 32). @@ -129,6 +131,9 @@ bulk_send_small(Config) when is_list(Config) -> bulk_send_big(Config) when is_list(Config) -> ?line bulk_send(32, 64). +bulk_send_bigbig(Config) when is_list(Config) -> + ?line bulk_sendsend(32*5, 4). + bulk_send(Terms, BinSize) -> ?line Dog = test_server:timetrap(test_server:seconds(30)), @@ -145,6 +150,53 @@ bulk_send(Terms, BinSize) -> ?line test_server:timetrap_cancel(Dog), {comment, integer_to_list(trunc(Size/1024/Elapsed+0.5)) ++ " K/s"}. +bulk_sendsend(Terms, BinSize) -> + {Rate1, MonitorCount1} = bulk_sendsend2(Terms, BinSize, 5), + {Rate2, MonitorCount2} = bulk_sendsend2(Terms, BinSize, 995), + Ratio = if MonitorCount2 == 0 -> MonitorCount1 / 1.0; + true -> MonitorCount1 / MonitorCount2 + end, + %% A somewhat arbitrary ratio, but hopefully one that will accomodate + %% a wide range of CPU speeds. + true = (Ratio > 8.0), + {comment, + integer_to_list(Rate1) ++ " K/s, " ++ + integer_to_list(Rate2) ++ " K/s, " ++ + integer_to_list(MonitorCount1) ++ " monitor msgs, " ++ + integer_to_list(MonitorCount2) ++ " monitor msgs, " ++ + float_to_list(Ratio) ++ " monitor ratio"}. + +bulk_sendsend2(Terms, BinSize, BusyBufSize) -> + ?line Dog = test_server:timetrap(test_server:seconds(30)), + + ?line io:format("Sending ~w binaries, each of size ~w K", + [Terms, BinSize]), + ?line {ok, NodeRecv} = start_node(bulk_receiver), + ?line Recv = spawn(NodeRecv, erlang, apply, [fun receiver/2, [0, 0]]), + ?line Bin = list_to_binary(lists:duplicate(BinSize*1024, 253)), + ?line Size = Terms*size(Bin), + + %% SLF LEFT OFF HERE. + %% When the caller uses small hunks, like 4k via + %% bulk_sendsend(32*5, 4), then (on my laptop at least), we get + %% zero monitor messages. But if we use "+zdbbl 5", then we + %% get a lot of monitor messages. So, if we can count up the + %% total number of monitor messages that we get when running both + %% default busy size and "+zdbbl 5", and if the 5 case gets + %% "many many more" monitor messages, then we know we're working. + + ?line {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)), + ?line _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]), + ?line {Elapsed, {TermsN, SizeN}, MonitorCount} = + receive {sendersender, BigRes} -> + BigRes + end, + ?line stop_node(NodeRecv), + ?line stop_node(NodeSend), + + ?line test_server:timetrap_cancel(Dog), + {trunc(SizeN/1024/Elapsed+0.5), MonitorCount}. + sender(To, _Bin, 0) -> To ! {done, self()}, receive @@ -155,6 +207,43 @@ sender(To, Bin, Left) -> To ! {term, Bin}, sender(To, Bin, Left-1). +%% Sender process to be run on a slave node + +sendersender(Parent, To, Bin, Left) -> + erlang:system_monitor(self(), [busy_dist_port]), + [spawn(fun() -> sendersender2(To, Bin, Left, false) end) || + _ <- lists:seq(1,1)], + {USec, {Res, MonitorCount}} = + timer:tc(?MODULE, sendersender2, [To, Bin, Left, true]), + Parent ! {sendersender, {USec/1000000, Res, MonitorCount}}. + +sendersender2(To, Bin, Left, SendDone) -> + sendersender3(To, Bin, Left, SendDone, 0). + +sendersender3(To, _Bin, 0, SendDone, MonitorCount) -> + if SendDone -> + To ! {done, self()}; + true -> + ok + end, + receive + {monitor, _Pid, _Type, _Info} = M -> + sendersender3(To, _Bin, 0, SendDone, MonitorCount + 1) + after 0 -> + if SendDone -> + receive + Any when is_tuple(Any), size(Any) == 2 -> + {Any, MonitorCount} + end; + true -> + exit(normal) + end + end; +sendersender3(To, Bin, Left, SendDone, MonitorCount) -> + To ! {term, Bin}, + %%timer:sleep(50), + sendersender3(To, Bin, Left-1, SendDone, MonitorCount). + %% Receiver process to be run on a slave node. receiver(Terms, Size) -> diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index f45cfa3e4a..42947aa6be 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -73,7 +73,7 @@ basic(Config) when is_list(Config) -> ?line true = (lib_version() =/= undefined), ?line [{load,1,1,101},{lib_version,1,2,102}] = call_history(), ?line [] = call_history(), - ?line [?MODULE] = erlang:system_info(taints), + ?line true = lists:member(?MODULE, erlang:system_info(taints)), ok. reload(doc) -> ["Test reload callback in nif lib"]; @@ -107,7 +107,8 @@ reload(Config) when is_list(Config) -> ?line true = erlang:purge_module(nif_mod), ?line [{unload,1,3,103}] = nif_mod_call_history(), - ?line [?MODULE, nif_mod] = erlang:system_info(taints), + ?line true = lists:member(?MODULE, erlang:system_info(taints)), + ?line true = lists:member(nif_mod, erlang:system_info(taints)), ?line verify_tmpmem(TmpMem), ok. @@ -197,7 +198,8 @@ upgrade(Config) when is_list(Config) -> ?line true = erlang:purge_module(nif_mod), ?line [{unload,2,4,204}] = nif_mod_call_history(), - ?line [?MODULE, nif_mod] = erlang:system_info(taints), + ?line true = lists:member(?MODULE, erlang:system_info(taints)), + ?line true = lists:member(nif_mod, erlang:system_info(taints)), ?line verify_tmpmem(TmpMem), ok. @@ -727,7 +729,8 @@ resource_takeover(Config) when is_list(Config) -> ?line ok = forget_resource(AN4), ?line [] = nif_mod_call_history(), - ?line [?MODULE, nif_mod] = erlang:system_info(taints), + ?line true = lists:member(?MODULE, erlang:system_info(taints)), + ?line true = lists:member(nif_mod, erlang:system_info(taints)), ?line verify_tmpmem(TmpMem), ok. diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl index a7476ca9bb..7fe532abd0 100644 --- a/erts/emulator/test/port_SUITE.erl +++ b/erts/emulator/test/port_SUITE.erl @@ -2302,14 +2302,35 @@ load_driver(Dir, Driver) -> end. -close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port."]; +close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port." + "Primary targeting Windows to test threaded_handle_closer in sys.c"]; close_deaf_port(suite) -> []; close_deaf_port(Config) when is_list(Config) -> ?line Dog = test_server:timetrap(test_server:seconds(100)), ?line DataDir = ?config(data_dir, Config), ?line DeadPort = os:find_executable("dead_port", DataDir), - ?line Port = open_port({spawn,DeadPort++" 60"},[]), ?line erlang:port_command(Port,"Hello, can you hear me!?!?"), ?line port_close(Port), - ok. + + Res = close_deaf_port_1(0, DeadPort), + io:format("Waiting for OS procs to terminate...\n"), + receive after 5*1000 -> ok end, + ?line test_server:timetrap_cancel(Dog), + Res. + +close_deaf_port_1(1000, _) -> + ok; +close_deaf_port_1(N, Cmd) -> + Timeout = integer_to_list(random:uniform(5*1000)), + ?line try open_port({spawn_executable,Cmd},[{args,[Timeout]}]) of + Port -> + ?line erlang:port_command(Port,"Hello, can you hear me!?!?"), + ?line port_close(Port), + close_deaf_port_1(N+1, Cmd) + catch + _:eagain -> + {comment, "Could not spawn more than " ++ integer_to_list(N) ++ " OS processes."} + end. + + diff --git a/erts/emulator/test/port_SUITE_data/dead_port.c b/erts/emulator/test/port_SUITE_data/dead_port.c index 6fa77112be..68e96fbf14 100644 --- a/erts/emulator/test/port_SUITE_data/dead_port.c +++ b/erts/emulator/test/port_SUITE_data/dead_port.c @@ -72,14 +72,14 @@ char *argv[]; { int x; if (argc < 2) { - fprintf(stderr,"Usage %s <seconds>\n",argv[0]); + fprintf(stderr,"Usage %s <milliseconds>\n",argv[0]); return 1; } if ((x = atoi(argv[1])) <= 0) { - fprintf(stderr,"Usage %s <seconds>\n",argv[0]); + fprintf(stderr,"Usage %s <milliseconds>\n",argv[0]); return 1; } - delay(x*1000); + delay(x); return 0; } diff --git a/erts/emulator/test/send_term_SUITE.erl b/erts/emulator/test/send_term_SUITE.erl index 5fd01a9ac5..819aa34886 100644 --- a/erts/emulator/test/send_term_SUITE.erl +++ b/erts/emulator/test/send_term_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. +%% Copyright Ericsson AB 2005-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 @@ -61,7 +61,7 @@ basic(Config) when is_list(Config) -> ?line ExpectExt2Term = term(P, 5), %% ERL_DRV_INT, ERL_DRV_UINT - ?line case erlang:system_info(wordsize) of + ?line case erlang:system_info({wordsize, external}) of 4 -> ?line {-1, 4294967295} = term(P, 6); 8 -> diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index ba433d4e11..cd940f3ddf 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -132,6 +132,7 @@ misc_smoke_tests(Config) when is_list(Config) -> ?line true = is_binary(erlang:system_info(procs)), ?line true = is_binary(erlang:system_info(loaded)), ?line true = is_binary(erlang:system_info(dist)), + ?line ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end, ?line ok. diff --git a/erts/emulator/zlib/zutil.h b/erts/emulator/zlib/zutil.h index d560382691..a8872e1c88 100644 --- a/erts/emulator/zlib/zutil.h +++ b/erts/emulator/zlib/zutil.h @@ -142,6 +142,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b +# define F_OPEN(name, mode) _wfopen((WCHAR *)(name), (WCHAR *)(mode)) /* Unicode */ # endif #endif diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index df4d1a5715..ef471a473a 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -39,8 +39,10 @@ * server keeps the socket open where the request for registration was * made. * - * The protocol is briefly documented in "erl_ext_dist.txt". All requests - * to this server are done with a packet + * The protocol is briefly documented in the ERTS User's Guide, see + * http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html + * + * All requests to this server are done with a packet * * 2 n * +--------+---------+ diff --git a/erts/etc/common/Makefile.in b/erts/etc/common/Makefile.in index 96655662b8..4754328c0b 100644 --- a/erts/etc/common/Makefile.in +++ b/erts/etc/common/Makefile.in @@ -178,7 +178,7 @@ MC_OUTPUTS= \ MT_FLAG="-MD" endif INET_GETHOST = $(BINDIR)/inet_gethost.exe -INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer.exe $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/run_test.exe +INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer.exe $(BINDIR)/dialyzer.exe $(BINDIR)/erlc.exe $(BINDIR)/start_erl.exe $(BINDIR)/escript.exe $(BINDIR)/ct_run.exe INSTALL_SRC = $(WINETC)/start_erl.c $(WINETC)/Nmakefile.start_erl ERLEXECDIR=. INSTALL_LIBS = @@ -211,7 +211,7 @@ ERLSRV_OBJECTS= MC_OUTPUTS= INET_GETHOST = $(BINDIR)/inet_gethost@EXEEXT@ INSTALL_EMBEDDED_PROGS += $(BINDIR)/typer@EXEEXT@ $(BINDIR)/dialyzer@EXEEXT@ \ - $(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/run_test@EXEEXT@ \ + $(BINDIR)/erlc@EXEEXT@ $(BINDIR)/escript@EXEEXT@ $(BINDIR)/ct_run@EXEEXT@ \ $(BINDIR)/run_erl $(BINDIR)/to_erl $(BINDIR)/dyn_erl INSTALL_EMBEDDED_DATA = ../unix/start.src ../unix/start_erl.src INSTALL_TOP = Install @@ -274,7 +274,7 @@ endif rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/dyn_erl.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/safe_string.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/typer.o - rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/run_test.o + rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/ct_run.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/vxcall.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/erl.o rm -f $(ERL_TOP)/erts/obj*/$(TARGET)/werl.o @@ -327,34 +327,34 @@ $(OBJDIR)/$(ERLEXEC).o: $(ERLEXECDIR)/$(ERLEXEC).c $(CC) -I$(EMUDIR) $(CFLAGS) -o $@ -c $(ERLEXECDIR)/$(ERLEXEC).c endif $(BINDIR)/erlc@EXEEXT@: $(OBJDIR)/erlc.o - $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS) + $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/erlc.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) $(OBJDIR)/erlc.o: erlc.c $(CC) $(CFLAGS) -o $@ -c erlc.c $(BINDIR)/dialyzer@EXEEXT@: $(OBJDIR)/dialyzer.o - $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/dialyzer.o -L$(OBJDIR) $(LIBS) + $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/dialyzer.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) $(OBJDIR)/dialyzer.o: dialyzer.c $(CC) $(CFLAGS) -o $@ -c dialyzer.c $(BINDIR)/typer@EXEEXT@: $(OBJDIR)/typer.o - $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/typer.o -L$(OBJDIR) $(LIBS) + $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/typer.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) $(OBJDIR)/typer.o: typer.c $(CC) $(CFLAGS) -o $@ -c typer.c $(BINDIR)/escript@EXEEXT@: $(OBJDIR)/escript.o - $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/escript.o -L$(OBJDIR) $(LIBS) + $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/escript.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) $(OBJDIR)/escript.o: escript.c $(CC) $(CFLAGS) -o $@ -c escript.c -$(BINDIR)/run_test@EXEEXT@: $(OBJDIR)/run_test.o - $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/run_test.o -L$(OBJDIR) $(LIBS) +$(BINDIR)/ct_run@EXEEXT@: $(OBJDIR)/ct_run.o + $(PURIFY) $(LD) $(LDFLAGS) -o $@ $(OBJDIR)/ct_run.o -L$(OBJDIR) $(LIBS) $(ERTS_INTERNAL_LIBS) -$(OBJDIR)/run_test.o: run_test.c - $(CC) $(CFLAGS) -o $@ -c run_test.c +$(OBJDIR)/ct_run.o: ct_run.c + $(CC) $(CFLAGS) -o $@ -c ct_run.c #------------------------------------------------------------------------ diff --git a/erts/etc/common/run_test.c b/erts/etc/common/ct_run.c index 016d9c6afd..7aaab716f7 100644 --- a/erts/etc/common/run_test.c +++ b/erts/etc/common/ct_run.c @@ -85,6 +85,7 @@ static char* strsave(char* string); static void push_words(char* src); static int run_erlang(char* name, char** argv); static char* get_default_emulator(char* progname); +static void print_deprecation_warning(char *progname); #ifdef __WIN32__ static char* possibly_quote(char* arg); #endif @@ -131,6 +132,8 @@ main(int argc, char** argv) int erl_args; char** argv0 = argv; + print_deprecation_warning(argv[0]); + emulator = get_default_emulator(argv[0]); /* @@ -164,11 +167,13 @@ main(int argc, char** argv) erl_args = cnt; } else if (strcmp(argv[1], "-sname") == 0) { - strcpy(nodename, argv[2]); + strncpy(nodename, argv[2], sizeof(nodename)); + nodename[sizeof(nodename)-1] = '\0'; cnt++, argv++; } else if (strcmp(argv[1], "-name") == 0) { - strcpy(nodename, argv[2]); + strncpy(nodename, argv[2], sizeof(nodename)); + nodename[sizeof(nodename)-1] = '\0'; dist_mode = FULL_NAME; cnt++, argv++; } @@ -178,7 +183,8 @@ main(int argc, char** argv) ct_mode = VTS_MODE; } else if (strcmp(argv[1], "-browser") == 0) { - strcpy(browser, argv[2]); + strncpy(browser, argv[2], sizeof(browser)); + browser[sizeof(browser)-1] = '\0'; cnt++, argv++; } else if (strcmp(argv[1], "-shell") == 0) { @@ -189,7 +195,8 @@ main(int argc, char** argv) ct_mode = MASTER_MODE; } else if (strcmp(argv[1], "-ctname") == 0) { - strcpy(nodename, argv[2]); + strncpy(nodename, argv[2], sizeof(nodename)); + nodename[sizeof(nodename)-1] = '\0'; ct_mode = ERL_SHELL_MODE; cnt++, argv++; } @@ -273,7 +280,7 @@ main(int argc, char** argv) static void push_words(char* src) { - char sbuf[1024]; + char sbuf[MAXPATHLEN]; char* dst; dst = sbuf; @@ -387,7 +394,7 @@ run_erlang(char* progname, char** argv) status = my_spawnvp(argv)/*_spawnvp(_P_WAIT,progname,argv)*/; if (status == -1) { - fprintf(stderr, "run_test: Error executing '%s': %d", progname, + fprintf(stderr, "ct_run: Error executing '%s': %d", progname, GetLastError()); } return status; @@ -405,9 +412,9 @@ error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); - fprintf(stderr, "run_test: %s\n", sbuf); + fprintf(stderr, "ct_run: %s\n", sbuf); exit(1); } @@ -428,12 +435,36 @@ strsave(char* string) return p; } +/* Instead of making sure basename exists, we do our own */ +static char *simple_basename(char *path) +{ + char *ptr; + for (ptr = path; *ptr != '\0'; ++ptr) { + if (*ptr == '/' || *ptr == '\\') { + path = ptr + 1; + } + } + return path; +} + +static void print_deprecation_warning(char* progpath) +{ + char *basename = simple_basename(progpath); + if(strcmp(basename,"run_test") == 0 || + strcmp(basename, "run_test.exe") == 0) { + printf("---***---\nDeprecated: run_test is deprecated and will be removed in R16B,\n please use ct_run instead\n---***---\n"); + } +} + static char* get_default_emulator(char* progname) { char sbuf[MAXPATHLEN]; char* s; + if (strlen(progname) >= sizeof(sbuf)) + return ERL_NAME; + strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { diff --git a/erts/etc/common/dialyzer.c b/erts/etc/common/dialyzer.c index 4b4c1124f1..4453e63f1c 100644 --- a/erts/etc/common/dialyzer.c +++ b/erts/etc/common/dialyzer.c @@ -147,6 +147,9 @@ main(int argc, char** argv) env = get_env("DIALYZER_EMULATOR"); emulator = env ? env : get_default_emulator(argv[0]); + if (strlen(emulator) >= MAXPATHLEN) + error("Value of environment variable DIALYZER_EMULATOR is too large"); + /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of @@ -228,7 +231,7 @@ main(int argc, char** argv) static void push_words(char* src) { - char sbuf[1024]; + char sbuf[MAXPATHLEN]; char* dst; dst = sbuf; @@ -360,7 +363,7 @@ error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); fprintf(stderr, "dialyzer: %s\n", sbuf); exit(1); @@ -389,6 +392,9 @@ get_default_emulator(char* progname) char sbuf[MAXPATHLEN]; char* s; + if (strlen(progname) >= sizeof(sbuf)) + return ERL_NAME; + strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c index 09aca19e6c..cd137435d1 100644 --- a/erts/etc/common/erlc.c +++ b/erts/etc/common/erlc.c @@ -148,10 +148,6 @@ int main(int argc, char** argv) { char cwd[MAXPATHLEN]; /* Current working directory. */ - char** rpc_eargv; /* Pointer to the beginning of arguments - * if calling a running Erlang system - * via erl_rpc(). - */ int eargv_size; int eargc_base; /* How many arguments in the base of eargv. */ char* emulator; @@ -160,6 +156,9 @@ main(int argc, char** argv) env = get_env("ERLC_EMULATOR"); emulator = env ? env : get_default_emulator(argv[0]); + if (strlen(emulator) >= MAXPATHLEN) + error("Value of environment variable ERLC_EMULATOR is too large"); + /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of @@ -170,7 +169,7 @@ main(int argc, char** argv) * base of the eargv vector, and move it up later. */ - eargv_size = argc*4+100; + eargv_size = argc*6+100; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; @@ -189,7 +188,6 @@ main(int argc, char** argv) PUSH2("-mode", "minimal"); PUSH2("-boot", "start_clean"); PUSH3("-s", "erl_compile", "compile_cmdline"); - rpc_eargv = eargv+eargc; /* * Push standard arguments to Erlang. @@ -419,7 +417,7 @@ process_opt(int* pArgc, char*** pArgv, int offset) static void push_words(char* src) { - char sbuf[1024]; + char sbuf[MAXPATHLEN]; char* dst; dst = sbuf; @@ -595,7 +593,7 @@ error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); fprintf(stderr, "erlc: %s\n", sbuf); exit(1); @@ -624,6 +622,9 @@ get_default_emulator(char* progname) char sbuf[MAXPATHLEN]; char* s; + if (strlen(progname) >= sizeof(sbuf)) + return ERL_NAME; + strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index c1fc2aebee..60b3af7db7 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -138,6 +138,12 @@ static char *plusr_val_switches[] = { NULL }; +/* +z arguments with values */ +static char *plusz_val_switches[] = { + "dbbl", + NULL +}; + /* * Define sleep(seconds) in terms of Sleep() on Windows. @@ -309,7 +315,7 @@ free_env_val(char *value) } /* - * Add the arcitecture suffix to the program name if needed, + * Add the architecture suffix to the program name if needed, * except on Windows, where we insert it just before ".DLL". */ static char* @@ -560,7 +566,7 @@ int main(int argc, char **argv) usage("+MYm"); } emu = add_extra_suffixes(emu, emu_type); - sprintf(tmpStr, "%s" DIRSEP "%s" BINARY_EXT, bindir, emu); + erts_snprintf(tmpStr, sizeof(tmpStr), "%s" DIRSEP "%s" BINARY_EXT, bindir, emu); emu = strsave(tmpStr); add_Eargs(emu); /* Will be argv[0] -- necessary! */ @@ -571,12 +577,12 @@ int main(int argc, char **argv) s = get_env("PATH"); if (!s) { - sprintf(tmpStr, "%s" PATHSEP "%s" DIRSEP "bin", bindir, rootdir); + erts_snprintf(tmpStr, sizeof(tmpStr), "%s" PATHSEP "%s" DIRSEP "bin", bindir, rootdir); } else if (strstr(s, bindir) == NULL) { - sprintf(tmpStr, "%s" PATHSEP "%s" DIRSEP "bin" PATHSEP "%s", bindir, + erts_snprintf(tmpStr, sizeof(tmpStr), "%s" PATHSEP "%s" DIRSEP "bin" PATHSEP "%s", bindir, rootdir, s); } else { - sprintf(tmpStr, "%s", s); + erts_snprintf(tmpStr, sizeof(tmpStr), "%s", s); } free_env_val(s); set_env("PATH", tmpStr); @@ -714,7 +720,7 @@ int main(int argc, char **argv) error("-man not supported on Windows"); #else argv[i] = "man"; - sprintf(tmpStr, "%s/man", rootdir); + erts_snprintf(tmpStr, sizeof(tmpStr), "%s/man", rootdir); set_env("MANPATH", tmpStr); execvp("man", argv+i); error("Could not execute the 'man' command."); @@ -909,6 +915,20 @@ int main(int argc, char **argv) i++; } break; + case 'z': + if (!is_one_of_strings(&argv[i][2], plusz_val_switches)) { + goto the_default; + } else { + if (i+1 >= argc + || argv[i+1][0] == '-' + || argv[i+1][0] == '+') + usage(argv[i]); + argv[i][0] = '-'; + add_Eargs(argv[i]); + add_Eargs(argv[i+1]); + i++; + } + break; default: the_default: argv[i][0] = '-'; /* Change +option to -option. */ @@ -1096,7 +1116,7 @@ usage_aux(void) "[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+R COMPAT_REL] " "[+r] [+rg READER_GROUPS_LIMIT] [+s SCHEDULER_OPTION] " "[+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] " - "[+W<i|w>] [args ...]\n"); + "[+W<i|w>] [+z MISC_OPTION] [args ...]\n"); exit(1); } @@ -1145,10 +1165,10 @@ start_epmd(char *epmd) if (!epmd) { epmd = epmd_cmd; #ifdef __WIN32__ - sprintf(epmd_cmd, "%s" DIRSEP "epmd", bindir); + erts_snprintf(epmd_cmd, sizeof(epmd_cmd), "%s" DIRSEP "epmd", bindir); arg1 = "-daemon"; #else - sprintf(epmd_cmd, "%s" DIRSEP "epmd -daemon", bindir); + erts_snprintf(epmd_cmd, sizeof(epmd_cmd), "%s" DIRSEP "epmd -daemon", bindir); #endif } #ifdef __WIN32__ @@ -1224,7 +1244,7 @@ void error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); fprintf(stderr, "erlexec: %s\n", sbuf); exit(1); @@ -1304,14 +1324,14 @@ static void get_start_erl_data(char *file) if (env) reldir = strsave(env); else { - sprintf(tmpbuffer, "%s/releases", rootdir); + erts_snprintf(tmpbuffer, sizeof(tmpbuffer), "%s/releases", rootdir); reldir = strsave(tmpbuffer); } free_env_val(env); if (file == NULL) - sprintf(start_erl_data, "%s/start_erl.data", reldir); + erts_snprintf(start_erl_data, sizeof(start_erl_data), "%s/start_erl.data", reldir); else - sprintf(start_erl_data, "%s", file); + erts_snprintf(start_erl_data, sizeof(start_erl_data), "%s", file); fp = _open(start_erl_data, _O_RDONLY ); if( fp == -1 ) error( "open failed on %s",start_erl_data ); @@ -1341,16 +1361,16 @@ static void get_start_erl_data(char *file) } bindir = emalloc(512); - sprintf(bindir,"%s/erts-%s/bin",rootdir,tmpbuffer); + erts_snprintf(bindir,512,"%s/erts-%s/bin",rootdir,tmpbuffer); /* BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin */ tprogname = progname; progname = emalloc(strlen(tprogname) + 20); - sprintf(progname,"%s -start_erl",tprogname); + erts_snprintf(progname,strlen(tprogname) + 20,"%s -start_erl",tprogname); boot_script = emalloc(512); config_script = emalloc(512); - sprintf(boot_script, "%s/%s/start", reldir, otpstring); - sprintf(config_script, "%s/%s/sys", reldir, otpstring); + erts_snprintf(boot_script, 512, "%s/%s/start", reldir, otpstring); + erts_snprintf(config_script, 512, "%s/%s/sys", reldir, otpstring); } @@ -1358,7 +1378,7 @@ static void get_start_erl_data(char *file) static char *replace_filename(char *path, char *new_base) { int plen = strlen(path); - char *res = malloc((plen+strlen(new_base)+1)*sizeof(char)); + char *res = emalloc((plen+strlen(new_base)+1)*sizeof(char)); char *p; strcpy(res,path); @@ -1373,7 +1393,7 @@ static char *path_massage(char *long_path) { char *p; - p = malloc(MAX_PATH+1); + p = emalloc(MAX_PATH+1); strcpy(p, long_path); GetShortPathName(p, p, MAX_PATH); return p; @@ -1509,7 +1529,8 @@ get_parameters(int argc, char** argv) /* Determine bindir from absolute path to executable */ char *p; char buffer[PATH_MAX]; - strcpy(buffer, argv[0]); + strncpy(buffer, argv[0], sizeof(buffer)); + buffer[sizeof(buffer)-1] = '\0'; for (p = buffer+strlen(buffer)-1 ; p >= buffer && *p != '/'; --p) ; @@ -1522,7 +1543,8 @@ get_parameters(int argc, char** argv) /* Determine rootdir from absolute path to bindir */ char *p; char buffer[PATH_MAX]; - strcpy(buffer, bindir); + strncpy(buffer, bindir, sizeof(buffer)); + buffer[sizeof(buffer)-1] = '\0'; for (p = buffer+strlen(buffer)-1; p >= buffer && *p != '/'; --p) ; diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c index 1bc5eb7651..6ed79c91e3 100644 --- a/erts/etc/common/escript.c +++ b/erts/etc/common/escript.c @@ -151,6 +151,9 @@ find_prog(char *origpath) char relpath[PMAX]; char abspath[PMAX]; + if (strlen(origpath) >= sizeof(relpath)) + error("Path too long"); + strcpy(relpath, origpath); if (strstr(relpath, DIRSEPSTR) == NULL) { @@ -180,19 +183,21 @@ find_prog(char *origpath) end = strstr(beg, PATHSEPSTR); if (end != NULL) { sz = end - beg; - strncpy(dir, beg, sz); - dir[sz] = '\0'; } else { sz = strlen(beg); - strcpy(dir, beg); look_for_sep = FALSE; } + if (sz >= sizeof(dir)) { + beg = end + 1; + continue; + } + strncpy(dir, beg, sz); + dir[sz] = '\0'; beg = end + 1; #ifdef __WIN32__ - strcpy(wildcard, dir); - strcat(wildcard, DIRSEPSTR); - strcat(wildcard, relpath); /* basename */ + erts_snprintf(wildcard, sizeof(wildcard), "%s" DIRSEPSTR "%s", + dir, relpath /* basename */); dir_handle = FindFirstFile(wildcard, &find_data); if (dir_handle == INVALID_HANDLE_VALUE) { /* Try next directory in path */ @@ -217,9 +222,8 @@ find_prog(char *origpath) if (strcmp(origpath, dirp->d_name) == 0) { /* Wow we found the executable. */ - strcpy(relpath, dir); - strcat(relpath, DIRSEPSTR); - strcat(relpath, dirp->d_name); + erts_snprintf(relpath, sizeof(relpath), "%s" DIRSEPSTR "%s", + dir, dirp->d_name); closedir(dp); look_for_sep = FALSE; break; @@ -291,7 +295,7 @@ append_shebang_args(char* scriptname) /* Find end of arg */ end = beg; - while (end && end[0] != ' ') { + while (end && end < (linebuf+LINEBUFSZ-1) && end[0] != ' ') { if (end[0] == '\n') { newline = TRUE; end[0]= '\0'; @@ -335,13 +339,16 @@ main(int argc, char** argv) emulator = get_default_emulator(argv[0]); } + if (strlen(emulator) >= PMAX) + error("Value of environment variable ESCRIPT_EMULATOR is too large"); + /* * Allocate the argv vector to be used for arguments to Erlang. * Arrange for starting to pushing information in the middle of * the array, to allow easy addition of commands in the beginning. */ - eargv_size = argc*4+1000; + eargv_size = argc*4+1000+LINEBUFSZ/2; eargv_base = (char **) emalloc(eargv_size*sizeof(char*)); eargv = eargv_base; eargc = 0; @@ -387,7 +394,8 @@ main(int argc, char** argv) if (argc <= 1) { error("Missing filename\n"); } - strcpy(scriptname, argv[1]); + strncpy(scriptname, argv[1], sizeof(scriptname)); + scriptname[sizeof(scriptname)-1] = '\0'; argc--; argv++; } else { @@ -395,16 +403,17 @@ main(int argc, char** argv) int len; #endif absname = find_prog(argv[0]); - strcpy(scriptname, absname); - efree(absname); #ifdef __WIN32__ - len = strlen(scriptname); - if (len >= 4 && _stricmp(scriptname+len-4, ".exe") == 0) { - scriptname[len-4] = '\0'; + len = strlen(absname); + if (len >= 4 && _stricmp(absname+len-4, ".exe") == 0) { + absname[len-4] = '\0'; } #endif - strcat(scriptname, ".escript"); + erts_snprintf(scriptname, sizeof(scriptname), "%s.escript", + absname); + efree(absname); + } /* @@ -455,7 +464,7 @@ main(int argc, char** argv) static void push_words(char* src) { - char sbuf[1024]; + char sbuf[PMAX]; char* dst; dst = sbuf; @@ -584,7 +593,7 @@ error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); fprintf(stderr, "escript: %s\n", sbuf); exit(1); @@ -619,6 +628,9 @@ get_default_emulator(char* progname) char sbuf[MAXPATHLEN]; char* s; + if (strlen(progname) >= sizeof(sbuf)) + return ERL_NAME; + strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c index 4f738947b7..3e19e5f386 100644 --- a/erts/etc/common/heart.c +++ b/erts/etc/common/heart.c @@ -375,7 +375,8 @@ main(int argc, char **argv) _setmode(erlin_fd,_O_BINARY); _setmode(erlout_fd,_O_BINARY); #endif - strcpy(program_name, argv[0]); + strncpy(program_name, argv[0], sizeof(program_name)); + program_name[sizeof(program_name)-1] = '\0'; notify_ack(erlout_fd); cmd[0] = '\0'; do_terminate(message_loop(erlin_fd,erlout_fd)); @@ -728,7 +729,11 @@ heart_cmd_reply(int fd, char *s) struct msg m; int len = strlen(s) + 1; /* Include \0 */ - /* FIXME if s >= MSG_BODY_SIZE error */ + /* if s >= MSG_BODY_SIZE, return a write + * failure immediately. + */ + if (len > sizeof(m.fill)) + return -1; m.op = HEART_CMD; m.len = htons(len + 2); /* Include Op */ diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c index d3ff4874ac..8bd9368aa1 100644 --- a/erts/etc/common/inet_gethost.c +++ b/erts/etc/common/inet_gethost.c @@ -59,15 +59,14 @@ #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <windows.h> +#include <ws2tcpip.h> #include <process.h> #include <stdio.h> #include <stdlib.h> /* These are not used even if they would exist which they should not */ -#undef HAVE_GETADDRINFO #undef HAVE_GETIPNODEBYNAME #undef HAVE_GETHOSTBYNAME2 -#undef HAVE_GETNAMEINFO #undef HAVE_GETIPNODEBYADDR #else /* Unix */ @@ -1761,7 +1760,7 @@ static int worker_loop(void) struct addrinfo hints; memset(&hints, 0, sizeof(hints)); - hints.ai_flags = (AI_CANONNAME|AI_V4MAPPED|AI_ADDRCONFIG); + hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_INET6; DEBUGF(5, ("Starting getaddrinfo(%s, ...)", data)); diff --git a/erts/etc/common/typer.c b/erts/etc/common/typer.c index c2567cb8b4..de48daf002 100644 --- a/erts/etc/common/typer.c +++ b/erts/etc/common/typer.c @@ -175,7 +175,7 @@ main(int argc, char** argv) static void push_words(char* src) { - char sbuf[1024]; + char sbuf[MAXPATHLEN]; char* dst; dst = sbuf; @@ -307,7 +307,7 @@ error(char* format, ...) va_list ap; va_start(ap, format); - vsprintf(sbuf, format, ap); + erts_vsnprintf(sbuf, sizeof(sbuf), format, ap); va_end(ap); fprintf(stderr, "typer: %s\n", sbuf); exit(1); @@ -336,6 +336,9 @@ get_default_emulator(char* progname) char sbuf[MAXPATHLEN]; char* s; + if (strlen(progname) >= sizeof(sbuf)) + return ERL_NAME; + strcpy(sbuf, progname); for (s = sbuf+strlen(sbuf); s >= sbuf; s--) { if (IS_DIRSEP(*s)) { diff --git a/erts/etc/unix/Install.src b/erts/etc/unix/Install.src index 7dead62ab0..8f40c43874 100644 --- a/erts/etc/unix/Install.src +++ b/erts/etc/unix/Install.src @@ -89,9 +89,12 @@ cp -p $ERL_ROOT/erts-%I_VSN%/bin/erl . cp -p $ERL_ROOT/erts-%I_VSN%/bin/erlc . cp -p $ERL_ROOT/erts-%I_VSN%/bin/dialyzer . cp -p $ERL_ROOT/erts-%I_VSN%/bin/typer . -cp -p $ERL_ROOT/erts-%I_VSN%/bin/run_test . +cp -p $ERL_ROOT/erts-%I_VSN%/bin/ct_run . cp -p $ERL_ROOT/erts-%I_VSN%/bin/escript . +# Remove in R16B +ln -s ct_run run_test + # # Set a soft link to epmd # This should not be done for an embedded system! diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src index 9dab9fcfcc..73b1bafbe0 100644 --- a/erts/etc/unix/cerl.src +++ b/erts/etc/unix/cerl.src @@ -66,6 +66,7 @@ core= GDB= GDBBP= +GDBARGS= TYPE= EMU_TYPE= debug= @@ -280,16 +281,11 @@ else # Set annotation level for gdb in emacs 22 and higher. emacs_major=`$EMACS --version | head -1 | sed 's,^[^0-9]*\([0-9]*\).*,\1,g'` if [ '!' -z "$emacs_major" -a $emacs_major -gt 21 ]; then - # Hack - wait for etp-commands to be loaded and then set - # annotation level, could be done more beautifully than with sit-for... - gdbcmd="$gdbcmd \ - (sit-for 1) \ - (insert-string \"set annotate 3\") \ - (comint-send-input)" + GDBARGS="--annotate=3 " fi gdbcmd="$gdbcmd $GDBBP \ (insert-string \"source $ROOTDIR/erts/etc/unix/etp-commands\") \ (comint-send-input)" # Fire up gdb in emacs... - exec $EMACS --eval "(progn (gdb \"gdb $EMU\") $gdbcmd)" + exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU\") $gdbcmd)" fi diff --git a/erts/etc/unix/format_man_pages b/erts/etc/unix/format_man_pages index 2c4f6eee4f..93dcdcd8fa 100644 --- a/erts/etc/unix/format_man_pages +++ b/erts/etc/unix/format_man_pages @@ -3,7 +3,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2009. All Rights Reserved. +# Copyright Ericsson AB 1996-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 @@ -59,34 +59,21 @@ esac # Create the 'cat' directories (probably not needed) # -cd $ERL_ROOT +cd $ERL_ROOT/man -if [ ! -d man/cat1 ] -then - mkdir man/cat1 -fi +for d in 0 1 2 3 4 5 6 7 8 9 +do + if [ ! -d cat$d ] + then + mkdir cat$d + fi -if [ ! -d man/cat3 ] -then - mkdir man/cat3 -fi - -if [ ! -d man/cat4 ] -then - mkdir man/cat4 -fi - -if [ ! -d man/cat6 ] -then - mkdir man/cat6 -fi +done # # Cleanup old formatting # -cd $ERL_ROOT/man - rm -f whatis windex # Remove old cat files diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c index 4bb148df98..cadff12c6f 100644 --- a/erts/etc/unix/run_erl.c +++ b/erts/etc/unix/run_erl.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. + * Copyright Ericsson AB 1996-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 @@ -75,6 +75,9 @@ #ifdef HAVE_SYS_IOCTL_H # include <sys/ioctl.h> #endif +#if defined(__sun) && defined(__SVR4) +# include <stropts.h> +#endif #include "run_erl.h" #include "safe_string.h" /* sn_printf, strn_cpy, strn_cat, etc */ @@ -864,8 +867,12 @@ static int open_pty_master(char **ptyslave) /* Use the posix_openpt if working, as this guarantees creation of the slave device properly. */ -#ifdef HAVE_WORKING_POSIX_OPENPT +#if defined(HAVE_WORKING_POSIX_OPENPT) || (defined(__sun) && defined(__SVR4)) +# ifdef HAVE_WORKING_POSIX_OPENPT if ((mfd = posix_openpt(O_RDWR)) >= 0) { +# elif defined(__sun) && defined(__SVR4) + if ((mfd = open("/dev/ptmx", O_RDWR)) >= 0) { +# endif if ((*ptyslave = ptsname(mfd)) != NULL && grantpt(mfd) == 0 && unlockpt(mfd) == 0) { @@ -981,8 +988,28 @@ static int open_pty_slave(char *name) return -1; } +#if defined(__sun) && defined(__SVR4) + /* Load the necessary STREAMS modules for Solaris */ + if ((ioctl(sfd, I_FIND, "ldterm")) < 0) { + ERROR0(LOG_ERR, "Failed to find ldterm STREAMS module"); + return -1; + } + if (ioctl(sfd, I_PUSH, "ptem") < 0) { + ERROR0(LOG_ERR, "Failed to push ptem STREAMS module"); + return -1; + } + if (ioctl(sfd, I_PUSH, "ldterm") < 0) { + ERROR0(LOG_ERR, "Failed to push ldterm STREAMS module"); + return -1; + } + if (ioctl(sfd, I_PUSH, "ttcompat") < 0) { + ERROR0(LOG_ERR, "Failed to push ttcompat STREAMS module"); + return -1; + } +#endif + #ifdef DEBUG - if (tcgetattr(sfd, &tty_rmode) , 0) { + if (tcgetattr(sfd, &tty_rmode) < 0) { fprintf(stderr, "Cannot get terminals current mode\n"); exit(-1); } diff --git a/erts/etc/win32/Install.c b/erts/etc/win32/Install.c index ca814e3f80..6e60512f6d 100644 --- a/erts/etc/win32/Install.c +++ b/erts/etc/win32/Install.c @@ -46,7 +46,7 @@ int main(int argc, char **argv) HANDLE module = GetModuleHandle(NULL); char *binaries[] = { "erl.exe", "werl.exe", "erlc.exe", "dialyzer.exe", "typer.exe", - "escript.exe", "run_test.exe", NULL }; + "escript.exe", "ct_run.exe", NULL }; char *scripts[] = { "start_clean.boot", "start_sasl.boot", NULL }; char fromname[MAX_PATH]; char toname[MAX_PATH]; @@ -172,6 +172,20 @@ int main(int argc, char **argv) } } + // Remove in R16B + sprintf(fromname,"%s\\%s",bin_dir,"ct_run.exe"); + sprintf(toname,"%s\\%s",bin_dir,"run_test.exe"); + if (GetFileAttributes(fromname) == 0xFFFFFFFF) { + fprintf(stderr,"Could not find file %s\n", + fromname); + exit(1); + } + if (!CopyFile(fromname,toname,FALSE)) { + fprintf(stderr,"Could not copy file %s to %s\n", + fromname,toname); + fprintf(stderr,"Continuing installation anyway...\n"); + } + for (i = 0; scripts[i] != NULL; ++i) { sprintf(fromname,"%s\\%s",release_dir,scripts[i]); sprintf(toname,"%s\\%s",bin_dir,scripts[i]); diff --git a/erts/etc/win32/cygwin_tools/vc/ld.sh b/erts/etc/win32/cygwin_tools/vc/ld.sh index b04935ed9b..406c63ffee 100755 --- a/erts/etc/win32/cygwin_tools/vc/ld.sh +++ b/erts/etc/win32/cygwin_tools/vc/ld.sh @@ -53,7 +53,7 @@ while test -n "$1" ; do STDLIB_FORCED=true; STDLIB=LIBCMTD.LIB;; -lsocket) - DEFAULT_LIBRARIES="$DEFAULT_LIBRARIES WS2_32.LIB";; + DEFAULT_LIBRARIES="$DEFAULT_LIBRARIES WS2_32.LIB IPHLPAPI.LIB";; -l*) y=`echo $x | sed 's,^-l\(.*\),\1,g'`; MPATH=`cygpath -m $y`; @@ -158,7 +158,7 @@ else fi p=$$ -CMD="$linktype -nologo -incremental:no $CMD $STDLIB $DEFAULT_LIBRARIES" +CMD="$linktype -nologo -incremental:no -largeaddressaware $CMD $STDLIB $DEFAULT_LIBRARIES" if [ "X$LD_SH_DEBUG_LOG" != "X" ]; then echo ld.sh "$SAVE" >>$LD_SH_DEBUG_LOG echo link.exe $CMD >>$LD_SH_DEBUG_LOG @@ -168,6 +168,7 @@ RES=$? CMANIFEST=`cygpath $MANIFEST` if [ "$RES" = "0" -a -f "$CMANIFEST" ]; then # Add stuff to manifest to turn off "virtualization" + sed -n -i '1h;1!H;${;g;s,<trustInfo.*</trustInfo>.,,g;p;}' $CMANIFEST sed -i "s/<\/assembly>/ <ms_asmv2:trustInfo xmlns:ms_asmv2=\"urn:schemas-microsoft-com:asm.v2\">\n <ms_asmv2:security>\n <ms_asmv2:requestedPrivileges>\n <ms_asmv2:requestedExecutionLevel level=\"AsInvoker\" uiAccess=\"false\"\/>\n <\/ms_asmv2:requestedPrivileges>\n <\/ms_asmv2:security>\n <\/ms_asmv2:trustInfo>\n<\/assembly>/" $CMANIFEST eval mt.exe -nologo -manifest "$MANIFEST" -outputresource:"$OUTPUTRES" >>/tmp/link.exe.${p}.1 2>>/tmp/link.exe.${p}.2 diff --git a/erts/etc/win32/nsis/Makefile b/erts/etc/win32/nsis/Makefile index ebb3ad9a96..981a232c69 100644 --- a/erts/etc/win32/nsis/Makefile +++ b/erts/etc/win32/nsis/Makefile @@ -45,6 +45,7 @@ WTARGET_DIR=$(shell (cygpath -d $(TARGET_DIR) 2>/dev/null || cygpath -d $(TARGET REDIST_FILE=$(shell (sh ./find_redist.sh || echo "")) REDIST_DLL_VERSION=$(shell (sh ./dll_version_helper.sh || echo "")) +REDIST_DLL_NAME=$(shell (sh ./dll_version_helper.sh -n || echo "")) release_spec: @NSIS_VER=`makensis /hdrinfo | head -1 | awk '{print $$2}'`; \ @@ -73,6 +74,7 @@ release_spec: cp $(REDIST_FILE) $(RELEASE_PATH)/vcredist_x86.exe;\ echo '!define HAVE_REDIST_FILE 1' >> $(VERSION_HEADER); \ echo '!define REDIST_DLL_VERSION "$(REDIST_DLL_VERSION)"' >> $(VERSION_HEADER);\ + echo '!define REDIST_DLL_NAME "$(REDIST_DLL_NAME)"' >> $(VERSION_HEADER);\ fi;\ if [ -f $(RELEASE_PATH)/docs/doc/index.html ];\ then \ diff --git a/erts/etc/win32/nsis/dll_version_helper.sh b/erts/etc/win32/nsis/dll_version_helper.sh index e0047dea8b..571ee3e39e 100755 --- a/erts/etc/win32/nsis/dll_version_helper.sh +++ b/erts/etc/win32/nsis/dll_version_helper.sh @@ -2,7 +2,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2009. All Rights Reserved. +# Copyright Ericsson AB 2007-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 @@ -41,9 +41,15 @@ if [ '!' -f hello.exe.manifest ]; then exit 0 fi VERSION=`grep '<assemblyIdentity' hello.exe.manifest | sed 's,.*version=.\([0-9\.]*\).*,\1,g' | grep -v '<'` +NAME=`grep '<assemblyIdentity' hello.exe.manifest | sed 's,.*name=.[A-Za-z\.]*\([0-9]*\).*,msvcr\1.dll,g' | grep -v '<'` rm -f hello.c hello.obj hello.exe hello.exe.manifest -if [ -z "$VERSION" ]; then +if [ "$1" = "-n" ]; then + ASKEDFOR=$NAME +else + ASKEDFOR=$VERSION +fi +if [ -z "$ASKEDFOR" ]; then exit 1 fi -echo $VERSION +echo $ASKEDFOR exit 0 diff --git a/erts/etc/win32/nsis/erlang20.nsi b/erts/etc/win32/nsis/erlang20.nsi index 43e5d91604..941e8e6f5d 100644 --- a/erts/etc/win32/nsis/erlang20.nsi +++ b/erts/etc/win32/nsis/erlang20.nsi @@ -311,23 +311,23 @@ FunctionEnd Function .onInit
SectionGetFlags 0 $MYTEMP
-; MessageBox MB_YESNO "Found $SYSDIR\msvcr80.dll" IDYES FoundLbl
- IfFileExists $SYSDIR\msvcr80.dll MaybeFoundInSystemLbl
+ ;MessageBox MB_YESNO "Found $SYSDIR\${REDIST_DLL_NAME}" IDYES FoundLbl
+ IfFileExists $SYSDIR\${REDIST_DLL_NAME} MaybeFoundInSystemLbl
SearchSxsLbl:
FindFirst $0 $1 $WINDIR\WinSxS\x86*
LoopLbl:
StrCmp $1 "" NotFoundLbl
- IfFileExists $WINDIR\WinSxS\$1\msvcr80.dll MaybeFoundInSxsLbl
+ IfFileExists $WINDIR\WinSxS\$1\${REDIST_DLL_NAME} MaybeFoundInSxsLbl
FindNext $0 $1
Goto LoopLbl
MaybeFoundInSxsLbl:
- GetDllVersion $WINDIR\WinSxS\$1\msvcr80.dll $R0 $R1
+ GetDllVersion $WINDIR\WinSxS\$1\${REDIST_DLL_NAME} $R0 $R1
Call DllVersionGoodEnough
FindNext $0 $1
IntCmp 2 $R0 LoopLbl
Goto FoundLbl
MaybeFoundInSystemLbl:
- GetDllVersion $SYSDIR\msvcr80.dll $R0 $R1
+ GetDllVersion $SYSDIR\${REDIST_DLL_NAME} $R0 $R1
Call DllVersionGoodEnough
IntCmp 2 $R0 SearchSxSLbl
FoundLbl:
diff --git a/erts/etc/win32/nsis/find_redist.sh b/erts/etc/win32/nsis/find_redist.sh index c5572839c5..153977ded5 100755 --- a/erts/etc/win32/nsis/find_redist.sh +++ b/erts/etc/win32/nsis/find_redist.sh @@ -2,7 +2,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2007-2009. All Rights Reserved. +# Copyright Ericsson AB 2007-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 @@ -107,16 +107,56 @@ for x in cl bin vc; do fi BPATH="$NBPATH" done +BPATH_LIST=$BPATH + +# rc.exe is in the Microsoft SDK directory of VS2008 +RCPATH=`lookup_prog_in_path rc` +fail=false +if [ '!' -z "$RCPATH" ]; then + BPATH=$RCPATH + for x in rc bin v6.0A ; do + NBPATH=`remove_path_element $x "$BPATH"` + if [ "$NBPATH" = "$BPATH" ]; then + fail=true + break; + fi + BPATH="$NBPATH" + done + if [ $fail = false ]; then + BPATH_LIST="$BPATH_LIST $BPATH" + fi +fi + +# Frantic search through two roots with different +# version directories. We want to be very specific about the +# directory structures as we woildnt want to find the wrong +# redistributables... + #echo $BPATH -for x in sdk v2.0 bootstrapper packages vcredist_x86 vcredist_x86.exe; do - #echo "x=$x" - #echo "BPATH=$BPATH" - NBPATH=`add_path_element $x "$BPATH"` - if [ "$NBPATH" = "$BPATH" ]; then - echo "Failed to locate vcredist_x86.exe because directory structure was unexpected" >&2 - exit 3 +for BP in $BPATH_LIST; do + for verdir in "sdk v2.0" "sdk v3.5" "v6.0A"; do + BPATH=$BP + fail=false + for x in $verdir bootstrapper packages vcredist_x86 vcredist_x86.exe; do + #echo "x=$x" + #echo "BPATH=$BPATH" + NBPATH=`add_path_element $x "$BPATH"` + if [ "$NBPATH" = "$BPATH" ]; then + fail=true + break; + fi + BPATH="$NBPATH" + done + if [ $fail = false ]; then + break; + fi + done + if [ $fail = false ]; then + echo $BPATH + exit 0 fi - BPATH="$NBPATH" done -echo $BPATH -exit 0
\ No newline at end of file + +echo "Failed to locate vcredist_x86.exe because directory structure was unexpected" >&2 +exit 3 + diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h index 4a205699bd..53fa1acdc2 100644 --- a/erts/include/internal/ethread.h +++ b/erts/include/internal/ethread.h @@ -239,6 +239,8 @@ typedef DWORD ethr_tsd_key; # include "gcc/ethread.h" # include "libatomic_ops/ethread.h" # endif +# elif defined(ETHR_HAVE_LIBATOMIC_OPS) +# include "libatomic_ops/ethread.h" # elif defined(ETHR_WIN32_THREADS) # include "win/ethread.h" # endif @@ -757,7 +759,7 @@ ETHR_INLINE_FUNC_NAME_(ethr_atomic_set_relb)(ethr_atomic_t *var, long val) #ifdef ETHR_HAVE_NATIVE_ATOMICS ethr_native_atomic_set_relb(var, val); #else - return ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(var, val); + ETHR_INLINE_FUNC_NAME_(ethr_atomic_set)(var, val); #endif } diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c index 116c9886d8..4c881993a5 100644 --- a/erts/lib_src/common/erl_misc_utils.c +++ b/erts/lib_src/common/erl_misc_utils.c @@ -71,6 +71,19 @@ (CPUSET)) != 0 ? -errno : 0) #define ERTS_MU_SET_THR_AFFINITY__(SETP) \ (sched_setaffinity(0, sizeof(cpu_set_t), (SETP)) != 0 ? -errno : 0) +#elif defined(HAVE_CPUSET_xETAFFINITY) +# include <sys/param.h> +# include <sys/cpuset.h> +# define ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__ +#define ERTS_MU_GET_PROC_AFFINITY__(CPUINFOP, CPUSET) \ + (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, \ + sizeof(cpuset_t), \ + (CPUSET)) != 0 ? -errno : 0) +#define ERTS_MU_SET_THR_AFFINITY__(CPUSETP) \ + (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, \ + sizeof(cpuset_t), \ + (CPUSETP)) != 0 ? -errno : 0) +# define cpu_set_t cpuset_t #elif defined(__WIN32__) # define ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__ # define cpu_set_t DWORD @@ -100,6 +113,11 @@ # define ERTS_SYS_CPU_PATH "/sys/devices/system/cpu" #endif +#ifdef __FreeBSD__ +#include <sys/types.h> +#include <sys/sysctl.h> +#endif + static int read_topology(erts_cpu_info_t *cpuinfo); #if defined(ERTS_HAVE_MISC_UTIL_AFFINITY_MASK__) @@ -1228,7 +1246,10 @@ read_topology(erts_cpu_info_t *cpuinfo) nodes++; } - core_id = malloc(sizeof(int)*(packages ? packages : 1)); + if (!packages) { + packages = 1; + } + core_id = malloc(sizeof(int)*packages); if (!core_id) { res = -ENOMEM; goto error; @@ -1286,11 +1307,13 @@ read_topology(erts_cpu_info_t *cpuinfo) * Nodes and packages may not be supported; pretend * that there are one if this is the case... */ - if (!nodes) - cpuinfo->topology[l].node = 0; - if (!packages) - cpuinfo->topology[l].processor = 0; if (slpip[rix].ProcessorMask & (((ULONG_PTR) 1) << l)) { + if (!nodes) { + cpuinfo->topology[l].node = 0; + } + if (!packages) { + cpuinfo->topology[l].processor = 0; + } if (processor < 0) { processor = cpuinfo->topology[l].processor; if (processor < 0) { @@ -1375,6 +1398,245 @@ read_topology(erts_cpu_info_t *cpuinfo) return res; } +#elif defined(__FreeBSD__) + +/** + * FreeBSD topology detection is based on kern.sched.topology_spec XML as + * exposed by the ULE scheduler and described in SMP(4). It is available in + * 8.0 and higher. + * + * Threads are identified in this XML chunk with a THREAD flag. The function + * (simplistically) distinguishes cores and processors by the amount of cache + * they share (0 => processor, otherwise => core). Nodes are not identified + * (ULE doesn't handle NUMA yet, I believe). + */ + +/** + * Recursively parse a topology_spec <group> tag. + */ +static +const char* parse_topology_spec_group(erts_cpu_info_t *cpuinfo, const char* xml, int parentCacheLevel, int* processor_p, int* core_p, int* index_procs_p) { + int error = 0; + int cacheLevel = parentCacheLevel; + const char* next_group_start = strstr(xml + 1, "<group"); + int is_thread_group = 0; + const char* next_cache_level; + const char* next_thread_flag; + const char* next_group_end; + const char* next_children; + const char* next_children_end; + + /* parse the cache level */ + next_cache_level = strstr(xml, "cache-level=\""); + if (next_cache_level && (next_group_start == NULL || next_cache_level < next_group_start)) { + sscanf(next_cache_level, "cache-level=\"%i\"", &cacheLevel); + } + + /* parse the threads flag */ + next_thread_flag = strstr(xml, "THREAD"); + if (next_thread_flag && (next_group_start == NULL || next_thread_flag < next_group_start)) + is_thread_group = 1; + + /* Determine if it's a leaf with the position of the next children tag */ + next_group_end = strstr(xml, "</group>"); + next_children = strstr(xml, "<children>"); + next_children_end = strstr(xml, "</children>"); + if (next_children == NULL || next_group_end < next_children) { + do { + const char* next_cpu_start; + const char* next_cpu_cdata; + const char* next_cpu_end; + int cpu_str_size; + char* cpu_str; + char* cpu_crsr; + char* brkb; + int thread = 0; + int index_procs = *index_procs_p; + + next_cpu_start = strstr(xml, "<cpu"); + if (!next_cpu_start) { + error = 1; + break; + } + next_cpu_cdata = strstr(next_cpu_start, ">") + 1; + if (!next_cpu_cdata) { + error = 1; + break; + } + next_cpu_end = strstr(next_cpu_cdata, "</cpu>"); + if (!next_cpu_end) { + error = 1; + break; + } + cpu_str_size = next_cpu_end - next_cpu_cdata; + cpu_str = (char*) malloc(cpu_str_size + 1); + memcpy(cpu_str, (const char*) next_cpu_cdata, cpu_str_size); + cpu_str[cpu_str_size] = 0; + for (cpu_crsr = strtok_r(cpu_str, " \t,", &brkb); cpu_crsr; cpu_crsr = strtok_r(NULL, " \t,", &brkb)) { + int cpu_id; + if (index_procs >= cpuinfo->configured) { + void* t = realloc(cpuinfo->topology, (sizeof(erts_cpu_topology_t) * (index_procs + 1))); + if (t) { + cpuinfo->topology = t; + } else { + error = 1; + break; + } + } + cpu_id = atoi(cpu_crsr); + cpuinfo->topology[index_procs].node = -1; + cpuinfo->topology[index_procs].processor = *processor_p; + cpuinfo->topology[index_procs].processor_node = -1; + cpuinfo->topology[index_procs].core = *core_p; + cpuinfo->topology[index_procs].thread = thread; + cpuinfo->topology[index_procs].logical = cpu_id; + if (is_thread_group) { + thread++; + } else { + *core_p = (*core_p)++; + } + index_procs++; + } + *index_procs_p = index_procs; + free(cpu_str); + } while (0); + xml = next_group_end; + } else { + while (next_group_start != NULL && next_group_start < next_children_end) { + xml = parse_topology_spec_group(cpuinfo, next_group_start, cacheLevel, processor_p, core_p, index_procs_p); + if (!xml) + break; + next_group_start = strstr(xml, "<group"); + next_children_end = strstr(xml, "</children>"); + } + } + + if (cacheLevel == 0) { + *core_p = 0; + *processor_p = (*processor_p)++; + } else { + *core_p = (*core_p)++; + } + + if (error) + xml = NULL; + + return xml; +} + +/** + * Parse the topology_spec. Return the number of CPUs or 0 if parsing failed. + */ +static +int parse_topology_spec(erts_cpu_info_t *cpuinfo, const char* xml) { + int res = 1; + int index_procs = 0; + int core = 0; + int processor = 0; + xml = strstr(xml, "<groups"); + if (!xml) + return -1; + + xml += 7; + xml = strstr(xml, "<group"); + while (xml) { + xml = parse_topology_spec_group(cpuinfo, xml, 0, &processor, &core, &index_procs); + if (!xml) { + res = 0; + break; + } + xml = strstr(xml, "<group"); + } + + if (res) + res = index_procs; + + return res; +} + +static int +read_topology(erts_cpu_info_t *cpuinfo) +{ + int ix; + int res = 0; + size_t topology_spec_size = 0; + void* topology_spec = NULL; + + errno = 0; + + if (cpuinfo->configured < 1) + goto error; + + cpuinfo->topology_size = cpuinfo->configured; + cpuinfo->topology = malloc(sizeof(erts_cpu_topology_t) + * cpuinfo->configured); + if (!cpuinfo->topology) { + res = -ENOMEM; + goto error; + } + + for (ix = 0; ix < cpuinfo->configured; ix++) { + cpuinfo->topology[ix].node = -1; + cpuinfo->topology[ix].processor = -1; + cpuinfo->topology[ix].processor_node = -1; + cpuinfo->topology[ix].core = -1; + cpuinfo->topology[ix].thread = -1; + cpuinfo->topology[ix].logical = -1; + } + + if (!sysctlbyname("kern.sched.topology_spec", NULL, &topology_spec_size, NULL, 0)) { + topology_spec = malloc(topology_spec_size); + if (!topology_spec) { + res = -ENOMEM; + goto error; + } + + if (sysctlbyname("kern.sched.topology_spec", topology_spec, &topology_spec_size, NULL, 0)) { + goto error; + } + + res = parse_topology_spec(cpuinfo, topology_spec); + if (!res || res < cpuinfo->online) + res = 0; + else { + cpuinfo->topology_size = res; + + if (cpuinfo->topology_size != cpuinfo->configured) { + void *t = realloc(cpuinfo->topology, (sizeof(erts_cpu_topology_t) + * cpuinfo->topology_size)); + if (t) + cpuinfo->topology = t; + } + + adjust_processor_nodes(cpuinfo, 1); + + qsort(cpuinfo->topology, + cpuinfo->topology_size, + sizeof(erts_cpu_topology_t), + cpu_cmp); + } + } + +error: + + if (res == 0) { + cpuinfo->topology_size = 0; + if (cpuinfo->topology) { + free(cpuinfo->topology); + cpuinfo->topology = NULL; + } + if (errno) + res = -errno; + else + res = -EINVAL; + } + + if (topology_spec) + free(topology_spec); + + return res; +} + #else static int diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam Binary files differindex 222809e662..87ff5119fd 100644 --- a/erts/preloaded/ebin/erl_prim_loader.beam +++ b/erts/preloaded/ebin/erl_prim_loader.beam diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 65c7369b76..6b0d96ff8e 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam Binary files differindex f1b54b7fcb..8a7a9a1314 100644 --- a/erts/preloaded/ebin/init.beam +++ b/erts/preloaded/ebin/init.beam diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam Binary files differindex abf17bcb0e..5d544ff4aa 100644 --- a/erts/preloaded/ebin/otp_ring0.beam +++ b/erts/preloaded/ebin/otp_ring0.beam diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam Binary files differindex a3f300268f..3ed02ecd44 100644 --- a/erts/preloaded/ebin/prim_file.beam +++ b/erts/preloaded/ebin/prim_file.beam diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam Binary files differindex a777971b32..79a8d22366 100644 --- a/erts/preloaded/ebin/prim_inet.beam +++ b/erts/preloaded/ebin/prim_inet.beam diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam Binary files differindex 0fe38a1fb2..3cc8c6b8be 100644 --- a/erts/preloaded/ebin/prim_zip.beam +++ b/erts/preloaded/ebin/prim_zip.beam diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam Binary files differindex 7108bf44d0..3f9e867542 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/erts/preloaded/src/Makefile b/erts/preloaded/src/Makefile index 785ad531f3..145638802f 100644 --- a/erts/preloaded/src/Makefile +++ b/erts/preloaded/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2009. All Rights Reserved. +# Copyright Ericsson AB 2008-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 @@ -20,8 +20,7 @@ # be used when the preloaded modules actually are to be updated (i.e. the # beam files are to be recompiled, which is normally not done). # The beam files are placed in the current directory and should be copied -# to the ../ebin directory by using the commit target (only works in -# clearcase). +# to the ../ebin directory by using the copy target. include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -62,26 +61,9 @@ debug opt: $(TARGET_FILES) clean: rm -f $(TARGET_FILES) -prepare: - cleartool co -nc $(STATIC_EBIN)/* - cleartool co -nc $(STATIC_EBIN) - copy: - for x in *.beam; do\ - if test '!' -f $(STATIC_EBIN)/$$x; then\ - cleartool mkelem -nc $$x;\ - fi;\ - done cp *.beam $(STATIC_EBIN) -commit: - cleartool ci -ident -nc $(STATIC_EBIN)/*.beam - cleartool ci -ident -nc $(STATIC_EBIN) - -cancel: - -cleartool unco -rm $(STATIC_EBIN) - -cleartool unco -rm $(STATIC_EBIN)/*.beam - include $(ERL_TOP)/make/otp_release_targets.mk diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl index 3b98b9cddc..24430a3d40 100644 --- a/erts/preloaded/src/init.erl +++ b/erts/preloaded/src/init.erl @@ -51,6 +51,9 @@ get_status/0,boot/1,get_arguments/0,get_plain_arguments/0, get_argument/1,script_id/0]). +%% for the on_load functionality; not for general use +-export([run_on_load_handlers/0]). + %% internal exports -export([fetch_loaded/0,ensure_loaded/1,make_permanent/2, notify_when_started/1,wait_until_started/0, @@ -69,6 +72,7 @@ script_id = [], loaded = [], subscribed = []}). +-type state() :: #state{}. -define(ON_LOAD_HANDLER, init__boot__on_load_handler). @@ -143,10 +147,10 @@ restart() -> init ! {stop,restart}, ok. -spec reboot() -> 'ok'. reboot() -> init ! {stop,reboot}, ok. --spec stop() -> no_return(). +-spec stop() -> 'ok'. stop() -> init ! {stop,stop}, ok. --spec stop(non_neg_integer() | string()) -> no_return(). +-spec stop(non_neg_integer() | string()) -> 'ok'. stop(Status) -> init ! {stop,{stop,Status}}, ok. -spec boot([binary()]) -> no_return(). @@ -275,7 +279,7 @@ crash(String, List) -> halt(halt_string(String, List)). %% Status is {InternalStatus,ProvidedStatus} --spec boot_loop(pid(), #state{}) -> no_return(). +-spec boot_loop(pid(), state()) -> no_return(). boot_loop(BootPid, State) -> receive {BootPid,loaded,ModLoaded} -> @@ -308,24 +312,6 @@ boot_loop(BootPid, State) -> {stop,Reason} -> stop(Reason,State); {From,fetch_loaded} -> %% Fetch and reset initially loaded modules. - case whereis(?ON_LOAD_HANDLER) of - undefined -> - %% There is no on_load handler process, - %% probably because init:restart/0 has been - %% called and it is not the first time we - %% pass through here. - ok; - Pid when is_pid(Pid) -> - Pid ! run_on_load, - receive - {'EXIT',Pid,on_load_done} -> - ok; - {'EXIT',Pid,Res} -> - %% Failure to run an on_load handler. - %% This is fatal during start-up. - exit(Res) - end - end, From ! {init,State#state.loaded}, garb_boot_loop(BootPid,State#state{loaded = []}); {From,{ensure_loaded,Module}} -> @@ -736,6 +722,7 @@ do_boot(Init,Flags,Start) -> BootList = get_boot(BootFile,Root), LoadMode = b2a(get_flag('-mode',Flags,false)), Deb = b2a(get_flag('-init_debug',Flags,false)), + catch ?ON_LOAD_HANDLER ! {init_debug_flag,Deb}, BootVars = get_flag_args('-boot_var',Flags), ParallelLoad = (Pgm =:= "efile") and (erlang:system_info(thread_pool_size) > 0), @@ -1335,23 +1322,44 @@ archive_extension() -> %%% Support for handling of on_load functions. %%% +run_on_load_handlers() -> + Ref = monitor(process, ?ON_LOAD_HANDLER), + catch ?ON_LOAD_HANDLER ! run_on_load, + receive + {'DOWN',Ref,process,_,noproc} -> + %% There is no on_load handler process, + %% probably because init:restart/0 has been + %% called and it is not the first time we + %% pass through here. + ok; + {'DOWN',Ref,process,_,on_load_done} -> + ok; + {'DOWN',Ref,process,_,Res} -> + %% Failure to run an on_load handler. + %% This is fatal during start-up. + exit(Res) + end. + start_on_load_handler_process() -> register(?ON_LOAD_HANDLER, - spawn_link(fun on_load_handler_init/0)). + spawn(fun on_load_handler_init/0)). on_load_handler_init() -> - on_load_loop([]). + on_load_loop([], false). -on_load_loop(Mods) -> +on_load_loop(Mods, Debug0) -> receive + {init_debug_flag,Debug} -> + on_load_loop(Mods, Debug); {loaded,Mod} -> - on_load_loop([Mod|Mods]); + on_load_loop([Mod|Mods], Debug0); run_on_load -> - run_on_load_handlers(Mods), + run_on_load_handlers(Mods, Debug0), exit(on_load_done) end. -run_on_load_handlers([M|Ms]) -> +run_on_load_handlers([M|Ms], Debug) -> + debug(Debug, {running_on_load_handler,M}), Fun = fun() -> Res = erlang:call_on_load_function(M), exit(Res) @@ -1363,9 +1371,12 @@ run_on_load_handlers([M|Ms]) -> erlang:finish_after_on_load(M, Keep), case Keep of false -> - exit({on_load_function_failed,M}); + Error = {on_load_function_failed,M}, + debug(Debug, Error), + exit(Error); true -> - run_on_load_handlers(Ms) + debug(Debug, {on_load_handler_returned_ok,M}), + run_on_load_handlers(Ms, Debug) end end; -run_on_load_handlers([]) -> ok. +run_on_load_handlers([], _) -> ok. diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 7f24889bb2..10be852e92 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -109,6 +109,8 @@ -define(FILE_RESP_LDATA, 6). -define(FILE_RESP_N2DATA, 7). -define(FILE_RESP_EOF, 8). +-define(FILE_RESP_FNAME, 9). +-define(FILE_RESP_ALL_DATA, 10). %% Open modes for the driver's open function. -define(EFILE_MODE_READ, 1). @@ -153,7 +155,7 @@ %% Opens a file using the driver port Port. Returns {error, Reason} %% | {ok, FileDescriptor} open(Port, File, ModeList) when is_port(Port), - is_list(File), + (is_list(File) orelse is_binary(File)), is_list(ModeList) -> case open_mode(ModeList) of {Mode, _Portopts, _Setopts} -> @@ -165,10 +167,11 @@ open(_,_,_) -> {error, badarg}. %% Opens a file. Returns {error, Reason} | {ok, FileDescriptor}. -open(File, ModeList) when is_list(File), is_list(ModeList) -> +open(File, ModeList) when (is_list(File) orelse is_binary(File)), + is_list(ModeList) -> case open_mode(ModeList) of {Mode, Portopts, Setopts} -> - open_int({?FD_DRV, Portopts}, File, Mode, Setopts); + open_int({?FD_DRV, Portopts},File, Mode, Setopts); Reason -> {error, Reason} end; @@ -196,7 +199,7 @@ open_int({Driver, Portopts}, File, Mode, Setopts) -> end; open_int(Port, File, Mode, Setopts) -> M = Mode band ?EFILE_MODE_MASK, - case drv_command(Port, [<<?FILE_OPEN, M:32>>, File, 0]) of + case drv_command(Port, [<<?FILE_OPEN, M:32>>, pathname(File)]) of {ok, Number} -> open_int_setopts(Port, Number, Setopts); Error -> @@ -489,7 +492,7 @@ ipread_s32bu_p32bu(#file_descriptor{module = ?MODULE, data = {_, _}}, %% Returns {ok, Contents} | {error, Reason} -read_file(File) -> +read_file(File) when (is_list(File) orelse is_binary(File)) -> case drv_open(?FD_DRV, [binary]) of {ok, Port} -> Result = read_file(Port, File), @@ -497,11 +500,14 @@ read_file(File) -> Result; {error, _} = Error -> Error - end. + end; +read_file(_) -> + {error, badarg}. %% Takes a Port opened with open/1. -read_file(Port, File) when is_port(Port) -> - Cmd = [?FILE_READ_FILE | File], +read_file(Port, File) when is_port(Port), + (is_list(File) orelse is_binary(File))-> + Cmd = [?FILE_READ_FILE | pathname(File)], case drv_command(Port, Cmd) of {error, enomem} -> %% It could possibly help to do a @@ -512,12 +518,14 @@ read_file(Port, File) when is_port(Port) -> drv_command(Port, Cmd); Result -> Result - end. + end; +read_file(_,_) -> + {error, badarg}. %% Returns {error, Reason} | ok. -write_file(File, Bin) -> +write_file(File, Bin) when (is_list(File) orelse is_binary(File)) -> case open(File, [binary, write]) of {ok, Handle} -> Result = write(Handle, Bin), @@ -525,8 +533,10 @@ write_file(File, Bin) -> Result; Error -> Error - end. - + end; +write_file(_, _) -> + {error, badarg}. + %%%----------------------------------------------------------------- @@ -539,7 +549,7 @@ write_file(File, Bin) -> %% Returns {ok, Port}, the Port should be used as first argument in all %% the following functions. Returns {error, Reason} upon failure. start() -> - try erlang:open_port({spawn, atom_to_list(?DRV)}, []) of + try erlang:open_port({spawn, atom_to_list(?DRV)}, [binary]) of Port -> {ok, Port} catch @@ -596,7 +606,7 @@ get_cwd(_, _) -> {error, badarg}. get_cwd_int(Drive) -> - get_cwd_int({?DRV, []}, Drive). + get_cwd_int({?DRV, [binary]}, Drive). get_cwd_int(Port, Drive) -> drv_command(Port, <<?FILE_PWD, Drive>>). @@ -606,7 +616,7 @@ get_cwd_int(Port, Drive) -> %% set_cwd/{1,2} set_cwd(Dir) -> - set_cwd_int({?DRV, []}, Dir). + set_cwd_int({?DRV, [binary]}, Dir). set_cwd(Port, Dir) when is_port(Port) -> set_cwd_int(Port, Dir). @@ -632,89 +642,88 @@ set_cwd_int(Port, Dir0) -> end), %% Dir is now either a string or an EXIT tuple. %% An EXIT tuple will fail in the following catch. - drv_command(Port, [?FILE_CHDIR, Dir, 0]). + drv_command(Port, [?FILE_CHDIR, pathname(Dir)]). %% delete/{1,2} delete(File) -> - delete_int({?DRV, []}, File). + delete_int({?DRV, [binary]}, File). delete(Port, File) when is_port(Port) -> delete_int(Port, File). delete_int(Port, File) -> - drv_command(Port, [?FILE_DELETE, File, 0]). + drv_command(Port, [?FILE_DELETE, pathname(File)]). %% rename/{2,3} rename(From, To) -> - rename_int({?DRV, []}, From, To). + rename_int({?DRV, [binary]}, From, To). rename(Port, From, To) when is_port(Port) -> rename_int(Port, From, To). rename_int(Port, From, To) -> - drv_command(Port, [?FILE_RENAME, From, 0, To, 0]). + drv_command(Port, [?FILE_RENAME, pathname(From), pathname(To)]). %% make_dir/{1,2} make_dir(Dir) -> - make_dir_int({?DRV, []}, Dir). + make_dir_int({?DRV, [binary]}, Dir). make_dir(Port, Dir) when is_port(Port) -> make_dir_int(Port, Dir). make_dir_int(Port, Dir) -> - drv_command(Port, [?FILE_MKDIR, Dir, 0]). + drv_command(Port, [?FILE_MKDIR, pathname(Dir)]). %% del_dir/{1,2} del_dir(Dir) -> - del_dir_int({?DRV, []}, Dir). + del_dir_int({?DRV, [binary]}, Dir). del_dir(Port, Dir) when is_port(Port) -> del_dir_int(Port, Dir). del_dir_int(Port, Dir) -> - drv_command(Port, [?FILE_RMDIR, Dir, 0]). + drv_command(Port, [?FILE_RMDIR, pathname(Dir)]). %% read_file_info/{1,2} read_file_info(File) -> - read_file_info_int({?DRV, []}, File). + read_file_info_int({?DRV, [binary]}, File). read_file_info(Port, File) when is_port(Port) -> read_file_info_int(Port, File). read_file_info_int(Port, File) -> - drv_command(Port, [?FILE_FSTAT, File, 0]). + drv_command(Port, [?FILE_FSTAT, pathname(File)]). %% altname/{1,2} altname(File) -> - altname_int({?DRV, []}, File). + altname_int({?DRV, [binary]}, File). altname(Port, File) when is_port(Port) -> altname_int(Port, File). altname_int(Port, File) -> - drv_command(Port, [?FILE_ALTNAME, File, 0]). - + drv_command(Port, [?FILE_ALTNAME, pathname(File)]). %% write_file_info/{2,3} write_file_info(File, Info) -> - write_file_info_int({?DRV, []}, File, Info). + write_file_info_int({?DRV, [binary]}, File, Info). write_file_info(Port, File, Info) when is_port(Port) -> write_file_info_int(Port, File, Info). @@ -740,72 +749,72 @@ write_file_info_int(Port, date_to_bytes(Atime), date_to_bytes(Mtime), date_to_bytes(Ctime), - File, 0]). + pathname(File)]). %% make_link/{2,3} make_link(Old, New) -> - make_link_int({?DRV, []}, Old, New). + make_link_int({?DRV, [binary]}, Old, New). make_link(Port, Old, New) when is_port(Port) -> make_link_int(Port, Old, New). make_link_int(Port, Old, New) -> - drv_command(Port, [?FILE_LINK, Old, 0, New, 0]). + drv_command(Port, [?FILE_LINK, pathname(Old), pathname(New)]). %% make_symlink/{2,3} make_symlink(Old, New) -> - make_symlink_int({?DRV, []}, Old, New). + make_symlink_int({?DRV, [binary]}, Old, New). make_symlink(Port, Old, New) when is_port(Port) -> make_symlink_int(Port, Old, New). make_symlink_int(Port, Old, New) -> - drv_command(Port, [?FILE_SYMLINK, Old, 0, New, 0]). + drv_command(Port, [?FILE_SYMLINK, pathname(Old), pathname(New)]). %% read_link/{2,3} read_link(Link) -> - read_link_int({?DRV, []}, Link). + read_link_int({?DRV, [binary]}, Link). read_link(Port, Link) when is_port(Port) -> read_link_int(Port, Link). read_link_int(Port, Link) -> - drv_command(Port, [?FILE_READLINK, Link, 0]). + drv_command(Port, [?FILE_READLINK, pathname(Link)]). %% read_link_info/{2,3} read_link_info(Link) -> - read_link_info_int({?DRV, []}, Link). + read_link_info_int({?DRV, [binary]}, Link). read_link_info(Port, Link) when is_port(Port) -> read_link_info_int(Port, Link). read_link_info_int(Port, Link) -> - drv_command(Port, [?FILE_LSTAT, Link, 0]). + drv_command(Port, [?FILE_LSTAT, pathname(Link)]). %% list_dir/{1,2} list_dir(Dir) -> - list_dir_int({?DRV, []}, Dir). + list_dir_int({?DRV, [binary]}, Dir). list_dir(Port, Dir) when is_port(Port) -> list_dir_int(Port, Dir). list_dir_int(Port, Dir) -> - drv_command(Port, [?FILE_READDIR, Dir, 0], []). + drv_command(Port, [?FILE_READDIR, pathname(Dir)], []). @@ -1026,8 +1035,6 @@ lseek_position(_) -> translate_response(?FILE_RESP_OK, []) -> ok; -translate_response(?FILE_RESP_OK, Data) -> - {ok, Data}; translate_response(?FILE_RESP_ERROR, List) when is_list(List) -> {error, list_to_atom(List)}; translate_response(?FILE_RESP_NUMBER, List) -> @@ -1074,6 +1081,16 @@ translate_response(?FILE_RESP_N2DATA = X, L0) when is_list(L0) -> end; translate_response(?FILE_RESP_EOF, []) -> eof; +translate_response(?FILE_RESP_FNAME, []) -> + ok; +translate_response(?FILE_RESP_FNAME, Data) when is_binary(Data) -> + {ok, prim_file:internal_native2name(Data)}; +translate_response(?FILE_RESP_FNAME, Data) -> + {ok, Data}; + +translate_response(?FILE_RESP_ALL_DATA, Data) -> + {ok, Data}; + translate_response(X, Data) -> {error, {bad_response_from_port, [X | Data]}}. @@ -1209,3 +1226,9 @@ lists_split([Hd | Tl], N, Rev) -> reverse(X) -> lists:reverse(X, []). reverse(L, T) -> lists:reverse(L, T). + +% Will add zero termination too +% The 'EXIT' tuple from a bad argument will eventually generate an error +% in list_to_binary, which is caught and generates the {error,badarg} return +pathname(File) -> + (catch prim_file:internal_name2native(File)). diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl index 91d39c6a73..446656e45f 100644 --- a/erts/preloaded/src/prim_inet.erl +++ b/erts/preloaded/src/prim_inet.erl @@ -37,7 +37,7 @@ -export([setopt/3, setopts/2, getopt/2, getopts/2, is_sockopt_val/2]). -export([chgopt/3, chgopts/2]). -export([getstat/2, getfd/1, getindex/1, getstatus/1, gettype/1, - getiflist/1, ifget/3, ifset/3, + getifaddrs/1, getiflist/1, ifget/3, ifset/3, gethostname/1]). -export([getservbyname/3, getservbyport/3]). -export([peername/1, setpeername/2]). @@ -216,9 +216,10 @@ bindx(S, AddFlag, Addrs) -> sctp -> %% Really multi-homed "bindx". Stringified args: %% [AddFlag, (Port, IP)+]: - Args = ?int8(AddFlag) ++ - lists:concat([?int16(Port)++ip_to_bytes(IP) || - {IP, Port} <- Addrs]), + Args = + [?int8(AddFlag)| + [[?int16(Port)|ip_to_bytes(IP)] || + {IP, Port} <- Addrs]], case ctl_cmd(S, ?SCTP_REQ_BINDX, Args) of {ok,_} -> {ok, S}; Error -> Error @@ -623,7 +624,7 @@ chgopt(S, Opt, Value) when is_port(S) -> chgopts(S, [{Opt,Value}]). chgopts(S, Opts) when is_port(S), is_list(Opts) -> - case inet:getopts(S, need_template(Opts)) of + case getopts(S, need_template(Opts)) of {ok,Templates} -> try merge_options(Opts, Templates) of NewOpts -> @@ -636,7 +637,94 @@ chgopts(S, Opts) when is_port(S), is_list(Opts) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% -%% IFLIST(insock()) -> {ok,IfNameList} | {error, Reason} +%% getifaddrs(insock()) -> {ok,IfAddrsList} | {error, Reason} +%% +%% IfAddrsList = [{Name,[Opts]}] +%% Name = string() +%% Opts = {flags,[Flag]} | {addr,Addr} | {netmask,Addr} | {broadaddr,Addr} +%% | {dstaddr,Addr} | {hwaddr,HwAddr} | {mtu,integer()} +%% Flag = up | broadcast | loopback | running | multicast +%% Addr = ipv4addr() | ipv6addr() +%% HwAddr = ethernet_addr() +%% +%% get interface name and addresses list +%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +getifaddrs(S) when is_port(S) -> + case ctl_cmd(S, ?INET_REQ_GETIFADDRS, []) of + {ok, Data} -> + {ok, comp_ifaddrs(build_ifaddrs(Data), ktree_empty())}; + {error,enotsup} -> + case getiflist(S) of + {ok, IFs} -> + {ok, getifaddrs_ifget(S, IFs)}; + Err1 -> Err1 + end; + Err2 -> Err2 + end. + +%% Restructure interface properties per interface and remove duplicates + +comp_ifaddrs([{If,Opts}|IfOpts], T) -> + case ktree_is_defined(If, T) of + true -> + OptSet = comp_ifaddrs_add(ktree_get(If, T), Opts), + comp_ifaddrs(IfOpts, ktree_update(If, OptSet, T)); + false -> + OptSet = comp_ifaddrs_add(ktree_empty(), Opts), + comp_ifaddrs(IfOpts, ktree_insert(If, OptSet, T)) + end; +comp_ifaddrs([], T) -> + [{If,ktree_keys(ktree_get(If, T))} || If <- ktree_keys(T)]. + +comp_ifaddrs_add(OptSet, [Opt|Opts]) -> + case ktree_is_defined(Opt, OptSet) of + true + when element(1, Opt) =:= flags; + element(1, Opt) =:= hwaddr -> + comp_ifaddrs_add(OptSet, Opts); + _ -> + comp_ifaddrs_add(ktree_insert(Opt, undefined, OptSet), Opts) + end; +comp_ifaddrs_add(OptSet, []) -> OptSet. + +%% Legacy emulation of getifaddrs + +getifaddrs_ifget(_, []) -> []; +getifaddrs_ifget(S, [IF|IFs]) -> + case ifget(S, IF, [flags]) of + {ok,[{flags,Flags}]=FlagsVals} -> + BroadOpts = + case member(broadcast, Flags) of + true -> + [broadaddr,hwaddr]; + false -> + [hwaddr] + end, + P2POpts = + case member(pointtopoint, Flags) of + true -> + [dstaddr|BroadOpts]; + false -> + BroadOpts + end, + getifaddrs_ifget(S, IFs, IF, FlagsVals, [addr,netmask|P2POpts]); + _ -> + getifaddrs_ifget(S, IFs, IF, [], [addr,netmask,hwaddr]) + end. + +getifaddrs_ifget(S, IFs, IF, FlagsVals, Opts) -> + OptVals = + case ifget(S, IF, Opts) of + {ok,OVs} -> OVs; + _ -> [] + end, + [{IF,FlagsVals++OptVals}|getifaddrs_ifget(S, IFs)]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% +%% getiflist(insock()) -> {ok,IfNameList} | {error, Reason} %% %% get interface name list %% @@ -1325,6 +1413,19 @@ type_value_2({enum,List}, Enum) -> {value,_} -> true; false -> false end; +type_value_2(sockaddr, Addr) -> + case Addr of + any -> true; + loopback -> true; + {A,B,C,D} when ?ip(A,B,C,D) -> true; + {A,B,C,D,E,F,G,H} when ?ip6(A,B,C,D,E,F,G,H) -> true; + _ -> false + end; +type_value_2(linkaddr, Addr) when is_list(Addr) -> + case len(Addr, 32768) of + undefined -> false; + _ -> true + end; type_value_2({bitenumlist,List}, EnumList) -> case enum_vals(EnumList, List) of Ls when is_list(Ls) -> true; @@ -1413,14 +1514,21 @@ enc_value_2(addr, {any,Port}) -> [?INET_AF_ANY|?int16(Port)]; enc_value_2(addr, {loopback,Port}) -> [?INET_AF_LOOPBACK|?int16(Port)]; -enc_value_2(addr, {IP,Port}) -> - case tuple_size(IP) of - 4 -> - [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)]; - 8 -> - [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)] - end; +enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 4 -> + [?INET_AF_INET,?int16(Port)|ip4_to_bytes(IP)]; +enc_value_2(addr, {IP,Port}) when tuple_size(IP) =:= 8 -> + [?INET_AF_INET6,?int16(Port)|ip6_to_bytes(IP)]; enc_value_2(ether, [X1,X2,X3,X4,X5,X6]) -> [X1,X2,X3,X4,X5,X6]; +enc_value_2(sockaddr, any) -> + [?INET_AF_ANY]; +enc_value_2(sockaddr, loopback) -> + [?INET_AF_LOOPBACK]; +enc_value_2(sockaddr, IP) when tuple_size(IP) =:= 4 -> + [?INET_AF_INET|ip4_to_bytes(IP)]; +enc_value_2(sockaddr, IP) when tuple_size(IP) =:= 8 -> + [?INET_AF_INET6|ip6_to_bytes(IP)]; +enc_value_2(linkaddr, Linkaddr) -> + [?int16(length(Linkaddr)),Linkaddr]; enc_value_2(sctp_assoc_id, Val) -> ?int32(Val); %% enc_value_2(sctp_assoc_id, Bin) -> [byte_size(Bin),Bin]; enc_value_2({enum,List}, Enum) -> @@ -1465,6 +1573,10 @@ dec_value(time, [X3,X2,X1,X0|T]) -> end; dec_value(ip, [A,B,C,D|T]) -> {{A,B,C,D}, T}; dec_value(ether,[X1,X2,X3,X4,X5,X6|T]) -> {[X1,X2,X3,X4,X5,X6],T}; +dec_value(sockaddr, [X|T]) -> + get_ip(X, T); +dec_value(linkaddr, [X1,X0|T]) -> + split(?i16(X1,X0), T); dec_value({enum,List}, [X3,X2,X1,X0|T]) -> Val = ?i32(X3,X2,X1,X0), case enum_name(Val, List) of @@ -1480,7 +1592,7 @@ dec_value({bitenumlist,List}, [X3,X2,X1,X0|T]) -> %% {enum_names(Val, List), T}; dec_value(binary,[L0,L1,L2,L3|List]) -> Len = ?i32(L0,L1,L2,L3), - {X,T}=lists:split(Len,List), + {X,T}=split(Len,List), {list_to_binary(X),T}; dec_value(Types, List) when is_tuple(Types) -> {L,T} = dec_value_tuple(Types, List, 1, []), @@ -1495,7 +1607,7 @@ dec_value_tuple(Types, List, N, Acc) {Term,Tail} = dec_value(element(N, Types), List), dec_value_tuple(Types, Tail, N+1, [Term|Acc]); dec_value_tuple(_, List, _, Acc) -> - {lists:reverse(Acc),List}. + {rev(Acc),List}. borlist([V|Vs], Value) -> borlist(Vs, V bor Value); @@ -1702,11 +1814,11 @@ merge_fields(_, _, _) -> []. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -type_ifopt(addr) -> ip; -type_ifopt(broadaddr) -> ip; -type_ifopt(dstaddr) -> ip; +type_ifopt(addr) -> sockaddr; +type_ifopt(broadaddr) -> sockaddr; +type_ifopt(dstaddr) -> sockaddr; type_ifopt(mtu) -> int; -type_ifopt(netmask) -> ip; +type_ifopt(netmask) -> sockaddr; type_ifopt(flags) -> {bitenumlist, [{up, ?INET_IFF_UP}, @@ -1718,7 +1830,7 @@ type_ifopt(flags) -> {no_pointtopoint, ?INET_IFF_NPOINTTOPOINT}, {running, ?INET_IFF_RUNNING}, {multicast, ?INET_IFF_MULTICAST}]}; -type_ifopt(hwaddr) -> ether; +type_ifopt(hwaddr) -> linkaddr; type_ifopt(Opt) when is_atom(Opt) -> undefined. enc_ifopt(addr) -> ?INET_IFOPT_ADDR; @@ -1903,6 +2015,30 @@ encode_ifname(Name) -> if N > 255 -> {error, einval}; true -> {ok,[N | Name]} end. + +build_ifaddrs(Cs) -> + build_ifaddrs(Cs, []). +%% +build_ifaddrs([], []) -> + []; +build_ifaddrs([0|Cs], Acc) -> + Name = utf8_to_characters(rev(Acc)), + {Opts,Rest} = build_ifaddrs_opts(Cs, []), + [{Name,Opts}|build_ifaddrs(Rest)]; +build_ifaddrs([C|Cs], Acc) -> + build_ifaddrs(Cs, [C|Acc]). + +build_ifaddrs_opts([0|Cs], Acc) -> + {rev(Acc),Cs}; +build_ifaddrs_opts([C|Cs]=CCs, Acc) -> + case dec_ifopt(C) of + undefined -> + erlang:error(badarg, [CCs,Acc]); + Opt -> + Type = type_ifopt(Opt), + {Val,Rest} = dec_value(Type, Cs), + build_ifaddrs_opts(Rest, [{Opt,Val}|Acc]) + end. build_iflist(Cs) -> build_iflist(Cs, [], []). @@ -1927,6 +2063,80 @@ rev(L) -> rev(L,[]). rev([C|L],Acc) -> rev(L,[C|Acc]); rev([],Acc) -> Acc. +split(N, L) -> split(N, L, []). +split(0, L, R) when is_list(L) -> {rev(R),L}; +split(N, [H|T], R) when is_integer(N), N > 0 -> split(N-1, T, [H|R]). + +len(L, N) -> len(L, N, 0). +len([], N, C) when is_integer(N), N >= 0 -> C; +len(L, 0, _) when is_list(L) -> undefined; +len([_|L], N, C) when is_integer(N), N >= 0 -> len(L, N-1, C+1). + +member(X, [X|_]) -> true; +member(X, [_|Xs]) -> member(X, Xs); +member(_, []) -> false. + + + +%% Lookup tree that keeps key insert order + +ktree_empty() -> {[],tree()}. +ktree_is_defined(Key, {_,T}) -> tree(T, Key, is_defined). +ktree_get(Key, {_,T}) -> tree(T, Key, get). +ktree_insert(Key, V, {Keys,T}) -> {[Key|Keys],tree(T, Key, {insert,V})}. +ktree_update(Key, V, {Keys,T}) -> {Keys,tree(T, Key, {update,V})}. +ktree_keys({Keys,_}) -> rev(Keys). + +%% Simple lookup tree. Hash the key to get statistical balance. +%% Key is matched equal, not compared equal. + +tree() -> nil. +tree(T, Key, Op) -> tree(T, Key, Op, erlang:phash2(Key)). + +tree(nil, _, is_defined, _) -> false; +tree(nil, K, {insert,V}, _) -> {K,V,nil,nil}; +tree({K,_,_,_}, K, is_defined, _) -> true; +tree({K,V,_,_}, K, get, _) -> V; +tree({K,_,L,R}, K, {update,V}, _) -> {K,V,L,R}; +tree({K0,V0,L,R}, K, Op, H) -> + H0 = erlang:phash2(K0), + if H0 < H; H0 =:= H, K0 < K -> + if is_tuple(Op) -> + {K0,V0,tree(L, K, Op, H),R}; + true -> + tree(L, K, Op, H) + end; + true -> + if is_tuple(Op) -> + {K0,V0,L,tree(R, K, Op, H)}; + true -> + tree(R, K, Op, H) + end + end. + + + +utf8_to_characters([]) -> []; +utf8_to_characters([B|Bs]=Arg) when (B band 16#FF) =:= B -> + if 16#F8 =< B -> + erlang:error(badarg, [Arg]); + 16#F0 =< B -> + utf8_to_characters(Bs, B band 16#07, 3); + 16#E0 =< B -> + utf8_to_characters(Bs, B band 16#0F, 2); + 16#C0 =< B -> + utf8_to_characters(Bs, B band 16#1F, 1); + 16#80 =< B -> + erlang:error(badarg, [Arg]); + true -> + [B|utf8_to_characters(Bs)] + end. +%% +utf8_to_characters(Bs, U, 0) -> + [U|utf8_to_characters(Bs)]; +utf8_to_characters([B|Bs], U, N) when ((B band 16#3F) bor 16#80) =:= B -> + utf8_to_characters(Bs, (U bsl 6) bor (B band 16#3F), N-1). + ip_to_bytes(IP) when tuple_size(IP) =:= 4 -> ip4_to_bytes(IP); ip_to_bytes(IP) when tuple_size(IP) =:= 8 -> ip6_to_bytes(IP). diff --git a/erts/test/erlc_SUITE.erl b/erts/test/erlc_SUITE.erl index 437f020f99..4797f78be2 100644 --- a/erts/test/erlc_SUITE.erl +++ b/erts/test/erlc_SUITE.erl @@ -21,13 +21,13 @@ %% Tests the erlc command by compiling various types of files. -export([all/1, compile_erl/1, compile_yecc/1, compile_script/1, - compile_mib/1, good_citizen/1, deep_cwd/1]). + compile_mib/1, good_citizen/1, deep_cwd/1, arg_overflow/1]). -include_lib("test_server/include/test_server.hrl"). all(suite) -> [compile_erl, compile_yecc, compile_script, compile_mib, - good_citizen, deep_cwd]. + good_citizen, deep_cwd, arg_overflow]. %% Copy from erlc_SUITE_data/include/erl_test.hrl. @@ -189,6 +189,18 @@ deep_cwd_1(PrivDir) -> ?line true = filelib:is_file("test.beam"), ok. +%% Test that a large number of command line switches does not +%% overflow the argument buffer +arg_overflow(Config) when is_list(Config) -> + ?line {SrcDir, _OutDir, Cmd} = get_cmd(Config), + ?line FileName = filename:join(SrcDir, "erl_test_ok.erl"), + ?line Args = lists:flatten([ ["-D", integer_to_list(N), "=1 "] || + N <- lists:seq(1,10000) ]), + ?line run(Config, Cmd, FileName, Args, + ["Warning: function foo/0 is unused\$", + "_OK_"]), + ok. + erlc() -> case os:find_executable("erlc") of false -> diff --git a/erts/test/erlexec_SUITE.erl b/erts/test/erlexec_SUITE.erl index 164ce9faaf..6adb865f6d 100644 --- a/erts/test/erlexec_SUITE.erl +++ b/erts/test/erlexec_SUITE.erl @@ -33,7 +33,7 @@ -export([all/1, init_per_testcase/2, fin_per_testcase/2]). --export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1]). +-export([args_file/1, evil_args_file/1, env/1, args_file_env/1, otp_7461/1, otp_7461_remote/1, otp_8209/1, zdbbl_dist_buf_busy_limit/1]). -include_lib("test_server/include/test_server.hrl"). @@ -53,7 +53,8 @@ fin_per_testcase(_Case, Config) -> all(doc) -> []; all(suite) -> - [args_file, evil_args_file, env, args_file_env, otp_7461, otp_8209]. + [args_file, evil_args_file, env, args_file_env, otp_7461, otp_8209, + zdbbl_dist_buf_busy_limit]. otp_8209(doc) -> @@ -330,6 +331,25 @@ otp_7461_remote([halt, Pid]) -> io:format("halt order from ~p to node ~p\n",[Pid,node()]), halt(). +zdbbl_dist_buf_busy_limit(doc) -> + ["Check +zdbbl flag"]; +zdbbl_dist_buf_busy_limit(suite) -> + []; +zdbbl_dist_buf_busy_limit(Config) when is_list(Config) -> + LimKB = 1122233, + LimB = LimKB*1024, + ?line {ok,[[PName]]} = init:get_argument(progname), + ?line SNameS = "erlexec_test_02", + ?line SName = list_to_atom(SNameS++"@"++ + hd(tl(string:tokens(atom_to_list(node()),"@")))), + ?line Cmd = PName ++ " -sname "++SNameS++" -setcookie "++ + atom_to_list(erlang:get_cookie()) ++ + " +zdbbl " ++ integer_to_list(LimKB), + ?line open_port({spawn,Cmd},[]), + ?line pong = loop_ping(SName,40), + ?line LimB = rpc:call(SName,erlang,system_info,[dist_buf_busy_limit]), + ?line ok = cleanup_node(SNameS, 10), + ok. %% diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl index 0cc315e9be..93e27fa8d3 100644 --- a/erts/test/ethread_SUITE.erl +++ b/erts/test/ethread_SUITE.erl @@ -171,7 +171,15 @@ max_threads(doc) -> max_threads(suite) -> []; max_threads(Config) -> - run_case(Config, "max_threads", ""). + case {os:type(), os:version()} of + {{unix,darwin}, {9, _, _}} -> + %% For some reason pthread_create() crashes when more + %% threads cannot be created, instead of returning an + %% error code on our MacOS X Leopard machine... + {skipped, "MacOS X Leopard cannot cope with this test..."}; + _ -> + run_case(Config, "max_threads", "") + end. tsd(doc) -> ["Tests thread specific data."]; diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl index 8faddeb0d3..9f13a7083d 100644 --- a/erts/test/z_SUITE.erl +++ b/erts/test/z_SUITE.erl @@ -253,6 +253,8 @@ core_file_search(#core_search_conf{search_dir = Base, core_cand(Conf, Core, Cores); "core." ++ _ -> core_cand(Conf, Core, Cores); + Bin when is_binary(Bin) -> %Icky filename; ignore + Cores; BName -> case lists:suffix(".core", BName) of true -> core_cand(Conf, Core, Cores); diff --git a/erts/vsn.mk b/erts/vsn.mk index ce6330e6dd..a5dd62feb2 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -17,8 +17,8 @@ # %CopyrightEnd% # -VSN = 5.8.1 -SYSTEM_VSN = R14B +VSN = 5.8.2 +SYSTEM_VSN = R14B01 # Port number 4365 in 4.2 # Port number 4366 in 4.3 diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index df430c4f88..cce6eb9831 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -66,9 +66,9 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> end, case Typename of ['EXTERNAL'] -> - emit({{var,asn1ct_name:next(val)}, + emit({{next,val}, " = asn1rt_check:transform_to_EXTERNAL1990(", - {var,asn1ct_name:curr(val)},"),",nl}), + {curr,val},"),",nl}), asn1ct_name:new(val); _ -> ok @@ -77,23 +77,40 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> {[],EmptyCL} when EmptyCL == {[],[],[]};EmptyCL == {[],[]};EmptyCL == [] -> emit(["%%Variable setting just to eliminate ", "compiler warning for unused vars!",nl, - "_Val = ",{var,asn1ct_name:curr(val)},",",nl]); + "_Val = ",{curr,val},",",nl]); {[],_} -> - emit([{var,asn1ct_name:next(val)}," = ?RT_PER:list_to_record("]), + emit([{next,val}," = ?RT_PER:list_to_record("]), emit(["'",asn1ct_gen:list2rname(Typename),"'"]), - emit([", ",{var,asn1ct_name:curr(val)},"),",nl]); + emit([", ",{curr,val},"),",nl]); _ -> Fixoptcall = ",Opt} = ?RT_PER:fixoptionals(", - emit({"{",{var,asn1ct_name:next(val)},Fixoptcall, + emit({"{",{next,val},Fixoptcall, {asis,Optionals},",",length(Optionals), - ",",{var,asn1ct_name:curr(val)},"),",nl}) + ",",{curr,val},"),",nl}) end, asn1ct_name:new(val), Ext = extensible_enc(CompList), case Ext of {ext,_,NumExt} when NumExt > 0 -> - emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext}, - ", ",{curr,val},"),",nl]); + case extgroup_pos_and_length(CompList) of + {extgrouppos,ExtGroupPos,ExtGroupLen} -> + Elements = make_elements(ExtGroupPos+1, + "Val1",lists:seq(1,ExtGroupLen)), + emit([ + {next,val}," = case [X || X <- [",Elements, + "],X =/= asn1_NOVALUE] of",nl, + "[] -> ",{curr,val},";",nl, + "_ -> setelement(",{asis,ExtGroupPos+1},",", + {curr,val},",", + "{extaddgroup,", Elements,"})",nl, + "end,",nl]), + asn1ct_name:new(val); + _ -> % no extensionAdditionGroup + ok + end, + asn1ct_name:new(tmpval), + emit(["Extensions = ?RT_PER:fixextensions(",{asis,Ext},",", + {curr,val},"),",nl]); _ -> true end, EncObj = @@ -303,7 +320,7 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> mkvlist(textual_order(to_encoding_order(CompList),asn1ct_name:all(term))), emit("},") end, - emit({{var,asn1ct_name:curr(bytes)},"}"}), + emit({{curr,bytes},"}"}), emit({".",nl,nl}). textual_order([#'ComponentType'{textual_order=undefined}|_],TermList) -> @@ -596,6 +613,27 @@ ext_length([#'ComponentType'{}|T],State=normal,Acc) -> ext_length([],_,Acc) -> Acc. +extgroup_pos_and_length(CompList) when is_list(CompList) -> + noextgroup; +extgroup_pos_and_length({RootList,ExtList}) -> + extgrouppos(ExtList,length(RootList)+1); +extgroup_pos_and_length({Rl1,Ext,_Rl2}) -> + extgrouppos(Ext,length(Rl1)+1). + +extgrouppos([{'ExtensionAdditionGroup',_Num}|T],Pos) -> + extgrouppos(T,Pos,0); +extgrouppos([_|T],Pos) -> + extgrouppos(T,Pos+1); +extgrouppos([],_) -> + noextgroup. + +extgrouppos(['ExtensionAdditionGroupEnd'|_T],Pos,Len) -> + {extgrouppos,Pos,Len}; +extgrouppos([_|T],Pos,Len) -> + extgrouppos(T,Pos,Len+1). + + + gen_dec_extension_value(_) -> emit({"{Ext,",{next,bytes},"} = ?RT_PER:getext(",{curr,bytes},")"}), asn1ct_name:new(bytes). @@ -743,7 +781,7 @@ gen_enc_components_call1(_Erule,_TopType,[],Pos,_,_,_) -> Pos. gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal) -> - Element = make_element(Pos+1,"Val1",Cname), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), emit({"case ",Element," of",nl}), % emit({"asn1_DEFAULT -> [];",nl}), emit({"DFLT when DFLT == asn1_DEFAULT; DFLT == ",{asis,DefaultVal}," -> [];",nl}), @@ -760,24 +798,23 @@ gen_enc_component_default(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext,DefaultVal gen_enc_component_optional(Erule,TopType,Cname, Type=#type{def=#'SEQUENCE'{ extaddgroup=Number, - components=ExtGroupCompList}}, + components=_ExtGroupCompList}}, Pos,DynamicEnc,Ext) when is_integer(Number) -> - emit({nl,"begin",nl}), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), + emit({"case ",Element," of",nl}), + + emit({"asn1_NOVALUE -> [];",nl}), asn1ct_name:new(tmpval), - ExtAddGroupTypeName = asn1ct_gen:list2name([Cname|TopType]), - emit({{curr,tmpval}," = {'",ExtAddGroupTypeName,"', "}), - ExtNames = [ExtName||#'ComponentType'{name=ExtName}<-ExtGroupCompList], - Elements = make_elements(Pos+1,"Val1",ExtNames), - emit({Elements,"},"}), - InnerType = asn1ct_gen:get_inner(Type#type.def), + emit({{curr,tmpval}," ->",nl}), + InnerType = asn1ct_gen:get_inner(Type#type.def), emit({nl,"%% attribute number ",Pos," with type ", InnerType,nl}), NextElement = asn1ct_gen:mk_var(asn1ct_name:curr(tmpval)), gen_enc_line(Erule,TopType,Cname,Type,NextElement, Pos,DynamicEnc,Ext), emit({nl,"end"}); gen_enc_component_optional(Erule,TopType,Cname,Type,Pos,DynamicEnc,Ext) -> - Element = make_element(Pos+1,"Val1",Cname), + Element = make_element(Pos+1,asn1ct_gen:mk_var(asn1ct_name:curr(val)),Cname), emit({"case ",Element," of",nl}), emit({"asn1_NOVALUE -> [];",nl}), diff --git a/lib/asn1/src/asn1rt_driver_handler.erl b/lib/asn1/src/asn1rt_driver_handler.erl index c95b243ae0..cc2b501e16 100644 --- a/lib/asn1/src/asn1rt_driver_handler.erl +++ b/lib/asn1/src/asn1rt_driver_handler.erl @@ -71,7 +71,10 @@ load_driver(Reason) -> end. init(FromPid,FromRef) -> - register(asn1_driver_owner,self()), + case catch register(asn1_driver_owner,self()) of + true -> true; + _Other -> exit(normal) + end, Dir = filename:join([code:priv_dir(asn1),"lib"]), case catch erl_ddll:load_driver(Dir,asn1_erl_drv) of ok -> diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src index fad094c988..e1a09adc82 100644 --- a/lib/asn1/test/asn1_SUITE.erl.src +++ b/lib/asn1/test/asn1_SUITE.erl.src @@ -2302,9 +2302,12 @@ testExtensionAdditionGroup(Config) -> ?line ok = asn1ct:compile(filename:join(DataDir,"Extension-Addition-Group"),Erule ++ [{outdir,PrivDir}]), ?line {ok,_M} = compile:file(filename:join(DataDir,"extensionAdditionGroup"),[{i,PrivDir},{outdir,PrivDir},debug_info]), ?line ok = extensionAdditionGroup:run(Erule), - ?line ok = extensionAdditionGroup:run2(Erule) + ?line ok = extensionAdditionGroup:run2(Erule), + ?line ok = asn1ct:compile(filename:join(DataDir,"EUTRA-RRC-Definitions"),Erule ++ [{record_name_prefix,"RRC-"},{outdir,PrivDir}]), + ?line ok = extensionAdditionGroup:run3(Erule) end, - ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin],[ber_bin],[ber_bin,optimize]]], + ?line [DoIt(Rule)|| Rule <- [[per_bin],[per_bin,optimize],[uper_bin]]], + %% FIXME problems with automatic tags [ber_bin],[ber_bin,optimize] ?line code:set_path(Path). diff --git a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn index a451874ef0..3b811dafe6 100644 --- a/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn +++ b/lib/asn1/test/asn1_SUITE_data/EUTRA-RRC-Definitions.asn @@ -1,2640 +1,3155 @@ --- 3GPP TS 36.331 V8.8.0 (2009-12) --- $Id$ --- -EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::= - -BEGIN - - -BCCH-BCH-Message ::= SEQUENCE { - message BCCH-BCH-MessageType -} - -BCCH-BCH-MessageType ::= MasterInformationBlock - - -BCCH-DL-SCH-Message ::= SEQUENCE { - message BCCH-DL-SCH-MessageType -} - -BCCH-DL-SCH-MessageType ::= CHOICE { - c1 CHOICE { - systemInformation SystemInformation, - systemInformationBlockType1 SystemInformationBlockType1 - }, - messageClassExtension SEQUENCE {} -} - - -PCCH-Message ::= SEQUENCE { - message PCCH-MessageType -} - -PCCH-MessageType ::= CHOICE { - c1 CHOICE { - paging Paging - }, - messageClassExtension SEQUENCE {} -} - - -DL-CCCH-Message ::= SEQUENCE { - message DL-CCCH-MessageType -} - -DL-CCCH-MessageType ::= CHOICE { - c1 CHOICE { - rrcConnectionReestablishment RRCConnectionReestablishment, - rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject, - rrcConnectionReject RRCConnectionReject, - rrcConnectionSetup RRCConnectionSetup - }, - messageClassExtension SEQUENCE {} -} - - -DL-DCCH-Message ::= SEQUENCE { - message DL-DCCH-MessageType -} - -DL-DCCH-MessageType ::= CHOICE { - c1 CHOICE { - csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000, - dlInformationTransfer DLInformationTransfer, - handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest, - mobilityFromEUTRACommand MobilityFromEUTRACommand, - rrcConnectionReconfiguration RRCConnectionReconfiguration, - rrcConnectionRelease RRCConnectionRelease, - securityModeCommand SecurityModeCommand, - ueCapabilityEnquiry UECapabilityEnquiry, - counterCheck CounterCheck, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - messageClassExtension SEQUENCE {} -} - - -UL-CCCH-Message ::= SEQUENCE { - message UL-CCCH-MessageType -} - -UL-CCCH-MessageType ::= CHOICE { - c1 CHOICE { - rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest, - rrcConnectionRequest RRCConnectionRequest - }, - messageClassExtension SEQUENCE {} -} - - -UL-DCCH-Message ::= SEQUENCE { - message UL-DCCH-MessageType -} - -UL-DCCH-MessageType ::= CHOICE { - c1 CHOICE { - csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000, - measurementReport MeasurementReport, - rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete, - rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete, - rrcConnectionSetupComplete RRCConnectionSetupComplete, - securityModeComplete SecurityModeComplete, - securityModeFailure SecurityModeFailure, - ueCapabilityInformation UECapabilityInformation, - ulHandoverPreparationTransfer ULHandoverPreparationTransfer, - ulInformationTransfer ULInformationTransfer, - counterCheckResponse CounterCheckResponse, - spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - messageClassExtension SEQUENCE {} -} - - -CounterCheck ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - counterCheck-r8 CounterCheck-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -CounterCheck-r8-IEs ::= SEQUENCE { - drb-CountMSB-InfoList DRB-CountMSB-InfoList, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - -DRB-CountMSB-InfoList::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info - -DRB-CountMSB-Info ::= SEQUENCE { - drb-Identity DRB-Identity, - countMSB-Uplink INTEGER(0..33554431), - countMSB-Downlink INTEGER(0..33554431) -} - - -CounterCheckResponse ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - counterCheckResponse-r8 CounterCheckResponse-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CounterCheckResponse-r8-IEs ::= SEQUENCE { - drb-CountInfoList DRB-CountInfoList, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo - -DRB-CountInfo ::= SEQUENCE { - drb-Identity DRB-Identity, - count-Uplink INTEGER(0..4294967295), - count-Downlink INTEGER(0..4294967295) -} - - -CSFBParametersRequestCDMA2000 ::= SEQUENCE { - criticalExtensions CHOICE { - csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -CSFBParametersResponseCDMA2000 ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE { - rand RAND-CDMA2000, - mobilityParameters MobilityParametersCDMA2000, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - - -DLInformationTransfer ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - dlInformationTransfer-r8 DLInformationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -DLInformationTransfer-r8-IEs ::= SEQUENCE { - dedicatedInfoType CHOICE { - dedicatedInfoNAS DedicatedInfoNAS, - dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, - dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 - }, - nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP -} - - -HandoverFromEUTRAPreparationRequest ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - handoverFromEUTRAPreparationRequest-r8 - HandoverFromEUTRAPreparationRequest-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type - mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -MasterInformationBlock ::= SEQUENCE { - dl-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100}, - phich-Config PHICH-Config, - systemFrameNumber BIT STRING (SIZE (8)), - spare BIT STRING (SIZE (10)) -} - - - -MeasurementReport ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE{ - measurementReport-r8 MeasurementReport-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -MeasurementReport-r8-IEs ::= SEQUENCE { - measResults MeasResults, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -MobilityFromEUTRACommand ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE { - cs-FallbackIndicator BOOLEAN, - purpose CHOICE{ - handover Handover, - cellChangeOrder CellChangeOrder - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -Handover ::= SEQUENCE { - targetRAT-Type ENUMERATED { - utra, geran, cdma2000-1XRTT, cdma2000-HRPD, - spare4, spare3, spare2, spare1, ...}, - targetRAT-MessageContainer OCTET STRING, - nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN - systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO -} - -CellChangeOrder ::= SEQUENCE { - t304 ENUMERATED { - ms100, ms200, ms500, ms1000, - ms2000, ms4000, ms8000, spare1}, - targetRAT-Type CHOICE { - geran SEQUENCE { - physCellId PhysCellIdGERAN, - carrierFreq CarrierFreqGERAN, - networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP - systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP - }, - ... - } -} - -SI-OrPSI-GERAN ::= CHOICE { - si SystemInfoListGERAN, - psi SystemInfoListGERAN -} - -SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF - OCTET STRING (SIZE (1..23)) - - -Paging ::= SEQUENCE { - pagingRecordList PagingRecordList OPTIONAL, -- Need ON - systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON - etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord - -PagingRecord ::= SEQUENCE { - ue-Identity PagingUE-Identity, - cn-Domain ENUMERATED {ps, cs}, - ... -} - -PagingUE-Identity ::= CHOICE { - s-TMSI S-TMSI, - imsi IMSI, - ... -} - -IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit - -IMSI-Digit::= INTEGER (0..9) - - -RRCConnectionReconfiguration ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE { - measConfig MeasConfig OPTIONAL, -- Need ON - mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO - dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF - DedicatedInfoNAS OPTIONAL, -- Cond nonHO - radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA - securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -SecurityConfigHO ::= SEQUENCE { - handoverType CHOICE { - intraLTE SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Need OP - keyChangeIndicator BOOLEAN, - nextHopChainingCount NextHopChainingCount - }, - interRAT SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig, - nas-SecurityParamToEUTRA OCTET STRING (SIZE(6)) - } - }, - ... -} - - -RRCConnectionReconfigurationComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - rrcConnectionReconfigurationComplete-r8 - RRCConnectionReconfigurationComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -RRCConnectionReestablishment ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishment-r8-IEs ::= SEQUENCE { - radioResourceConfigDedicated RadioResourceConfigDedicated, - nextHopChainingCount NextHopChainingCount, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionReestablishmentComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - rrcConnectionReestablishmentComplete-r8 - RRCConnectionReestablishmentComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -RRCConnectionReestablishmentReject ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionReestablishmentReject-r8 - RRCConnectionReestablishmentReject-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionReestablishmentRequest ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionReestablishmentRequest-r8 - RRCConnectionReestablishmentRequest-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE { - ue-Identity ReestabUE-Identity, - reestablishmentCause ReestablishmentCause, - spare BIT STRING (SIZE (2)) -} - -ReestabUE-Identity ::= SEQUENCE { - c-RNTI C-RNTI, - physCellId PhysCellId, - shortMAC-I ShortMAC-I -} - -ReestablishmentCause ::= ENUMERATED { - reconfigurationFailure, handoverFailure, - otherFailure, spare1} - - -RRCConnectionReject ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionReject-r8 RRCConnectionReject-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionReject-r8-IEs ::= SEQUENCE { - waitTime INTEGER (1..16), - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionRelease ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionRelease-r8-IEs ::= SEQUENCE { - releaseCause ReleaseCause, - redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON - idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired, - other,spare2, spare1 } - -RedirectedCarrierInfo ::= CHOICE { - eutra ARFCN-ValueEUTRA, - geran CarrierFreqsGERAN, - utra-FDD ARFCN-ValueUTRA, - utra-TDD ARFCN-ValueUTRA, - cdma2000-HRPD CarrierFreqCDMA2000, - cdma2000-1xRTT CarrierFreqCDMA2000, - ... -} - -IdleModeMobilityControlInfo ::= SEQUENCE { - freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON - freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON - freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON - freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON - bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON - bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON - t320 ENUMERATED { - min5, min10, min20, min30, min60, min120, min180, - spare1} OPTIONAL, -- Need OR - ... -} - -FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA - -FreqPriorityEUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueEUTRA, - cellReselectionPriority CellReselectionPriority -} - -FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN - -FreqsPriorityGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - cellReselectionPriority CellReselectionPriority -} - -FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD - -FreqPriorityUTRA-FDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority -} - -FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD - -FreqPriorityUTRA-TDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority -} - -BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD - -BandClassPriorityHRPD ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority -} - -BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT - -BandClassPriority1XRTT ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority -} - -RRCConnectionRequest ::= SEQUENCE { - criticalExtensions CHOICE { - rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionRequest-r8-IEs ::= SEQUENCE { - ue-Identity InitialUE-Identity, - establishmentCause EstablishmentCause, - spare BIT STRING (SIZE (1)) -} - -InitialUE-Identity ::= CHOICE { - s-TMSI S-TMSI, - randomValue BIT STRING (SIZE (40)) -} - -EstablishmentCause ::= ENUMERATED { - emergency, highPriorityAccess, mt-Access, mo-Signalling, - mo-Data, spare3, spare2, spare1} - - -RRCConnectionSetup ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionSetup-r8-IEs ::= SEQUENCE { - radioResourceConfigDedicated RadioResourceConfigDedicated, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -RRCConnectionSetupComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE { - selectedPLMN-Identity INTEGER (1..6), - registeredMME RegisteredMME OPTIONAL, - dedicatedInfoNAS DedicatedInfoNAS, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -RegisteredMME ::= SEQUENCE { - plmn-Identity PLMN-Identity OPTIONAL, - mmegi BIT STRING (SIZE (16)), - mmec MMEC -} - - -SecurityModeCommand ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - securityModeCommand-r8 SecurityModeCommand-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeCommand-r8-IEs ::= SEQUENCE { - securityConfigSMC SecurityConfigSMC, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -SecurityConfigSMC ::= SEQUENCE { - securityAlgorithmConfig SecurityAlgorithmConfig, - ... -} - - -SecurityModeComplete ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - securityModeComplete-r8 SecurityModeComplete-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeComplete-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SecurityModeFailure ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - securityModeFailure-r8 SecurityModeFailure-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} - -SecurityModeFailure-r8-IEs ::= SEQUENCE { - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SystemInformation ::= SEQUENCE { - criticalExtensions CHOICE { - systemInformation-r8 SystemInformation-r8-IEs, - criticalExtensionsFuture SEQUENCE {} - } -} -SystemInformation-r8-IEs ::= SEQUENCE { - sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE { - sib2 SystemInformationBlockType2, - sib3 SystemInformationBlockType3, - sib4 SystemInformationBlockType4, - sib5 SystemInformationBlockType5, - sib6 SystemInformationBlockType6, - sib7 SystemInformationBlockType7, - sib8 SystemInformationBlockType8, - sib9 SystemInformationBlockType9, - sib10 SystemInformationBlockType10, - sib11 SystemInformationBlockType11, - ... - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - - -SystemInformationBlockType1 ::= SEQUENCE { - cellAccessRelatedInfo SEQUENCE { - plmn-IdentityList PLMN-IdentityList, - trackingAreaCode TrackingAreaCode, - cellIdentity CellIdentity, - cellBarred ENUMERATED {barred, notBarred}, - intraFreqReselection ENUMERATED {allowed, notAllowed}, - csg-Indication BOOLEAN, - csg-Identity BIT STRING (SIZE (27)) OPTIONAL -- Need OR - }, - cellSelectionInfo SEQUENCE { - q-RxLevMin Q-RxLevMin, - q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP - }, - p-Max P-Max OPTIONAL, -- Need OP - freqBandIndicator INTEGER (1..64), - schedulingInfoList SchedulingInfoList, - tdd-Config TDD-Config OPTIONAL, -- Cond TDD - si-WindowLength ENUMERATED { - ms1, ms2, ms5, ms10, ms15, ms20, - ms40}, - systemInfoValueTag INTEGER (0..31), - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo - -PLMN-IdentityInfo ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellReservedForOperatorUse ENUMERATED {reserved, notReserved} -} - -SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo - -SchedulingInfo ::= SEQUENCE { - si-Periodicity ENUMERATED { - rf8, rf16, rf32, rf64, rf128, rf256, rf512}, - sib-MappingInfo SIB-MappingInfo -} - -SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type - -SIB-Type ::= ENUMERATED { - sibType3, sibType4, sibType5, sibType6, - sibType7, sibType8, sibType9, sibType10, - sibType11, spare7, spare6, spare5, - spare4, spare3, spare2, spare1, ...} - - -UECapabilityEnquiry ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE { - ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -UECapabilityEnquiry-r8-IEs ::= SEQUENCE { - ue-CapabilityRequest UE-CapabilityRequest, - nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP -} - -UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type - - -UECapabilityInformation ::= SEQUENCE { - rrc-TransactionIdentifier RRC-TransactionIdentifier, - criticalExtensions CHOICE { - c1 CHOICE{ - ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs, - spare7 NULL, - spare6 NULL, spare5 NULL, spare4 NULL, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -UECapabilityInformation-r8-IEs ::= SEQUENCE { - ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -ULHandoverPreparationTransfer ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - meid BIT STRING (SIZE (56)) OPTIONAL, - dedicatedInfo DedicatedInfoCDMA2000, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -ULInformationTransfer ::= SEQUENCE { - criticalExtensions CHOICE { - c1 CHOICE { - ulInformationTransfer-r8 ULInformationTransfer-r8-IEs, - spare3 NULL, spare2 NULL, spare1 NULL - }, - criticalExtensionsFuture SEQUENCE {} - } -} - -ULInformationTransfer-r8-IEs ::= SEQUENCE { - dedicatedInfoType CHOICE { - dedicatedInfoNAS DedicatedInfoNAS, - dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000, - dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000 - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - - -SystemInformationBlockType2 ::= SEQUENCE { - ac-BarringInfo SEQUENCE { - ac-BarringForEmergency BOOLEAN, - ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP - ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP - } OPTIONAL, -- Need OP - radioResourceConfigCommon RadioResourceConfigCommonSIB, - ue-TimersAndConstants UE-TimersAndConstants, - freqInfo SEQUENCE { - ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP - ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100} - OPTIONAL, -- Need OP - additionalSpectrumEmission AdditionalSpectrumEmission - }, - mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR - timeAlignmentTimerCommon TimeAlignmentTimer, - ... -} - -AC-BarringConfig ::= SEQUENCE { - ac-BarringFactor ENUMERATED { - p00, p05, p10, p15, p20, p25, p30, p40, - p50, p60, p70, p75, p80, p85, p90, p95}, - ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512}, - ac-BarringForSpecialAC BIT STRING (SIZE(5)) -} - -MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig - -MBSFN-SubframeConfig ::= SEQUENCE { - radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32}, - radioframeAllocationOffset INTEGER (0..7), - subframeAllocation CHOICE { - oneFrame BIT STRING (SIZE(6)), - fourFrames BIT STRING (SIZE(24)) - } -} - -SystemInformationBlockType3 ::= SEQUENCE { - cellReselectionInfoCommon SEQUENCE { - q-Hyst ENUMERATED { - dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10, - dB12, dB14, dB16, dB18, dB20, dB22, dB24}, - speedStateReselectionPars SEQUENCE { - mobilityStateParameters MobilityStateParameters, - q-HystSF SEQUENCE { - sf-Medium ENUMERATED { - dB-6, dB-4, dB-2, dB0}, - sf-High ENUMERATED { - dB-6, dB-4, dB-2, dB0} - } - } OPTIONAL -- Need OP - }, - cellReselectionServingFreqInfo SEQUENCE { - s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP - threshServingLow ReselectionThreshold, - cellReselectionPriority CellReselectionPriority - }, - intraFreqCellReselectionInfo SEQUENCE { - q-RxLevMin Q-RxLevMin, - p-Max P-Max OPTIONAL, -- Need OP - s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP - allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP - presenceAntennaPort1 PresenceAntennaPort1, - neighCellConfig NeighCellConfig, - t-ReselectionEUTRA T-Reselection, - t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP - }, - ... -} - - -SystemInformationBlockType4 ::= SEQUENCE { - intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR - intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR - csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG - ... -} - -IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo - -IntraFreqNeighCellInfo ::= SEQUENCE { - physCellId PhysCellId, - q-OffsetCell Q-OffsetRange, - ... -} - -IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange - - -SystemInformationBlockType5 ::= SEQUENCE { - interFreqCarrierFreqList InterFreqCarrierFreqList, - ... -} - -InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo - -InterFreqCarrierFreqInfo ::= SEQUENCE { - dl-CarrierFreq ARFCN-ValueEUTRA, - q-RxLevMin Q-RxLevMin, - p-Max P-Max OPTIONAL, -- Need OP - t-ReselectionEUTRA T-Reselection, - t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - allowedMeasBandwidth AllowedMeasBandwidth, - presenceAntennaPort1 PresenceAntennaPort1, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - neighCellConfig NeighCellConfig, - q-OffsetFreq Q-OffsetRange DEFAULT dB0, - interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR - interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR - ... -} - -InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo - -InterFreqNeighCellInfo ::= SEQUENCE { - physCellId PhysCellId, - q-OffsetCell Q-OffsetRange -} - -InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange - - -SystemInformationBlockType6 ::= SEQUENCE { - carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR - carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR - t-ReselectionUTRA T-Reselection, - t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP - ... -} - -CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD - -CarrierFreqUTRA-FDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - q-RxLevMin INTEGER (-60..-13), - p-MaxUTRA INTEGER (-50..33), - q-QualMin INTEGER (-24..0), - ... -} - -CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD - -CarrierFreqUTRA-TDD ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold, - q-RxLevMin INTEGER (-60..-13), - p-MaxUTRA INTEGER (-50..33), - ... -} - - -SystemInformationBlockType7 ::= SEQUENCE { - t-ReselectionGERAN T-Reselection, - t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR - carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR - ... -} - -CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN - -CarrierFreqsInfoGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - commonInfo SEQUENCE { - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - ncc-Permitted BIT STRING (SIZE (8)), - q-RxLevMin INTEGER (0..45), - p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP - threshX-High ReselectionThreshold, - threshX-Low ReselectionThreshold - }, - ... -} - - -SystemInformationBlockType8 ::= SEQUENCE { - systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR - searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR - parametersHRPD SEQUENCE { - preRegistrationInfoHRPD PreRegistrationInfoHRPD, - cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR - } OPTIONAL, -- Need OR - parameters1XRTT SEQUENCE { - csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP - longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR - cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR - } OPTIONAL, -- Need OR - ... -} - -CellReselectionParametersCDMA2000 ::= SEQUENCE { - bandClassList BandClassListCDMA2000, - neighCellList NeighCellListCDMA2000, - t-ReselectionCDMA2000 T-Reselection, - t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP -} -NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000 - -NeighCellCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000 -} - -NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000 - -NeighCellsPerBandclassCDMA2000 ::= SEQUENCE { - arfcn ARFCN-ValueCDMA2000, - physCellIdList PhysCellIdListCDMA2000 -} - -PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000 - -BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000 - -BandClassInfoCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP - threshX-High INTEGER (0..63), - threshX-Low INTEGER (0..63), - ... -} - - -SystemInformationBlockType9 ::= SEQUENCE { - hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR - ... -} - - -SystemInformationBlockType10 ::= SEQUENCE { - messageIdentifier BIT STRING (SIZE (16)), - serialNumber BIT STRING (SIZE (16)), - warningType OCTET STRING (SIZE (2)), - warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP - ... -} - - -SystemInformationBlockType11 ::= SEQUENCE { - messageIdentifier BIT STRING (SIZE (16)), - serialNumber BIT STRING (SIZE (16)), - warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment}, - warningMessageSegmentNumber INTEGER (0..63), - warningMessageSegment OCTET STRING, - dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1 - ... -} - - -AntennaInfoCommon ::= SEQUENCE { - antennaPortsCount ENUMERATED {an1, an2, an4, spare1} -} - -AntennaInfoDedicated ::= SEQUENCE { - transmissionMode ENUMERATED { - tm1, tm2, tm3, tm4, tm5, tm6, - tm7, spare1}, - codebookSubsetRestriction CHOICE { - n2TxAntenna-tm3 BIT STRING (SIZE (2)), - n4TxAntenna-tm3 BIT STRING (SIZE (4)), - n2TxAntenna-tm4 BIT STRING (SIZE (6)), - n4TxAntenna-tm4 BIT STRING (SIZE (64)), - n2TxAntenna-tm5 BIT STRING (SIZE (4)), - n4TxAntenna-tm5 BIT STRING (SIZE (16)), - n2TxAntenna-tm6 BIT STRING (SIZE (4)), - n4TxAntenna-tm6 BIT STRING (SIZE (16)) - } OPTIONAL, -- Cond TM - ue-TransmitAntennaSelection CHOICE{ - release NULL, - setup ENUMERATED {closedLoop, openLoop} - } -} - - -CQI-ReportConfig ::= SEQUENCE { - cqi-ReportModeAperiodic ENUMERATED { - rm12, rm20, rm22, rm30, rm31, - spare3, spare2, spare1} OPTIONAL, -- Need OR - nomPDSCH-RS-EPRE-Offset INTEGER (-1..6), - cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON -} - -CQI-ReportPeriodic ::= CHOICE { - release NULL, - setup SEQUENCE { - cqi-PUCCH-ResourceIndex INTEGER (0.. 1185), - cqi-pmi-ConfigIndex INTEGER (0..1023), - cqi-FormatIndicatorPeriodic CHOICE { - widebandCQI NULL, - subbandCQI SEQUENCE { - k INTEGER (1..4) - } - }, - ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR - simultaneousAckNackAndCQI BOOLEAN - } -} - - -DRB-Identity ::= INTEGER (1..32) - - -LogicalChannelConfig ::= SEQUENCE { - ul-SpecificParameters SEQUENCE { - priority INTEGER (1..16), - prioritisedBitRate ENUMERATED { - kBps0, kBps8, kBps16, kBps32, kBps64, kBps128, - kBps256, infinity, spare8, spare7, spare6, - spare5, spare4, spare3, spare2, spare1}, - bucketSizeDuration ENUMERATED { - ms50, ms100, ms150, ms300, ms500, ms1000, spare2, - spare1}, - logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR - } OPTIONAL, -- Cond UL - ... -} - - -MAC-MainConfig ::= SEQUENCE { - ul-SCH-Config SEQUENCE { - maxHARQ-Tx ENUMERATED { - n1, n2, n3, n4, n5, n6, n7, n8, - n10, n12, n16, n20, n24, n28, - spare2, spare1} OPTIONAL, -- Need ON - periodicBSR-Timer ENUMERATED { - sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, sf1280, sf2560, - infinity, spare1} OPTIONAL, -- Need ON - retxBSR-Timer ENUMERATED { - sf320, sf640, sf1280, sf2560, sf5120, - sf10240, spare2, spare1}, - ttiBundling BOOLEAN - } OPTIONAL, -- Need ON - drx-Config DRX-Config OPTIONAL, -- Need ON - timeAlignmentTimerDedicated TimeAlignmentTimer, - phr-Config CHOICE { - release NULL, - setup SEQUENCE { - periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200, - sf500, sf1000, infinity}, - prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100, - sf200, sf500, sf1000}, - dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity} - } - } OPTIONAL, -- Need ON - ... -} - -DRX-Config ::= CHOICE { - release NULL, - setup SEQUENCE { - onDurationTimer ENUMERATED { - psf1, psf2, psf3, psf4, psf5, psf6, - psf8, psf10, psf20, psf30, psf40, - psf50, psf60, psf80, psf100, - psf200}, - drx-InactivityTimer ENUMERATED { - psf1, psf2, psf3, psf4, psf5, psf6, - psf8, psf10, psf20, psf30, psf40, - psf50, psf60, psf80, psf100, - psf200, psf300, psf500, psf750, - psf1280, psf1920, psf2560, spare10, - spare9, spare8, spare7, spare6, - spare5, spare4, spare3, spare2, - spare1}, - drx-RetransmissionTimer ENUMERATED { - psf1, psf2, psf4, psf6, psf8, psf16, - psf24, psf33}, - longDRX-CycleStartOffset CHOICE { - sf10 INTEGER(0..9), - sf20 INTEGER(0..19), - sf32 INTEGER(0..31), - sf40 INTEGER(0..39), - sf64 INTEGER(0..63), - sf80 INTEGER(0..79), - sf128 INTEGER(0..127), - sf160 INTEGER(0..159), - sf256 INTEGER(0..255), - sf320 INTEGER(0..319), - sf512 INTEGER(0..511), - sf640 INTEGER(0..639), - sf1024 INTEGER(0..1023), - sf1280 INTEGER(0..1279), - sf2048 INTEGER(0..2047), - sf2560 INTEGER(0..2559) - }, - shortDRX SEQUENCE { - shortDRX-Cycle ENUMERATED { - sf2, sf5, sf8, sf10, sf16, sf20, - sf32, sf40, sf64, sf80, sf128, sf160, - sf256, sf320, sf512, sf640}, - drxShortCycleTimer INTEGER (1..16) - } OPTIONAL -- Need OR - } -} - - -PDCP-Config ::= SEQUENCE { - discardTimer ENUMERATED { - ms50, ms100, ms150, ms300, ms500, - ms750, ms1500, infinity - } OPTIONAL, -- Cond Setup - rlc-AM SEQUENCE { - statusReportRequired BOOLEAN - } OPTIONAL, -- Cond Rlc-AM - rlc-UM SEQUENCE { - pdcp-SN-Size ENUMERATED {len7bits, len12bits} - } OPTIONAL, -- Cond Rlc-UM - headerCompression CHOICE { - notUsed NULL, - rohc SEQUENCE { - maxCID INTEGER (1..16383) DEFAULT 15, - profiles SEQUENCE { - profile0x0001 BOOLEAN, - profile0x0002 BOOLEAN, - profile0x0003 BOOLEAN, - profile0x0004 BOOLEAN, - profile0x0006 BOOLEAN, - profile0x0101 BOOLEAN, - profile0x0102 BOOLEAN, - profile0x0103 BOOLEAN, - profile0x0104 BOOLEAN - }, - ... - } - }, - ... -} - - -PDSCH-ConfigCommon::= SEQUENCE { - referenceSignalPower INTEGER (-60..50), - p-b INTEGER (0..3) -} - -PDSCH-ConfigDedicated::= SEQUENCE { - p-a ENUMERATED { - dB-6, dB-4dot77, dB-3, dB-1dot77, - dB0, dB1, dB2, dB3 } -} - - -PHICH-Config ::= SEQUENCE { - phich-Duration ENUMERATED {normal, extended}, - phich-Resource ENUMERATED {oneSixth, half, one, two} -} - - -PhysicalConfigDedicated ::= SEQUENCE { - pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON - pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON - pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON - uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON - tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON - tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON - cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON - soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON - antennaInfo CHOICE { - explicitValue AntennaInfoDedicated, - defaultValue NULL - } OPTIONAL, -- Need ON - schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON - ... -} - - -P-Max ::= INTEGER (-30..33) - - -PRACH-ConfigSIB ::= SEQUENCE { - rootSequenceIndex INTEGER (0..837), - prach-ConfigInfo PRACH-ConfigInfo -} - -PRACH-Config ::= SEQUENCE { - rootSequenceIndex INTEGER (0..837), - prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON -} - -PRACH-ConfigInfo ::= SEQUENCE { - prach-ConfigIndex INTEGER (0..63), - highSpeedFlag BOOLEAN, - zeroCorrelationZoneConfig INTEGER (0..15), - prach-FreqOffset INTEGER (0..94) -} - - -PresenceAntennaPort1 ::= BOOLEAN - - -PUCCH-ConfigCommon ::= SEQUENCE { - deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3}, - nRB-CQI INTEGER (0..98), - nCS-AN INTEGER (0..7), - n1PUCCH-AN INTEGER (0..2047) -} - -PUCCH-ConfigDedicated ::= SEQUENCE { - ackNackRepetition CHOICE{ - release NULL, - setup SEQUENCE { - repetitionFactor ENUMERATED { n2, n4, n6, spare1}, - n1PUCCH-AN-Rep INTEGER (0..2047) - } - }, - tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD -} - - -PUSCH-ConfigCommon ::= SEQUENCE { - pusch-ConfigBasic SEQUENCE { - n-SB INTEGER (1..4), - hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame}, - pusch-HoppingOffset INTEGER (0..98), - enable64QAM BOOLEAN - }, - ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH -} - -PUSCH-ConfigDedicated ::= SEQUENCE { - betaOffset-ACK-Index INTEGER (0..15), - betaOffset-RI-Index INTEGER (0..15), - betaOffset-CQI-Index INTEGER (0..15) -} - -UL-ReferenceSignalsPUSCH ::= SEQUENCE { - groupHoppingEnabled BOOLEAN, - groupAssignmentPUSCH INTEGER (0..29), - sequenceHoppingEnabled BOOLEAN, - cyclicShift INTEGER (0..7) -} - - -RACH-ConfigCommon ::= SEQUENCE { - preambleInfo SEQUENCE { - numberOfRA-Preambles ENUMERATED { - n4, n8, n12, n16 ,n20, n24, n28, - n32, n36, n40, n44, n48, n52, n56, - n60, n64}, - preamblesGroupAConfig SEQUENCE { - sizeOfRA-PreamblesGroupA ENUMERATED { - n4, n8, n12, n16 ,n20, n24, n28, - n32, n36, n40, n44, n48, n52, n56, - n60}, - messageSizeGroupA ENUMERATED {b56, b144, b208, b256}, - messagePowerOffsetGroupB ENUMERATED { - minusinfinity, dB0, dB5, dB8, dB10, dB12, - dB15, dB18}, - ... - } OPTIONAL -- Need OP - }, - powerRampingParameters SEQUENCE { - powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6}, - preambleInitialReceivedTargetPower ENUMERATED { - dBm-120, dBm-118, dBm-116, dBm-114, dBm-112, - dBm-110, dBm-108, dBm-106, dBm-104, dBm-102, - dBm-100, dBm-98, dBm-96, dBm-94, - dBm-92, dBm-90} - }, - ra-SupervisionInfo SEQUENCE { - preambleTransMax ENUMERATED { - n3, n4, n5, n6, n7, n8, n10, n20, n50, - n100, n200}, - ra-ResponseWindowSize ENUMERATED { - sf2, sf3, sf4, sf5, sf6, sf7, - sf8, sf10}, - mac-ContentionResolutionTimer ENUMERATED { - sf8, sf16, sf24, sf32, sf40, sf48, - sf56, sf64} - }, - maxHARQ-Msg3Tx INTEGER (1..8), - ... -} - - -RACH-ConfigDedicated ::= SEQUENCE { - ra-PreambleIndex INTEGER (0..63), - ra-PRACH-MaskIndex INTEGER (0..15) -} - - -RadioResourceConfigCommonSIB ::= SEQUENCE { - rach-ConfigCommon RACH-ConfigCommon, - bcch-Config BCCH-Config, - pcch-Config PCCH-Config, - prach-Config PRACH-ConfigSIB, - pdsch-ConfigCommon PDSCH-ConfigCommon, - pusch-ConfigCommon PUSCH-ConfigCommon, - pucch-ConfigCommon PUCCH-ConfigCommon, - soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon, - uplinkPowerControlCommon UplinkPowerControlCommon, - ul-CyclicPrefixLength UL-CyclicPrefixLength, - ... -} - -RadioResourceConfigCommon ::= SEQUENCE { - rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON - prach-Config PRACH-Config, - pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON - pusch-ConfigCommon PUSCH-ConfigCommon, - phich-Config PHICH-Config OPTIONAL, -- Need ON - pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON - soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON - uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON - antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON - p-Max P-Max OPTIONAL, -- Need OP - tdd-Config TDD-Config OPTIONAL, -- Cond TDD - ul-CyclicPrefixLength UL-CyclicPrefixLength, - ... -} - -BCCH-Config ::= SEQUENCE { - modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16} -} - -PCCH-Config ::= SEQUENCE { - defaultPagingCycle ENUMERATED { - rf32, rf64, rf128, rf256}, - nB ENUMERATED { - fourT, twoT, oneT, halfT, quarterT, oneEighthT, - oneSixteenthT, oneThirtySecondT} -} - -UL-CyclicPrefixLength ::= ENUMERATED {len1, len2} - - -RadioResourceConfigDedicated ::= SEQUENCE { - srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn - drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA - drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON - mac-MainConfig CHOICE { - explicitValue MAC-MainConfig, - defaultValue NULL - } OPTIONAL, -- Cond HO-toEUTRA2 - sps-Config SPS-Config OPTIONAL, -- Need ON - physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON - ... -} - -SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod - -SRB-ToAddMod ::= SEQUENCE { - srb-Identity INTEGER (1..2), - rlc-Config CHOICE { - explicitValue RLC-Config, - defaultValue NULL - } OPTIONAL, -- Cond Setup - logicalChannelConfig CHOICE { - explicitValue LogicalChannelConfig, - defaultValue NULL - } OPTIONAL, -- Cond Setup - ... -} - -DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod - -DRB-ToAddMod ::= SEQUENCE { - eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup - drb-Identity DRB-Identity, - pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP - rlc-Config RLC-Config OPTIONAL, -- Cond Setup - logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup - logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup - ... -} - -DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity - - -RLC-Config ::= CHOICE { - am SEQUENCE { - ul-AM-RLC UL-AM-RLC, - dl-AM-RLC DL-AM-RLC - }, - um-Bi-Directional SEQUENCE { - ul-UM-RLC UL-UM-RLC, - dl-UM-RLC DL-UM-RLC - }, - um-Uni-Directional-UL SEQUENCE { - ul-UM-RLC UL-UM-RLC - }, - um-Uni-Directional-DL SEQUENCE { - dl-UM-RLC DL-UM-RLC - }, - ... -} - -UL-AM-RLC ::= SEQUENCE { - t-PollRetransmit T-PollRetransmit, - pollPDU PollPDU, - pollByte PollByte, - maxRetxThreshold ENUMERATED { - t1, t2, t3, t4, t6, t8, t16, t32} -} - -DL-AM-RLC ::= SEQUENCE { - t-Reordering T-Reordering, - t-StatusProhibit T-StatusProhibit -} - -UL-UM-RLC ::= SEQUENCE { - sn-FieldLength SN-FieldLength -} - -DL-UM-RLC ::= SEQUENCE { - sn-FieldLength SN-FieldLength, - t-Reordering T-Reordering -} - -SN-FieldLength ::= ENUMERATED {size5, size10} - -T-PollRetransmit ::= ENUMERATED { - ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms105, - ms110, ms115, ms120, ms125, ms130, ms135, - ms140, ms145, ms150, ms155, ms160, ms165, - ms170, ms175, ms180, ms185, ms190, ms195, - ms200, ms205, ms210, ms215, ms220, ms225, - ms230, ms235, ms240, ms245, ms250, ms300, - ms350, ms400, ms450, ms500, spare9, spare8, - spare7, spare6, spare5, spare4, spare3, - spare2, spare1} - -PollPDU ::= ENUMERATED { - p4, p8, p16, p32, p64, p128, p256, pInfinity} - -PollByte ::= ENUMERATED { - kB25, kB50, kB75, kB100, kB125, kB250, kB375, - kB500, kB750, kB1000, kB1250, kB1500, kB2000, - kB3000, kBinfinity, spare1} - -T-Reordering ::= ENUMERATED { - ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms110, - ms120, ms130, ms140, ms150, ms160, ms170, - ms180, ms190, ms200, spare1} - -T-StatusProhibit ::= ENUMERATED { - ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35, - ms40, ms45, ms50, ms55, ms60, ms65, ms70, - ms75, ms80, ms85, ms90, ms95, ms100, ms105, - ms110, ms115, ms120, ms125, ms130, ms135, - ms140, ms145, ms150, ms155, ms160, ms165, - ms170, ms175, ms180, ms185, ms190, ms195, - ms200, ms205, ms210, ms215, ms220, ms225, - ms230, ms235, ms240, ms245, ms250, ms300, - ms350, ms400, ms450, ms500, spare8, spare7, - spare6, spare5, spare4, spare3, spare2, - spare1} - - -SchedulingRequestConfig ::= CHOICE { - release NULL, - setup SEQUENCE { - sr-PUCCH-ResourceIndex INTEGER (0..2047), - sr-ConfigIndex INTEGER (0..155), - dsr-TransMax ENUMERATED { - n4, n8, n16, n32, n64, spare3, spare2, spare1} - } -} - - -SoundingRS-UL-ConfigCommon ::= CHOICE { - release NULL, - setup SEQUENCE { - srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7}, - srs-SubframeConfig ENUMERATED { - sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7, - sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15}, - ackNackSRS-SimultaneousTransmission BOOLEAN, - srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD - } -} - -SoundingRS-UL-ConfigDedicated ::= CHOICE{ - release NULL, - setup SEQUENCE { - srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3}, - srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3}, - freqDomainPosition INTEGER (0..23), - duration BOOLEAN, - srs-ConfigIndex INTEGER (0..1023), - transmissionComb INTEGER (0..1), - cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7} - } -} - - - -SPS-Config ::= SEQUENCE { - semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR - sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON - sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON -} - -SPS-ConfigDL ::= CHOICE{ - release NULL, - setup SEQUENCE { - semiPersistSchedIntervalDL ENUMERATED { - sf10, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, spare6, - spare5, spare4, spare3, spare2, - spare1}, - numberOfConfSPS-Processes INTEGER (1..8), - n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList, - ... - } -} - -SPS-ConfigUL ::= CHOICE { - release NULL, - setup SEQUENCE { - semiPersistSchedIntervalUL ENUMERATED { - sf10, sf20, sf32, sf40, sf64, sf80, - sf128, sf160, sf320, sf640, spare6, - spare5, spare4, spare3, spare2, - spare1}, - implicitReleaseAfter ENUMERATED {e2, e3, e4, e8}, - p0-Persistent SEQUENCE { - p0-NominalPUSCH-Persistent INTEGER (-126..24), - p0-UE-PUSCH-Persistent INTEGER (-8..7) - } OPTIONAL, -- Need OP - twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD - ... - } -} - -N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047) - - -TDD-Config ::= SEQUENCE { - subframeAssignment ENUMERATED { - sa0, sa1, sa2, sa3, sa4, sa5, sa6}, - specialSubframePatterns ENUMERATED { - ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7, - ssp8} -} - - -TimeAlignmentTimer ::= ENUMERATED { - sf500, sf750, sf1280, sf1920, sf2560, sf5120, - sf10240, infinity} - -TPC-PDCCH-Config::= CHOICE { - release NULL, - setup SEQUENCE { - tpc-RNTI BIT STRING (SIZE (16)), - tpc-Index TPC-Index - } -} - -TPC-Index ::= CHOICE { - indexOfFormat3 INTEGER (1..15), - indexOfFormat3A INTEGER (1..31) -} - - -UplinkPowerControlCommon ::= SEQUENCE { - p0-NominalPUSCH INTEGER (-126..24), - alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1}, - p0-NominalPUCCH INTEGER (-127..-96), - deltaFList-PUCCH DeltaFList-PUCCH, - deltaPreambleMsg3 INTEGER (-1..6) -} - -UplinkPowerControlDedicated ::= SEQUENCE { - p0-UE-PUSCH INTEGER (-8..7), - deltaMCS-Enabled ENUMERATED {en0, en1}, - accumulationEnabled BOOLEAN, - p0-UE-PUCCH INTEGER (-8..7), - pSRS-Offset INTEGER (0..15), - filterCoefficient FilterCoefficient DEFAULT fc4 -} - -DeltaFList-PUCCH ::= SEQUENCE { - deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2}, - deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5}, - deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2}, - deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2}, - deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2} -} - - -NextHopChainingCount ::= INTEGER (0..7) - - -SecurityAlgorithmConfig ::= SEQUENCE { - cipheringAlgorithm ENUMERATED { - eea0, eea1, eea2, spare5, spare4, spare3, - spare2, spare1, ...}, - integrityProtAlgorithm ENUMERATED { - reserved, eia1, eia2, spare5, spare4, spare3, - spare2, spare1, ...} -} - - -ShortMAC-I ::= BIT STRING (SIZE (16)) - - -AdditionalSpectrumEmission ::= INTEGER (1..32) - - -ARFCN-ValueCDMA2000 ::= INTEGER (0..2047) - - -ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN) - - -ARFCN-ValueGERAN ::= INTEGER (0..1023) - - -ARFCN-ValueUTRA ::= INTEGER (0..16383) - - -BandclassCDMA2000 ::= ENUMERATED { - bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8, - bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16, - bc17, spare14, spare13, spare12, spare11, spare10, - spare9, spare8, spare7, spare6, spare5, spare4, - spare3, spare2, spare1, ...} - - -BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900} - - -CarrierFreqCDMA2000 ::= SEQUENCE { - bandClass BandclassCDMA2000, - arfcn ARFCN-ValueCDMA2000 -} - - -CarrierFreqGERAN ::= SEQUENCE { - arfcn ARFCN-ValueGERAN, - bandIndicator BandIndicatorGERAN -} - - -CarrierFreqsGERAN ::= SEQUENCE { - startingARFCN ARFCN-ValueGERAN, - bandIndicator BandIndicatorGERAN, - followingARFCNs CHOICE { - explicitListOfARFCNs ExplicitListOfARFCNs, - equallySpacedARFCNs SEQUENCE { - arfcn-Spacing INTEGER (1..8), - numberOfFollowingARFCNs INTEGER (0..31) - }, - variableBitMapOfARFCNs OCTET STRING (SIZE (1..16)) - } -} - -ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN - - -CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD} - - -CellIdentity ::= BIT STRING (SIZE (28)) - - -CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex - -CellIndex ::= INTEGER (1..maxCellMeas) - - -CellReselectionPriority ::= INTEGER (0..7) - - -CSFB-RegistrationParam1XRTT ::= SEQUENCE { - sid BIT STRING (SIZE (15)), - nid BIT STRING (SIZE (16)), - multipleSID BOOLEAN, - multipleNID BOOLEAN, - homeReg BOOLEAN, - foreignSIDReg BOOLEAN, - foreignNIDReg BOOLEAN, - parameterReg BOOLEAN, - powerUpReg BOOLEAN, - registrationPeriod BIT STRING (SIZE (7)), - registrationZone BIT STRING (SIZE (12)), - totalZone BIT STRING (SIZE (3)), - zoneTimer BIT STRING (SIZE (3)) -} - - -CellGlobalIdEUTRA ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellIdentity CellIdentity -} - - -CellGlobalIdUTRA ::= SEQUENCE { - plmn-Identity PLMN-Identity, - cellIdentity BIT STRING (SIZE (28)) -} - - -CellGlobalIdGERAN ::= SEQUENCE { - plmn-Identity PLMN-Identity, - locationAreaCode BIT STRING (SIZE (16)), - cellIdentity BIT STRING (SIZE (16)) -} - - -CellGlobalIdCDMA2000 ::= CHOICE { - cellGlobalId1XRTT BIT STRING (SIZE (47)), - cellGlobalIdHRPD BIT STRING (SIZE (128)) -} - - -MobilityControlInfo ::= SEQUENCE { - targetPhysCellId PhysCellId, - carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA - carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA - additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA - t304 ENUMERATED { - ms50, ms100, ms150, ms200, ms500, ms1000, - ms2000, spare1}, - newUE-Identity C-RNTI, - radioResourceConfigCommon RadioResourceConfigCommon, - rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP - ... -} - -CarrierBandwidthEUTRA ::= SEQUENCE { - dl-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100, spare10, - spare9, spare8, spare7, spare6, spare5, - spare4, spare3, spare2, spare1}, - ul-Bandwidth ENUMERATED { - n6, n15, n25, n50, n75, n100, spare10, - spare9, spare8, spare7, spare6, spare5, - spare4, spare3, spare2, spare1} OPTIONAL -- Need OP -} - -CarrierFreqEUTRA ::= SEQUENCE { - dl-CarrierFreq ARFCN-ValueEUTRA, - ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD -} - - -MobilityParametersCDMA2000 ::= OCTET STRING - - -MobilityStateParameters ::= SEQUENCE { - t-Evaluation ENUMERATED { - s30, s60, s120, s180, s240, spare3, spare2, spare1}, - t-HystNormal ENUMERATED { - s30, s60, s120, s180, s240, spare3, spare2, spare1}, - n-CellChangeMedium INTEGER (1..16), - n-CellChangeHigh INTEGER (1..16) -} - - -PhysCellId ::= INTEGER (0..503) - - -PhysCellIdRange ::= SEQUENCE { - start PhysCellId, - range ENUMERATED { - n4, n8, n12, n16, n24, n32, n48, n64, n84, - n96, n128, n168, n252, n504, spare2, - spare1} OPTIONAL -- Need OP -} - - -PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset) - - -PhysCellIdGERAN ::= SEQUENCE { - networkColourCode BIT STRING (SIZE (3)), - baseStationColourCode BIT STRING (SIZE (3)) -} - - -PhysCellIdUTRA-FDD ::= INTEGER (0..511) - - -PhysCellIdUTRA-TDD ::= INTEGER (0..127) - - -PLMN-Identity ::= SEQUENCE { - mcc MCC OPTIONAL, -- Cond MCC - mnc MNC -} - -MCC ::= SEQUENCE (SIZE (3)) OF - MCC-MNC-Digit - -MNC ::= SEQUENCE (SIZE (2..3)) OF - MCC-MNC-Digit - -MCC-MNC-Digit ::= INTEGER (0..9) - - - -PreRegistrationInfoHRPD ::= SEQUENCE { - preRegistrationAllowed BOOLEAN, - preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed - secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR -} - -SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD - -PreRegistrationZoneIdHRPD ::= INTEGER (0..255) - - -Q-RxLevMin ::= INTEGER (-70..-22) - - -Q-OffsetRange ::= ENUMERATED { - dB-24, dB-22, dB-20, dB-18, dB-16, dB-14, - dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3, - dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5, - dB6, dB8, dB10, dB12, dB14, dB16, dB18, - dB20, dB22, dB24} - - -Q-OffsetRangeInterRAT ::= INTEGER (-15..15) - - -ReselectionThreshold ::= INTEGER (0..31) - - -SpeedStateScaleFactors ::= SEQUENCE { - sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0}, - sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0} -} - -SystemTimeInfoCDMA2000 ::= SEQUENCE { - cdma-EUTRA-Synchronisation BOOLEAN, - cdma-SystemTime CHOICE { - synchronousSystemTime BIT STRING (SIZE (39)), - asynchronousSystemTime BIT STRING (SIZE (49)) - } -} - - -TrackingAreaCode ::= BIT STRING (SIZE (16)) - - -T-Reselection ::= INTEGER (0..7) - - -AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100} - - -Hysteresis ::= INTEGER (0..30) - - -MeasConfig ::= SEQUENCE { - -- Measurement objects - measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON - measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON - -- Reporting configurations - reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON - reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON - -- Measurement identities - measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON - measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON - -- Other parameters - quantityConfig QuantityConfig OPTIONAL, -- Need ON - measGapConfig MeasGapConfig OPTIONAL, -- Need ON - s-Measure RSRP-Range OPTIONAL, -- Need ON - preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP - speedStatePars CHOICE { - release NULL, - setup SEQUENCE { - mobilityStateParameters MobilityStateParameters, - timeToTrigger-SF SpeedStateScaleFactors - } - } OPTIONAL, -- Need ON - ... -} - -MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId - -MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId - -ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId - - -MeasGapConfig ::= CHOICE { - release NULL, - setup SEQUENCE { - gapOffset CHOICE { - gp0 INTEGER (0..39), - gp1 INTEGER (0..79), - ... - } - } -} - - -MeasId ::= INTEGER (1..maxMeasId) - - -MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod - -MeasIdToAddMod ::= SEQUENCE { - measId MeasId, - measObjectId MeasObjectId, - reportConfigId ReportConfigId -} - - -MeasObjectCDMA2000 ::= SEQUENCE { - cdma2000-Type CDMA2000-Type, - carrierFreq CarrierFreqCDMA2000, - searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON - cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON - ... -} - -CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000 - -CellsToAddModCDMA2000 ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdCDMA2000 -} - - -MeasObjectEUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueEUTRA, - allowedMeasBandwidth AllowedMeasBandwidth, - presenceAntennaPort1 PresenceAntennaPort1, - neighCellConfig NeighCellConfig, - offsetFreq Q-OffsetRange DEFAULT dB0, - -- Neighbour cell list - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON - -- Black list - blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON - blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON - cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON - ... -} - -CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod - -CellsToAddMod ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellId, - cellIndividualOffset Q-OffsetRange -} - -BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod - -BlackCellsToAddMod ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellIdRange PhysCellIdRange -} - - -MeasObjectGERAN ::= SEQUENCE { - carrierFreqs CarrierFreqsGERAN, - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B, - cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON - ... -} - - -MeasObjectId ::= INTEGER (1..maxObjectId) - - -MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod - -MeasObjectToAddMod ::= SEQUENCE { - measObjectId MeasObjectId, - measObject CHOICE { - measObjectEUTRA MeasObjectEUTRA, - measObjectUTRA MeasObjectUTRA, - measObjectGERAN MeasObjectGERAN, - measObjectCDMA2000 MeasObjectCDMA2000, - ... - } -} - - -MeasObjectUTRA ::= SEQUENCE { - carrierFreq ARFCN-ValueUTRA, - offsetFreq Q-OffsetRangeInterRAT DEFAULT 0, - cellsToRemoveList CellIndexList OPTIONAL, -- Need ON - cellsToAddModList CHOICE { - cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD, - cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD - } OPTIONAL, -- Need ON - cellForWhichToReportCGI CHOICE { - utra-FDD PhysCellIdUTRA-FDD, - utra-TDD PhysCellIdUTRA-TDD - } OPTIONAL, -- Need ON - ... -} - -CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD - -CellsToAddModUTRA-FDD ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdUTRA-FDD -} - -CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD - -CellsToAddModUTRA-TDD ::= SEQUENCE { - cellIndex INTEGER (1..maxCellMeas), - physCellId PhysCellIdUTRA-TDD -} - - -MeasResults ::= SEQUENCE { - measId MeasId, - measResultServCell SEQUENCE { - rsrpResult RSRP-Range, - rsrqResult RSRQ-Range - }, - measResultNeighCells CHOICE { - measResultListEUTRA MeasResultListEUTRA, - measResultListUTRA MeasResultListUTRA, - measResultListGERAN MeasResultListGERAN, - measResultsCDMA2000 MeasResultsCDMA2000, - ... - } OPTIONAL, - ... -} - -MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA - -MeasResultEUTRA ::= SEQUENCE { - physCellId PhysCellId, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdEUTRA, - trackingAreaCode TrackingAreaCode, - plmn-IdentityList PLMN-IdentityList2 OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - rsrpResult RSRP-Range OPTIONAL, - rsrqResult RSRQ-Range OPTIONAL, - ... - } -} - -MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA - -MeasResultUTRA ::= SEQUENCE { - physCellId CHOICE { - fdd PhysCellIdUTRA-FDD, - tdd PhysCellIdUTRA-TDD - }, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdUTRA, - locationAreaCode BIT STRING (SIZE (16)) OPTIONAL, - routingAreaCode BIT STRING (SIZE (8)) OPTIONAL, - plmn-IdentityList PLMN-IdentityList2 OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - utra-RSCP INTEGER (-5..91) OPTIONAL, - utra-EcN0 INTEGER (0..49) OPTIONAL, - ... - } -} - -MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN - -MeasResultGERAN ::= SEQUENCE { - carrierFreq CarrierFreqGERAN, - physCellId PhysCellIdGERAN, - cgi-Info SEQUENCE { - cellGlobalId CellGlobalIdGERAN, - routingAreaCode BIT STRING (SIZE (8)) OPTIONAL - } OPTIONAL, - measResult SEQUENCE { - rssi INTEGER (0..63), - ... - } -} - -MeasResultsCDMA2000 ::= SEQUENCE { - preRegistrationStatusHRPD BOOLEAN, - measResultListCDMA2000 MeasResultListCDMA2000 -} - -MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000 - -MeasResultCDMA2000 ::= SEQUENCE { - physCellId PhysCellIdCDMA2000, - cgi-Info CellGlobalIdCDMA2000 OPTIONAL, - measResult SEQUENCE { - pilotPnPhase INTEGER (0..32767) OPTIONAL, - pilotStrength INTEGER (0..63), - ... - } -} - -PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity - - -QuantityConfig ::= SEQUENCE { - quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON - quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON - quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON - quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON - ... -} - -QuantityConfigEUTRA ::= SEQUENCE { - filterCoefficientRSRP FilterCoefficient DEFAULT fc4, - filterCoefficientRSRQ FilterCoefficient DEFAULT fc4 -} - -QuantityConfigUTRA ::= SEQUENCE { - measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0}, - measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP}, - filterCoefficient FilterCoefficient DEFAULT fc4 -} - -QuantityConfigGERAN ::= SEQUENCE { - measQuantityGERAN ENUMERATED {rssi}, - filterCoefficient FilterCoefficient DEFAULT fc2 -} - -QuantityConfigCDMA2000 ::= SEQUENCE { - measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength} -} - - -ReportConfigEUTRA ::= SEQUENCE { - triggerType CHOICE { - event SEQUENCE { - eventId CHOICE { - eventA1 SEQUENCE { - a1-Threshold ThresholdEUTRA - }, - eventA2 SEQUENCE { - a2-Threshold ThresholdEUTRA - }, - eventA3 SEQUENCE { - a3-Offset INTEGER (-30..30), - reportOnLeave BOOLEAN - }, - eventA4 SEQUENCE { - a4-Threshold ThresholdEUTRA - }, - eventA5 SEQUENCE { - a5-Threshold1 ThresholdEUTRA, - a5-Threshold2 ThresholdEUTRA - }, - ... - }, - hysteresis Hysteresis, - timeToTrigger TimeToTrigger - }, - periodical SEQUENCE { - purpose ENUMERATED { - reportStrongestCells, reportCGI} - } - }, - triggerQuantity ENUMERATED {rsrp, rsrq}, - reportQuantity ENUMERATED {sameAsTriggerQuantity, both}, - maxReportCells INTEGER (1..maxCellReport), - reportInterval ReportInterval, - reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, - ... -} - -ThresholdEUTRA ::= CHOICE{ - threshold-RSRP RSRP-Range, - threshold-RSRQ RSRQ-Range -} - - -ReportConfigId ::= INTEGER (1..maxReportConfigId) - - -ReportConfigInterRAT ::= SEQUENCE { - triggerType CHOICE { - event SEQUENCE { - eventId CHOICE { - eventB1 SEQUENCE { - b1-Threshold CHOICE { - b1-ThresholdUTRA ThresholdUTRA, - b1-ThresholdGERAN ThresholdGERAN, - b1-ThresholdCDMA2000 ThresholdCDMA2000 - } - }, - eventB2 SEQUENCE { - b2-Threshold1 ThresholdEUTRA, - b2-Threshold2 CHOICE { - b2-Threshold2UTRA ThresholdUTRA, - b2-Threshold2GERAN ThresholdGERAN, - b2-Threshold2CDMA2000 ThresholdCDMA2000 - } - }, - ... - }, - hysteresis Hysteresis, - timeToTrigger TimeToTrigger - }, - periodical SEQUENCE { - purpose ENUMERATED { - reportStrongestCells, - reportStrongestCellsForSON, - reportCGI} - } - }, - maxReportCells INTEGER (1..maxCellReport), - reportInterval ReportInterval, - reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity}, - ... -} - -ThresholdUTRA ::= CHOICE{ - utra-RSCP INTEGER (-5..91), - utra-EcN0 INTEGER (0..49) -} - -ThresholdGERAN ::= INTEGER (0..63) - -ThresholdCDMA2000 ::= INTEGER (0..63) - - -ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod - -ReportConfigToAddMod ::= SEQUENCE { - reportConfigId ReportConfigId, - reportConfig CHOICE { - reportConfigEUTRA ReportConfigEUTRA, - reportConfigInterRAT ReportConfigInterRAT - } -} - - - -ReportInterval ::= ENUMERATED { - ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240, - min1, min6, min12, min30, min60, spare3, spare2, spare1} - - -RSRP-Range ::= INTEGER(0..97) - - -RSRQ-Range ::= INTEGER(0..34) - - -TimeToTrigger ::= ENUMERATED { - ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256, - ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560, - ms5120} - - -C-RNTI ::= BIT STRING (SIZE (16)) - - -DedicatedInfoCDMA2000 ::= OCTET STRING - - -DedicatedInfoNAS ::= OCTET STRING - - -FilterCoefficient ::= ENUMERATED { - fc0, fc1, fc2, fc3, fc4, fc5, - fc6, fc7, fc8, fc9, fc11, fc13, - fc15, fc17, fc19, spare1, ...} - - -MMEC ::= BIT STRING (SIZE (8)) - - -NeighCellConfig ::= BIT STRING (SIZE (2)) - - -RAND-CDMA2000 ::= BIT STRING (SIZE (32)) - - -RAT-Type ::= ENUMERATED { - eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT, - spare3, spare2, spare1, ...} - - -RRC-TransactionIdentifier ::= INTEGER (0..3) - - -S-TMSI ::= SEQUENCE { - mmec MMEC, - m-TMSI BIT STRING (SIZE (32)) -} - - -UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container - -UE-CapabilityRAT-Container ::= SEQUENCE { - rat-Type RAT-Type, - ueCapabilityRAT-Container OCTET STRING -} - - -UE-EUTRA-Capability ::= SEQUENCE { - accessStratumRelease AccessStratumRelease, - ue-Category INTEGER (1..5), - pdcp-Parameters PDCP-Parameters, - phyLayerParameters PhyLayerParameters, - rf-Parameters RF-Parameters, - measParameters MeasParameters, - featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL, - interRAT-Parameters SEQUENCE { - utraFDD IRAT-ParametersUTRA-FDD OPTIONAL, - utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL, - utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL, - utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL, - geran IRAT-ParametersGERAN OPTIONAL, - cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL, - cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL - }, - nonCriticalExtension SEQUENCE {} OPTIONAL -} - -AccessStratumRelease ::= ENUMERATED { - rel8, spare7, spare6, spare5, spare4, spare3, - spare2, spare1, ...} - -PDCP-Parameters ::= SEQUENCE { - supportedROHC-Profiles SEQUENCE { - profile0x0001 BOOLEAN, - profile0x0002 BOOLEAN, - profile0x0003 BOOLEAN, - profile0x0004 BOOLEAN, - profile0x0006 BOOLEAN, - profile0x0101 BOOLEAN, - profile0x0102 BOOLEAN, - profile0x0103 BOOLEAN, - profile0x0104 BOOLEAN - }, - maxNumberROHC-ContextSessions ENUMERATED { - cs2, cs4, cs8, cs12, cs16, cs24, cs32, - cs48, cs64, cs128, cs256, cs512, cs1024, - cs16384, spare2, spare1} DEFAULT cs16, - ... -} - -PhyLayerParameters ::= SEQUENCE { - ue-TxAntennaSelectionSupported BOOLEAN, - ue-SpecificRefSigsSupported BOOLEAN -} - -RF-Parameters ::= SEQUENCE { - supportedBandListEUTRA SupportedBandListEUTRA -} - -SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA - -SupportedBandEUTRA ::= SEQUENCE { - bandEUTRA INTEGER (1..64), - halfDuplex BOOLEAN -} - -MeasParameters ::= SEQUENCE { - bandListEUTRA BandListEUTRA -} - -BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA - -BandInfoEUTRA ::= SEQUENCE { - interFreqBandList InterFreqBandList, - interRAT-BandList InterRAT-BandList OPTIONAL -} - -InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo - -InterFreqBandInfo ::= SEQUENCE { - interFreqNeedForGaps BOOLEAN -} - -InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo - -InterRAT-BandInfo ::= SEQUENCE { - interRAT-NeedForGaps BOOLEAN -} - -IRAT-ParametersUTRA-FDD ::= SEQUENCE { - supportedBandListUTRA-FDD SupportedBandListUTRA-FDD -} - -SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD - -SupportedBandUTRA-FDD ::= ENUMERATED { - bandI, bandII, bandIII, bandIV, bandV, bandVI, - bandVII, bandVIII, bandIX, bandX, bandXI, - bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...} - -IRAT-ParametersUTRA-TDD128 ::= SEQUENCE { - supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128 -} - -SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128 - -SupportedBandUTRA-TDD128 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersUTRA-TDD384 ::= SEQUENCE { - supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384 -} - -SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384 - -SupportedBandUTRA-TDD384 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersUTRA-TDD768 ::= SEQUENCE { - supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768 -} - -SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768 - -SupportedBandUTRA-TDD768 ::= ENUMERATED { - a, b, c, d, e, f, g, h, i, j, k, l, m, n, - o, p, ...} - -IRAT-ParametersGERAN ::= SEQUENCE { - supportedBandListGERAN SupportedBandListGERAN, - interRAT-PS-HO-ToGERAN BOOLEAN -} - -SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN - -SupportedBandGERAN ::= ENUMERATED { - gsm450, gsm480, gsm710, gsm750, gsm810, gsm850, - gsm900P, gsm900E, gsm900R, gsm1800, gsm1900, - spare5, spare4, spare3, spare2, spare1, ...} - -IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE { - supportedBandListHRPD SupportedBandListHRPD, - tx-ConfigHRPD ENUMERATED {single, dual}, - rx-ConfigHRPD ENUMERATED {single, dual} -} - -SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 - -IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE { - supportedBandList1XRTT SupportedBandList1XRTT, - tx-Config1XRTT ENUMERATED {single, dual}, - rx-Config1XRTT ENUMERATED {single, dual} -} - -SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000 - - -UE-TimersAndConstants ::= SEQUENCE { - t300 ENUMERATED { - ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, - ms2000}, - t301 ENUMERATED { - ms100, ms200, ms300, ms400, ms600, ms1000, ms1500, - ms2000}, - t310 ENUMERATED { - ms0, ms50, ms100, ms200, ms500, ms1000, ms2000}, - n310 ENUMERATED { - n1, n2, n3, n4, n6, n8, n10, n20}, - t311 ENUMERATED { - ms1000, ms3000, ms5000, ms10000, ms15000, - ms20000, ms30000}, - n311 ENUMERATED { - n1, n2, n3, n4, n5, n6, n8, n10}, - ... -} - - -maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps -maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes -maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells - -- listed in SIB type 4 and 5 -maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency - -- cells listed in SIB type 5 -maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency - -- cells listed in SIB type 4 -maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour - -- cell lists in a measurement object -maxCellReport INTEGER ::= 8 -- Maximum number of reported cells -maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers -maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency -maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies -maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be - -- provided as part of NACC information -maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups -maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with - -- different offset -maxMCS-1 INTEGER ::= 16 -- Maximum number of PUCCH formats (MCS) -maxMeasId INTEGER ::= 32 -maxObjectId INTEGER ::= 32 -maxPageRec INTEGER ::= 16 -- -maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets -maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA) -maxReportConfigId INTEGER ::= 32 -maxSIB INTEGER ::= 32 -- Maximum number of SIBs -maxSIB-1 INTEGER ::= 31 -maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages -maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies -maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies - - -END +-- 3GPP TS 36.331 v9.2.0
+-- http://cdmweb.ericsson.se/TeamCenter/controller/ViewDocs?DocumentName=51%2F15519-10%2FFCP1039669%2F11&Revision=A
+
+EUTRA-RRC-Definitions DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+
+BCCH-BCH-Message ::= SEQUENCE {
+ message BCCH-BCH-MessageType
+}
+
+BCCH-BCH-MessageType ::= MasterInformationBlock
+
+
+BCCH-DL-SCH-Message ::= SEQUENCE {
+ message BCCH-DL-SCH-MessageType
+}
+
+BCCH-DL-SCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ systemInformation SystemInformation,
+ systemInformationBlockType1 SystemInformationBlockType1
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+MCCH-Message ::= SEQUENCE {
+ message MCCH-MessageType
+}
+
+MCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ mbsfnAreaConfiguration-r9 MBSFNAreaConfiguration-r9
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+PCCH-Message ::= SEQUENCE {
+ message PCCH-MessageType
+}
+
+PCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ paging Paging
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-CCCH-Message ::= SEQUENCE {
+ message DL-CCCH-MessageType
+}
+
+DL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishment RRCConnectionReestablishment,
+ rrcConnectionReestablishmentReject RRCConnectionReestablishmentReject,
+ rrcConnectionReject RRCConnectionReject,
+ rrcConnectionSetup RRCConnectionSetup
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+DL-DCCH-Message ::= SEQUENCE {
+ message DL-DCCH-MessageType
+}
+
+DL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersResponseCDMA2000 CSFBParametersResponseCDMA2000,
+ dlInformationTransfer DLInformationTransfer,
+ handoverFromEUTRAPreparationRequest HandoverFromEUTRAPreparationRequest,
+ mobilityFromEUTRACommand MobilityFromEUTRACommand,
+ rrcConnectionReconfiguration RRCConnectionReconfiguration,
+ rrcConnectionRelease RRCConnectionRelease,
+ securityModeCommand SecurityModeCommand,
+ ueCapabilityEnquiry UECapabilityEnquiry,
+ counterCheck CounterCheck,
+ ueInformationRequest-r9 UEInformationRequest-r9,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-CCCH-Message ::= SEQUENCE {
+ message UL-CCCH-MessageType
+}
+
+UL-CCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ rrcConnectionReestablishmentRequest RRCConnectionReestablishmentRequest,
+ rrcConnectionRequest RRCConnectionRequest
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+UL-DCCH-Message ::= SEQUENCE {
+ message UL-DCCH-MessageType
+}
+
+UL-DCCH-MessageType ::= CHOICE {
+ c1 CHOICE {
+ csfbParametersRequestCDMA2000 CSFBParametersRequestCDMA2000,
+ measurementReport MeasurementReport,
+ rrcConnectionReconfigurationComplete RRCConnectionReconfigurationComplete,
+ rrcConnectionReestablishmentComplete RRCConnectionReestablishmentComplete,
+ rrcConnectionSetupComplete RRCConnectionSetupComplete,
+ securityModeComplete SecurityModeComplete,
+ securityModeFailure SecurityModeFailure,
+ ueCapabilityInformation UECapabilityInformation,
+ulHandoverPreparationTransfer ULHandoverPreparationTransfer,
+ ulInformationTransfer ULInformationTransfer,
+ counterCheckResponse CounterCheckResponse,
+ ueInformationResponse-r9 UEInformationResponse-r9,
+ proximityIndication-r9 ProximityIndication-r9,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ messageClassExtension SEQUENCE {}
+}
+
+
+CounterCheck ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ counterCheck-r8 CounterCheck-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheck-r8-IEs ::= SEQUENCE {
+ drb-CountMSB-InfoList DRB-CountMSB-InfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+DRB-CountMSB-InfoList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-CountMSB-Info
+
+DRB-CountMSB-Info ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ countMSB-Uplink INTEGER(0..33554431),
+ countMSB-Downlink INTEGER(0..33554431)
+}
+
+
+CounterCheckResponse ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ counterCheckResponse-r8 CounterCheckResponse-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CounterCheckResponse-r8-IEs ::= SEQUENCE {
+ drb-CountInfoList DRB-CountInfoList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+DRB-CountInfoList ::= SEQUENCE (SIZE (0..maxDRB)) OF DRB-CountInfo
+
+DRB-CountInfo ::= SEQUENCE {
+ drb-Identity DRB-Identity,
+ count-Uplink INTEGER(0..4294967295),
+ count-Downlink INTEGER(0..4294967295)
+}
+
+
+CSFBParametersRequestCDMA2000 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ csfbParametersRequestCDMA2000-r8 CSFBParametersRequestCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersRequestCDMA2000-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+CSFBParametersResponseCDMA2000 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ csfbParametersResponseCDMA2000-r8 CSFBParametersResponseCDMA2000-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+CSFBParametersResponseCDMA2000-r8-IEs ::= SEQUENCE {
+ rand RAND-CDMA2000,
+ mobilityParameters MobilityParametersCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+DLInformationTransfer ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ dlInformationTransfer-r8 DLInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+DLInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL --Need OP
+}
+
+
+HandoverFromEUTRAPreparationRequest ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ handoverFromEUTRAPreparationRequest-r8
+ HandoverFromEUTRAPreparationRequest-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+HandoverFromEUTRAPreparationRequest-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ rand RAND-CDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ mobilityParameters MobilityParametersCDMA2000 OPTIONAL, -- Cond cdma2000-Type
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v890-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension HandoverFromEUTRAPreparationRequest-v920-IEs OPTIONAL
+}
+
+HandoverFromEUTRAPreparationRequest-v920-IEs ::= SEQUENCE {
+ concurrPrepCDMA2000-HRPD-r9 BOOLEAN OPTIONAL, -- Cond PSHO
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+MasterInformationBlock ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100},
+ phich-Config PHICH-Config,
+ systemFrameNumber BIT STRING (SIZE (8)),
+ spare BIT STRING (SIZE (10))
+}
+
+
+
+MBSFNAreaConfiguration-r9 ::= SEQUENCE {
+ commonSF-Alloc-r9 CommonSF-AllocPatternList-r9,
+ commonSF-AllocPeriod-r9 ENUMERATED {
+ rf4, rf8, rf16, rf32, rf64, rf128, rf256},
+ pmch-InfoList-r9 PMCH-InfoList-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+CommonSF-AllocPatternList-r9 ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+MeasurementReport ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ measurementReport-r8 MeasurementReport-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MeasurementReport-r8-IEs ::= SEQUENCE {
+ measResults MeasResults,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+MobilityFromEUTRACommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ mobilityFromEUTRACommand-r8 MobilityFromEUTRACommand-r8-IEs,
+ mobilityFromEUTRACommand-r9 MobilityFromEUTRACommand-r9-IEs,
+ spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+MobilityFromEUTRACommand-r8-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+MobilityFromEUTRACommand-r9-IEs ::= SEQUENCE {
+ cs-FallbackIndicator BOOLEAN,
+ purpose CHOICE{
+ handover Handover,
+ cellChangeOrder CellChangeOrder,
+ e-CSFB-r9 E-CSFB-r9,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+Handover ::= SEQUENCE {
+ targetRAT-Type ENUMERATED {
+ utra, geran, cdma2000-1XRTT, cdma2000-HRPD,
+ spare4, spare3, spare2, spare1, ...},
+ targetRAT-MessageContainer OCTET STRING,
+ nas-SecurityParamFromEUTRA OCTET STRING (SIZE (1)) OPTIONAL, -- Cond UTRAGERAN
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Cond PSHO
+}
+
+CellChangeOrder ::= SEQUENCE {
+ t304 ENUMERATED {
+ ms100, ms200, ms500, ms1000,
+ ms2000, ms4000, ms8000, spare1},
+ targetRAT-Type CHOICE {
+ geran SEQUENCE {
+ physCellId PhysCellIdGERAN,
+ carrierFreq CarrierFreqGERAN,
+ networkControlOrder BIT STRING (SIZE (2)) OPTIONAL, -- Need OP
+ systemInformation SI-OrPSI-GERAN OPTIONAL -- Need OP
+ },
+ ...
+ }
+}
+
+SI-OrPSI-GERAN ::= CHOICE {
+ si SystemInfoListGERAN,
+ psi SystemInfoListGERAN
+}
+
+E-CSFB-r9 ::= SEQUENCE {
+ messageContCDMA2000-1XRTT-r9 OCTET STRING OPTIONAL, -- Need ON
+ mobilityCDMA2000-HRPD-r9 ENUMERATED {
+ handover, redirection
+ } OPTIONAL, -- Need OP
+ messageContCDMA2000-HRPD-r9 OCTET STRING OPTIONAL, -- Cond concHO
+ redirectCarrierCDMA2000-HRPD-r9 CarrierFreqCDMA2000 OPTIONAL -- Cond concRedir
+}
+
+
+Paging ::= SEQUENCE {
+ pagingRecordList PagingRecordList OPTIONAL, -- Need ON
+ systemInfoModification ENUMERATED {true} OPTIONAL, -- Need ON
+ etws-Indication ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension Paging-v890-IEs OPTIONAL
+}
+
+Paging-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension Paging-v920-IEs OPTIONAL
+}
+
+Paging-v920-IEs ::= SEQUENCE {
+ cmas-Indication-r9 ENUMERATED {true} OPTIONAL, -- Need ON
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PagingRecordList ::= SEQUENCE (SIZE (1..maxPageRec)) OF PagingRecord
+
+PagingRecord ::= SEQUENCE {
+ ue-Identity PagingUE-Identity,
+ cn-Domain ENUMERATED {ps, cs},
+ ...
+}
+
+PagingUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ imsi IMSI,
+ ...
+}
+
+IMSI ::= SEQUENCE (SIZE (6..21)) OF IMSI-Digit
+
+IMSI-Digit ::= INTEGER (0..9)
+
+
+ProximityIndication-r9 ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ proximityIndication-r9 ProximityIndication-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ProximityIndication-r9-IEs ::= SEQUENCE {
+ type-r9 ENUMERATED {entering, leaving},
+ carrierFreq-r9 CHOICE {
+ eutra-r9 ARFCN-ValueEUTRA,
+ utra-r9 ARFCN-ValueUTRA,
+ ...
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReconfiguration ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReconfiguration-r8 RRCConnectionReconfiguration-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfiguration-r8-IEs ::= SEQUENCE {
+ measConfig MeasConfig OPTIONAL, -- Need ON
+ mobilityControlInfo MobilityControlInfo OPTIONAL, -- Cond HO
+ dedicatedInfoNASList SEQUENCE (SIZE(1..maxDRB)) OF
+ DedicatedInfoNAS OPTIONAL, -- Cond nonHO
+ radioResourceConfigDedicated RadioResourceConfigDedicated OPTIONAL, -- Cond HO-toEUTRA
+ securityConfigHO SecurityConfigHO OPTIONAL, -- Cond HO
+ nonCriticalExtension RRCConnectionReconfiguration-v890-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionReconfiguration-v920-IEs OPTIONAL
+}
+
+RRCConnectionReconfiguration-v920-IEs ::= SEQUENCE {
+ otherConfig-r9 OtherConfig-r9 OPTIONAL, -- Need ON
+ fullConfig-r9 ENUMERATED {true} OPTIONAL, -- Cond HO-Reestab
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigHO ::= SEQUENCE {
+ handoverType CHOICE {
+ intraLTE SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig OPTIONAL, -- Cond fullConfig
+ keyChangeIndicator BOOLEAN,
+ nextHopChainingCount NextHopChainingCount
+ },
+ interRAT SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ nas-SecurityParamToEUTRA OCTET STRING (SIZE(6))
+ }
+ },
+ ...
+}
+
+
+
+RRCConnectionReconfigurationComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReconfigurationComplete-r8
+ RRCConnectionReconfigurationComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReconfigurationComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishment ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionReestablishment-r8 RRCConnectionReestablishment-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishment-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nextHopChainingCount NextHopChainingCount,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentComplete-r8
+ RRCConnectionReestablishmentComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension RRCConnectionReestablishmentComplete-v920-IEs OPTIONAL
+}
+
+RRCConnectionReestablishmentComplete-v920-IEs ::= SEQUENCE {
+ rlf-InfoAvailable-r9 ENUMERATED {true} OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+RRCConnectionReestablishmentReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentReject-r8
+ RRCConnectionReestablishmentReject-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentReject-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionReestablishmentRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionReestablishmentRequest-r8
+ RRCConnectionReestablishmentRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReestablishmentRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity ReestabUE-Identity,
+ reestablishmentCause ReestablishmentCause,
+ spare BIT STRING (SIZE (2))
+}
+
+ReestabUE-Identity ::= SEQUENCE {
+ c-RNTI C-RNTI,
+ physCellId PhysCellId,
+ shortMAC-I ShortMAC-I
+}
+
+ReestablishmentCause ::= ENUMERATED {
+ reconfigurationFailure, handoverFailure,
+ otherFailure, spare1}
+
+
+RRCConnectionReject ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionReject-r8 RRCConnectionReject-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionReject-r8-IEs ::= SEQUENCE {
+ waitTime INTEGER (1..16),
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionRelease ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionRelease-r8 RRCConnectionRelease-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRelease-r8-IEs ::= SEQUENCE {
+ releaseCause ReleaseCause,
+ redirectedCarrierInfo RedirectedCarrierInfo OPTIONAL, -- Need ON
+ idleModeMobilityControlInfo IdleModeMobilityControlInfo OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v890-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v890-IEs ::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension RRCConnectionRelease-v920-IEs OPTIONAL
+}
+
+RRCConnectionRelease-v920-IEs ::= SEQUENCE {
+ cellInfoList-r9 CHOICE {
+ geran-r9 CellInfoListGERAN-r9,
+ utra-FDD-r9 CellInfoListUTRA-FDD-r9,
+ utra-TDD-r9 CellInfoListUTRA-TDD-r9,
+ ...
+ } OPTIONAL, -- Cond Redirection
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+ReleaseCause ::= ENUMERATED {loadBalancingTAUrequired,
+ other,spare2,spare1}
+
+RedirectedCarrierInfo ::= CHOICE {
+ eutra ARFCN-ValueEUTRA,
+ geran CarrierFreqsGERAN,
+ utra-FDD ARFCN-ValueUTRA,
+ utra-TDD ARFCN-ValueUTRA,
+ cdma2000-HRPD CarrierFreqCDMA2000,
+ cdma2000-1xRTT CarrierFreqCDMA2000,
+ ...
+}
+
+IdleModeMobilityControlInfo ::= SEQUENCE {
+ freqPriorityListEUTRA FreqPriorityListEUTRA OPTIONAL, -- Need ON
+ freqPriorityListGERAN FreqsPriorityListGERAN OPTIONAL, -- Need ON
+ freqPriorityListUTRA-FDD FreqPriorityListUTRA-FDD OPTIONAL, -- Need ON
+ freqPriorityListUTRA-TDD FreqPriorityListUTRA-TDD OPTIONAL, -- Need ON
+ bandClassPriorityListHRPD BandClassPriorityListHRPD OPTIONAL, -- Need ON
+ bandClassPriorityList1XRTT BandClassPriorityList1XRTT OPTIONAL, -- Need ON
+ t320 ENUMERATED {
+ min5, min10, min20, min30, min60, min120, min180,
+ spare1} OPTIONAL, -- Need OR
+ ...
+}
+
+FreqPriorityListEUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF FreqPriorityEUTRA
+
+FreqPriorityEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqsPriorityListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF FreqsPriorityGERAN
+
+FreqsPriorityGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF FreqPriorityUTRA-FDD
+
+FreqPriorityUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+FreqPriorityListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF FreqPriorityUTRA-TDD
+
+FreqPriorityUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriorityHRPD
+
+BandClassPriorityHRPD ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+BandClassPriorityList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassPriority1XRTT
+
+BandClassPriority1XRTT ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority
+}
+
+CellInfoListGERAN-r9 ::= SEQUENCE (SIZE (1..maxCellInfo-GERAN-r9 )) OF CellInfoGERAN-r9
+
+CellInfoGERAN-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdGERAN,
+ carrierFreq-r9 CarrierFreqGERAN,
+ systemInformation-r9 SystemInfoListGERAN
+}
+
+CellInfoListUTRA-FDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-FDD-r9
+
+CellInfoUTRA-FDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-FDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+CellInfoListUTRA-TDD-r9 ::= SEQUENCE (SIZE (1..maxUTRA-CellInfo-r9)) OF CellInfoUTRA-TDD-r9
+
+CellInfoUTRA-TDD-r9 ::= SEQUENCE {
+ physCellId-r9 PhysCellIdUTRA-TDD,
+ utra-BCCH-Container-r9 OCTET STRING
+}
+
+
+RRCConnectionRequest ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ rrcConnectionRequest-r8 RRCConnectionRequest-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionRequest-r8-IEs ::= SEQUENCE {
+ ue-Identity InitialUE-Identity,
+ establishmentCause EstablishmentCause,
+ spare BIT STRING (SIZE (1))
+}
+
+InitialUE-Identity ::= CHOICE {
+ s-TMSI S-TMSI,
+ randomValue BIT STRING (SIZE (40))
+}
+
+EstablishmentCause ::= ENUMERATED {
+ emergency, highPriorityAccess, mt-Access, mo-Signalling,
+ mo-Data, spare3, spare2, spare1}
+
+
+RRCConnectionSetup ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ rrcConnectionSetup-r8 RRCConnectionSetup-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetup-r8-IEs ::= SEQUENCE {
+ radioResourceConfigDedicated RadioResourceConfigDedicated,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+RRCConnectionSetupComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ rrcConnectionSetupComplete-r8 RRCConnectionSetupComplete-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+RRCConnectionSetupComplete-r8-IEs ::= SEQUENCE {
+ selectedPLMN-Identity INTEGER (1..6),
+ registeredMME RegisteredMME OPTIONAL,
+ dedicatedInfoNAS DedicatedInfoNAS,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RegisteredMME ::= SEQUENCE {
+ plmn-Identity PLMN-Identity OPTIONAL,
+ mmegi BIT STRING (SIZE (16)),
+ mmec MMEC
+}
+
+
+SecurityModeCommand ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ securityModeCommand-r8 SecurityModeCommand-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeCommand-r8-IEs ::= SEQUENCE {
+ securityConfigSMC SecurityConfigSMC,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+SecurityConfigSMC ::= SEQUENCE {
+ securityAlgorithmConfig SecurityAlgorithmConfig,
+ ...
+}
+
+
+SecurityModeComplete ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeComplete-r8 SecurityModeComplete-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeComplete-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SecurityModeFailure ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ securityModeFailure-r8 SecurityModeFailure-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+SecurityModeFailure-r8-IEs ::= SEQUENCE {
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformation ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ systemInformation-r8 SystemInformation-r8-IEs,
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+SystemInformation-r8-IEs ::= SEQUENCE {
+ sib-TypeAndInfo SEQUENCE (SIZE (1..maxSIB)) OF CHOICE {
+ sib2 SystemInformationBlockType2,
+ sib3 SystemInformationBlockType3,
+ sib4 SystemInformationBlockType4,
+ sib5 SystemInformationBlockType5,
+ sib6 SystemInformationBlockType6,
+ sib7 SystemInformationBlockType7,
+ sib8 SystemInformationBlockType8,
+ sib9 SystemInformationBlockType9,
+ sib10 SystemInformationBlockType10,
+ sib11 SystemInformationBlockType11,
+ ...,
+ sib12-v920 SystemInformationBlockType12-r9,
+ sib13-v920 SystemInformationBlockType13-r9
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+SystemInformationBlockType1 ::= SEQUENCE {
+ cellAccessRelatedInfo SEQUENCE {
+ plmn-IdentityList PLMN-IdentityList,
+ trackingAreaCode TrackingAreaCode,
+ cellIdentity CellIdentity,
+ cellBarred ENUMERATED {barred, notBarred},
+ intraFreqReselection ENUMERATED {allowed, notAllowed},
+ csg-Indication BOOLEAN,
+ csg-Identity CSG-Identity OPTIONAL -- Need OR
+ },
+ cellSelectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ q-RxLevMinOffset INTEGER (1..8) OPTIONAL -- Need OP
+ },
+ p-Max P-Max OPTIONAL, -- Need OP
+ freqBandIndicator INTEGER (1..64),
+ schedulingInfoList SchedulingInfoList,
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ si-WindowLength ENUMERATED {
+ ms1, ms2, ms5, ms10, ms15, ms20,
+ ms40},
+ systemInfoValueTag INTEGER (0..31),
+ nonCriticalExtension SystemInformationBlockType1-v890-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v890-IEs::= SEQUENCE {
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ nonCriticalExtension SystemInformationBlockType1-v920-IEs OPTIONAL
+}
+
+SystemInformationBlockType1-v920-IEs ::= SEQUENCE {
+ ims-EmergencySupport-r9 ENUMERATED {true} OPTIONAL, -- Need OR
+ cellSelectionInfo-v920 CellSelectionInfo-v920 OPTIONAL, -- Need OP
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+PLMN-IdentityList ::= SEQUENCE (SIZE (1..6)) OF PLMN-IdentityInfo
+
+PLMN-IdentityInfo ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellReservedForOperatorUse ENUMERATED {reserved, notReserved}
+}
+
+SchedulingInfoList ::= SEQUENCE (SIZE (1..maxSI-Message)) OF SchedulingInfo
+
+SchedulingInfo ::= SEQUENCE {
+ si-Periodicity ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512},
+ sib-MappingInfo SIB-MappingInfo
+}
+
+SIB-MappingInfo ::= SEQUENCE (SIZE (0..maxSIB-1)) OF SIB-Type
+
+SIB-Type ::= ENUMERATED {
+ sibType3, sibType4, sibType5, sibType6,
+ sibType7, sibType8, sibType9, sibType10,
+ sibType11, sibType12-v920, sibType13-v920, spare5,
+ spare4, spare3, spare2, spare1, ...}
+
+CellSelectionInfo-v920 ::= SEQUENCE {
+ q-QualMin-r9 Q-QualMin-r9,
+ q-QualMinOffset-r9 INTEGER (1..8) OPTIONAL -- Need OP
+}
+
+
+UECapabilityEnquiry ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueCapabilityEnquiry-r8 UECapabilityEnquiry-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityEnquiry-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRequest UE-CapabilityRequest,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+UE-CapabilityRequest ::= SEQUENCE (SIZE (1..maxRAT-Capabilities)) OF RAT-Type
+
+
+UECapabilityInformation ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE{
+ ueCapabilityInformation-r8 UECapabilityInformation-r8-IEs,
+ spare7 NULL,
+ spare6 NULL, spare5 NULL, spare4 NULL,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UECapabilityInformation-r8-IEs ::= SEQUENCE {
+ ue-CapabilityRAT-ContainerList UE-CapabilityRAT-ContainerList,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+UEInformationRequest-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationRequest-r9 UEInformationRequest-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationRequest-r9-IEs ::= SEQUENCE {
+ rach-ReportReq-r9 BOOLEAN,
+ rlf-ReportReq-r9 BOOLEAN,
+ nonCriticalExtension SEQUENCE {} OPTIONAL -- Need OP
+}
+
+
+UEInformationResponse-r9 ::= SEQUENCE {
+ rrc-TransactionIdentifier RRC-TransactionIdentifier,
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ueInformationResponse-r9 UEInformationResponse-r9-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+UEInformationResponse-r9-IEs ::= SEQUENCE {
+ rach-Report-r9 SEQUENCE {
+ numberOfPreamblesSent-r9 INTEGER (1..200),
+ contentionDetected-r9 BOOLEAN
+ } OPTIONAL,
+ rlfReport-r9 RLF-Report-r9 OPTIONAL,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+RLF-Report-r9 ::= SEQUENCE {
+ measResultLastServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range OPTIONAL
+ },
+ measResultNeighCells SEQUENCE {
+ measResultListEUTRA MeasResultList2EUTRA OPTIONAL,
+ measResultListUTRA MeasResultList2UTRA OPTIONAL,
+ measResultListGERAN MeasResultListGERAN OPTIONAL,
+ measResultsCDMA2000 MeasResultList2CDMA2000 OPTIONAL
+ } OPTIONAL,
+ ...
+}
+
+MeasResultList2EUTRA ::= SEQUENCE (SIZE (1..maxFreq)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ measResultList MeasResultListEUTRA
+}
+
+MeasResultList2UTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ measResultList MeasResultListUTRA
+}
+
+MeasResultList2CDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF SEQUENCE {
+ carrierFreq CarrierFreqCDMA2000,
+ measResultList MeasResultsCDMA2000
+}
+
+
+ULHandoverPreparationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulHandoverPreparationTransfer-r8 ULHandoverPreparationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULHandoverPreparationTransfer-r8-IEs ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ meid BIT STRING (SIZE (56)) OPTIONAL,
+ dedicatedInfo DedicatedInfoCDMA2000,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+ULInformationTransfer ::= SEQUENCE {
+ criticalExtensions CHOICE {
+ c1 CHOICE {
+ ulInformationTransfer-r8 ULInformationTransfer-r8-IEs,
+ spare3 NULL, spare2 NULL, spare1 NULL
+ },
+ criticalExtensionsFuture SEQUENCE {}
+ }
+}
+
+ULInformationTransfer-r8-IEs ::= SEQUENCE {
+ dedicatedInfoType CHOICE {
+ dedicatedInfoNAS DedicatedInfoNAS,
+ dedicatedInfoCDMA2000-1XRTT DedicatedInfoCDMA2000,
+ dedicatedInfoCDMA2000-HRPD DedicatedInfoCDMA2000
+ },
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+
+SystemInformationBlockType2 ::= SEQUENCE {
+ ac-BarringInfo SEQUENCE {
+ ac-BarringForEmergency BOOLEAN,
+ ac-BarringForMO-Signalling AC-BarringConfig OPTIONAL, -- Need OP
+ ac-BarringForMO-Data AC-BarringConfig OPTIONAL -- Need OP
+ } OPTIONAL, -- Need OP
+ radioResourceConfigCommon RadioResourceConfigCommonSIB,
+ ue-TimersAndConstants UE-TimersAndConstants,
+ freqInfo SEQUENCE {
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL, -- Need OP
+ ul-Bandwidth ENUMERATED {n6, n15, n25, n50, n75, n100}
+ OPTIONAL, -- Need OP
+ additionalSpectrumEmission AdditionalSpectrumEmission
+ },
+ mbsfn-SubframeConfigList MBSFN-SubframeConfigList OPTIONAL, -- Need OR
+ timeAlignmentTimerCommon TimeAlignmentTimer,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ ssac-BarringForMMTEL-Voice-r9 AC-BarringConfig OPTIONAL, -- Need OP
+ ssac-BarringForMMTEL-Video-r9 AC-BarringConfig OPTIONAL -- Need OP
+ ]]
+}
+
+AC-BarringConfig ::= SEQUENCE {
+ ac-BarringFactor ENUMERATED {
+ p00, p05, p10, p15, p20, p25, p30, p40,
+ p50, p60, p70, p75, p80, p85, p90, p95},
+ ac-BarringTime ENUMERATED {s4, s8, s16, s32, s64, s128, s256, s512},
+ ac-BarringForSpecialAC BIT STRING (SIZE(5))
+}
+
+MBSFN-SubframeConfigList ::= SEQUENCE (SIZE (1..maxMBSFN-Allocations)) OF MBSFN-SubframeConfig
+
+
+SystemInformationBlockType3 ::= SEQUENCE {
+ cellReselectionInfoCommon SEQUENCE {
+ q-Hyst ENUMERATED {
+ dB0, dB1, dB2, dB3, dB4, dB5, dB6, dB8, dB10,
+ dB12, dB14, dB16, dB18, dB20, dB22, dB24},
+ speedStateReselectionPars SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ q-HystSF SEQUENCE {
+ sf-Medium ENUMERATED {
+ dB-6, dB-4, dB-2, dB0},
+ sf-High ENUMERATED {
+ dB-6, dB-4, dB-2, dB0}
+ }
+ } OPTIONAL -- Need OP
+ },
+ cellReselectionServingFreqInfo SEQUENCE {
+ s-NonIntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ threshServingLow ReselectionThreshold,
+ cellReselectionPriority CellReselectionPriority
+ },
+ intraFreqCellReselectionInfo SEQUENCE {
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ s-IntraSearch ReselectionThreshold OPTIONAL, -- Need OP
+ allowedMeasBandwidth AllowedMeasBandwidth OPTIONAL, -- Need OP
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+ },
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ s-IntraSearch-v920 SEQUENCE {
+ s-IntraSearchP-r9 ReselectionThreshold,
+ s-IntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ s-NonIntraSearch-v920 SEQUENCE {
+ s-NonIntraSearchP-r9 ReselectionThreshold,
+ s-NonIntraSearchQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL, -- Need OP
+ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshServingLowQ-r9 ReselectionThresholdQ-r9 OPTIONAL -- Need OP
+ ]]
+}
+
+
+SystemInformationBlockType4 ::= SEQUENCE {
+ intraFreqNeighCellList IntraFreqNeighCellList OPTIONAL, -- Need OR
+ intraFreqBlackCellList IntraFreqBlackCellList OPTIONAL, -- Need OR
+ csg-PhysCellIdRange PhysCellIdRange OPTIONAL, -- Cond CSG
+ ...
+}
+
+IntraFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellIntra)) OF IntraFreqNeighCellInfo
+
+IntraFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange,
+ ...
+}
+
+IntraFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType5 ::= SEQUENCE {
+ interFreqCarrierFreqList InterFreqCarrierFreqList,
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+InterFreqCarrierFreqList ::= SEQUENCE (SIZE (1..maxFreq)) OF InterFreqCarrierFreqInfo
+
+InterFreqCarrierFreqInfo ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ q-RxLevMin Q-RxLevMin,
+ p-Max P-Max OPTIONAL, -- Need OP
+ t-ReselectionEUTRA T-Reselection,
+ t-ReselectionEUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ neighCellConfig NeighCellConfig,
+ q-OffsetFreq Q-OffsetRange DEFAULT dB0,
+ interFreqNeighCellList InterFreqNeighCellList OPTIONAL, -- Need OR
+ interFreqBlackCellList InterFreqBlackCellList OPTIONAL, -- Need OR
+ ...,
+ [[ q-QualMin-r9 Q-QualMin-r9 OPTIONAL, -- Need OP
+ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+InterFreqNeighCellList ::= SEQUENCE (SIZE (1..maxCellInter)) OF InterFreqNeighCellInfo
+
+InterFreqNeighCellInfo ::= SEQUENCE {
+ physCellId PhysCellId,
+ q-OffsetCell Q-OffsetRange
+}
+
+InterFreqBlackCellList ::= SEQUENCE (SIZE (1..maxCellBlack)) OF PhysCellIdRange
+
+
+SystemInformationBlockType6 ::= SEQUENCE {
+ carrierFreqListUTRA-FDD CarrierFreqListUTRA-FDD OPTIONAL, -- Need OR
+ carrierFreqListUTRA-TDD CarrierFreqListUTRA-TDD OPTIONAL, -- Need OR
+ t-ReselectionUTRA T-Reselection,
+ t-ReselectionUTRA-SF SpeedStateScaleFactors OPTIONAL, -- Need OP
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL -- Need OP
+}
+
+CarrierFreqListUTRA-FDD ::= SEQUENCE (SIZE (1..maxUTRA-FDD-Carrier)) OF CarrierFreqUTRA-FDD
+
+CarrierFreqUTRA-FDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ q-QualMin INTEGER (-24..0),
+ ...,
+ [[ threshX-Q-r9 SEQUENCE {
+ threshX-HighQ-r9 ReselectionThresholdQ-r9,
+ threshX-LowQ-r9 ReselectionThresholdQ-r9
+ } OPTIONAL -- Cond RSRQ
+ ]]
+}
+
+CarrierFreqListUTRA-TDD ::= SEQUENCE (SIZE (1..maxUTRA-TDD-Carrier)) OF CarrierFreqUTRA-TDD
+
+CarrierFreqUTRA-TDD ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold,
+ q-RxLevMin INTEGER (-60..-13),
+ p-MaxUTRA INTEGER (-50..33),
+ ...
+}
+
+
+SystemInformationBlockType7 ::= SEQUENCE {
+ t-ReselectionGERAN T-Reselection,
+ t-ReselectionGERAN-SF SpeedStateScaleFactors OPTIONAL, -- Need OR
+ carrierFreqsInfoList CarrierFreqsInfoListGERAN OPTIONAL, -- Need OR
+ ...
+}
+
+CarrierFreqsInfoListGERAN ::= SEQUENCE (SIZE (1..maxGNFG)) OF CarrierFreqsInfoGERAN
+
+CarrierFreqsInfoGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ commonInfo SEQUENCE {
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ ncc-Permitted BIT STRING (SIZE (8)),
+ q-RxLevMin INTEGER (0..45),
+ p-MaxGERAN INTEGER (0..39) OPTIONAL, -- Need OP
+ threshX-High ReselectionThreshold,
+ threshX-Low ReselectionThreshold
+ },
+ ...
+}
+
+
+SystemInformationBlockType8 ::= SEQUENCE {
+ systemTimeInfo SystemTimeInfoCDMA2000 OPTIONAL, -- Need OR
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need OR
+ parametersHRPD SEQUENCE {
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD,
+ cellReselectionParametersHRPD CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ parameters1XRTT SEQUENCE {
+ csfb-RegistrationParam1XRTT CSFB-RegistrationParam1XRTT OPTIONAL, -- Need OP
+ longCodeState1XRTT BIT STRING (SIZE (42)) OPTIONAL, -- Need OR
+ cellReselectionParameters1XRTT CellReselectionParametersCDMA2000 OPTIONAL -- Need OR
+ } OPTIONAL, -- Need OR
+ ...,
+ lateR8NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ [[ csfb-SupportForDualRxUEs-r9 BOOLEAN OPTIONAL, -- Need OR
+ cellReselectionParametersHRPD-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-HRPD
+ cellReselectionParameters1XRTT-v920 CellReselectionParametersCDMA2000-v920 OPTIONAL, -- Cond NCL-1XRTT
+ csfb-RegistrationParam1XRTT-v920 CSFB-RegistrationParam1XRTT-v920 OPTIONAL, -- Cond REG-1XRTT
+ ac-BarringConfig1XRTT-r9 AC-BarringConfig1XRTT-r9 OPTIONAL -- Cond REG-1XRTT
+ ]]
+}
+
+CellReselectionParametersCDMA2000 ::= SEQUENCE {
+ bandClassList BandClassListCDMA2000,
+ neighCellList NeighCellListCDMA2000,
+ t-ReselectionCDMA2000 T-Reselection,
+ t-ReselectionCDMA2000-SF SpeedStateScaleFactors OPTIONAL -- Need OP
+}
+
+CellReselectionParametersCDMA2000-v920 ::= SEQUENCE {
+ neighCellList-v920 NeighCellListCDMA2000-v920
+}
+
+NeighCellListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000
+
+NeighCellCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ neighCellsPerFreqList NeighCellsPerBandclassListCDMA2000
+}
+
+NeighCellsPerBandclassListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000
+
+NeighCellsPerBandclassCDMA2000 ::= SEQUENCE {
+ arfcn ARFCN-ValueCDMA2000,
+ physCellIdList PhysCellIdListCDMA2000
+}
+
+NeighCellListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellCDMA2000-v920
+
+NeighCellCDMA2000-v920 ::= SEQUENCE {
+ neighCellsPerFreqList-v920 NeighCellsPerBandclassListCDMA2000-v920
+}
+
+NeighCellsPerBandclassListCDMA2000-v920 ::= SEQUENCE (SIZE (1..16)) OF NeighCellsPerBandclassCDMA2000-v920
+
+NeighCellsPerBandclassCDMA2000-v920 ::= SEQUENCE {
+ physCellIdList-v920 PhysCellIdListCDMA2000-v920
+}
+
+PhysCellIdListCDMA2000 ::= SEQUENCE (SIZE (1..16)) OF PhysCellIdCDMA2000
+
+PhysCellIdListCDMA2000-v920 ::= SEQUENCE (SIZE (0..24)) OF PhysCellIdCDMA2000
+
+BandClassListCDMA2000 ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandClassInfoCDMA2000
+
+BandClassInfoCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ cellReselectionPriority CellReselectionPriority OPTIONAL, -- Need OP
+ threshX-High INTEGER (0..63),
+ threshX-Low INTEGER (0..63),
+ ...
+}
+
+AC-BarringConfig1XRTT-r9 ::= SEQUENCE {
+ ac-Barring0to9-r9 INTEGER (0..63),
+ ac-Barring10-r9 INTEGER (0..7),
+ ac-Barring11-r9 INTEGER (0..7),
+ ac-Barring12-r9 INTEGER (0..7),
+ ac-Barring13-r9 INTEGER (0..7),
+ ac-Barring14-r9 INTEGER (0..7),
+ ac-Barring15-r9 INTEGER (0..7),
+ ac-BarringMsg-r9 INTEGER (0..7),
+ ac-BarringReg-r9 INTEGER (0..7),
+ ac-BarringEmg-r9 INTEGER (0..7)
+}
+
+
+SystemInformationBlockType9 ::= SEQUENCE {
+ hnb-Name OCTET STRING (SIZE(1..48)) OPTIONAL, -- Need OR
+ ...
+}
+
+
+SystemInformationBlockType10 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningType OCTET STRING (SIZE (2)),
+ warningSecurityInfo OCTET STRING (SIZE (50)) OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType11 ::= SEQUENCE {
+ messageIdentifier BIT STRING (SIZE (16)),
+ serialNumber BIT STRING (SIZE (16)),
+ warningMessageSegmentType ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber INTEGER (0..63),
+ warningMessageSegment OCTET STRING,
+ dataCodingScheme OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ ...
+}
+
+
+SystemInformationBlockType12-r9 ::= SEQUENCE {
+ messageIdentifier-r9 BIT STRING (SIZE (16)),
+ serialNumber-r9 BIT STRING (SIZE (16)),
+ warningMessageSegmentType-r9 ENUMERATED {notLastSegment, lastSegment},
+ warningMessageSegmentNumber-r9 INTEGER (0..63),
+ warningMessageSegment-r9 OCTET STRING,
+ dataCodingScheme-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Cond Segment1
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+SystemInformationBlockType13-r9 ::= SEQUENCE {
+ mbsfn-AreaInfoList-r9 MBSFN-AreaInfoList-r9,
+ notificationConfig-r9 MBMS-NotificationConfig-r9,
+ lateR9NonCriticalExtension OCTET STRING OPTIONAL, -- Need OP
+ ...
+}
+
+
+AntennaInfoCommon ::= SEQUENCE {
+ antennaPortsCount ENUMERATED {an1, an2, an4, spare1}
+}
+
+AntennaInfoDedicated ::= SEQUENCE {
+ transmissionMode ENUMERATED {
+ tm1, tm2, tm3, tm4, tm5, tm6,
+ tm7, tm8-v920},
+ codebookSubsetRestriction CHOICE {
+ n2TxAntenna-tm3 BIT STRING (SIZE (2)),
+ n4TxAntenna-tm3 BIT STRING (SIZE (4)),
+ n2TxAntenna-tm4 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm4 BIT STRING (SIZE (64)),
+ n2TxAntenna-tm5 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm5 BIT STRING (SIZE (16)),
+ n2TxAntenna-tm6 BIT STRING (SIZE (4)),
+ n4TxAntenna-tm6 BIT STRING (SIZE (16))
+ } OPTIONAL, -- Cond TM
+ ue-TransmitAntennaSelection CHOICE{
+ release NULL,
+ setup ENUMERATED {closedLoop, openLoop}
+ }
+}
+
+AntennaInfoDedicated-v920 ::= SEQUENCE {
+ codebookSubsetRestriction-v920 CHOICE {
+ n2TxAntenna-tm8-r9 BIT STRING (SIZE (6)),
+ n4TxAntenna-tm8-r9 BIT STRING (SIZE (32))
+ } OPTIONAL -- Cond TM8
+}
+
+
+CQI-ReportConfig ::= SEQUENCE {
+ cqi-ReportModeAperiodic ENUMERATED {
+ rm12, rm20, rm22, rm30, rm31,
+ spare3, spare2, spare1} OPTIONAL, -- Need OR
+ nomPDSCH-RS-EPRE-Offset INTEGER (-1..6),
+ cqi-ReportPeriodic CQI-ReportPeriodic OPTIONAL -- Need ON
+}
+
+CQI-ReportConfig-v920 ::= SEQUENCE {
+ cqi-Mask-r9 ENUMERATED {setup} OPTIONAL, -- Cond cqi-Setup
+ pmi-RI-Report-r9 ENUMERATED {setup} OPTIONAL -- Cond PMIRI
+}
+
+CQI-ReportPeriodic ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ cqi-PUCCH-ResourceIndex INTEGER (0.. 1185),
+ cqi-pmi-ConfigIndex INTEGER (0..1023),
+ cqi-FormatIndicatorPeriodic CHOICE {
+ widebandCQI NULL,
+ subbandCQI SEQUENCE {
+ k INTEGER (1..4)
+ }
+ },
+ ri-ConfigIndex INTEGER (0..1023) OPTIONAL, -- Need OR
+ simultaneousAckNackAndCQI BOOLEAN
+ }
+}
+
+
+DRB-Identity ::= INTEGER (1..32)
+
+
+LogicalChannelConfig ::= SEQUENCE {
+ ul-SpecificParameters SEQUENCE {
+ priority INTEGER (1..16),
+ prioritisedBitRate ENUMERATED {
+ kBps0, kBps8, kBps16, kBps32, kBps64, kBps128,
+ kBps256, infinity, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2, spare1},
+ bucketSizeDuration ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500, ms1000, spare2,
+ spare1},
+ logicalChannelGroup INTEGER (0..3) OPTIONAL -- Need OR
+ } OPTIONAL, -- Cond UL
+ ...,
+ [[ logicalChannelSR-Mask-r9 ENUMERATED {setup} OPTIONAL -- Cond SRmask
+ ]]
+}
+
+
+MAC-MainConfig ::= SEQUENCE {
+ ul-SCH-Config SEQUENCE {
+ maxHARQ-Tx ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n7, n8,
+ n10, n12, n16, n20, n24, n28,
+ spare2, spare1} OPTIONAL, -- Need ON
+ periodicBSR-Timer ENUMERATED {
+ sf5, sf10, sf16, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, sf1280, sf2560,
+ infinity, spare1} OPTIONAL, -- Need ON
+ retxBSR-Timer ENUMERATED {
+ sf320, sf640, sf1280, sf2560, sf5120,
+ sf10240, spare2, spare1},
+ ttiBundling BOOLEAN
+ } OPTIONAL, -- Need ON
+ drx-Config DRX-Config OPTIONAL, -- Need ON
+ timeAlignmentTimerDedicated TimeAlignmentTimer,
+ phr-Config CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ periodicPHR-Timer ENUMERATED {sf10, sf20, sf50, sf100, sf200,
+ sf500, sf1000, infinity},
+ prohibitPHR-Timer ENUMERATED {sf0, sf10, sf20, sf50, sf100,
+ sf200, sf500, sf1000},
+ dl-PathlossChange ENUMERATED {dB1, dB3, dB6, infinity}
+ }
+ } OPTIONAL, -- Need ON
+ ...,
+ [[ sr-ProhibitTimer-r9 INTEGER (0..7) OPTIONAL -- Need ON
+ ]]
+}
+
+DRX-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ onDurationTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200},
+ drx-InactivityTimer ENUMERATED {
+ psf1, psf2, psf3, psf4, psf5, psf6,
+ psf8, psf10, psf20, psf30, psf40,
+ psf50, psf60, psf80, psf100,
+ psf200, psf300, psf500, psf750,
+ psf1280, psf1920, psf2560, spare10,
+ spare9, spare8, spare7, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ drx-RetransmissionTimer ENUMERATED {
+ psf1, psf2, psf4, psf6, psf8, psf16,
+ psf24, psf33},
+ longDRX-CycleStartOffset CHOICE {
+ sf10 INTEGER(0..9),
+ sf20 INTEGER(0..19),
+ sf32 INTEGER(0..31),
+ sf40 INTEGER(0..39),
+ sf64 INTEGER(0..63),
+ sf80 INTEGER(0..79),
+ sf128 INTEGER(0..127),
+ sf160 INTEGER(0..159),
+ sf256 INTEGER(0..255),
+ sf320 INTEGER(0..319),
+ sf512 INTEGER(0..511),
+ sf640 INTEGER(0..639),
+ sf1024 INTEGER(0..1023),
+ sf1280 INTEGER(0..1279),
+ sf2048 INTEGER(0..2047),
+ sf2560 INTEGER(0..2559)
+ },
+ shortDRX SEQUENCE {
+ shortDRX-Cycle ENUMERATED {
+ sf2, sf5, sf8, sf10, sf16, sf20,
+ sf32, sf40, sf64, sf80, sf128, sf160,
+ sf256, sf320, sf512, sf640},
+ drxShortCycleTimer INTEGER (1..16)
+ } OPTIONAL -- Need OR
+ }
+}
+
+
+PDCP-Config ::= SEQUENCE {
+ discardTimer ENUMERATED {
+ ms50, ms100, ms150, ms300, ms500,
+ ms750, ms1500, infinity
+ } OPTIONAL, -- Cond Setup
+ rlc-AM SEQUENCE {
+ statusReportRequired BOOLEAN
+ } OPTIONAL, -- Cond Rlc-AM
+ rlc-UM SEQUENCE {
+ pdcp-SN-Size ENUMERATED {len7bits, len12bits}
+ } OPTIONAL, -- Cond Rlc-UM
+ headerCompression CHOICE {
+ notUsed NULL,
+ rohc SEQUENCE {
+ maxCID INTEGER (1..16383) DEFAULT 15,
+ profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ ...
+ }
+ },
+ ...
+}
+
+
+PDSCH-ConfigCommon ::= SEQUENCE {
+ referenceSignalPower INTEGER (-60..50),
+ p-b INTEGER (0..3)
+}
+
+PDSCH-ConfigDedicated::= SEQUENCE {
+ p-a ENUMERATED {
+ dB-6, dB-4dot77, dB-3, dB-1dot77,
+ dB0, dB1, dB2, dB3}
+}
+
+
+PHICH-Config ::= SEQUENCE {
+ phich-Duration ENUMERATED {normal, extended},
+ phich-Resource ENUMERATED {oneSixth, half, one, two}
+}
+
+
+PhysicalConfigDedicated ::= SEQUENCE {
+ pdsch-ConfigDedicated PDSCH-ConfigDedicated OPTIONAL, -- Need ON
+ pucch-ConfigDedicated PUCCH-ConfigDedicated OPTIONAL, -- Need ON
+ pusch-ConfigDedicated PUSCH-ConfigDedicated OPTIONAL, -- Need ON
+ uplinkPowerControlDedicated UplinkPowerControlDedicated OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUCCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ tpc-PDCCH-ConfigPUSCH TPC-PDCCH-Config OPTIONAL, -- Need ON
+ cqi-ReportConfig CQI-ReportConfig OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigDedicated SoundingRS-UL-ConfigDedicated OPTIONAL, -- Need ON
+ antennaInfo CHOICE {
+ explicitValue AntennaInfoDedicated,
+ defaultValue NULL
+ } OPTIONAL, -- Need ON
+ schedulingRequestConfig SchedulingRequestConfig OPTIONAL, -- Need ON
+ ...,
+ [[ cqi-ReportConfig-v920 CQI-ReportConfig-v920 OPTIONAL, -- Need ON
+ antennaInfo-v920 AntennaInfoDedicated-v920 OPTIONAL -- Need ON
+ ]]
+}
+
+
+P-Max ::= INTEGER (-30..33)
+
+
+PRACH-ConfigSIB ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo
+}
+
+PRACH-Config ::= SEQUENCE {
+ rootSequenceIndex INTEGER (0..837),
+ prach-ConfigInfo PRACH-ConfigInfo OPTIONAL -- Need ON
+}
+
+PRACH-ConfigInfo ::= SEQUENCE {
+ prach-ConfigIndex INTEGER (0..63),
+ highSpeedFlag BOOLEAN,
+ zeroCorrelationZoneConfig INTEGER (0..15),
+ prach-FreqOffset INTEGER (0..94)
+}
+
+
+PresenceAntennaPort1 ::= BOOLEAN
+
+
+PUCCH-ConfigCommon ::= SEQUENCE {
+ deltaPUCCH-Shift ENUMERATED {ds1, ds2, ds3},
+ nRB-CQI INTEGER (0..98),
+ nCS-AN INTEGER (0..7),
+ n1PUCCH-AN INTEGER (0..2047)
+}
+
+PUCCH-ConfigDedicated ::= SEQUENCE {
+ ackNackRepetition CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ repetitionFactor ENUMERATED {n2, n4, n6, spare1},
+ n1PUCCH-AN-Rep INTEGER (0..2047)
+ }
+ },
+ tdd-AckNackFeedbackMode ENUMERATED {bundling, multiplexing} OPTIONAL -- Cond TDD
+}
+
+
+PUSCH-ConfigCommon ::= SEQUENCE {
+ pusch-ConfigBasic SEQUENCE {
+ n-SB INTEGER (1..4),
+ hoppingMode ENUMERATED {interSubFrame, intraAndInterSubFrame},
+ pusch-HoppingOffset INTEGER (0..98),
+ enable64QAM BOOLEAN
+ },
+ ul-ReferenceSignalsPUSCH UL-ReferenceSignalsPUSCH
+}
+
+PUSCH-ConfigDedicated ::= SEQUENCE {
+ betaOffset-ACK-Index INTEGER (0..15),
+ betaOffset-RI-Index INTEGER (0..15),
+ betaOffset-CQI-Index INTEGER (0..15)
+}
+
+UL-ReferenceSignalsPUSCH ::= SEQUENCE {
+ groupHoppingEnabled BOOLEAN,
+ groupAssignmentPUSCH INTEGER (0..29),
+ sequenceHoppingEnabled BOOLEAN,
+ cyclicShift INTEGER (0..7)
+}
+
+
+RACH-ConfigCommon ::= SEQUENCE {
+ preambleInfo SEQUENCE {
+ numberOfRA-Preambles ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60, n64},
+ preamblesGroupAConfig SEQUENCE {
+ sizeOfRA-PreamblesGroupA ENUMERATED {
+ n4, n8, n12, n16 ,n20, n24, n28,
+ n32, n36, n40, n44, n48, n52, n56,
+ n60},
+ messageSizeGroupA ENUMERATED {b56, b144, b208, b256},
+ messagePowerOffsetGroupB ENUMERATED {
+ minusinfinity, dB0, dB5, dB8, dB10, dB12,
+ dB15, dB18},
+ ...
+ } OPTIONAL -- Need OP
+ },
+ powerRampingParameters SEQUENCE {
+ powerRampingStep ENUMERATED {dB0, dB2,dB4, dB6},
+ preambleInitialReceivedTargetPower ENUMERATED {
+ dBm-120, dBm-118, dBm-116, dBm-114, dBm-112,
+ dBm-110, dBm-108, dBm-106, dBm-104, dBm-102,
+ dBm-100, dBm-98, dBm-96, dBm-94,
+ dBm-92, dBm-90}
+ },
+ ra-SupervisionInfo SEQUENCE {
+ preambleTransMax ENUMERATED {
+ n3, n4, n5, n6, n7, n8, n10, n20, n50,
+ n100, n200},
+ ra-ResponseWindowSize ENUMERATED {
+ sf2, sf3, sf4, sf5, sf6, sf7,
+ sf8, sf10},
+ mac-ContentionResolutionTimer ENUMERATED {
+ sf8, sf16, sf24, sf32, sf40, sf48,
+ sf56, sf64}
+ },
+ maxHARQ-Msg3Tx INTEGER (1..8),
+ ...
+}
+
+
+RACH-ConfigDedicated ::= SEQUENCE {
+ ra-PreambleIndex INTEGER (0..63),
+ ra-PRACH-MaskIndex INTEGER (0..15)
+}
+
+
+RadioResourceConfigCommonSIB ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon,
+ bcch-Config BCCH-Config,
+ pcch-Config PCCH-Config,
+ prach-Config PRACH-ConfigSIB,
+ pdsch-ConfigCommon PDSCH-ConfigCommon,
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ pucch-ConfigCommon PUCCH-ConfigCommon,
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon,
+ uplinkPowerControlCommon UplinkPowerControlCommon,
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+RadioResourceConfigCommon ::= SEQUENCE {
+ rach-ConfigCommon RACH-ConfigCommon OPTIONAL, -- Need ON
+ prach-Config PRACH-Config,
+ pdsch-ConfigCommon PDSCH-ConfigCommon OPTIONAL, -- Need ON
+ pusch-ConfigCommon PUSCH-ConfigCommon,
+ phich-Config PHICH-Config OPTIONAL, -- Need ON
+ pucch-ConfigCommon PUCCH-ConfigCommon OPTIONAL, -- Need ON
+ soundingRS-UL-ConfigCommon SoundingRS-UL-ConfigCommon OPTIONAL, -- Need ON
+ uplinkPowerControlCommon UplinkPowerControlCommon OPTIONAL, -- Need ON
+ antennaInfoCommon AntennaInfoCommon OPTIONAL, -- Need ON
+ p-Max P-Max OPTIONAL, -- Need OP
+ tdd-Config TDD-Config OPTIONAL, -- Cond TDD
+ ul-CyclicPrefixLength UL-CyclicPrefixLength,
+ ...
+}
+
+BCCH-Config ::= SEQUENCE {
+ modificationPeriodCoeff ENUMERATED {n2, n4, n8, n16}
+}
+
+PCCH-Config ::= SEQUENCE {
+ defaultPagingCycle ENUMERATED {
+ rf32, rf64, rf128, rf256},
+ nB ENUMERATED {
+ fourT, twoT, oneT, halfT, quarterT, oneEighthT,
+ oneSixteenthT, oneThirtySecondT}
+}
+
+UL-CyclicPrefixLength ::= ENUMERATED {len1, len2}
+
+
+RadioResourceConfigDedicated ::= SEQUENCE {
+ srb-ToAddModList SRB-ToAddModList OPTIONAL, -- Cond HO-Conn
+ drb-ToAddModList DRB-ToAddModList OPTIONAL, -- Cond HO-toEUTRA
+ drb-ToReleaseList DRB-ToReleaseList OPTIONAL, -- Need ON
+ mac-MainConfig CHOICE {
+ explicitValue MAC-MainConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond HO-toEUTRA2
+ sps-Config SPS-Config OPTIONAL, -- Need ON
+ physicalConfigDedicated PhysicalConfigDedicated OPTIONAL, -- Need ON
+ ...,
+ [[ rlf-TimersAndConstants-r9 RLF-TimersAndConstants-r9 OPTIONAL -- Need ON
+ ]]
+}
+
+SRB-ToAddModList ::= SEQUENCE (SIZE (1..2)) OF SRB-ToAddMod
+
+SRB-ToAddMod ::= SEQUENCE {
+ srb-Identity INTEGER (1..2),
+ rlc-Config CHOICE {
+ explicitValue RLC-Config,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ logicalChannelConfig CHOICE {
+ explicitValue LogicalChannelConfig,
+ defaultValue NULL
+ } OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToAddModList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-ToAddMod
+
+DRB-ToAddMod ::= SEQUENCE {
+ eps-BearerIdentity INTEGER (0..15) OPTIONAL, -- Cond DRB-Setup
+ drb-Identity DRB-Identity,
+ pdcp-Config PDCP-Config OPTIONAL, -- Cond PDCP
+ rlc-Config RLC-Config OPTIONAL, -- Cond Setup
+ logicalChannelIdentity INTEGER (3..10) OPTIONAL, -- Cond DRB-Setup
+ logicalChannelConfig LogicalChannelConfig OPTIONAL, -- Cond Setup
+ ...
+}
+
+DRB-ToReleaseList ::= SEQUENCE (SIZE (1..maxDRB)) OF DRB-Identity
+
+
+RLC-Config ::= CHOICE {
+ am SEQUENCE {
+ ul-AM-RLC UL-AM-RLC,
+ dl-AM-RLC DL-AM-RLC
+ },
+ um-Bi-Directional SEQUENCE {
+ ul-UM-RLC UL-UM-RLC,
+ dl-UM-RLC DL-UM-RLC
+ },
+ um-Uni-Directional-UL SEQUENCE {
+ ul-UM-RLC UL-UM-RLC
+ },
+ um-Uni-Directional-DL SEQUENCE {
+ dl-UM-RLC DL-UM-RLC
+ },
+ ...
+}
+
+UL-AM-RLC ::= SEQUENCE {
+ t-PollRetransmit T-PollRetransmit,
+ pollPDU PollPDU,
+ pollByte PollByte,
+ maxRetxThreshold ENUMERATED {
+ t1, t2, t3, t4, t6, t8, t16, t32}
+}
+
+DL-AM-RLC ::= SEQUENCE {
+ t-Reordering T-Reordering,
+ t-StatusProhibit T-StatusProhibit
+}
+
+UL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength
+}
+
+DL-UM-RLC ::= SEQUENCE {
+ sn-FieldLength SN-FieldLength,
+ t-Reordering T-Reordering
+}
+
+SN-FieldLength ::= ENUMERATED {size5, size10}
+
+T-PollRetransmit ::= ENUMERATED {
+ ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare9, spare8,
+ spare7, spare6, spare5, spare4, spare3,
+ spare2, spare1}
+
+PollPDU ::= ENUMERATED {
+ p4, p8, p16, p32, p64, p128, p256, pInfinity}
+
+PollByte ::= ENUMERATED {
+ kB25, kB50, kB75, kB100, kB125, kB250, kB375,
+ kB500, kB750, kB1000, kB1250, kB1500, kB2000,
+ kB3000, kBinfinity, spare1}
+
+T-Reordering ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms110,
+ ms120, ms130, ms140, ms150, ms160, ms170,
+ ms180, ms190, ms200, spare1}
+
+T-StatusProhibit ::= ENUMERATED {
+ ms0, ms5, ms10, ms15, ms20, ms25, ms30, ms35,
+ ms40, ms45, ms50, ms55, ms60, ms65, ms70,
+ ms75, ms80, ms85, ms90, ms95, ms100, ms105,
+ ms110, ms115, ms120, ms125, ms130, ms135,
+ ms140, ms145, ms150, ms155, ms160, ms165,
+ ms170, ms175, ms180, ms185, ms190, ms195,
+ ms200, ms205, ms210, ms215, ms220, ms225,
+ ms230, ms235, ms240, ms245, ms250, ms300,
+ ms350, ms400, ms450, ms500, spare8, spare7,
+ spare6, spare5, spare4, spare3, spare2,
+ spare1}
+
+
+RLF-TimersAndConstants-r9 ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ t301-r9 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310-r9 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310-r9 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311-r9 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311-r9 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+ }
+}
+
+
+SchedulingRequestConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ sr-PUCCH-ResourceIndex INTEGER (0..2047),
+ sr-ConfigIndex INTEGER (0..157),
+ dsr-TransMax ENUMERATED {
+ n4, n8, n16, n32, n64, spare3, spare2, spare1}
+ }
+}
+
+
+SoundingRS-UL-ConfigCommon ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ srs-BandwidthConfig ENUMERATED {bw0, bw1, bw2, bw3, bw4, bw5, bw6, bw7},
+ srs-SubframeConfig ENUMERATED {
+ sc0, sc1, sc2, sc3, sc4, sc5, sc6, sc7,
+ sc8, sc9, sc10, sc11, sc12, sc13, sc14, sc15},
+ ackNackSRS-SimultaneousTransmission BOOLEAN,
+ srs-MaxUpPts ENUMERATED {true} OPTIONAL -- Cond TDD
+ }
+}
+
+SoundingRS-UL-ConfigDedicated ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ srs-Bandwidth ENUMERATED {bw0, bw1, bw2, bw3},
+ srs-HoppingBandwidth ENUMERATED {hbw0, hbw1, hbw2, hbw3},
+ freqDomainPosition INTEGER (0..23),
+ duration BOOLEAN,
+ srs-ConfigIndex INTEGER (0..1023),
+ transmissionComb INTEGER (0..1),
+ cyclicShift ENUMERATED {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7}
+ }
+}
+
+
+
+SPS-Config ::= SEQUENCE {
+ semiPersistSchedC-RNTI C-RNTI OPTIONAL, -- Need OR
+ sps-ConfigDL SPS-ConfigDL OPTIONAL, -- Need ON
+ sps-ConfigUL SPS-ConfigUL OPTIONAL -- Need ON
+}
+
+SPS-ConfigDL ::= CHOICE{
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalDL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ numberOfConfSPS-Processes INTEGER (1..8),
+ n1-PUCCH-AN-PersistentList N1-PUCCH-AN-PersistentList,
+ ...
+ }
+}
+
+SPS-ConfigUL ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ semiPersistSchedIntervalUL ENUMERATED {
+ sf10, sf20, sf32, sf40, sf64, sf80,
+ sf128, sf160, sf320, sf640, spare6,
+ spare5, spare4, spare3, spare2,
+ spare1},
+ implicitReleaseAfter ENUMERATED {e2, e3, e4, e8},
+ p0-Persistent SEQUENCE {
+ p0-NominalPUSCH-Persistent INTEGER (-126..24),
+ p0-UE-PUSCH-Persistent INTEGER (-8..7)
+ } OPTIONAL, -- Need OP
+ twoIntervalsConfig ENUMERATED {true} OPTIONAL, -- Cond TDD
+ ...
+ }
+}
+
+N1-PUCCH-AN-PersistentList ::= SEQUENCE (SIZE (1..4)) OF INTEGER (0..2047)
+
+
+TDD-Config ::= SEQUENCE {
+ subframeAssignment ENUMERATED {
+ sa0, sa1, sa2, sa3, sa4, sa5, sa6},
+ specialSubframePatterns ENUMERATED {
+ ssp0, ssp1, ssp2, ssp3, ssp4,ssp5, ssp6, ssp7,
+ ssp8}
+}
+
+
+TimeAlignmentTimer ::= ENUMERATED {
+ sf500, sf750, sf1280, sf1920, sf2560, sf5120,
+ sf10240, infinity}
+
+TPC-PDCCH-Config ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ tpc-RNTI BIT STRING (SIZE (16)),
+ tpc-Index TPC-Index
+ }
+}
+
+TPC-Index ::= CHOICE {
+ indexOfFormat3 INTEGER (1..15),
+ indexOfFormat3A INTEGER (1..31)
+}
+
+
+UplinkPowerControlCommon ::= SEQUENCE {
+ p0-NominalPUSCH INTEGER (-126..24),
+ alpha ENUMERATED {al0, al04, al05, al06, al07, al08, al09, al1},
+ p0-NominalPUCCH INTEGER (-127..-96),
+ deltaFList-PUCCH DeltaFList-PUCCH,
+ deltaPreambleMsg3 INTEGER (-1..6)
+}
+
+UplinkPowerControlDedicated ::= SEQUENCE {
+ p0-UE-PUSCH INTEGER (-8..7),
+ deltaMCS-Enabled ENUMERATED {en0, en1},
+ accumulationEnabled BOOLEAN,
+ p0-UE-PUCCH INTEGER (-8..7),
+ pSRS-Offset INTEGER (0..15),
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+DeltaFList-PUCCH ::= SEQUENCE {
+ deltaF-PUCCH-Format1 ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format1b ENUMERATED {deltaF1, deltaF3, deltaF5},
+ deltaF-PUCCH-Format2 ENUMERATED {deltaF-2, deltaF0, deltaF1, deltaF2},
+ deltaF-PUCCH-Format2a ENUMERATED {deltaF-2, deltaF0, deltaF2},
+ deltaF-PUCCH-Format2b ENUMERATED {deltaF-2, deltaF0, deltaF2}
+}
+
+
+NextHopChainingCount ::= INTEGER (0..7)
+
+
+SecurityAlgorithmConfig ::= SEQUENCE {
+ cipheringAlgorithm ENUMERATED {
+ eea0, eea1, eea2, spare5, spare4, spare3,
+ spare2, spare1, ...},
+ integrityProtAlgorithm ENUMERATED {
+ eia0-v920, eia1, eia2, spare5, spare4, spare3,
+ spare2, spare1, ...}
+}
+
+
+ShortMAC-I ::= BIT STRING (SIZE (16))
+
+
+AdditionalSpectrumEmission ::= INTEGER (1..32)
+
+
+ARFCN-ValueCDMA2000 ::= INTEGER (0..2047)
+
+
+ARFCN-ValueEUTRA ::= INTEGER (0..maxEARFCN)
+
+
+ARFCN-ValueGERAN ::= INTEGER (0..1023)
+
+
+ARFCN-ValueUTRA ::= INTEGER (0..16383)
+
+
+BandclassCDMA2000 ::= ENUMERATED {
+ bc0, bc1, bc2, bc3, bc4, bc5, bc6, bc7, bc8,
+ bc9, bc10, bc11, bc12, bc13, bc14, bc15, bc16,
+ bc17, spare14, spare13, spare12, spare11, spare10,
+ spare9, spare8, spare7, spare6, spare5, spare4,
+ spare3, spare2, spare1, ...}
+
+
+BandIndicatorGERAN ::= ENUMERATED {dcs1800, pcs1900}
+
+
+CarrierFreqCDMA2000 ::= SEQUENCE {
+ bandClass BandclassCDMA2000,
+ arfcn ARFCN-ValueCDMA2000
+}
+
+
+CarrierFreqGERAN ::= SEQUENCE {
+ arfcn ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN
+}
+
+
+CarrierFreqsGERAN ::= SEQUENCE {
+ startingARFCN ARFCN-ValueGERAN,
+ bandIndicator BandIndicatorGERAN,
+ followingARFCNs CHOICE {
+ explicitListOfARFCNs ExplicitListOfARFCNs,
+ equallySpacedARFCNs SEQUENCE {
+ arfcn-Spacing INTEGER (1..8),
+ numberOfFollowingARFCNs INTEGER (0..31)
+ },
+ variableBitMapOfARFCNs OCTET STRING (SIZE (1..16))
+ }
+}
+
+ExplicitListOfARFCNs ::= SEQUENCE (SIZE (0..31)) OF ARFCN-ValueGERAN
+
+
+CDMA2000-Type ::= ENUMERATED {type1XRTT, typeHRPD}
+
+
+CellIdentity ::= BIT STRING (SIZE (28))
+
+
+CellIndexList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellIndex
+
+CellIndex ::= INTEGER (1..maxCellMeas)
+
+
+CellReselectionPriority ::= INTEGER (0..7)
+
+
+CSFB-RegistrationParam1XRTT ::= SEQUENCE {
+ sid BIT STRING (SIZE (15)),
+ nid BIT STRING (SIZE (16)),
+ multipleSID BOOLEAN,
+ multipleNID BOOLEAN,
+ homeReg BOOLEAN,
+ foreignSIDReg BOOLEAN,
+ foreignNIDReg BOOLEAN,
+ parameterReg BOOLEAN,
+ powerUpReg BOOLEAN,
+ registrationPeriod BIT STRING (SIZE (7)),
+ registrationZone BIT STRING (SIZE (12)),
+ totalZone BIT STRING (SIZE (3)),
+ zoneTimer BIT STRING (SIZE (3))
+}
+
+CSFB-RegistrationParam1XRTT-v920 ::= SEQUENCE {
+ powerDownReg-r9 ENUMERATED {true}
+}
+
+
+CellGlobalIdEUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity CellIdentity
+}
+
+
+CellGlobalIdUTRA ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ cellIdentity BIT STRING (SIZE (28))
+}
+
+
+CellGlobalIdGERAN ::= SEQUENCE {
+ plmn-Identity PLMN-Identity,
+ locationAreaCode BIT STRING (SIZE (16)),
+ cellIdentity BIT STRING (SIZE (16))
+}
+
+
+CellGlobalIdCDMA2000 ::= CHOICE {
+ cellGlobalId1XRTT BIT STRING (SIZE (47)),
+ cellGlobalIdHRPD BIT STRING (SIZE (128))
+}
+
+
+CSG-Identity ::= BIT STRING (SIZE (27))
+
+
+MobilityControlInfo ::= SEQUENCE {
+ targetPhysCellId PhysCellId,
+ carrierFreq CarrierFreqEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ carrierBandwidth CarrierBandwidthEUTRA OPTIONAL, -- Cond HO-toEUTRA
+ additionalSpectrumEmission AdditionalSpectrumEmission OPTIONAL, -- Cond HO-toEUTRA
+ t304 ENUMERATED {
+ ms50, ms100, ms150, ms200, ms500, ms1000,
+ ms2000, spare1},
+ newUE-Identity C-RNTI,
+ radioResourceConfigCommon RadioResourceConfigCommon,
+ rach-ConfigDedicated RACH-ConfigDedicated OPTIONAL, -- Need OP
+ ...
+}
+
+CarrierBandwidthEUTRA ::= SEQUENCE {
+ dl-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1},
+ ul-Bandwidth ENUMERATED {
+ n6, n15, n25, n50, n75, n100, spare10,
+ spare9, spare8, spare7, spare6, spare5,
+ spare4, spare3, spare2, spare1} OPTIONAL -- Need OP
+}
+
+CarrierFreqEUTRA ::= SEQUENCE {
+ dl-CarrierFreq ARFCN-ValueEUTRA,
+ ul-CarrierFreq ARFCN-ValueEUTRA OPTIONAL -- Cond FDD
+}
+
+
+MobilityParametersCDMA2000 ::= OCTET STRING
+
+
+MobilityStateParameters ::= SEQUENCE {
+ t-Evaluation ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ t-HystNormal ENUMERATED {
+ s30, s60, s120, s180, s240, spare3, spare2, spare1},
+ n-CellChangeMedium INTEGER (1..16),
+ n-CellChangeHigh INTEGER (1..16)
+}
+
+
+PhysCellId ::= INTEGER (0..503)
+
+
+PhysCellIdRange ::= SEQUENCE {
+ start PhysCellId,
+ range ENUMERATED {
+ n4, n8, n12, n16, n24, n32, n48, n64, n84,
+ n96, n128, n168, n252, n504, spare2,
+ spare1} OPTIONAL -- Need OP
+}
+
+
+PhysCellIdCDMA2000 ::= INTEGER (0..maxPNOffset)
+
+
+PhysCellIdGERAN ::= SEQUENCE {
+ networkColourCode BIT STRING (SIZE (3)),
+ baseStationColourCode BIT STRING (SIZE (3))
+}
+
+
+PhysCellIdUTRA-FDD ::= INTEGER (0..511)
+
+
+PhysCellIdUTRA-TDD ::= INTEGER (0..127)
+
+
+PLMN-Identity ::= SEQUENCE {
+ mcc MCC OPTIONAL, -- Cond MCC
+ mnc MNC
+}
+
+MCC ::= SEQUENCE (SIZE (3)) OF
+ MCC-MNC-Digit
+
+MNC ::= SEQUENCE (SIZE (2..3)) OF
+ MCC-MNC-Digit
+
+MCC-MNC-Digit ::= INTEGER (0..9)
+
+
+
+PreRegistrationInfoHRPD ::= SEQUENCE {
+ preRegistrationAllowed BOOLEAN,
+ preRegistrationZoneId PreRegistrationZoneIdHRPD OPTIONAL, -- cond PreRegAllowed
+ secondaryPreRegistrationZoneIdList SecondaryPreRegistrationZoneIdListHRPD OPTIONAL -- Need OR
+}
+
+SecondaryPreRegistrationZoneIdListHRPD ::= SEQUENCE (SIZE (1..2)) OF PreRegistrationZoneIdHRPD
+
+PreRegistrationZoneIdHRPD ::= INTEGER (0..255)
+
+
+Q-QualMin-r9 ::= INTEGER (-34..-3)
+
+
+Q-RxLevMin ::= INTEGER (-70..-22)
+
+
+Q-OffsetRange ::= ENUMERATED {
+ dB-24, dB-22, dB-20, dB-18, dB-16, dB-14,
+ dB-12, dB-10, dB-8, dB-6, dB-5, dB-4, dB-3,
+ dB-2, dB-1, dB0, dB1, dB2, dB3, dB4, dB5,
+ dB6, dB8, dB10, dB12, dB14, dB16, dB18,
+ dB20, dB22, dB24}
+
+
+Q-OffsetRangeInterRAT ::= INTEGER (-15..15)
+
+
+ReselectionThreshold ::= INTEGER (0..31)
+
+
+ReselectionThresholdQ-r9 ::= INTEGER (0..31)
+
+
+SpeedStateScaleFactors ::= SEQUENCE {
+ sf-Medium ENUMERATED {oDot25, oDot5, oDot75, lDot0},
+ sf-High ENUMERATED {oDot25, oDot5, oDot75, lDot0}
+}
+
+SystemInfoListGERAN ::= SEQUENCE (SIZE (1..maxGERAN-SI)) OF
+ OCTET STRING (SIZE (1..23))
+
+
+SystemTimeInfoCDMA2000 ::= SEQUENCE {
+ cdma-EUTRA-Synchronisation BOOLEAN,
+ cdma-SystemTime CHOICE {
+ synchronousSystemTime BIT STRING (SIZE (39)),
+ asynchronousSystemTime BIT STRING (SIZE (49))
+ }
+}
+
+
+TrackingAreaCode ::= BIT STRING (SIZE (16))
+
+
+T-Reselection ::= INTEGER (0..7)
+
+
+AllowedMeasBandwidth ::= ENUMERATED {mbw6, mbw15, mbw25, mbw50, mbw75, mbw100}
+
+
+Hysteresis ::= INTEGER (0..30)
+
+
+MeasConfig ::= SEQUENCE {
+ -- Measurement objects
+ measObjectToRemoveList MeasObjectToRemoveList OPTIONAL, -- Need ON
+ measObjectToAddModList MeasObjectToAddModList OPTIONAL, -- Need ON
+ -- Reporting configurations
+ reportConfigToRemoveList ReportConfigToRemoveList OPTIONAL, -- Need ON
+ reportConfigToAddModList ReportConfigToAddModList OPTIONAL, -- Need ON
+ -- Measurement identities
+ measIdToRemoveList MeasIdToRemoveList OPTIONAL, -- Need ON
+ measIdToAddModList MeasIdToAddModList OPTIONAL, -- Need ON
+ -- Other parameters
+ quantityConfig QuantityConfig OPTIONAL, -- Need ON
+ measGapConfig MeasGapConfig OPTIONAL, -- Need ON
+ s-Measure RSRP-Range OPTIONAL, -- Need ON
+ preRegistrationInfoHRPD PreRegistrationInfoHRPD OPTIONAL, -- Need OP
+ speedStatePars CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ mobilityStateParameters MobilityStateParameters,
+ timeToTrigger-SF SpeedStateScaleFactors
+ }
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+MeasIdToRemoveList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasId
+
+MeasObjectToRemoveList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectId
+
+ReportConfigToRemoveList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigId
+
+
+MeasGapConfig ::= CHOICE {
+ release NULL,
+ setup SEQUENCE {
+ gapOffset CHOICE {
+ gp0 INTEGER (0..39),
+ gp1 INTEGER (0..79),
+ ...
+ }
+ }
+}
+
+
+MeasId ::= INTEGER (1..maxMeasId)
+
+
+MeasIdToAddModList ::= SEQUENCE (SIZE (1..maxMeasId)) OF MeasIdToAddMod
+
+MeasIdToAddMod ::= SEQUENCE {
+ measId MeasId,
+ measObjectId MeasObjectId,
+ reportConfigId ReportConfigId
+}
+
+
+MeasObjectCDMA2000 ::= SEQUENCE {
+ cdma2000-Type CDMA2000-Type,
+ carrierFreq CarrierFreqCDMA2000,
+ searchWindowSize INTEGER (0..15) OPTIONAL, -- Need ON
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModListCDMA2000 OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellIdCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModCDMA2000
+
+CellsToAddModCDMA2000 ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdCDMA2000
+}
+
+
+MeasObjectEUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueEUTRA,
+ allowedMeasBandwidth AllowedMeasBandwidth,
+ presenceAntennaPort1 PresenceAntennaPort1,
+ neighCellConfig NeighCellConfig,
+ offsetFreq Q-OffsetRange DEFAULT dB0,
+ -- Neighbour cell list
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CellsToAddModList OPTIONAL, -- Need ON
+ -- Black list
+ blackCellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ blackCellsToAddModList BlackCellsToAddModList OPTIONAL, -- Need ON
+ cellForWhichToReportCGI PhysCellId OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddMod
+
+CellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellId,
+ cellIndividualOffset Q-OffsetRange
+}
+
+BlackCellsToAddModList ::= SEQUENCE (SIZE (1..maxCellMeas)) OF BlackCellsToAddMod
+
+BlackCellsToAddMod ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellIdRange PhysCellIdRange
+}
+
+
+MeasObjectGERAN ::= SEQUENCE {
+ carrierFreqs CarrierFreqsGERAN,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ ncc-Permitted BIT STRING(SIZE (8)) DEFAULT '11111111'B,
+ cellForWhichToReportCGI PhysCellIdGERAN OPTIONAL, -- Need ON
+ ...
+}
+
+
+MeasObjectId ::= INTEGER (1..maxObjectId)
+
+
+MeasObjectToAddModList ::= SEQUENCE (SIZE (1..maxObjectId)) OF MeasObjectToAddMod
+
+MeasObjectToAddMod ::= SEQUENCE {
+ measObjectId MeasObjectId,
+ measObject CHOICE {
+ measObjectEUTRA MeasObjectEUTRA,
+ measObjectUTRA MeasObjectUTRA,
+ measObjectGERAN MeasObjectGERAN,
+ measObjectCDMA2000 MeasObjectCDMA2000,
+ ...
+ }
+}
+
+
+MeasObjectUTRA ::= SEQUENCE {
+ carrierFreq ARFCN-ValueUTRA,
+ offsetFreq Q-OffsetRangeInterRAT DEFAULT 0,
+ cellsToRemoveList CellIndexList OPTIONAL, -- Need ON
+ cellsToAddModList CHOICE {
+ cellsToAddModListUTRA-FDD CellsToAddModListUTRA-FDD,
+ cellsToAddModListUTRA-TDD CellsToAddModListUTRA-TDD
+ } OPTIONAL, -- Need ON
+ cellForWhichToReportCGI CHOICE {
+ utra-FDD PhysCellIdUTRA-FDD,
+ utra-TDD PhysCellIdUTRA-TDD
+ } OPTIONAL, -- Need ON
+ ...
+}
+
+CellsToAddModListUTRA-FDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-FDD
+
+CellsToAddModUTRA-FDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-FDD
+}
+
+CellsToAddModListUTRA-TDD ::= SEQUENCE (SIZE (1..maxCellMeas)) OF CellsToAddModUTRA-TDD
+
+CellsToAddModUTRA-TDD ::= SEQUENCE {
+ cellIndex INTEGER (1..maxCellMeas),
+ physCellId PhysCellIdUTRA-TDD
+}
+
+
+MeasResults ::= SEQUENCE {
+ measId MeasId,
+ measResultServCell SEQUENCE {
+ rsrpResult RSRP-Range,
+ rsrqResult RSRQ-Range
+ },
+ measResultNeighCells CHOICE {
+ measResultListEUTRA MeasResultListEUTRA,
+ measResultListUTRA MeasResultListUTRA,
+ measResultListGERAN MeasResultListGERAN,
+ measResultsCDMA2000 MeasResultsCDMA2000,
+ ...
+ } OPTIONAL,
+ ...,
+ [[ measResultForECID-r9 MeasResultForECID-r9 OPTIONAL
+ ]]
+}
+
+MeasResultListEUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultEUTRA
+
+MeasResultEUTRA ::= SEQUENCE {
+ physCellId PhysCellId,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdEUTRA,
+ trackingAreaCode TrackingAreaCode,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rsrpResult RSRP-Range OPTIONAL,
+ rsrqResult RSRQ-Range OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListUTRA ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultUTRA
+
+MeasResultUTRA ::= SEQUENCE {
+ physCellId CHOICE {
+ fdd PhysCellIdUTRA-FDD,
+ tdd PhysCellIdUTRA-TDD
+ },
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdUTRA,
+ locationAreaCode BIT STRING (SIZE (16)) OPTIONAL,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL,
+ plmn-IdentityList PLMN-IdentityList2 OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ utra-RSCP INTEGER (-5..91) OPTIONAL,
+ utra-EcN0 INTEGER (0..49) OPTIONAL,
+ ...,
+ [[ additionalSI-Info-r9 AdditionalSI-Info-r9 OPTIONAL
+ ]]
+ }
+}
+
+MeasResultListGERAN ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultGERAN
+
+MeasResultGERAN ::= SEQUENCE {
+ carrierFreq CarrierFreqGERAN,
+ physCellId PhysCellIdGERAN,
+ cgi-Info SEQUENCE {
+ cellGlobalId CellGlobalIdGERAN,
+ routingAreaCode BIT STRING (SIZE (8)) OPTIONAL
+ } OPTIONAL,
+ measResult SEQUENCE {
+ rssi INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultsCDMA2000 ::= SEQUENCE {
+ preRegistrationStatusHRPD BOOLEAN,
+ measResultListCDMA2000 MeasResultListCDMA2000
+}
+
+MeasResultListCDMA2000 ::= SEQUENCE (SIZE (1..maxCellReport)) OF MeasResultCDMA2000
+
+MeasResultCDMA2000 ::= SEQUENCE {
+ physCellId PhysCellIdCDMA2000,
+ cgi-Info CellGlobalIdCDMA2000 OPTIONAL,
+ measResult SEQUENCE {
+ pilotPnPhase INTEGER (0..32767) OPTIONAL,
+ pilotStrength INTEGER (0..63),
+ ...
+ }
+}
+
+MeasResultForECID-r9 ::= SEQUENCE {
+ ue-RxTxTimeDiffResult-r9 INTEGER (0..4095),
+ currentSFN-r9 BIT STRING (SIZE (10))
+}
+
+PLMN-IdentityList2 ::= SEQUENCE (SIZE (1..5)) OF PLMN-Identity
+
+AdditionalSI-Info-r9 ::= SEQUENCE {
+ csg-MemberStatus-r9 ENUMERATED {member} OPTIONAL,
+ csg-Identity-r9 CSG-Identity OPTIONAL
+}
+
+
+QuantityConfig ::= SEQUENCE {
+ quantityConfigEUTRA QuantityConfigEUTRA OPTIONAL, -- Need ON
+ quantityConfigUTRA QuantityConfigUTRA OPTIONAL, -- Need ON
+ quantityConfigGERAN QuantityConfigGERAN OPTIONAL, -- Need ON
+ quantityConfigCDMA2000 QuantityConfigCDMA2000 OPTIONAL, -- Need ON
+ ...
+}
+
+QuantityConfigEUTRA ::= SEQUENCE {
+ filterCoefficientRSRP FilterCoefficient DEFAULT fc4,
+ filterCoefficientRSRQ FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigUTRA ::= SEQUENCE {
+ measQuantityUTRA-FDD ENUMERATED {cpich-RSCP, cpich-EcN0},
+ measQuantityUTRA-TDD ENUMERATED {pccpch-RSCP},
+ filterCoefficient FilterCoefficient DEFAULT fc4
+}
+
+QuantityConfigGERAN ::= SEQUENCE {
+ measQuantityGERAN ENUMERATED {rssi},
+ filterCoefficient FilterCoefficient DEFAULT fc2
+}
+
+QuantityConfigCDMA2000 ::= SEQUENCE {
+ measQuantityCDMA2000 ENUMERATED {pilotStrength, pilotPnPhaseAndPilotStrength}
+}
+
+
+ReportConfigEUTRA ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventA1 SEQUENCE {
+ a1-Threshold ThresholdEUTRA
+ },
+ eventA2 SEQUENCE {
+ a2-Threshold ThresholdEUTRA
+ },
+ eventA3 SEQUENCE {
+ a3-Offset INTEGER (-30..30),
+ reportOnLeave BOOLEAN
+ },
+ eventA4 SEQUENCE {
+ a4-Threshold ThresholdEUTRA
+ },
+ eventA5 SEQUENCE {
+ a5-Threshold1 ThresholdEUTRA,
+ a5-Threshold2 ThresholdEUTRA
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells, reportCGI}
+ }
+ },
+ triggerQuantity ENUMERATED {rsrp, rsrq},
+ reportQuantity ENUMERATED {sameAsTriggerQuantity, both},
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL, -- Cond reportCGI
+ ue-RxTxTimeDiffPeriodical-r9 ENUMERATED {setup} OPTIONAL -- Need OR
+ ]]
+}
+
+ThresholdEUTRA ::= CHOICE{
+ threshold-RSRP RSRP-Range,
+ threshold-RSRQ RSRQ-Range
+}
+
+
+ReportConfigId ::= INTEGER (1..maxReportConfigId)
+
+
+ReportConfigInterRAT ::= SEQUENCE {
+ triggerType CHOICE {
+ event SEQUENCE {
+ eventId CHOICE {
+ eventB1 SEQUENCE {
+ b1-Threshold CHOICE {
+ b1-ThresholdUTRA ThresholdUTRA,
+ b1-ThresholdGERAN ThresholdGERAN,
+ b1-ThresholdCDMA2000 ThresholdCDMA2000
+ }
+ },
+ eventB2 SEQUENCE {
+ b2-Threshold1 ThresholdEUTRA,
+ b2-Threshold2 CHOICE {
+ b2-Threshold2UTRA ThresholdUTRA,
+ b2-Threshold2GERAN ThresholdGERAN,
+ b2-Threshold2CDMA2000 ThresholdCDMA2000
+ }
+ },
+ ...
+ },
+ hysteresis Hysteresis,
+ timeToTrigger TimeToTrigger
+ },
+ periodical SEQUENCE {
+ purpose ENUMERATED {
+ reportStrongestCells,
+ reportStrongestCellsForSON,
+ reportCGI}
+ }
+ },
+ maxReportCells INTEGER (1..maxCellReport),
+ reportInterval ReportInterval,
+ reportAmount ENUMERATED {r1, r2, r4, r8, r16, r32, r64, infinity},
+ ...,
+ [[ si-RequestForHO-r9 ENUMERATED {setup} OPTIONAL -- Cond reportCGI
+ ]]
+}
+
+ThresholdUTRA ::= CHOICE{
+ utra-RSCP INTEGER (-5..91),
+ utra-EcN0 INTEGER (0..49)
+}
+
+ThresholdGERAN ::= INTEGER (0..63)
+
+ThresholdCDMA2000 ::= INTEGER (0..63)
+
+
+ReportConfigToAddModList ::= SEQUENCE (SIZE (1..maxReportConfigId)) OF ReportConfigToAddMod
+
+ReportConfigToAddMod ::= SEQUENCE {
+ reportConfigId ReportConfigId,
+ reportConfig CHOICE {
+ reportConfigEUTRA ReportConfigEUTRA,
+ reportConfigInterRAT ReportConfigInterRAT
+ }
+}
+
+
+
+ReportInterval ::= ENUMERATED {
+ ms120, ms240, ms480, ms640, ms1024, ms2048, ms5120, ms10240,
+ min1, min6, min12, min30, min60, spare3, spare2, spare1}
+
+
+RSRP-Range ::= INTEGER(0..97)
+
+
+RSRQ-Range ::= INTEGER(0..34)
+
+
+TimeToTrigger ::= ENUMERATED {
+ ms0, ms40, ms64, ms80, ms100, ms128, ms160, ms256,
+ ms320, ms480, ms512, ms640, ms1024, ms1280, ms2560,
+ ms5120}
+
+
+C-RNTI ::= BIT STRING (SIZE (16))
+
+
+DedicatedInfoCDMA2000 ::= OCTET STRING
+
+
+DedicatedInfoNAS ::= OCTET STRING
+
+
+FilterCoefficient ::= ENUMERATED {
+ fc0, fc1, fc2, fc3, fc4, fc5,
+ fc6, fc7, fc8, fc9, fc11, fc13,
+ fc15, fc17, fc19, spare1, ...}
+
+
+MMEC ::= BIT STRING (SIZE (8))
+
+
+NeighCellConfig ::= BIT STRING (SIZE (2))
+
+
+OtherConfig-r9 ::= SEQUENCE {
+ reportProximityConfig-r9 ReportProximityConfig-r9 OPTIONAL, -- Need ON
+ ...
+}
+
+ReportProximityConfig-r9 ::= SEQUENCE {
+ proximityIndicationEUTRA-r9 ENUMERATED {enabled} OPTIONAL, -- Need OR
+ proximityIndicationUTRA-r9 ENUMERATED {enabled} OPTIONAL -- Need OR
+}
+
+
+RAND-CDMA2000 ::= BIT STRING (SIZE (32))
+
+
+RAT-Type ::= ENUMERATED {
+ eutra, utra, geran-cs, geran-ps, cdma2000-1XRTT,
+ spare3, spare2, spare1, ...}
+
+
+RRC-TransactionIdentifier ::= INTEGER (0..3)
+
+
+S-TMSI ::= SEQUENCE {
+ mmec MMEC,
+ m-TMSI BIT STRING (SIZE (32))
+}
+
+
+UE-CapabilityRAT-ContainerList ::=SEQUENCE (SIZE (0..maxRAT-Capabilities)) OF UE-CapabilityRAT-Container
+
+UE-CapabilityRAT-Container ::= SEQUENCE {
+ rat-Type RAT-Type,
+ ueCapabilityRAT-Container OCTET STRING
+}
+
+
+UE-EUTRA-Capability ::= SEQUENCE {
+ accessStratumRelease AccessStratumRelease,
+ ue-Category INTEGER (1..5),
+ pdcp-Parameters PDCP-Parameters,
+ phyLayerParameters PhyLayerParameters,
+ rf-Parameters RF-Parameters,
+ measParameters MeasParameters,
+ featureGroupIndicators BIT STRING (SIZE (32)) OPTIONAL,
+ interRAT-Parameters SEQUENCE {
+ utraFDD IRAT-ParametersUTRA-FDD OPTIONAL,
+ utraTDD128 IRAT-ParametersUTRA-TDD128 OPTIONAL,
+ utraTDD384 IRAT-ParametersUTRA-TDD384 OPTIONAL,
+ utraTDD768 IRAT-ParametersUTRA-TDD768 OPTIONAL,
+ geran IRAT-ParametersGERAN OPTIONAL,
+ cdma2000-HRPD IRAT-ParametersCDMA2000-HRPD OPTIONAL,
+ cdma2000-1xRTT IRAT-ParametersCDMA2000-1XRTT OPTIONAL
+ },
+ nonCriticalExtension UE-EUTRA-Capability-v920-IEs OPTIONAL
+}
+
+UE-EUTRA-Capability-v920-IEs ::= SEQUENCE {
+ phyLayerParameters-v920 PhyLayerParameters-v920,
+ interRAT-ParametersGERAN-v920 IRAT-ParametersGERAN-v920,
+ interRAT-ParametersUTRA-v920 IRAT-ParametersUTRA-v920 OPTIONAL,
+ interRAT-Parameters-v920 IRAT-ParametersCDMA2000-1XRTT-v920 OPTIONAL,
+ deviceType-r9 ENUMERATED {noBenFromBatConsumpOpt} OPTIONAL,
+ csg-ProximityIndicationParameters-r9 CSG-ProximityIndicationParameters-r9,
+ neighCellSI-AcquisitionParameters-r9 NeighCellSI-AcquisitionParameters-r9,
+ son-Parameters-r9 SON-Parameters-r9,
+ nonCriticalExtension SEQUENCE {} OPTIONAL
+}
+
+AccessStratumRelease ::= ENUMERATED {
+ rel8, rel9, spare6, spare5, spare4, spare3,
+ spare2, spare1, ...}
+
+PDCP-Parameters ::= SEQUENCE {
+ supportedROHC-Profiles SEQUENCE {
+ profile0x0001 BOOLEAN,
+ profile0x0002 BOOLEAN,
+ profile0x0003 BOOLEAN,
+ profile0x0004 BOOLEAN,
+ profile0x0006 BOOLEAN,
+ profile0x0101 BOOLEAN,
+ profile0x0102 BOOLEAN,
+ profile0x0103 BOOLEAN,
+ profile0x0104 BOOLEAN
+ },
+ maxNumberROHC-ContextSessions ENUMERATED {
+ cs2, cs4, cs8, cs12, cs16, cs24, cs32,
+ cs48, cs64, cs128, cs256, cs512, cs1024,
+ cs16384, spare2, spare1} DEFAULT cs16,
+ ...
+}
+
+PhyLayerParameters ::= SEQUENCE {
+ ue-TxAntennaSelectionSupported BOOLEAN,
+ ue-SpecificRefSigsSupported BOOLEAN
+}
+
+PhyLayerParameters-v920 ::= SEQUENCE {
+ enhancedDualLayerFDD-Supported-r9 BOOLEAN,
+ enhancedDualLayerTDD-Supported-r9 BOOLEAN
+}
+
+RF-Parameters ::= SEQUENCE {
+ supportedBandListEUTRA SupportedBandListEUTRA
+}
+
+SupportedBandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandEUTRA
+
+SupportedBandEUTRA ::= SEQUENCE {
+ bandEUTRA INTEGER (1..64),
+ halfDuplex BOOLEAN
+}
+
+MeasParameters ::= SEQUENCE {
+ bandListEUTRA BandListEUTRA
+}
+
+BandListEUTRA ::= SEQUENCE (SIZE (1..maxBands)) OF BandInfoEUTRA
+
+BandInfoEUTRA ::= SEQUENCE {
+ interFreqBandList InterFreqBandList,
+ interRAT-BandList InterRAT-BandList OPTIONAL
+}
+
+InterFreqBandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterFreqBandInfo
+
+InterFreqBandInfo ::= SEQUENCE {
+ interFreqNeedForGaps BOOLEAN
+}
+
+InterRAT-BandList ::= SEQUENCE (SIZE (1..maxBands)) OF InterRAT-BandInfo
+
+InterRAT-BandInfo ::= SEQUENCE {
+ interRAT-NeedForGaps BOOLEAN
+}
+
+IRAT-ParametersUTRA-FDD ::= SEQUENCE {
+ supportedBandListUTRA-FDD SupportedBandListUTRA-FDD
+}
+
+IRAT-ParametersUTRA-v920 ::= SEQUENCE {
+ e-Redirection-r9 ENUMERATED {supported}
+}
+
+SupportedBandListUTRA-FDD ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-FDD
+
+SupportedBandUTRA-FDD ::= ENUMERATED {
+ bandI, bandII, bandIII, bandIV, bandV, bandVI,
+ bandVII, bandVIII, bandIX, bandX, bandXI,
+ bandXII, bandXIII, bandXIV, bandXV, bandXVI, ...}
+
+IRAT-ParametersUTRA-TDD128 ::= SEQUENCE {
+ supportedBandListUTRA-TDD128 SupportedBandListUTRA-TDD128
+}
+
+SupportedBandListUTRA-TDD128 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD128
+
+SupportedBandUTRA-TDD128 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD384 ::= SEQUENCE {
+ supportedBandListUTRA-TDD384 SupportedBandListUTRA-TDD384
+}
+
+SupportedBandListUTRA-TDD384 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD384
+
+SupportedBandUTRA-TDD384 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersUTRA-TDD768 ::= SEQUENCE {
+ supportedBandListUTRA-TDD768 SupportedBandListUTRA-TDD768
+}
+
+SupportedBandListUTRA-TDD768 ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandUTRA-TDD768
+
+SupportedBandUTRA-TDD768 ::= ENUMERATED {
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n,
+ o, p, ...}
+
+IRAT-ParametersGERAN ::= SEQUENCE {
+ supportedBandListGERAN SupportedBandListGERAN,
+ interRAT-PS-HO-ToGERAN BOOLEAN
+}
+
+IRAT-ParametersGERAN-v920 ::= SEQUENCE {
+ dtm-r9 ENUMERATED {supported} OPTIONAL,
+ e-RedirectionGERAN-r9 ENUMERATED {supported} OPTIONAL
+}
+
+SupportedBandListGERAN ::= SEQUENCE (SIZE (1..maxBands)) OF SupportedBandGERAN
+
+SupportedBandGERAN ::= ENUMERATED {
+ gsm450, gsm480, gsm710, gsm750, gsm810, gsm850,
+ gsm900P, gsm900E, gsm900R, gsm1800, gsm1900,
+ spare5, spare4, spare3, spare2, spare1, ...}
+
+IRAT-ParametersCDMA2000-HRPD ::= SEQUENCE {
+ supportedBandListHRPD SupportedBandListHRPD,
+ tx-ConfigHRPD ENUMERATED {single, dual},
+ rx-ConfigHRPD ENUMERATED {single, dual}
+}
+
+SupportedBandListHRPD ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+IRAT-ParametersCDMA2000-1XRTT ::= SEQUENCE {
+ supportedBandList1XRTT SupportedBandList1XRTT,
+ tx-Config1XRTT ENUMERATED {single, dual},
+ rx-Config1XRTT ENUMERATED {single, dual}
+}
+
+IRAT-ParametersCDMA2000-1XRTT-v920 ::= SEQUENCE {
+ e-CSFB-r9 ENUMERATED {supported},
+ e-CSFB-ConcPS-Mob-r9 ENUMERATED {notSupported, supported}
+}
+
+SupportedBandList1XRTT ::= SEQUENCE (SIZE (1..maxCDMA-BandClass)) OF BandclassCDMA2000
+
+CSG-ProximityIndicationParameters-r9 ::= SEQUENCE {
+ intraFreqProximityIndicationSupported-r9 BOOLEAN,
+ interFreqProximityIndicationSupported-r9 BOOLEAN,
+ utran-ProximityIndicationSupported-r9 BOOLEAN
+}
+
+NeighCellSI-AcquisitionParameters-r9 ::= SEQUENCE {
+ intraFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ interFreqSI-AcquisitionForHO-Supported-r9 BOOLEAN,
+ utran-SI-AcquisitionForHO-Supported-r9 BOOLEAN
+}
+
+SON-Parameters-r9 ::= SEQUENCE {
+ rach-ReportSupported-r9 BOOLEAN
+}
+
+
+UE-TimersAndConstants ::= SEQUENCE {
+ t300 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t301 ENUMERATED {
+ ms100, ms200, ms300, ms400, ms600, ms1000, ms1500,
+ ms2000},
+ t310 ENUMERATED {
+ ms0, ms50, ms100, ms200, ms500, ms1000, ms2000},
+ n310 ENUMERATED {
+ n1, n2, n3, n4, n6, n8, n10, n20},
+ t311 ENUMERATED {
+ ms1000, ms3000, ms5000, ms10000, ms15000,
+ ms20000, ms30000},
+ n311 ENUMERATED {
+ n1, n2, n3, n4, n5, n6, n8, n10},
+ ...
+}
+
+
+MBMS-NotificationConfig-r9 ::= SEQUENCE {
+ notificationRepetitionCoeff-r9 ENUMERATED {n2, n4},
+ notificationOffset-r9 INTEGER (0..10),
+ notificationSF-Index-r9 INTEGER (1..6)
+}
+
+
+MBSFN-AreaInfoList-r9 ::= SEQUENCE (SIZE(1..maxMBSFN-Area)) OF MBSFN-AreaInfo-r9
+
+MBSFN-AreaInfo-r9 ::= SEQUENCE {
+ mbsfn-AreaId-r9 INTEGER (0..255),
+ non-MBSFNregionLength ENUMERATED {s1, s2},
+ notificationIndicator-r9 INTEGER (0..7),
+ mcch-Config-r9 SEQUENCE {
+ mcch-RepetitionPeriod-r9 ENUMERATED {rf32, rf64, rf128, rf256},
+ mcch-Offset-r9 INTEGER (0..10),
+ mcch-ModificationPeriod-r9 ENUMERATED {rf512, rf1024},
+ sf-AllocInfo-r9 BIT STRING (SIZE(6)),
+ signallingMCS-r9 ENUMERATED {n2, n7, n13, n19}
+ },
+ ...
+}
+
+
+MBSFN-SubframeConfig ::= SEQUENCE {
+ radioframeAllocationPeriod ENUMERATED {n1, n2, n4, n8, n16, n32},
+ radioframeAllocationOffset INTEGER (0..7),
+ subframeAllocation CHOICE {
+ oneFrame BIT STRING (SIZE(6)),
+ fourFrames BIT STRING (SIZE(24))
+ }
+}
+
+PMCH-InfoList-r9 ::= SEQUENCE (SIZE (0..maxPMCH-PerMBSFN)) OF PMCH-Info-r9
+
+PMCH-Info-r9 ::= SEQUENCE {
+ pmch-Config-r9 PMCH-Config-r9,
+ mbms-SessionInfoList-r9 MBMS-SessionInfoList-r9,
+ ...
+}
+
+MBMS-SessionInfoList-r9 ::= SEQUENCE (SIZE (0..maxSessionPerPMCH)) OF MBMS-SessionInfo-r9
+
+MBMS-SessionInfo-r9 ::= SEQUENCE {
+ tmgi-r9 TMGI-r9,
+ sessionId-r9 OCTET STRING (SIZE (1)) OPTIONAL, -- Need OR
+ logicalChannelIdentity-r9 INTEGER (0..maxSessionPerPMCH-1),
+ ...
+}
+
+PMCH-Config-r9 ::= SEQUENCE {
+ sf-AllocEnd-r9 INTEGER (0..1535),
+ dataMCS-r9 INTEGER (0..28),
+ mch-SchedulingPeriod-r9 ENUMERATED {
+ rf8, rf16, rf32, rf64, rf128, rf256, rf512, rf1024},
+ ...
+}
+
+TMGI-r9 ::= SEQUENCE {
+ plmn-Id-r9 CHOICE {
+ plmn-Index-r9 INTEGER (1..6),
+ explicitValue-r9 PLMN-Identity
+ },
+ serviceId-r9 OCTET STRING (SIZE (3))
+}
+
+
+maxBands INTEGER ::= 64 -- Maximum number of bands listed in EUTRA UE caps
+maxCDMA-BandClass INTEGER ::= 32 -- Maximum value of the CDMA band classes
+maxCellBlack INTEGER ::= 16 -- Maximum number of blacklisted cells
+ -- listed in SIB type 4 and 5
+maxCellInter INTEGER ::= 16 -- Maximum number of neighbouring inter-frequency
+ -- cells listed in SIB type 5
+maxCellIntra INTEGER ::= 16 -- Maximum number of neighbouring intra-frequency
+ -- cells listed in SIB type 4
+maxCellMeas INTEGER ::= 32 -- Maximum number of entries in each of the neighbour
+ -- cell lists in a measurement object
+maxCellReport INTEGER ::= 8 -- Maximum number of reported cells
+maxDRB INTEGER ::= 11 -- Maximum number of Data Radio Bearers
+maxEARFCN INTEGER ::= 65535 -- Maximum value of EUTRA carrier fequency
+maxFreq INTEGER ::= 8 -- Maximum number of EUTRA carrier frequencies
+maxCellInfo-GERAN-r9 INTEGER ::= 32 -- Maximum number of GERAN cells for which system in-
+ -- formation can be provided as redirection assistance
+maxGERAN-SI INTEGER ::= 10 -- Maximum number of GERAN SI blocks that can be
+ -- provided as part of NACC information
+maxGNFG INTEGER ::= 16 -- Maximum number of GERAN neighbour freq groups
+maxMBSFN-Allocations INTEGER ::= 8 -- Maximum number of MBSFN frame allocations with
+ -- different offset
+maxMBSFN-Area INTEGER ::= 8
+maxSessionPerPMCH INTEGER ::= 29
+maxSessionPerPMCH-1 INTEGER ::= 28
+maxPMCH-PerMBSFN INTEGER ::= 15
+maxMeasId INTEGER ::= 32
+maxObjectId INTEGER ::= 32
+maxPageRec INTEGER ::= 16 --
+maxPNOffset INTEGER ::= 511 -- Maximum number of CDMA2000 PNOffsets
+maxRAT-Capabilities INTEGER ::= 8 -- Maximum number of interworking RATs (incl EUTRA)
+maxReportConfigId INTEGER ::= 32
+maxSIB INTEGER ::= 32 -- Maximum number of SIBs
+maxSIB-1 INTEGER ::= 31
+maxSI-Message INTEGER ::= 32 -- Maximum number of SI messages
+maxUTRA-FDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA FDD carrier frequencies
+maxUTRA-TDD-Carrier INTEGER ::= 16 -- Maximum number of UTRA TDD carrier frequencies
+maxUTRA-CellInfo-r9 INTEGER ::= 16 -- Maximum number of cells for which system information
+ -- can be provided as redirection assistance
+
+
+END
diff --git a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl index c86c787610..5fcec23756 100644 --- a/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl +++ b/lib/asn1/test/asn1_SUITE_data/extensionAdditionGroup.erl @@ -54,3 +54,79 @@ run2(Erule) -> Val -> ok; _ -> exit({expected,Val, got, Val2}) end. + +run3(Erule) -> + Val = +{'RRC-DL-DCCH-Message', + {c1, + {rrcConnectionReconfiguration, + {'RRC-RRCConnectionReconfiguration',0, + {c1, + {'rrcConnectionReconfiguration-r8', + {'RRC-RRCConnectionReconfiguration-r8-IEs', + {'RRC-MeasConfig',asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE, + asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE, + [[80,66,0,5,10,0,5,0,24,11,7,84,54,33,0,1,1,0,0,0,1,39,5,66,127,0,0,1], + []], + {'RRC-RadioResourceConfigDedicated', + [{'RRC-SRB-ToAddMod',1, + {explicitValue, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms45,pInfinity,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms0}}}}, + {explicitValue, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',3,infinity, + ms50,0}, + asn1_NOVALUE}}}], + [{'RRC-DRB-ToAddMod',3,3, + {'RRC-PDCP-Config',infinity, + {'RRC-PDCP-Config_rlc-AM',false}, + asn1_NOVALUE, + {notUsed,'NULL'}}, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms40}}}, + 3, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50, + 1}, + asn1_NOVALUE}}, + {'RRC-DRB-ToAddMod',4,4, + {'RRC-PDCP-Config',infinity, + {'RRC-PDCP-Config_rlc-AM',false}, + asn1_NOVALUE, + {notUsed,'NULL'}}, + {am, + {'RRC-RLC-Config_am', + {'RRC-UL-AM-RLC',ms70,p256,kBinfinity,t4}, + {'RRC-DL-AM-RLC',ms35,ms40}}}, + 4, + {'RRC-LogicalChannelConfig', + {'RRC-LogicalChannelConfig_ul-SpecificParameters',5,infinity,ms50, + 1}, + asn1_NOVALUE}}], + asn1_NOVALUE, + {explicitValue, + {'RRC-MAC-MainConfig', + {'RRC-MAC-MainConfig_ul-SCH-Config',n4,sf10,sf10240,false}, + asn1_NOVALUE,sf500, + {setup,{'RRC-MAC-MainConfig_phr-Config_setup',sf200,sf200,dB3}}, + asn1_NOVALUE}}, + asn1_NOVALUE,asn1_NOVALUE,asn1_NOVALUE}, + asn1_NOVALUE,asn1_NOVALUE}}}}}}}, + io:format("~p:~p~n",[Erule,Val]), + {ok,List}= asn1rt:encode('EUTRA-RRC-Definitions','DL-DCCH-Message',Val), + Enc = iolist_to_binary(List), + io:format("Result from encode:~n~p~n",[Enc]), + {ok,Val2} = asn1rt:decode('EUTRA-RRC-Definitions','DL-DCCH-Message',Enc), + io:format("Result from decode:~n~p~n",[Val2]), + case Val2 of + Val -> ok; + _ -> exit({expected,Val, got, Val2}) + end. + diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile index 6322860088..1a767a8197 100644 --- a/lib/common_test/doc/src/Makefile +++ b/lib/common_test/doc/src/Makefile @@ -51,7 +51,7 @@ CT_MODULES = \ CT_XML_FILES = $(CT_MODULES:=.xml) XML_APPLICATION_FILES = ref_man.xml -XML_REF1_FILES = run_test.xml +XML_REF1_FILES = ct_run.xml XML_REF3_FILES = $(CT_XML_FILES) XML_REF6_FILES = common_test_app.xml diff --git a/lib/common_test/doc/src/config_file_chapter.xml b/lib/common_test/doc/src/config_file_chapter.xml index 77b0c0c0b7..59151a73ec 100644 --- a/lib/common_test/doc/src/config_file_chapter.xml +++ b/lib/common_test/doc/src/config_file_chapter.xml @@ -248,7 +248,7 @@ <p><c>Callback:check_parameter/1</c></p> <p>The input argument will be passed from Common Test, as defined in the test - specification or given as an option to <c>run_test</c>.</p> + specification or given as an option to <c>ct_run</c> or <c>ct:run_test</c>.</p> <p>The return value should be any of the following values indicating if given configuration parameter is valid:</p> diff --git a/lib/common_test/doc/src/cover_chapter.xml b/lib/common_test/doc/src/cover_chapter.xml index 6e4f59ef73..377409ed7b 100644 --- a/lib/common_test/doc/src/cover_chapter.xml +++ b/lib/common_test/doc/src/cover_chapter.xml @@ -94,10 +94,10 @@ <p>To activate the code coverage support, you simply specify the name of the cover specification file as you start Common Test. - This you do either by using the <c>-cover</c> flag with <c>run_test</c>. + This you do either by using the <c>-cover</c> flag with <c>ct_run</c>. Example:</p> - <p><c>$ run_test -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p> + <p><c>$ ct_run -dir $TESTOBJS/db -cover $TESTOBJS/db/config/db.coverspec</c></p> <p>You may also pass the cover specification file name in a call to <c>ct:run_test/1</c>, by adding a <c>{cover,CoverSpec}</c> diff --git a/lib/common_test/doc/src/ct_junit_report.xml b/lib/common_test/doc/src/ct_junit_report.xml new file mode 100644 index 0000000000..49a40cc1de --- /dev/null +++ b/lib/common_test/doc/src/ct_junit_report.xml @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="latin1" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> +<erlref> +<header> +<title>ct_junit_report</title> +<prepared></prepared> +<responsible></responsible> +<docno>1</docno> +<approved></approved> +<checked></checked> +<date></date> +<rev>A</rev> +<file>ct_junit_report.xml</file></header> +<module>ct_junit_report</module> +<modulesummary>Common Test Framework functions handling test specifications.</modulesummary> +<description> +<p>Common Test Framework functions handling test specifications.</p> + + <p>This module creates a junit report of the test run if plugged in + as a suite_callback.</p></description> +<funcs> +<func> +<name>init(Opts) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="init-1"/> + </desc></func> +<func> +<name>post_end_group(Group, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="post_end_group-3"/> + </desc></func> +<func> +<name>post_end_suite(Suite, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="post_end_suite-3"/> + </desc></func> +<func> +<name>post_end_tc(TC, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="post_end_tc-3"/> + </desc></func> +<func> +<name>post_init_group(Group, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="post_init_group-3"/> + </desc></func> +<func> +<name>post_init_suite(Suite, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="post_init_suite-3"/> + </desc></func> +<func> +<name>pre_end_group(Group, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="pre_end_group-3"/> + </desc></func> +<func> +<name>pre_end_suite(Suite, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="pre_end_suite-3"/> + </desc></func> +<func> +<name>pre_init_group(Group, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="pre_init_group-3"/> + </desc></func> +<func> +<name>pre_init_suite(Suite, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="pre_init_suite-3"/> + </desc></func> +<func> +<name>pre_init_tc(TC, Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="pre_init_tc-3"/> + </desc></func> +<func> +<name>terminate(Config, State) -> term() +</name> +<fsummary> </fsummary> + +<desc><marker id="terminate-2"/> + </desc></func></funcs> + +<authors> +<aname> </aname> +<email> </email></authors></erlref>
\ No newline at end of file diff --git a/lib/common_test/doc/src/ct_master_chapter.xml b/lib/common_test/doc/src/ct_master_chapter.xml index 01f8e61d36..f4f0ecad62 100644 --- a/lib/common_test/doc/src/ct_master_chapter.xml +++ b/lib/common_test/doc/src/ct_master_chapter.xml @@ -188,7 +188,7 @@ <seealso marker="run_test_chapter#test_specifications">Running Test Suites</seealso> chapter). The result is that any test specified to run on a node with the same name as the Common Test node in question (typically <c>ct@somehost</c> if started - with the <c>run_test</c> program), will be performed. Tests without explicit + with the <c>ct_run</c> program), will be performed. Tests without explicit node association will always be performed too of course!</p> <note><p>It is recommended that absolute paths are used for log directories, diff --git a/lib/common_test/doc/src/run_test.xml b/lib/common_test/doc/src/ct_run.xml index 2f0a94afba..1ab563d74f 100644 --- a/lib/common_test/doc/src/run_test.xml +++ b/lib/common_test/doc/src/ct_run.xml @@ -21,7 +21,7 @@ </legalnotice> - <title>The run_test program</title> + <title>The ct_run program</title> <prepared>Peter Andersson</prepared> <responsible>Peter Andersson</responsible> <docno></docno> @@ -29,18 +29,18 @@ <checked></checked> <date>2010-04-01</date> <rev>PA2</rev> - <file>run_test.xml</file> + <file>ct_run.xml</file> </header> - <com>run_test</com> + <com>ct_run</com> <comsummary>Program used for starting Common Test from the OS command line. </comsummary> <description> - <p>The <c>run_test</c> program is automatically installed with Erlang/OTP + <p>The <c>ct_run</c> program is automatically installed with Erlang/OTP and Common Test (please see the Installation chapter in the Common Test User's Guide for more information). The program accepts a number - of different start flags. Some flags trigger <c>run_test</c> + of different start flags. Some flags trigger <c>ct_run</c> to start the Common Test application and pass on data to it. Some flags start an Erlang node prepared for running Common Test in a particular mode.</p> @@ -50,20 +50,20 @@ shell (or an Erlang program). Please see the <c>ct</c> man page for details.</p> - <p><c>run_test</c> also accepts Erlang emulator flags. These are used - when <c>run_test</c> calls <c>erl</c> to start the Erlang node + <p><c>ct_run</c> also accepts Erlang emulator flags. These are used + when <c>ct_run</c> calls <c>erl</c> to start the Erlang node (making it possible to e.g. add directories to the code server path, change the cookie on the node, start additional applications, etc).</p> <p>With the optional flag:</p> <pre>-erl_args</pre> - <p>it's possible to divide the options on the <c>run_test</c> command line into + <p>it's possible to divide the options on the <c>ct_run</c> command line into two groups, one that Common Test should process (those preceding <c>-erl_args</c>), and one it should completely ignore and pass on directly to the emulator (those following <c>-erl_args</c>). Options preceding <c>-erl_args</c> that Common Test doesn't recognize, also get passed on to the emulator untouched. By means of <c>-erl_args</c> the user may specify flags with the same name, but - with different destinations, on the <c>run_test</c> command line.</p> + with different destinations, on the <c>ct_run</c> command line.</p> <p>If <c>-pa</c> or <c>-pz</c> flags are specified in the Common Test group of options (preceding <c>-erl_args</c>), relative directories will be converted to absolute and re-inserted into the code path by Common Test (to avoid @@ -72,17 +72,17 @@ following <c>-erl_args</c> on the command line. These directories are added to the code path normally (i.e. on specified form)</p> - <p>If <c>run_test</c> is called with option:</p> + <p>If <c>ct_run</c> is called with option:</p> <pre>-help</pre> <p>it prints all valid start flags to stdout.</p> </description> - <marker id="run_test"></marker> + <marker id="ct_run"></marker> <section> <title>Run tests from command line</title> <pre> - run_test [-dir TestDir1 TestDir2 .. TestDirN] | + ct_run [-dir TestDir1 TestDir2 .. TestDirN] | [-suite Suite1 Suite2 .. SuiteN [[-group Group1 Group2 .. GroupN] [-case Case1 Case2 .. CaseN]]] [-step [config | keep_inactive]] @@ -110,7 +110,7 @@ <section> <title>Run tests using test specification</title> <pre> - run_test -spec TestSpec1 TestSpec2 .. TestSpecN + ct_run -spec TestSpec1 TestSpec2 .. TestSpecN [-config ConfigFile1 ConfigFile2 .. ConfigFileN] [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 ConfigString2 and .. and CallbackModuleN ConfigStringN] @@ -136,7 +136,7 @@ <section> <title>Run tests in web based GUI</title> <pre> - run_test -vts [-browser Browser] + ct_run -vts [-browser Browser] [-dir TestDir1 TestDir2 .. TestDirN] | [-suite Suite [[-group Group] [-case Case]]] [-config ConfigFile1 ConfigFile2 .. ConfigFileN] @@ -152,12 +152,12 @@ <section> <title>Refresh the HTML index files</title> <pre> - run_test -refresh_logs [-logdir LogDir] [-basic_html]</pre> + ct_run -refresh_logs [-logdir LogDir] [-basic_html]</pre> </section> <section> <title>Run CT in interactive mode</title> <pre> - run_test -shell + ct_run -shell [-config ConfigFile1 ConfigFile2 ... ConfigFileN] [-userconfig CallbackModule1 ConfigString1 and CallbackModule2 ConfigString2 and .. and CallbackModuleN ConfigStringN] @@ -166,7 +166,7 @@ <section> <title>Start a Common Test Master node</title> <pre> - run_test -ctmaster</pre> + ct_run -ctmaster</pre> </section> <section> diff --git a/lib/common_test/doc/src/ct_slave.xml b/lib/common_test/doc/src/ct_slave.xml deleted file mode 100644 index ceebf51f1a..0000000000 --- a/lib/common_test/doc/src/ct_slave.xml +++ /dev/null @@ -1,139 +0,0 @@ -<?xml version="1.0" encoding="latin1" ?> -<!DOCTYPE erlref SYSTEM "erlref.dtd"> -<erlref> -<header> -<title>ct_slave</title> -<prepared></prepared> -<responsible></responsible> -<docno>1</docno> -<approved></approved> -<checked></checked> -<date></date> -<rev>A</rev> -<file>ct_slave.xml</file></header> -<module>ct_slave</module> -<modulesummary>Common Test Framework functions for starting and stopping nodes for -Large Scale Testing.</modulesummary> -<description> -<p>Common Test Framework functions for starting and stopping nodes for -Large Scale Testing.</p> - - <p>This module exports functions which are used by the Common Test Master - to start and stop "slave" nodes. It is the default callback module for the - <c>{init, node_start}</c> term of the Test Specification.</p></description> -<funcs> -<func> -<name>start(Node) -> Result</name> -<fsummary>Starts an Erlang node with name Node on the local host.</fsummary> -<type> -<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> -<desc><marker id="start-1"/> - -<p>Starts an Erlang node with name <c>Node</c> on the local host.</p> -<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p> -</desc></func> -<func> -<name>start(Host, Node) -> Result</name> -<fsummary>Starts an Erlang node with name Node on host - Host with the default options.</fsummary> -<type> -<v>Node = atom()</v><v>Host = atom()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> -<desc><marker id="start-2"/> - -<p>Starts an Erlang node with name <c>Node</c> on host - <c>Host</c> with the default options.</p> -<p><em>See also:</em> <seealso marker="#start-3">start/3</seealso>.</p> -</desc></func> -<func> -<name>start(Host, Node, Options::Opts) -> Result</name> -<fsummary>Starts an Erlang node with name Node on host - Host as specified by the combination of options in - Opts.</fsummary> -<type> -<v>Node = atom()</v><v>Host = atom()</v><v>Opts = [OptTuples]</v><v>OptTuples = {username, Username} | {password, Password} | {boot_timeout, BootTimeout} | {init_timeout, InitTimeout} | {startup_timeout, StartupTimeout} | {startup_functions, StartupFunctions} | {monitor_master, Monitor} | {kill_if_fail, KillIfFail} | {erl_flags, ErlangFlags}</v><v>Username = string()</v><v>Password = string()</v><v>BootTimeout = integer()</v><v>InitTimeout = integer()</v><v>StartupTimeout = integer()</v><v>StartupFunctions = [StartupFunctionSpec]</v><v>StartupFunctionSpec = {Module, Function, Arguments}</v><v>Module = atom()</v><v>Function = atom()</v><v>Arguments = [term]</v><v>Monitor = bool()</v><v>KillIfFail = bool()</v><v>ErlangFlags = string()</v><v>Result = {ok, NodeName} | {error, already_started, NodeName} | {error, started_not_connected, NodeName} | {error, boot_timeout, NodeName} | {error, init_timeout, NodeName} | {error, startup_timeout, NodeName} | {error, not_alive, NodeName}</v><v>NodeName = atom()</v></type> -<desc><marker id="start-3"/> - -<p>Starts an Erlang node with name <c>Node</c> on host - <c>Host</c> as specified by the combination of options in - <c>Opts</c>.</p> - - <p>Options <c>Username</c> and <c>Password</c> will be used - to log in onto the remote host <c>Host</c>. - Username, if omitted, defaults to the current user name, - and password is empty by default.</p> - - <p>A list of functions specified in the <c>Startup</c> option will be - executed after startup of the node. Note that all used modules should be - present in the code path on the <c>Host</c>.</p> - - <p>The timeouts are applied as follows: - <list> - <item> - <c>BootTimeout</c> - time to start the Erlang node, in seconds. - Defaults to 3 seconds. If node does not become pingable within this time, - the result <c>{error, boot_timeout, NodeName}</c> is returned; - </item> - <item> - <c>InitTimeout</c> - time to wait for the node until it calls the - internal callback function informing master about successfull startup. - Defaults to one second. - In case of timed out message the result - <c>{error, init_timeout, NodeName}</c> is returned; - </item> - <item> - <c>StartupTimeout</c> - time to wait intil the node finishes to run - the <c>StartupFunctions</c>. Defaults to one second. - If this timeout occurs, the result - <c>{error, startup_timeout, NodeName}</c> is returned. - </item> - </list></p> - - <p>Option <c>monitor_master</c> specifies, if the slave node should be - stopped in case of master node stop. Defaults to false.</p> - - <p>Option <c>kill_if_fail</c> specifies, if the slave node should be - killed in case of a timeout during initialization or startup. - Defaults to true. Note that node also may be still alive it the boot - timeout occurred, but it will not be killed in this case.</p> - - <p>Option <c>erlang_flags</c> specifies, which flags will be added - to the parameters of the <c>erl</c> executable.</p> - - <p>Special return values are: - <list> - <item><c>{error, already_started, NodeName}</c> - if the node with - the given name is already started on a given host;</item> - <item><c>{error, started_not_connected, NodeName}</c> - if node is - started, but not connected to the master node.</item> - <item><c>{error, not_alive, NodeName}</c> - if node on which the - <c>ct_slave:start/3</c> is called, is not alive. Note that - <c>NodeName</c> is the name of current node in this case.</item> - </list></p> - -</desc></func> -<func> -<name>stop(Node) -> Result</name> -<fsummary>Stops the running Erlang node with name Node on - the localhost.</fsummary> -<type> -<v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type> -<desc><marker id="stop-1"/> - -<p>Stops the running Erlang node with name <c>Node</c> on - the localhost.</p> -</desc></func> -<func> -<name>stop(Host, Node) -> Result</name> -<fsummary>Stops the running Erlang node with name Node on - host Host.</fsummary> -<type> -<v>Host = atom()</v><v>Node = atom()</v><v>Result = {ok, NodeName} | {error, not_started, NodeName} | {error, not_connected, NodeName} | {error, stop_timeout, NodeName}</v><v>NodeName = atom()</v></type> -<desc><marker id="stop-2"/> - -<p>Stops the running Erlang node with name <c>Node</c> on - host <c>Host</c>.</p> -</desc></func></funcs> - -<authors> -<aname> </aname> -<email> </email></authors></erlref>
\ No newline at end of file diff --git a/lib/common_test/doc/src/event_handler_chapter.xml b/lib/common_test/doc/src/event_handler_chapter.xml index 7f5144b760..904876ac46 100644 --- a/lib/common_test/doc/src/event_handler_chapter.xml +++ b/lib/common_test/doc/src/event_handler_chapter.xml @@ -63,12 +63,12 @@ <section> <title>Usage</title> <p>Event handlers may be installed by means of an <c>event_handler</c> - start flag (<c>run_test</c>) or option (<c>ct:run_test/1</c>), where the + start flag (<c>ct_run</c>) or option (<c>ct:run_test/1</c>), where the argument specifies the names of one or more event handler modules. Example:</p> - <p><c>$ run_test -suite test/my_SUITE -event_handler handlers/my_evh1 + <p><c>$ ct_run -suite test/my_SUITE -event_handler handlers/my_evh1 handlers/my_evh2 -pa $PWD/handlers</c></p> - <p>Use the <c><![CDATA[run_test -event_handler_init]]></c> option instead of + <p>Use the <c><![CDATA[ct_run -event_handler_init]]></c> option instead of <c><![CDATA[-event_handler]]></c> to pass start arguments to the event handler init function.</p> <p>All event handler modules must have gen_event behaviour. Note also that diff --git a/lib/common_test/doc/src/install_chapter.xml b/lib/common_test/doc/src/install_chapter.xml index 828588a673..89c497962d 100644 --- a/lib/common_test/doc/src/install_chapter.xml +++ b/lib/common_test/doc/src/install_chapter.xml @@ -34,8 +34,8 @@ <title>General information</title> <p>The two main interfaces for running tests with Common Test - are an executable program named run_test and an - erlang module named <c>ct</c>. The run_test program + are an executable program named ct_run and an + erlang module named <c>ct</c>. The ct_run program is compiled for the underlying operating system (e.g. Unix/Linux or Windows) during the build of the Erlang/OTP system, and is installed automatically with other executable programs in @@ -43,22 +43,22 @@ The <c>ct</c> interface functions can be called from the Erlang shell, or from any Erlang function, on any supported platform.</p> - <p>A legacy Bourne shell script - also named run_test - exists, + <p>A legacy Bourne shell script - named run_test - exists, which may be manually generated and installed. This script may be used - instead of the run_test program mentioned above, e.g. if the user + instead of the ct_run program mentioned above, e.g. if the user wishes to modify or customize the Common Test start flags in a simpler - way than making changes to the run_test C program.</p> + way than making changes to the ct_run C program.</p> <p>The Common Test application is installed with the Erlang/OTP system and no additional installation step is required to start using - Common Test by means of the run_test executable program, and/or the interface + Common Test by means of the ct_run executable program, and/or the interface functions in the <c>ct</c> module. If you wish to use the legacy Bourne - shell script version of run_test, however, this script needs to be + shell script version run_test, however, this script needs to be generated first, according to the instructions below.</p> <p><note>Before reading on, please note that since Common Test version 1.5, the run_test shell script is no longer required for starting - tests with Common Test from the OS command line. The run_test + tests with Common Test from the OS command line. The ct_run program (descibed above) is the new recommended command line interface for Common Test. The shell script exists mainly for legacy reasons and may not be updated in future releases of Common Test. It may even be removed. diff --git a/lib/common_test/doc/src/ref_man.xml b/lib/common_test/doc/src/ref_man.xml index 8be234d979..d5985bb021 100644 --- a/lib/common_test/doc/src/ref_man.xml +++ b/lib/common_test/doc/src/ref_man.xml @@ -63,7 +63,7 @@ Server application.</p> </description> <xi:include href="common_test_app.xml"/> - <xi:include href="run_test.xml"/> + <xi:include href="ct_run.xml"/> <!-- If you make modifications in the module list below, you also need to update CT_MODULES in Makefile. --> <xi:include href="ct.xml"/> diff --git a/lib/common_test/doc/src/run_test_chapter.xml b/lib/common_test/doc/src/run_test_chapter.xml index 1efff25f5b..94fcf6bf01 100644 --- a/lib/common_test/doc/src/run_test_chapter.xml +++ b/lib/common_test/doc/src/run_test_chapter.xml @@ -71,7 +71,7 @@ <p>If test suites or help modules include header files stored in other locations than the test directory, you may specify these include directories - by means of the <c><![CDATA[-include]]></c> flag with <c><![CDATA[run_test]]></c>, + by means of the <c><![CDATA[-include]]></c> flag with <c><![CDATA[ct_run]]></c>, or the <c><![CDATA[include]]></c> option with <c><![CDATA[ct:run_test/1]]></c>. In addition to this, an include path may be specified with an OS environment variable; <c><![CDATA[CT_INCLUDE_PATH]]></c>. Example (bash):</p> @@ -93,7 +93,7 @@ there instead.</p> <p>It is possible to disable the automatic compilation feature by using the - <c><![CDATA[-no_auto_compile]]></c> flag with <c><![CDATA[run_test]]></c>, or + <c><![CDATA[-no_auto_compile]]></c> flag with <c><![CDATA[ct_run]]></c>, or the <c><![CDATA[{auto_compile,false}]]></c> option with <c><![CDATA[ct:run_test/1]]></c>. With automatic compilation disabled, the user is responsible for compiling the test suite modules @@ -108,26 +108,26 @@ <section> <title>Running tests from the OS command line</title> - <p>The <c>run_test</c> program can be used for running tests from + <p>The <c>ct_run</c> program can be used for running tests from the OS command line, e.g. </p> <list> - <item><c><![CDATA[run_test -config <configfilenames> -dir <dirs>]]></c></item> - <item><c><![CDATA[run_test -config <configfilenames> -suite <suiteswithfullpath>]]></c> + <item><c><![CDATA[ct_run -config <configfilenames> -dir <dirs>]]></c></item> + <item><c><![CDATA[ct_run -config <configfilenames> -suite <suiteswithfullpath>]]></c> </item> - <item><c><![CDATA[run_test -userconfig <callbackmodulename> <configfilenames> -suite <suiteswithfullpath>]]></c> + <item><c><![CDATA[ct_run -userconfig <callbackmodulename> <configfilenames> -suite <suiteswithfullpath>]]></c> </item> - <item><c><![CDATA[run_test -config <configfilenames> -suite <suitewithfullpath> + <item><c><![CDATA[ct_run -config <configfilenames> -suite <suitewithfullpath> -group <groupnames> -case <casenames>]]></c></item> </list> <p>Examples:</p> - <p><c>$ run_test -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p> - <p><c>$ run_test -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p> - <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p> - <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -case start stop</c></p> - <p><c>$ run_test -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p> + <p><c>$ ct_run -config $CFGS/sys1.cfg $CFGS/sys2.cfg -dir $SYS1_TEST $SYS2_TEST</c></p> + <p><c>$ ct_run -userconfig ct_config_xml $CFGS/sys1.xml $CFGS/sys2.xml -dir $SYS1_TEST $SYS2_TEST</c></p> + <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE $SYS2_TEST/config_SUITE</c></p> + <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -case start stop</c></p> + <p><c>$ ct_run -suite $SYS1_TEST/setup_SUITE -group installation -case start stop</c></p> - <p>Other flags that may be used with <c>run_test</c>:</p> + <p>Other flags that may be used with <c>ct_run</c>:</p> <list> <item><c><![CDATA[-logdir <dir>]]></c>, specifies where the HTML log files are to be written.</item> <item><c><![CDATA[-label <name_of_test_run>]]></c>, associates the test run with a name that gets printed @@ -167,20 +167,20 @@ <note><p>Directories passed to Common Test may have either relative or absolute paths.</p></note> <note><p>Arbitrary start flags to the Erlang Runtime System may also be passed as - parameters to <c>run_test</c>. It is, for example, useful to be able to + parameters to <c>ct_run</c>. It is, for example, useful to be able to pass directories that should be added to the Erlang code server search path with the <c>-pa</c> or <c>-pz</c> flag. If you have common help- or library modules for test suites (separately compiled), stored in other directories than the test suite directories, these help/lib directories are preferrably added to the code path this way. Example:</p> - <p><c>$ run_test -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin</c></p> + <p><c>$ ct_run -dir ./chat_server -logdir ./chat_server/testlogs -pa $PWD/chat_server/ebin</c></p> <p>Note how in this example, the absolute path of the <c>chat_server/ebin</c> directory is passed to the code server. This is essential since relative paths are stored by the code server as relative, and Common Test changes the current working directory of the Erlang Runtime System during the test run!</p> </note> - <p>For more information about the <c>run_test</c> program, see the + <p>For more information about the <c>ct_run</c> program, see the <seealso marker="install_chapter#general">Installation</seealso> chapter. </p> </section> @@ -188,7 +188,7 @@ <section> <title>Running tests from the Web based GUI</title> - <p>The web based GUI, VTS, is started with the <c>run_test</c> + <p>The web based GUI, VTS, is started with the <c>ct_run</c> program. From the GUI you can load config files, and select directories, suites and cases to run. You can also state the config files, directories, suites and cases on the command line @@ -196,22 +196,22 @@ </p> <list> - <item><c>run_test -vts</c></item> - <item><c><![CDATA[run_test -vts -config <configfilename>]]></c></item> - <item><c><![CDATA[run_test -vts -config <configfilename> -suite <suitewithfullpath> + <item><c>ct_run -vts</c></item> + <item><c><![CDATA[ct_run -vts -config <configfilename>]]></c></item> + <item><c><![CDATA[ct_run -vts -config <configfilename> -suite <suitewithfullpath> -case <casename>]]></c></item> </list> <p>From the GUI you can run tests and view the result and the logs. </p> - <p>Note that <c>run_test -vts</c> will try to open the Common Test start + <p>Note that <c>ct_run -vts</c> will try to open the Common Test start page in an existing web browser window or start the browser if it is not running. Which browser should be started may be specified with the browser start command option:</p> - <p><c><![CDATA[run_test -vts -browser <browser_start_cmd>]]></c></p> + <p><c><![CDATA[ct_run -vts -browser <browser_start_cmd>]]></c></p> <p>Example:</p> - <p><c><![CDATA[$ run_test -vts -browser 'firefox&']]></c></p> + <p><c><![CDATA[$ ct_run -vts -browser 'firefox&']]></c></p> <p>Note that the browser must run as a separate OS process or VTS will hang!</p> <p>If no specific browser start command is specified, Firefox will be the default browser on Unix platforms and Internet Explorer on Windows. @@ -227,10 +227,10 @@ <p>Common Test provides an Erlang API for running tests. The main (and most flexible) function for specifying and executing tests is called <c>ct:run_test/1</c>. This function takes the same start parameters as - the <c>run_test</c> program described above, only the flags are instead + the <c>ct_run</c> program described above, only the flags are instead given as options in a list of key-value tuples. E.g. a test specified - with <c>run_test</c> like:</p> - <p><c>$ run_test -suite ./my_SUITE -logdir ./results</c></p> + with <c>ct_run</c> like:</p> + <p><c>$ ct_run -suite ./my_SUITE -logdir ./results</c></p> <p>is with <c>ct:run_test/1</c> specified as:</p> <p><c>1> ct:run_test([{suite,"./my_SUITE"},{logdir,"./results"}]).</c></p> <p>For detailed documentation, please see the <c>ct</c> manual page.</p> @@ -253,17 +253,17 @@ manually and call <c>ct:install/1</c> to install any configuration data you might need (use <c>[]</c> as argument otherwise), then call <c>ct:start_interactive/0</c> to start Common Test. If you use - the <c>run_test</c> program, you may start the Erlang shell and Common Test + the <c>ct_run</c> program, you may start the Erlang shell and Common Test in the same go by using the <c>-shell</c> and, optionally, the <c>-config</c> and/or <c>-userconfig</c> flag. Examples: </p> <list> - <item><c>run_test -shell</c></item> - <item><c><![CDATA[run_test -shell -config cfg/db.cfg]]></c></item> - <item><c><![CDATA[run_test -shell -userconfig db_login testuser x523qZ]]></c></item> + <item><c>ct_run -shell</c></item> + <item><c><![CDATA[ct_run -shell -config cfg/db.cfg]]></c></item> + <item><c><![CDATA[ct_run -shell -userconfig db_login testuser x523qZ]]></c></item> </list> - <p>If no config file is given with the <c>run_test</c> command, + <p>If no config file is given with the <c>ct_run</c> command, a warning will be displayed. If Common Test has been run from the same directory earlier, the same config file(s) will be used again. If Common Test has not been run from this directory before, no @@ -293,7 +293,7 @@ <c>ctlog.html</c> in the <c><![CDATA[ct_run.<timestamp>]]></c> directory. A link to this file will be available in the file named <c>last_interactive.html</c> in the directory from which - you executed <c>run_test</c>. Currently, specifying a different + you executed <c>ct_run</c>. Currently, specifying a different root directory for the logs than the current working directory, is not supported.</p> @@ -309,7 +309,7 @@ <section> <title>Step by step execution of test cases with the Erlang Debugger</title> - <p>By means of <c>run_test -step [opts]</c>, or by passing the + <p>By means of <c>ct_run -step [opts]</c>, or by passing the <c>{step,Opts}</c> option to <c>ct:run_test/1</c>, it is possible to get the Erlang Debugger started automatically and use its graphical interface to investigate the state of the current test @@ -345,12 +345,12 @@ for <c>ct</c>). There are two general types of terms: configuration terms and test specification terms.</p> <p>With configuration terms it is possible to e.g. label the test - run (similar to <c>run_test -label</c>), evaluate arbitrary expressions + run (similar to <c>ct_run -label</c>), evaluate arbitrary expressions before starting a test, import configuration data (similar to - <c>run_test -config/-userconfig</c>), specify HTML log directories (similar + <c>ct_run -config/-userconfig</c>), specify HTML log directories (similar to - <c>run_test -logdir</c>), give aliases to test nodes and test + <c>ct_run -logdir</c>), give aliases to test nodes and test directories (to make a specification easier to read and maintain), enable code coverage analysis (see the <seealso marker="cover_chapter#cover">Code Coverage @@ -359,7 +359,7 @@ Event Handling</seealso> chapter). There is also a term for specifying include directories that should be passed on to the compiler when automatic compilation is performed (similar - to <c>run_test -include</c>, see above).</p> + to <c>ct_run -include</c>, see above).</p> <p>With test specification terms it is possible to state exactly which tests should run and in which order. A test term specifies either one or more suites, one or more test case groups, or one @@ -535,7 +535,7 @@ <p>It is possible for the user to provide a test specification that includes (for Common Test) unrecognizable terms. If this is desired, the <c>-allow_user_terms</c> flag should be used when starting tests with - <c>run_test</c>. This forces Common Test to ignore unrecognizable terms. + <c>ct_run</c>. This forces Common Test to ignore unrecognizable terms. Note that in this mode, Common Test is not able to check the specification for errors as efficiently as if the scanner runs in default mode. If <c>ct:run_test/1</c> is used for starting the tests, the relaxed scanner @@ -661,11 +661,11 @@ </pre> <p>To install the CSS file (Common Test inlines the definition in the - HTML code), the name may be provided when executing <c>run_test</c>. + HTML code), the name may be provided when executing <c>ct_run</c>. Example:</p> <pre> - $ run_test -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css + $ ct_run -dir $TEST/prog -stylesheet $TEST/styles/test_categories.css </pre> <p>Categories in a CSS file installed with the <c>-stylesheet</c> flag @@ -738,7 +738,7 @@ means of time, it is also possible to specify what action Common Test should take upon timeout. Either Common Test performs all tests in the current run before stopping, or it stops as soon as the current test job is finished. Repetition can be activated by - means of <c>run_test</c> start flags, or tuples in the <c>ct:run:test/1</c> + means of <c>ct_run</c> start flags, or tuples in the <c>ct:run:test/1</c> option list argument. The flags (options in parenthesis) are:</p> <list> <item><c>-repeat N ({repeat,N})</c>, where <c>N</c> is a positive integer.</item> @@ -774,7 +774,7 @@ <p>Example 1:</p> <pre> - $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre> + $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -duration 001000 -force_stop</pre> <p>Here the suites in test directory to1, followed by the suites in to2, will be executed in one test run. A timeout event will occur after 10 minutes. As long as there is time left, Common Test will repeat the test run (i.e. starting over with the to1 test). @@ -787,7 +787,7 @@ $ date Fri Sep 28 15:00:00 MEST 2007 - $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre> + $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -until 160000</pre> <p>Here the same test run as in the example above will be executed (and possibly repeated). In this example, however, the timeout will occur after 1 hour and when that happens, Common Test will finish the entire test run before stopping (i.e. the to1 and to2 test @@ -795,7 +795,7 @@ <p>Example 3:</p> <pre> - $ run_test -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre> + $ ct_run -dir $TEST_ROOT/to1 $TEST_ROOT/to2 -repeat 5</pre> <p>Here the test run, including both the to1 and the to2 test, will be repeated 5 times.</p> <note><p>This feature should not be confused with the <c>repeat</c> property of a test @@ -814,7 +814,7 @@ of the <c>-silent_connections</c> flag:</p> <pre> - run_test -silent_connections [conn_types] + ct_run -silent_connections [conn_types] </pre> <p>where <c>conn_types</c> specifies <c>telnet, ftp, rpc</c> and/or <c>snmp</c>.</p> @@ -822,11 +822,11 @@ <p>Example:</p> <pre> - run_test ... -silent_connections telnet ftp</pre> + ct_run ... -silent_connections telnet ftp</pre> <p>switches off logging for telnet and ftp connections.</p> <pre> - run_test ... -silent_connections</pre> + ct_run ... -silent_connections</pre> <p>switches off logging for all connection types.</p> diff --git a/lib/common_test/doc/src/test_structure_chapter.xml b/lib/common_test/doc/src/test_structure_chapter.xml index cd38ae0c7c..b9ca59135d 100644 --- a/lib/common_test/doc/src/test_structure_chapter.xml +++ b/lib/common_test/doc/src/test_structure_chapter.xml @@ -144,7 +144,7 @@ be used when the test suite needs to write to files. </item> - <tag><em>run_test</em></tag> + <tag><em>ct_run</em></tag> <item> The name of an executable program that may be used as an interface for specifying and running diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in index 6372bbc8d5..a6ac0f1a02 100644 --- a/lib/common_test/priv/Makefile.in +++ b/lib/common_test/priv/Makefile.in @@ -56,8 +56,8 @@ ifneq ($(findstring win32,$(TARGET)),win32) # # Files # -FILES = -SCRIPTS = +FILES = vts.tool +SCRIPTS = IMAGES = tile1.jpg # diff --git a/lib/common_test/src/ct.erl b/lib/common_test/src/ct.erl index 8ae175f10d..405dc40c8b 100644 --- a/lib/common_test/src/ct.erl +++ b/lib/common_test/src/ct.erl @@ -97,7 +97,7 @@ %%% <code>install([{config,["config_node.ctc","config_user.ctc"]}])</code>.</p> %%% %%% <p>Note that this function is automatically run by the -%%% <code>run_test</code> program.</p> +%%% <code>ct_run</code> program.</p> install(Opts) -> ct_run:install(Opts). @@ -179,10 +179,10 @@ run(TestDirs) -> %%% Result = [TestResult] | {error,Reason} %%% @doc Run tests as specified by the combination of options in <code>Opts</code>. %%% The options are the same as those used with the -%%% <seealso marker="run_test#run_test"><code>run_test</code></seealso> program. +%%% <seealso marker="ct_run#ct_run"><code>ct_run</code></seealso> program. %%% Note that here a <code>TestDir</code> can be used to point out the path to %%% a <code>Suite</code>. Note also that the option <code>testcase</code> -%%% corresponds to the <code>-case</code> option in the <code>run_test</code> +%%% corresponds to the <code>-case</code> option in the <code>ct_run</code> %%% program. Configuration files specified in <code>Opts</code> will be %%% installed automatically at startup. run_test(Opts) -> @@ -225,7 +225,7 @@ step(TestDir,Suite,Case,Opts) -> %%% %%% <p>From this mode all test case support functions can be executed %%% directly from the erlang shell. The interactive mode can also be -%%% started from the OS command line with <code>run_test -shell +%%% started from the OS command line with <code>ct_run -shell %%% [-config File...]</code>.</p> %%% %%% <p>If any functions using "required config data" (e.g. telnet or @@ -694,7 +694,7 @@ userdata(TestDir, Suite, Case) -> %%%----------------------------------------------------------------- -%%% @spec get_status() -> TestStatus | {error,Reason} +%%% @spec get_status() -> TestStatus | {error,Reason} | no_tests_running %%% TestStatus = [StatusElem] %%% StatusElem = {current,{Suite,TestCase}} | {successful,Successful} | %%% {failed,Failed} | {skipped,Skipped} | {total,Total} diff --git a/lib/common_test/src/ct_master.erl b/lib/common_test/src/ct_master.erl index 42e4cf08f4..2ea2ba106a 100644 --- a/lib/common_test/src/ct_master.erl +++ b/lib/common_test/src/ct_master.erl @@ -101,12 +101,14 @@ run([TS|TestSpecs],AllowUserTerms,InclNodes,ExclNodes) when is_list(TS), TSRec=#testspec{logdir=AllLogDirs, config=StdCfgFiles, userconfig=UserCfgFiles, + include=AllIncludes, init=AllInitOpts, event_handler=AllEvHs} -> AllCfgFiles = {StdCfgFiles, UserCfgFiles}, RunSkipPerNode = ct_testspec:prepare_tests(TSRec), RunSkipPerNode2 = exclude_nodes(ExclNodes,RunSkipPerNode), - run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1) + run_all(RunSkipPerNode2,AllLogDirs,AllCfgFiles,AllEvHs, + AllIncludes,[],[],AllInitOpts,TS1) end, [{TS,Result} | run(TestSpecs,AllowUserTerms,InclNodes,ExclNodes)]; run([],_,_,_) -> @@ -163,11 +165,13 @@ run_on_node([TS|TestSpecs],AllowUserTerms,Node) when is_list(TS),is_atom(Node) - TSRec=#testspec{logdir=AllLogDirs, config=StdCfgFiles, init=AllInitOpts, + include=AllIncludes, userconfig=UserCfgFiles, event_handler=AllEvHs} -> AllCfgFiles = {StdCfgFiles, UserCfgFiles}, {Run,Skip} = ct_testspec:prepare_tests(TSRec,Node), - run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs,[],[],AllInitOpts,TS1) + run_all([{Node,Run,Skip}],AllLogDirs,AllCfgFiles,AllEvHs, + AllIncludes, [],[],AllInitOpts,TS1) end, [{TS,Result} | run_on_node(TestSpecs,AllowUserTerms,Node)]; run_on_node([],_,_) -> @@ -189,7 +193,7 @@ run_on_node(TestSpecs,Node) -> run_all([{Node,Run,Skip}|Rest],AllLogDirs, {AllStdCfgFiles, AllUserCfgFiles}=AllCfgFiles, - AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) -> + AllEvHs,AllIncludes,NodeOpts,LogDirs,InitOptions,Specs) -> LogDir = lists:foldl(fun({N,Dir},_Found) when N == Node -> Dir; @@ -211,6 +215,14 @@ run_all([{Node,Run,Skip}|Rest],AllLogDirs, ({_N,_F},Fs) -> Fs; (F,Fs) -> [{userconfig, F}|Fs] end,[],AllUserCfgFiles), + + Includes = lists:foldr(fun({N,I},Acc) when N =:= Node -> + [I|Acc]; + ({_,_},Acc) -> + Acc; + (I,Acc) -> + [I | Acc] + end, [], AllIncludes), EvHs = lists:foldr(fun({N,H,A},Hs) when N == Node -> [{H,A}|Hs]; ({_N,_H,_A},Hs) -> Hs; @@ -219,10 +231,13 @@ run_all([{Node,Run,Skip}|Rest],AllLogDirs, NO = {Node,[{prepared_tests,{Run,Skip},Specs}, {logdir,LogDir}, + {include, Includes}, {config,StdCfgFiles}, {event_handler,EvHs}] ++ UserCfgFiles}, - run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,[NO|NodeOpts],[LogDir|LogDirs],InitOptions,Specs); -run_all([],AllLogDirs,_,AllEvHs,NodeOpts,LogDirs,InitOptions,Specs) -> + run_all(Rest,AllLogDirs,AllCfgFiles,AllEvHs,AllIncludes, + [NO|NodeOpts],[LogDir|LogDirs],InitOptions,Specs); +run_all([],AllLogDirs,_,AllEvHs,_AllIncludes, + NodeOpts,LogDirs,InitOptions,Specs) -> Handlers = [{H,A} || {Master,H,A} <- AllEvHs, Master == master], MasterLogDir = case lists:keysearch(master,1,AllLogDirs) of {value,{_,Dir}} -> Dir; diff --git a/lib/common_test/src/ct_run.erl b/lib/common_test/src/ct_run.erl index 586b3893f1..d0e6ba5fa6 100644 --- a/lib/common_test/src/ct_run.erl +++ b/lib/common_test/src/ct_run.erl @@ -65,12 +65,12 @@ %%%----------------------------------------------------------------- %%% @spec script_start() -> void() %%% -%%% @doc Start tests via the run_test program or script. +%%% @doc Start tests via the ct_run program or script. %%% -%%% <p>Example:<br/><code>./run_test -config config.ctc -dir +%%% <p>Example:<br/><code>./ct_run -config config.ctc -dir %%% $TEST_DIR</code></p> %%% -%%% <p>Example:<br/><code>./run_test -config config.ctc -suite +%%% <p>Example:<br/><code>./ct_run -config config.ctc -suite %%% $SUITE_PATH/$SUITE_NAME [-case $CASE_NAME]</code></p> %%% script_start() -> @@ -80,7 +80,7 @@ script_start() -> (_) -> true end, Init), %% convert relative dirs added with pa or pz (pre erl_args on - %% the run_test command line) to absolute so that app modules + %% the ct_run command line) to absolute so that app modules %% can be found even after CT changes CWD to logdir rel_to_abs(CtArgs), @@ -482,11 +482,11 @@ script_start4(Opts = #opts{tests = Tests}, Args) -> %%%----------------------------------------------------------------- %%% @spec script_usage() -> ok -%%% @doc Print usage information for <code>run_test</code>. +%%% @doc Print usage information for <code>ct_run</code>. script_usage() -> io:format("\n\nUsage:\n\n"), io:format("Run tests in web based GUI:\n\n" - "\trun_test -vts [-browser Browser]" + "\tct_run -vts [-browser Browser]" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" "\n\t[-dir TestDir1 TestDir2 .. TestDirN] |" @@ -497,7 +497,7 @@ script_usage() -> "\n\t[-scale_timetraps]" "\n\t[-basic_html]\n\n"), io:format("Run tests from command line:\n\n" - "\trun_test [-dir TestDir1 TestDir2 .. TestDirN] |" + "\tct_run [-dir TestDir1 TestDir2 .. TestDirN] |" "\n\t[-suite Suite1 Suite2 .. SuiteN [-case Case1 Case2 .. CaseN]]" "\n\t[-step [config | keep_inactive]]" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" @@ -517,7 +517,7 @@ script_usage() -> "\n\t[-duration HHMMSS [-force_stop]] |" "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), io:format("Run tests using test specification:\n\n" - "\trun_test -spec TestSpec1 TestSpec2 .. TestSpecN" + "\tct_run -spec TestSpec1 TestSpec2 .. TestSpecN" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]" "\n\t[-logdir LogDir]" @@ -535,11 +535,11 @@ script_usage() -> "\n\t[-duration HHMMSS [-force_stop]] |" "\n\t[-until [YYMoMoDD]HHMMSS [-force_stop]]\n\n"), io:format("Refresh the HTML index files:\n\n" - "\trun_test -refresh_logs [LogDir]" + "\tct_run -refresh_logs [LogDir]" "[-logdir LogDir] " "[-basic_html]\n\n"), io:format("Run CT in interactive mode:\n\n" - "\trun_test -shell" + "\tct_run -shell" "\n\t[-config ConfigFile1 ConfigFile2 .. ConfigFileN]" "\n\t[-decrypt_key Key] | [-decrypt_file KeyFile]\n\n"). @@ -2103,7 +2103,7 @@ get_pa_pz([], PA, PZ) -> {PA,PZ}. %% This function translates ct:run_test/1 start options -%% to run_test start arguments (on the init arguments format) - +%% to ct_run start arguments (on the init arguments format) - %% this is useful mainly for testing the ct_run start functions. opts2args(EnvStartOpts) -> lists:flatmap(fun({config,CfgFiles}) -> diff --git a/lib/common_test/src/ct_util.erl b/lib/common_test/src/ct_util.erl index 0a434666fa..b5ab4cbb6e 100644 --- a/lib/common_test/src/ct_util.erl +++ b/lib/common_test/src/ct_util.erl @@ -556,10 +556,37 @@ listenv(Telnet) -> %%% @hidden %%% @equiv ct:parse_table/1 parse_table(Data) -> - [Heading|Lines]= - [remove_space(string:tokens(L, "|"),[]) || L <- Data, hd(L)==$|], + {Heading, Rest} = get_headings(Data), + Lines = parse_row(Rest,[],size(Heading)), {Heading,Lines}. +get_headings(["|" ++ Headings | Rest]) -> + {remove_space(string:tokens(Headings, "|"),[]), Rest}; +get_headings([_ | Rest]) -> + get_headings(Rest); +get_headings([]) -> + {{},[]}. + +parse_row(["|" ++ _ = Row | T], Rows, NumCols) when NumCols > 1 -> + case string:tokens(Row, "|") of + Values when length(Values) =:= NumCols -> + parse_row(T,[remove_space(Values,[])|Rows], NumCols); + Values when length(Values) < NumCols -> + parse_row([Row ++"\n"++ hd(T) | tl(T)], Rows, NumCols) + end; +parse_row(["|" ++ _ = Row | T], Rows, 1 = NumCols) -> + case string:rchr(Row, $|) of + 1 -> + parse_row([Row ++"\n"++hd(T) | tl(T)], Rows, NumCols); + _Else -> + parse_row(T, [remove_space(string:tokens(Row,"|"),[])|Rows], + NumCols) + end; +parse_row([_Skip | T], Rows, NumCols) -> + parse_row(T, Rows, NumCols); +parse_row([], Rows, _NumCols) -> + lists:reverse(Rows). + remove_space([Str|Rest],Acc) -> remove_space(Rest,[string:strip(string:strip(Str),both,$')|Acc]); remove_space([],Acc) -> diff --git a/lib/common_test/test/ct_master_SUITE.erl b/lib/common_test/test/ct_master_SUITE.erl index e0e1f93db2..5ac2866227 100644 --- a/lib/common_test/test/ct_master_SUITE.erl +++ b/lib/common_test/test/ct_master_SUITE.erl @@ -33,6 +33,13 @@ -define(eh, ct_test_support_eh). +-define(TEMP_DIR, case os:type() of + {win32,_} -> + "c:/Temp"; + _ -> + "/tmp" + end). + %%-------------------------------------------------------------------- %% TEST SERVER CALLBACK FUNCTIONS %%-------------------------------------------------------------------- @@ -43,18 +50,39 @@ %% there will be clashes with logging processes etc). %%-------------------------------------------------------------------- init_per_suite(Config) -> - Config1 = ct_test_support:init_per_suite(Config), - Config1. + ct_test_support:init_per_suite(Config). end_per_suite(Config) -> ct_test_support:end_per_suite(Config). init_per_testcase(TestCase, Config) -> - ct_test_support:init_per_testcase(TestCase, [{master, true}|Config]). + NodeCount = 5, + NodeNames = [list_to_atom("t_"++integer_to_list(N)) || + N <- lists:seq(1, NodeCount)], + ct_test_support:init_per_testcase( + TestCase,[{node_names,NodeNames}, + {master, true}|Config]). end_per_testcase(TestCase, Config) -> + case os:type() of + {win32,_} -> + %% If this is a windows run the logs are saved to /tmp and + %% then moved to private_dir as a tar because otherwise + %% the file names become too long! :( + Files = filelib:wildcard(filename:join(?TEMP_DIR,"slave.*")), + erl_tar:create( + filename:join( + proplists:get_value(priv_dir,Config),"slaves.tar.gz"), + Files,[compressed]), + os:cmd("rm -rf "++filename:join(?TEMP_DIR,"slave.*")); + _ -> + ok + end, + ct_test_support:end_per_testcase(TestCase, Config). +all() -> + all(suite). all(doc) -> [""]; @@ -67,15 +95,35 @@ all(suite) -> %% TEST CASES %%-------------------------------------------------------------------- ct_master_test(Config) when is_list(Config)-> - NodeCount = 5, + NodeNames = proplists:get_value(node_names, Config), DataDir = ?config(data_dir, Config), PrivDir = ?config(priv_dir, Config), - NodeNames = [list_to_atom("testnode_"++integer_to_list(N)) || - N <- lists:seq(1, NodeCount)], + FileName = filename:join(PrivDir, "ct_master_spec.spec"), Suites = [master_SUITE], TSFile = make_spec(DataDir, FileName, NodeNames, Suites, Config), + ERPid = ct_test_support:start_event_receiver(Config), + spawn(ct@ancalagon, + fun() -> + dbg:tracer(),dbg:p(all,c), + dbg:tpl(erlang, spawn_link, 4,x), + receive ok -> ok end + end), + [{TSFile, ok}] = run_test(ct_master_test, FileName, Config), + + Events = ct_test_support:get_events(ERPid, Config), + + ct_test_support:log_events(groups_suite_1, + reformat(Events, ?eh), + ?config(priv_dir, Config)), + find_events(NodeNames, [{tc_start,{master_SUITE,init_per_suite}}, + {tc_start,{master_SUITE,first_testcase}}, + {tc_start,{master_SUITE,second_testcase}}, + {tc_start,{master_SUITE,third_testcase}}, + {tc_start,{master_SUITE,end_per_suite}}], + Events), + ok. %%%----------------------------------------------------------------- @@ -112,13 +160,25 @@ make_spec(DataDir, FileName, NodeNames, Suites, Config)-> PrivDir = ?config(priv_dir, Config), LD = lists:map(fun(NodeName)-> - {logdir, NodeName, get_log_dir(PrivDir, NodeName)} + {logdir, NodeName, get_log_dir(os:type(),PrivDir, NodeName)} end, NodeNames) ++ [{logdir, master, PrivDir}], - - ct_test_support:write_testspec(N++C++S++LD++NS, FileName). - -get_log_dir(PrivDir, NodeName)-> + EvHArgs = [{cbm,ct_test_support},{trace_level,?config(trace_level,Config)}], + EH = [{event_handler,master,[?eh],EvHArgs}], + + Include = [{include,filename:join([DataDir,"master/include"])}], + + ct_test_support:write_testspec(N++Include++EH++C++S++LD++NS, FileName). + +get_log_dir({win32,_},PrivDir, NodeName)-> + case filelib:is_dir(?TEMP_DIR) of + false -> + file:make_dir(?TEMP_DIR); + _ -> + ok + end, + get_log_dir(tmp, ?TEMP_DIR,NodeName); +get_log_dir(_,PrivDir,NodeName) -> LogDir = filename:join(PrivDir, io_lib:format("slave.~p", [NodeName])), file:make_dir(LogDir), LogDir. @@ -126,11 +186,34 @@ get_log_dir(PrivDir, NodeName)-> run_test(_Name, FileName, Config)-> [{FileName, ok}] = ct_test_support:run(ct_master, run, [FileName], Config). -reformat_events(Events, EH) -> +reformat(Events, EH) -> ct_test_support:reformat(Events, EH). %%%----------------------------------------------------------------- %%% TEST EVENTS %%%----------------------------------------------------------------- +find_events([], _CheckEvents, _) -> + ok; +find_events([NodeName|NodeNames],CheckEvents,AllEvents) -> + find_events(NodeNames, CheckEvents, + remove_events(add_host(NodeName),CheckEvents, AllEvents, [])). + +remove_events(Node,[{Name,Data} | RestChecks], + [{?eh,#event{ name = Name, node = Node, data = Data }}|RestEvs], + Acc) -> + remove_events(Node, RestChecks, RestEvs, Acc); +remove_events(Node, Checks, [Event|RestEvs], Acc) -> + remove_events(Node, Checks, RestEvs, [Event | Acc]); +remove_events(_Node, [], [], Acc) -> + lists:reverse(Acc); +remove_events(Node, Events, [], Acc) -> + test_server:format("Could not find events: ~p in ~p for node ~p", + [Events, lists:reverse(Acc), Node]), + exit(event_not_found). + +add_host(NodeName) -> + {ok, HostName} = inet:gethostname(), + list_to_atom(atom_to_list(NodeName)++"@"++HostName). + expected_events(_)-> -[]. + []. diff --git a/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl b/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/common_test/test/ct_master_SUITE_data/master/include/test.hrl diff --git a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl index e37ec3659c..032d69ad9f 100644 --- a/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl +++ b/lib/common_test/test/ct_master_SUITE_data/master/master_SUITE.erl @@ -28,6 +28,7 @@ -compile(export_all). -include_lib("common_test/include/ct.hrl"). +-include("test.hrl"). suite() -> []. diff --git a/lib/common_test/test/ct_misc_1_SUITE.erl b/lib/common_test/test/ct_misc_1_SUITE.erl index eb6c6aa101..8c8b2d0d41 100644 --- a/lib/common_test/test/ct_misc_1_SUITE.erl +++ b/lib/common_test/test/ct_misc_1_SUITE.erl @@ -62,7 +62,7 @@ all(doc) -> all(suite) -> [ - beam_me_up + beam_me_up, parse_table ]. %%-------------------------------------------------------------------- @@ -106,6 +106,66 @@ beam_me_up(Config) when is_list(Config) -> TestEvents = events_to_check(beam_me_up, 1), ok = ct_test_support:verify_events(TestEvents, Events, Config). + +parse_table(suite) -> + [parse_table_empty, parse_table_single, + parse_table_multiline_row, + parse_table_one_column_multiline, + parse_table_one_column_simple]. + +parse_table_empty(Config) when is_list(Config) -> + + String = ["+----+-------+---------+---------+----------+------+--------+", + "| id | col11 | col2222 | col3333 | col4 | col5 | col6666 |", + "+----+-------+---------+---------+----------+------+--------+", + "+----+-------+---------+---------+----------+------+--------+", + "Query Done: 0 records selected"], + + {{"id","col11","col2222","col3333","col4","col5","col6666"},[]} = + ct:parse_table(String). + + +parse_table_single(Config) when is_list(Config) -> + + String = ["+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+", + "| id | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 |", +"+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+", + "| 0 | 0 | -1407231560 | -256 | -1407231489 | 1500 | 1 | 1 | 1 |", + "+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+" + "Query Done: 1 record selected"], + + {{"id","col1","col2","col3","col4","col5","col6","col7","col8"}, + [{"0","0","-1407231560","-256","-1407231489", "1500","1","1","1"}]} = + ct:parse_table(String). + +parse_table_multiline_row(Config) when is_list(Config) -> + + String = ["+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+", + "| id | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 |", +"+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+", + "| 0 | 0 | Free test string", + " on more lines", + "than one", + "| -256 | -1407231489 | 1500 | 1 | 1 | 1 |", + "+------+--------+--------------+------------+------------------+---------+--------+---------+-----------+" + "Query Done: 1 record selected"], + + {{"id","col1","col2","col3","col4","col5","col6","col7","col8"}, + [{"0","0","Free test string\n on more lines\nthan one\n", + "-256","-1407231489", "1500","1","1","1"}]} = + ct:parse_table(String). + +parse_table_one_column_simple(Config) when is_list(Config) -> + + String = ["|test|","|test value|"], + + {{"test"},[{"test value"}]} = ct:parse_table(String). + +parse_table_one_column_multiline(Config) when is_list(Config) -> + String = ["|test|","|test","value|"], + + {{"test"},[{"test\nvalue"}]} = ct:parse_table(String). + %%%----------------------------------------------------------------- %%% HELP FUNCTIONS %%%----------------------------------------------------------------- diff --git a/lib/common_test/test/ct_test_support.erl b/lib/common_test/test/ct_test_support.erl index 7bfb9ffb49..5e9792f02c 100644 --- a/lib/common_test/test/ct_test_support.erl +++ b/lib/common_test/test/ct_test_support.erl @@ -43,6 +43,14 @@ init_per_suite(Config) -> init_per_suite(Config, 50). init_per_suite(Config, Level) -> + case os:type() of + {win32, _} -> + %% Extend timeout for windows as starting node + %% can take a long time there + test_server:timetrap( 120000 * test_server:timetrap_scale_factor()); + _ -> + ok + end, case delete_old_logs(os:type(), Config) of {'EXIT',DelLogsReason} -> test_server:format(0, "Failed to delete old log directories: ~p~n", @@ -51,6 +59,8 @@ init_per_suite(Config, Level) -> ok end, [_,Host] = string:tokens(atom_to_list(node()), "@"), + + test_server:format(0, "Trying to start ~s~n", ["ct@"++Host]), case slave:start(Host, ct, []) of {error,Reason} -> test_server:fail(Reason); @@ -351,13 +361,33 @@ locate({parallel,TEvs}, Node, Evs, Config) -> case Evs of [{TEH,#event{name=tc_start, node=Node, - data={M,{init_per_group,GroupName,Props}}}}, - {TEH,#event{name=tc_done, - node=Node, - data={M,{init_per_group,GroupName,Props},R}}} | Es] -> + data={M,{init_per_group, + GroupName,Props}}}}|Es] -> + %% Use dropwhile here as a tc_done from a + %% previous testcase might sneak in here + EvsG = lists:dropwhile( + fun({EH,#event{name=tc_done, + node=EvNode, + data={EvM,{init_per_group, + EvGroupName, + EvProps},EvR}}}) + when TEH == EH, EvNode == Node, EvM == M, + EvGroupName == GroupName, + EvProps == Props, + EvR == R -> + false; + ({EH,#event{name=stop_logging, + node=EvNode,data=_}}) + when EH == TEH, EvNode == Node -> + exit({group_init_done_not_found, + GroupName,Props}); + (_) -> + true + end, Es), + test_server:format("Found ~p!", [InitStart]), test_server:format("Found ~p!", [InitDone]), - {TEs,Es}; + {TEs,EvsG}; _ -> nomatch end; diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index e1f24b602d..c3d65b4cb5 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -310,9 +310,9 @@ (there will not even be a warning if there is a mismatch).</p> </item> - <tag><c>{no_auto_import,[F/A, ...]}</c></tag> + <tag><c>{no_auto_import,[{F,A}, ...]}</c></tag> <item> - <p>Makes the function <c>F/A</c> no longer beeing + <p>Makes the function <c>F/A</c> no longer being auto-imported from the module <c>erlang</c>, which resolves BIF name clashes. This option has to be used to resolve name clashes with BIFs auto-imported before R14A, if one wants to @@ -323,8 +323,12 @@ without module prefix to local or imported functions before trying auto-imported BIFs. If the BIF is to be called, use the <c>erlang</c> module prefix in the call, not - <c>{ no_auto_import,[F/A, ...]}</c></p> + <c>{ no_auto_import,[{F,A}, ...]}</c></p> </note> + <p>If this option is written in the source code, as a + <c>-compile</c> directive, the syntax <c>F/A</c> can be used instead + of <c>{F,A}</c>. Example:</p> + <code>-compile({no_auto_import,[error/1]}).</code> </item> </taglist> diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index 9c6f835ab0..c45874597a 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -36,12 +36,13 @@ function({function,Name,Arity,CLabel,Is0}, Lc0) -> %% Collect basic blocks and optimize them. Is2 = blockify(Is1), - Is3 = beam_utils:live_opt(Is2), - Is4 = opt_blocks(Is3), - Is5 = beam_utils:delete_live_annos(Is4), + Is3 = move_allocates(Is2), + Is4 = beam_utils:live_opt(Is3), + Is5 = opt_blocks(Is4), + Is6 = beam_utils:delete_live_annos(Is5), %% Optimize bit syntax. - {Is,Lc} = bsm_opt(Is5, Lc0), + {Is,Lc} = bsm_opt(Is6, Lc0), %% Done. {{function,Name,Arity,CLabel,Is},Lc} @@ -156,11 +157,7 @@ opt_blocks([I|Is]) -> opt_blocks([]) -> []. opt_block(Is0) -> - %% We explicitly move any allocate instruction upwards before optimising - %% moves, to avoid any potential problems with the calculation of live - %% registers. - Is1 = move_allocates(Is0), - Is = find_fixpoint(fun opt/1, Is1), + Is = find_fixpoint(fun opt/1, Is0), opt_alloc(Is). find_fixpoint(OptFun, Is0) -> @@ -170,11 +167,21 @@ find_fixpoint(OptFun, Is0) -> end. %% move_allocates(Is0) -> Is -%% Move allocates upwards in the instruction stream, in the hope of -%% getting more possibilities for optimizing away moves later. - -move_allocates(Is) -> - move_allocates_1(reverse(Is), []). +%% Move allocate instructions upwards in the instruction stream, in the +%% hope of getting more possibilities for optimizing away moves later. +%% +%% NOTE: Moving allocation instructions is only safe because it is done +%% immediately after code generation so that we KNOW that if {x,X} is +%% initialized, all x registers with lower numbers are also initialized. +%% That assumption may not be true after other optimizations, such as +%% the beam_utils:live_opt/1 optimization. + +move_allocates([{block,Bl0}|Is]) -> + Bl = move_allocates_1(reverse(Bl0), []), + [{block,Bl}|move_allocates(Is)]; +move_allocates([I|Is]) -> + [I|move_allocates(Is)]; +move_allocates([]) -> []. move_allocates_1([{set,[],[],{alloc,_,_}=Alloc}|Is0], Acc0) -> {Is,Acc} = move_allocates_2(Alloc, Is0, Acc0), diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 761d4ffec0..45cdf8a659 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -407,16 +407,23 @@ check_liveness(R, [{bif,Op,{f,Fail},Ss,D}|Is], St0) -> Other -> Other end; -check_liveness(R, [{gc_bif,Op,{f,Fail},_,Ss,D}|Is], St0) -> - case check_liveness_fail(R, Op, Ss, Fail, St0) of - {killed,St} = Killed -> - case member(R, Ss) of - true -> {used,St}; - false when R =:= D -> Killed; - false -> check_liveness(R, Is, St) - end; - Other -> - Other +check_liveness(R, [{gc_bif,Op,{f,Fail},Live,Ss,D}|Is], St0) -> + case R of + {x,X} when X >= Live -> + {killed,St0}; + {x,_} -> + {used,St0}; + _ -> + case check_liveness_fail(R, Op, Ss, Fail, St0) of + {killed,St}=Killed -> + case member(R, Ss) of + true -> {used,St}; + false when R =:= D -> Killed; + false -> check_liveness(R, Is, St) + end; + Other -> + Other + end end; check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) -> case member(R, Ss) of @@ -482,10 +489,13 @@ check_liveness(R, [{bs_context_to_binary,S}|Is], St) -> S -> {used,St}; _ -> check_liveness(R, Is, St) end; -check_liveness(R, [{loop_rec,{f,_},{x,0}}|Is], St) -> +check_liveness(R, [{loop_rec,{f,_},{x,0}}|_], St) -> case R of - {x,_} -> {killed,St}; - _ -> check_liveness(R, Is, St) + {x,_} -> + {killed,St}; + _ -> + %% y register. Rarely happens. Be very conversative. + {unknown,St} end; check_liveness(R, [{loop_rec_end,{f,Fail}}|_], St) -> check_liveness_at(R, Fail, St); diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl index d1fd9d40e2..4b74d60e9f 100644 --- a/lib/compiler/src/cerl.erl +++ b/lib/compiler/src/cerl.erl @@ -973,7 +973,7 @@ atom_name(Node) -> %% TODO: replace the use of the unofficial 'write_string/2'. --spec atom_lit(cerl()) -> string(). +-spec atom_lit(cerl()) -> nonempty_string(). atom_lit(Node) -> io_lib:write_string(atom_name(Node), $'). %' stupid Emacs. @@ -1079,7 +1079,7 @@ char_val(Node) -> %% %% @see c_char/1 --spec char_lit(c_literal()) -> string(). +-spec char_lit(c_literal()) -> nonempty_string(). char_lit(Node) -> io_lib:write_char(char_val(Node)). @@ -1178,7 +1178,7 @@ string_val(Node) -> %% %% @see c_string/1 --spec string_lit(c_literal()) -> string(). +-spec string_lit(c_literal()) -> nonempty_string(). string_lit(Node) -> io_lib:write_string(string_val(Node)). diff --git a/lib/compiler/src/core_lint.erl b/lib/compiler/src/core_lint.erl index b633f568c9..b513a8965c 100644 --- a/lib/compiler/src/core_lint.erl +++ b/lib/compiler/src/core_lint.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -65,7 +65,8 @@ | {'return_mismatch', fa()} | {'undefined_function', fa()} | {'duplicate_var', cerl:var_name(), fa()} | {'unbound_var', cerl:var_name(), fa()} - | {'undefined_function', fa(), fa()}. + | {'undefined_function', fa(), fa()} + | {'tail_segment_not_at_end', fa()}. -type error() :: {module(), err_desc()}. -type warning() :: {module(), term()}. @@ -116,7 +117,9 @@ format_error({duplicate_var,N,{F,A}}) -> format_error({unbound_var,N,{F,A}}) -> io_lib:format("unbound variable ~s in ~w/~w", [N,F,A]); format_error({undefined_function,{F1,A1},{F2,A2}}) -> - io_lib:format("undefined function ~w/~w in ~w/~w", [F1,A1,F2,A2]). + io_lib:format("undefined function ~w/~w in ~w/~w", [F1,A1,F2,A2]); +format_error({tail_segment_not_at_end,{F,A}}) -> + io_lib:format("binary tail segment not at end in ~w/~w", [F,A]). -type ret() :: {'ok', [{module(), [warning(),...]}]} | {'error', [{module(), [error(),...]}], @@ -450,7 +453,8 @@ pattern(#c_cons{hd=H,tl=T}, Def, Ps, St) -> pattern_list([H,T], Def, Ps, St); pattern(#c_tuple{es=Es}, Def, Ps, St) -> pattern_list(Es, Def, Ps, St); -pattern(#c_binary{segments=Ss}, Def, Ps, St) -> +pattern(#c_binary{segments=Ss}, Def, Ps, St0) -> + St = pat_bin_tail_check(Ss, St0), pat_bin(Ss, Def, Ps, St); pattern(#c_alias{var=V,pat=P}, Def, Ps, St0) -> {Vvs,St1} = variable(V, Ps, St0), @@ -482,6 +486,19 @@ pat_segment(#c_bitstr{val=V,size=S,type=T}, Def0, Ps0, St0) -> pat_segment(_, Def, Ps, St) -> {Ps,Def,add_error({not_bs_pattern,St#lint.func}, St)}. +%% pat_bin_tail_check([Elem], State) -> State. +%% There must be at most one tail segment (a size-less segment of +%% type binary) and it must occur at the end. + +pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}], St) -> + %% Size-less field is OK at the end of the list of segments. + St; +pat_bin_tail_check([#c_bitstr{size=#c_literal{val=all}}|_], St) -> + add_error({tail_segment_not_at_end,St#lint.func}, St); +pat_bin_tail_check([_|Ss], St) -> + pat_bin_tail_check(Ss, St); +pat_bin_tail_check([], St) -> St. + %% pat_bit_expr(SizePat, Type, Defined, State) -> State. %% Check the Size pattern, this is an input! Because of optimizations, %% we must allow any kind of constant and literal here. diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 948937c438..77da6c8d00 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -1523,7 +1523,9 @@ cg_binary_size_1([], Bits, Acc) -> [{1,_}|_] -> {bs_init_bits,cg_binary_bytes_to_bits(Sizes, [])}; [{8,_}|_] -> - {bs_init2,[E || {8,E} <- Sizes]} + {bs_init2,[E || {8,E} <- Sizes]}; + [] -> + {bs_init_bits,[]} end. cg_binary_size_2({integer,N}, U, _, Next, Bits, Acc) -> diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index f6bb45787c..2da24b2908 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -892,25 +892,22 @@ lc_tq(Line, E, [{generate,Lg,P,G}|Qs0], Mc, St0) -> lc_tq(Line, E, [{b_generate,Lg,P,G}|Qs0], Mc, St0) -> {Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0), {Name,St1} = new_fun_name("blc", St0), - {Tname,St2} = new_var_name(St1), - LA = lineno_anno(Line, St2), + LA = lineno_anno(Line, St1), LAnno = #a{anno=LA}, - HeadBinPattern = pattern(P,St2), - #c_binary{segments=Ps} = HeadBinPattern, - {EPs,St3} = emasculate_segments(Ps,St2), - Tail = #c_var{anno=LA,name=Tname}, - TailSegment = #c_bitstr{val=Tail,size=#c_literal{val=all}, - unit=#c_literal{val=1}, - type=#c_literal{val=binary}, - flags=#c_literal{val=[big,unsigned]}}, - Pattern = HeadBinPattern#c_binary{segments=Ps ++ [TailSegment]}, - EPattern = HeadBinPattern#c_binary{segments=EPs ++ [TailSegment]}, + HeadBinPattern = pattern(P, St1), + #c_binary{segments=Ps0} = HeadBinPattern, + {Ps,Tail,St2} = append_tail_segment(Ps0, St1), + {EPs,St3} = emasculate_segments(Ps, St2), + Pattern = HeadBinPattern#c_binary{segments=Ps}, + EPattern = HeadBinPattern#c_binary{segments=EPs}, {Arg,St4} = new_var(St3), {Guardc,St5} = lc_guard_tests(Gs, St4), %These are always flat! + Tname = Tail#c_var.name, {Nc,[],St6} = expr({call,Lg,{atom,Lg,Name},[{var,Lg,Tname}]}, St5), {Bc,Bps,St7} = lc_tq(Line, E, Qs1, Nc, St6), {Gc,Gps,St10} = safe(G, St7), %Will be a function argument! Fc = function_clause([Arg], LA, {Name,1}), + {TailSegList,_,St} = append_tail_segment([], St10), Cs = [#iclause{anno=#a{anno=[compiler_generated|LA]}, pats=[Pattern], guard=Guardc, @@ -922,14 +919,14 @@ lc_tq(Line, E, [{b_generate,Lg,P,G}|Qs0], Mc, St0) -> op=#c_var{anno=LA,name={Name,1}}, args=[Tail]}]}, #iclause{anno=LAnno, - pats=[#c_binary{anno=LA, segments=[TailSegment]}],guard=[], + pats=[#c_binary{anno=LA,segments=TailSegList}],guard=[], body=[Mc]}], Fun = #ifun{anno=LAnno,id=[],vars=[Arg],clauses=Cs,fc=Fc}, {#iletrec{anno=LAnno,defs=[{{Name,1},Fun}], body=Gps ++ [#iapply{anno=LAnno, op=#c_var{anno=LA,name={Name,1}}, args=[Gc]}]}, - [],St10}; + [],St}; lc_tq(Line, E, [Fil0|Qs0], Mc, St0) -> %% Special case sequences guard tests. LA = lineno_anno(Line, St0), @@ -1037,26 +1034,24 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) -> {Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0), {Name,St1} = new_fun_name("lbc", St0), LA = lineno_anno(Line, St1), - {[Tail,AccVar],St2} = new_vars(LA, 2, St1), + {AccVar,St2} = new_var(LA, St1), LAnno = #a{anno=LA}, HeadBinPattern = pattern(P, St2), - #c_binary{segments=Ps} = HeadBinPattern, - {EPs,St3} = emasculate_segments(Ps, St2), - TailSegment = #c_bitstr{val=Tail,size=#c_literal{val=all}, - unit=#c_literal{val=1}, - type=#c_literal{val=binary}, - flags=#c_literal{val=[big,unsigned]}}, - Pattern = HeadBinPattern#c_binary{segments=Ps ++ [TailSegment]}, - EPattern = HeadBinPattern#c_binary{segments=EPs ++ [TailSegment]}, - {Arg,St4} = new_var(St3), + #c_binary{segments=Ps0} = HeadBinPattern, + {Ps,Tail,St3} = append_tail_segment(Ps0, St2), + {EPs,St4} = emasculate_segments(Ps, St3), + Pattern = HeadBinPattern#c_binary{segments=Ps}, + EPattern = HeadBinPattern#c_binary{segments=EPs}, + {Arg,St5} = new_var(St4), NewMore = {call,Lg,{atom,Lg,Name},[{var,Lg,Tail#c_var.name}, {var,Lg,AccVar#c_var.name}]}, - {Guardc,St5} = lc_guard_tests(Gs, St4), %These are always flat! - {Bc,Bps,St6} = bc_tq1(Line, E, Qs1, AccVar, St5), - {Nc,Nps,St7} = expr(NewMore, St6), - {Gc,Gps,St8} = safe(G, St7), %Will be a function argument! + {Guardc,St6} = lc_guard_tests(Gs, St5), %These are always flat! + {Bc,Bps,St7} = bc_tq1(Line, E, Qs1, AccVar, St6), + {Nc,Nps,St8} = expr(NewMore, St7), + {Gc,Gps,St9} = safe(G, St8), %Will be a function argument! Fc = function_clause([Arg,AccVar], LA, {Name,2}), Body = Bps ++ Nps ++ [#iset{var=AccVar,arg=Bc},Nc], + {TailSegList,_,St} = append_tail_segment([], St9), Cs = [#iclause{anno=LAnno, pats=[Pattern,AccVar], guard=Guardc, @@ -1066,7 +1061,7 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) -> guard=[], body=Nps ++ [Nc]}, #iclause{anno=LAnno, - pats=[#c_binary{anno=LA,segments=[TailSegment]},AccVar], + pats=[#c_binary{anno=LA,segments=TailSegList},AccVar], guard=[], body=[AccVar]}], Fun = #ifun{anno=LAnno,id=[],vars=[Arg,AccVar],clauses=Cs,fc=Fc}, @@ -1074,7 +1069,7 @@ bc_tq1(Line, E, [{b_generate,Lg,P,G}|Qs0], AccExpr, St0) -> body=Gps ++ [#iapply{anno=LAnno, op=#c_var{anno=LA,name={Name,2}}, args=[Gc,AccExpr]}]}, - [],St8}; + [],St}; bc_tq1(Line, E, [Fil0|Qs0], AccVar, St0) -> %% Special case sequences guard tests. LA = lineno_anno(Line, St0), @@ -1120,6 +1115,29 @@ bc_tq1(_, {bin,Bl,Elements}, [], AccVar, St0) -> %%Anno = Anno0#a{anno=[compiler_generated|A]}, {set_anno(E, Anno),Pre,St}. +append_tail_segment(Segs, St) -> + app_tail_seg(Segs, St, []). + +app_tail_seg([#c_bitstr{val=Var0,size=#c_literal{val=all}}=Seg0]=L, + St0, Acc) -> + case Var0 of + #c_var{name='_'} -> + {Var,St} = new_var(St0), + Seg = Seg0#c_bitstr{val=Var}, + {reverse(Acc, [Seg]),Var,St}; + #c_var{} -> + {reverse(Acc, L),Var0,St0} + end; +app_tail_seg([H|T], St, Acc) -> + app_tail_seg(T, St, [H|Acc]); +app_tail_seg([], St0, Acc) -> + {Var,St} = new_var(St0), + Tail = #c_bitstr{val=Var,size=#c_literal{val=all}, + unit=#c_literal{val=1}, + type=#c_literal{val=binary}, + flags=#c_literal{val=[unsigned,big]}}, + {reverse(Acc, [Tail]),Var,St}. + emasculate_segments(Segs, St) -> emasculate_segments(Segs, St, []). diff --git a/lib/compiler/test/bs_bincomp_SUITE.erl b/lib/compiler/test/bs_bincomp_SUITE.erl index a64a5d590b..74f69893af 100644 --- a/lib/compiler/test/bs_bincomp_SUITE.erl +++ b/lib/compiler/test/bs_bincomp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. +%% Copyright Ericsson AB 2006-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 @@ -24,7 +24,7 @@ -export([all/1, byte_aligned/1,bit_aligned/1,extended_byte_aligned/1, extended_bit_aligned/1,mixed/1,filters/1,trim_coverage/1, - nomatch/1,sizes/1]). + nomatch/1,sizes/1,tail/1]). -include("test_server.hrl"). @@ -32,7 +32,7 @@ all(suite) -> test_lib:recompile(?MODULE), [byte_aligned,bit_aligned,extended_byte_aligned, extended_bit_aligned,mixed,filters,trim_coverage, - nomatch,sizes]. + nomatch,sizes,tail]. byte_aligned(Config) when is_list(Config) -> @@ -270,6 +270,38 @@ sizes(Config) when is_list(Config) -> ?line cs_end(), ok. +tail(Config) when is_list(Config) -> + ?line [] = tail_1(<<0:7>>), + ?line [0] = tail_1(<<0>>), + ?line [0] = tail_1(<<0:12>>), + ?line [0,0] = tail_1(<<0:20>>), + + ?line [] = tail_2(<<0:7>>), + ?line [42] = tail_2(<<0>>), + ?line [] = tail_2(<<0:12>>), + ?line [42,42] = tail_2(<<0,1>>), + + ?line <<>> = tail_3(<<0:7>>), + ?line <<42>> = tail_3(<<0>>), + ?line <<42>> = tail_3(<<0:12>>), + ?line <<42,42>> = tail_3(<<0:20>>), + + ?line [] = tail_4(<<0:15>>), + ?line [7] = tail_4(<<7,8>>), + ?line [9] = tail_4(<<9,17:12>>), + ok. + +tail_1(Bits) -> + [X || <<X:8/integer, _/bits>> <= Bits]. + +tail_2(Bits) -> + [42 || <<_:8/integer, _/bytes>> <= Bits]. + +tail_3(Bits) -> + << <<42>> || <<_:8/integer, _/bits>> <= Bits >>. + +tail_4(Bits) -> + [X || <<X:8/integer, Tail/bits>> <= Bits, bit_size(Tail) >= 8]. cs_init() -> diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl index 1862a28bbe..dfe4301791 100644 --- a/lib/compiler/test/bs_construct_SUITE.erl +++ b/lib/compiler/test/bs_construct_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -66,6 +66,8 @@ id(I) -> I. l(I_13, I_big1, I_16, Bin) -> [ + ?T(<<I_13:0>>, + []), ?T(<<-43>>, [256-43]), ?T(<<4:4,7:4>>, diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl index 9c06740816..935e384d2d 100644 --- a/lib/compiler/test/compilation_SUITE.erl +++ b/lib/compiler/test/compilation_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -46,7 +46,7 @@ all(suite) -> trycatch_4, opt_crash, otp_5404,otp_5436,otp_5481,otp_5553,otp_5632, otp_5714,otp_5872,otp_6121,otp_6121a,otp_6121b, - otp_7202,otp_7345,on_load,string_table + otp_7202,otp_7345,on_load,string_table,otp_8949_a,otp_8949_a ]. -define(comp(N), @@ -606,5 +606,45 @@ string_table(Config) when is_list(Config) -> ?line {"StrT", <<"stringabletringtable">>} = StringTableChunk, ok. +otp_8949_a(Config) when is_list(Config) -> + value = otp_8949_a(), + ok. + +-record(cs, {exs,keys = [],flags = 1}). +-record(exs, {children = []}). + +otp_8949_a() -> + case id([#cs{}]) of + [#cs{}=Cs] -> + SomeVar = id(value), + if + Cs#cs.flags band 1 =/= 0 -> + id(SomeVar); + (((Cs#cs.exs)#exs.children /= []) + and + (Cs#cs.flags band (1 bsl 0 bor (1 bsl 22)) == 0)); + Cs#cs.flags band (1 bsl 22) =/= 0 -> + ok + end + end. + +otp_8949_b(Config) when is_list(Config) -> + self() ! something, + ?line value = otp_8949_b([], false), + ?line {'EXIT',_} = (catch otp_8949_b([], true)), + ok. + +%% Would cause an endless loop in beam_utils. +otp_8949_b(A, B) -> + Var = id(value), + if + A == [], B == false -> + ok + end, + receive + something -> + id(Var) + end. + id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index fca3f0387b..2a592dd669 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -21,7 +21,7 @@ -module(receive_SUITE). -export([all/1,init_per_testcase/2,fin_per_testcase/2, - recv/1,coverage/1,otp_7980/1,ref_opt/1]). + recv/1,coverage/1,otp_7980/1,ref_opt/1,export/1]). -include("test_server.hrl"). @@ -36,7 +36,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), - [recv,coverage,otp_7980,ref_opt]. + [recv,coverage,otp_7980,ref_opt,export]. -record(state, {ena = true}). @@ -205,4 +205,25 @@ collect_recv_opt_instrs(Code) -> end] || {function,_,_,_,Is} <- Code], lists:append(L). +export(Config) when is_list(Config) -> + Ref = make_ref(), + ?line self() ! {result,Ref,42}, + ?line 42 = export_1(Ref), + ?line {error,timeout} = export_1(Ref), + ok. + +export_1(Reference) -> + id(Reference), + receive + {result,Reference,Result} -> + Result + after 1 -> + Result = {error,timeout} + end, + %% Result ({x,1}) is used, but not the return value ({x,0}) + %% of the receive. Used to be incorrectly optimized + %% by beam_block. + id({build,self()}), + Result. + id(I) -> I. diff --git a/lib/cosFileTransfer/test/Makefile b/lib/cosFileTransfer/test/Makefile new file mode 100644 index 0000000000..60f72644bd --- /dev/null +++ b/lib/cosFileTransfer/test/Makefile @@ -0,0 +1,132 @@ +# +# %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% +# +# +include $(ERL_TOP)/make/target.mk +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSFILETRANSFER_VSN) +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/cosFileTransfer_test + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +TEST_SPEC_FILE = cosFileTransfer.spec + + +IDL_FILES = + +IDLOUTDIR = idl_output + +MODULES = \ + fileTransfer_SUITE \ + +GEN_MODULES = \ + +GEN_HRL_FILES = \ + +ERL_FILES = $(MODULES:%=%.erl) + +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 +# ---------------------------------------------------- +LOCAL_CLASSPATH = $(ERL_TOP)lib/cosFileTransfer/priv:$(ERL_TOP)lib/cosFileTransfer/test +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/src \ + -pa $(ERL_TOP)/lib/cosFileTransfer/include \ + -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -pa $(ERL_TOP)/lib/orber/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin + +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/ebin \ + -pa $(ERL_TOP)/lib/cosFileTransfer/include \ + -pa $(ERL_TOP)/lib/cosFileTransfer/test/idl_output \ + -I$(ERL_TOP)/lib/orber/include \ + -I$(ERL_TOP)/lib/cosProperty/include \ + -I$(ERL_TOP)/lib/cosFileTransfer/src \ + -I$(ERL_TOP)/lib/cosFileTransfer/include \ + -I$(ERL_TOP)/lib/cosFileTransfer \ + -I$(ERL_TOP)/lib/cosFileTransfer/test/$(IDLOUTDIR) \ + -I$(ERL_TOP)/lib/test_server/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + + +tests debug opt: $(TARGET_FILES) + +clean: + rm -f idl_output/* + rm -f $(TARGET_FILES) + rm -f errs core *~ + +docs: + +# ---------------------------------------------------- +# Special Targets +# ---------------------------------------------------- + +# ---------------------------------------------------- +# Release Targets +# ---------------------------------------------------- +# We don't copy generated intermediate erlang and hrl files + +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: + +release_docs_spec: + +release_tests_spec: tests + $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ + $(ERL_FILES) $(RELSYSDIR) + $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + chmod -f -R u+w $(RELSYSDIR) diff --git a/lib/cosFileTransfer/test/cosFileTransfer.spec b/lib/cosFileTransfer/test/cosFileTransfer.spec new file mode 100644 index 0000000000..80fe919f2a --- /dev/null +++ b/lib/cosFileTransfer/test/cosFileTransfer.spec @@ -0,0 +1 @@ +{topcase, {dir, "../cosFileTransfer_test"}}. diff --git a/lib/cosFileTransfer/test/fileTransfer_SUITE.erl b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl new file mode 100644 index 0000000000..f877e3ceda --- /dev/null +++ b/lib/cosFileTransfer/test/fileTransfer_SUITE.erl @@ -0,0 +1,954 @@ +%%----------------------------------------------------------------------- +%% +%% %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% +%% +%% +%%---------------------------------------------------------------------- +%% File : fileTransfer_SUITE.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(fileTransfer_SUITE). + + + +%%--------------- INCLUDES ----------------------------------- +-include_lib("cosFileTransfer/src/cosFileTransferApp.hrl"). + +-include("test_server.hrl"). + +%%--------------- DEFINES ------------------------------------ +-define(default_timeout, ?t:minutes(20)). +-define(match(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT ------~n~p~n", + [AcTuAlReS]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + +-define(matchnopr(ExpectedRes, Expr), + fun() -> + AcTuAlReS = (catch (Expr)), + case AcTuAlReS of + ExpectedRes -> + io:format("------ CORRECT RESULT (~p) ------~n", [?LINE]), + AcTuAlReS; + _ -> + io:format("###### ERROR ERROR ######~n~p~n", + [AcTuAlReS]), + exit(AcTuAlReS) + end + end()). + + + + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([all/1, + cases/0, + init_all/1, + finish_all/1, + fileIterator_api/1, + fts_ftp_file_api/1, + fts_ftp_file_ssl_api/1, + fts_ftp_dir_api/1, + fts_native_file_api/1, + fts_native_file_ssl_api/1, + fts_native_dir_api/1, + init_per_testcase/2, + fin_per_testcase/2, + install_data/2, + uninstall_data/1, + slave_sup/0, + app_test/1]). + +%%----------------------------------------------------------------- +%% Func: all/1 +%% Args: +%% Returns: +%%----------------------------------------------------------------- +all(doc) -> ["API tests for the cosFileTransfer interfaces", ""]; +all(suite) -> {req, + [mnesia, orber], + {conf, init_all, cases(), finish_all}}. + +cases() -> + [fts_ftp_dir_api, fts_ftp_file_api, fts_ftp_file_ssl_api, + fts_native_dir_api, fts_native_file_api, fts_native_file_ssl_api, + fileIterator_api, app_test]. + +%%----------------------------------------------------------------- +%% Init and cleanup functions. +%%----------------------------------------------------------------- + +init_per_testcase(_Case, Config) -> + ?line Dog=test_server:timetrap(?default_timeout), + [{watchdog, Dog}|Config]. + + +fin_per_testcase(_Case, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog), + ok. + +init_all(Config) -> + orber:jump_start(), + cosProperty:install(), + cosProperty:start(), + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + %% Client + cosFileTransferApp:configure(ssl_client_certfile, + filename:join([Dir, "client", "cert.pem"])), + cosFileTransferApp:configure(ssl_client_cacertfile, + filename:join([Dir, "client", "cacerts.pem"])), + cosFileTransferApp:configure(ssl_client_verify, 1), + cosFileTransferApp:configure(ssl_client_depth, 0), + %% Server + cosFileTransferApp:configure(ssl_server_certfile, + filename:join([Dir, "server", "cert.pem"])), + cosFileTransferApp:configure(ssl_server_cacertfile, + filename:join([Dir, "server", "cacerts.pem"])), + cosFileTransferApp:configure(ssl_server_verify, 1), + cosFileTransferApp:configure(ssl_server_depth, 0), + crypto:start(), + ssl:start(), + cosFileTransferApp:install(), + cosFileTransferApp:start(), + if + is_list(Config) -> + Config; + true -> + exit("Config not a list") + end. + +finish_all(Config) -> + ssl:stop(), + crypto:stop(), + cosFileTransferApp:stop(), + cosProperty:stop(), + cosProperty:uninstall(), + cosFileTransferApp:uninstall(), + orber:jump_stop(), + Config. + +%%----------------------------------------------------------------- +%% Local definitions +%%----------------------------------------------------------------- +-define(FTP_USER, "anonymous"). +-define(FTP_PASS, "fileTransfer_SUITE@localhost"). +-define(TEST_DIR,["/", "incoming"]). + + +-define(FTP_PORT, 21). +-define(FTP_ACC, "anonymous"). + +-define(BAD_HOST, "badhostname"). +-define(BAD_USER, "baduser"). +-define(BAD_DIR, "baddirectory"). + +-define(TEST_FILE_DATA, "If this file exists after a completed test an error occurred."). +-define(TEST_FILE_DATA2, "1234567890123"). + + +%%----------------------------------------------------------------- +%% aoo-file test +%%----------------------------------------------------------------- +app_test(doc) -> []; +app_test(suite) -> []; +app_test(_Config) -> + ?line ok=?t:app_test(cosFileTransfer), + ok. + +%%----------------------------------------------------------------- +%% FileIterator API tests +%%----------------------------------------------------------------- +fileIterator_api(doc) -> ["CosFileTransfer FileIterator API tests.", ""]; +fileIterator_api(suite) -> []; +fileIterator_api(Config) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + + ?line {ok, Node} = create_node("fileIterator_api", 4008, normal), + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [tcp, {{'NATIVE', + 'cosFileTransferNATIVE_file'}, Host, + "fileIterator_api"}])), + + %% Create a Virtual File System. +%% ?line VFS = ?match({_,_,_,_,_,_}, +%% cosFileTransferApp:create_VFS({'NATIVE', +%% 'cosFileTransferNATIVE_file'}, +%% [], Host, ?FTP_PORT)), + ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:4008/NameService#fileIterator_api")), + + %% Start two File Transfer Sessions (Source and Target). + ?line {FS, Dir} = ?matchnopr({{_,_,_},{_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(Dir)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(Dir)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(Dir)), + ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(Dir)), + {ok,[],FileIter} = ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir, 0)), + %% Usually the working directory for the test is not empty so no need for + %% creating files of our own?! + #any{value=Children} = ?match({any, _, _}, + 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + + if + Children > 5 -> + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)), + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, 3)), + ?line ?matchnopr({true, _}, 'CosFileTransfer_FileIterator':next_n(FileIter, + Children)), + ?line ?matchnopr({false, _}, 'CosFileTransfer_FileIterator':next_one(FileIter)), + ?line ?match({false, []}, 'CosFileTransfer_FileIterator':next_n(FileIter, 1)), + ok; + true -> + ok + end, + ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(FileIter)), + ?line ?match(false, corba_object:non_existent(FS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(1000), + ?line ?match(true, corba_object:non_existent(FS)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, ["fileIterator_api"])), + stop_orber_remote(Node, normal), + ok + end. + + +%%----------------------------------------------------------------- +%% FileTransferSession API tests +%%----------------------------------------------------------------- +fts_ftp_file_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_file_api(suite) -> []; +fts_ftp_file_api(Config) -> + ?line {ok, Node} = create_node("ftp_file_api", 4004, normal), + file_helper(Config, 'FTP', ?TEST_DIR, Node, 4004, "ftp_file_api", tcp). + +fts_ftp_file_ssl_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_file_ssl_api(suite) -> []; +fts_ftp_file_ssl_api(Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ?line {ok, Node} = create_node("ftp_file_api_ssl", {4005, 1}, ssl), + file_helper(Config, 'FTP', ?TEST_DIR, Node, 4005, "ftp_file_api_ssl", ssl) + end. + +fts_native_file_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_file_api(suite) -> []; +fts_native_file_api(Config) -> + ?line {ok, Node} = create_node("native_file_api", 4006, normal), + {ok, Pwd} = file:get_cwd(), + file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd), + Node, 4006, "native_file_api", tcp). + +fts_native_file_ssl_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_file_ssl_api(suite) -> []; +fts_native_file_ssl_api(Config) -> + case os:type() of + vxworks -> + {skipped, "No SSL-support for VxWorks."}; + _ -> + ?line {ok, Node} = create_node("native_file_ssl_api", {4007, 1}, ssl), + {ok, Pwd} = file:get_cwd(), + file_helper(Config,{'NATIVE', 'cosFileTransferNATIVE_file'},filename:split(Pwd), + Node, 4007, "native_file_ssl_api", ssl) + end. + + + +file_helper(Config, WhichType, TEST_DIR, Node, Port, Name, Type) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + TEST_SOURCE = TEST_DIR ++ [create_name(remove_me_source)], + TEST_SOURCE2 = TEST_DIR ++ [create_name(remove_me_source)], + TEST_TARGET = TEST_DIR ++ [create_name(remove_me_target)], + + io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]), + io:format("Source: ~p~nTarget: ~p~n", [TEST_SOURCE, TEST_TARGET]), + + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [Type, {WhichType, Host, Name}])), + + ?line VFST = ?match({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)), + + + %% Create a Virtual File System. + ?line VFS = ?match({_,_,_,_,_,_}, + cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT, + [{protocol, Type}])), + %% Start two File Transfer Sessions (Source and Target). + ?line {FST, _DirT} = ?match({{_,_,_},{_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFST, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + ?line {FSS, DirS} = ?match({{_,_,_,_,_,_},{_,_,_,_,_,_}}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)), + ?line ?match(FSS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)), + + %% Get a FileList before we create any new Files + ?line #'CosFileTransfer_FileWrapper'{the_file = Dir} = + ?match({'CosFileTransfer_FileWrapper', _, ndirectory}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_DIR)), + ?line {ok,FileList, Iter1} = ?match({ok,_,_}, 'CosFileTransfer_Directory':list(Dir, 10)), + ?line loop_files(FileList), + + case Iter1 of + {'IOP_IOR',[],[]} -> + ok; + _-> + ?line ?match(ok, 'CosFileTransfer_FileIterator':destroy(Iter1)) + end, + + #any{value=Count1} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + + %% Now we want to transfer a file from source to target. First, we'll create + %% a a file to work with. + ?line create_file_on_source_node(WhichType, Config, Host, + filename:join(TEST_SOURCE), TEST_DIR, + ?TEST_FILE_DATA), + ?line create_file_on_source_node(WhichType, Config, Host, + filename:join(TEST_SOURCE2), TEST_DIR, + ?TEST_FILE_DATA2), + + ?line #'CosFileTransfer_FileWrapper'{the_file = FileS} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE)), + ?line #'CosFileTransfer_FileWrapper'{the_file = FileS2} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, nfile}, + 'CosFileTransfer_FileTransferSession':get_file(FSS, TEST_SOURCE2)), + + #any{value=Count2} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + timer:sleep(2000), + ?match(true, (Count1+2 == Count2)), + + %% Create a target File + ?line FileT = ?matchnopr({_,_,_}, + 'CosFileTransfer_FileTransferSession':create_file(FST, TEST_TARGET)), + %% Try to delete the non-existing file. + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_FileTransferSession':delete(FST, FileT)), + + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':transfer(FSS, FileS, FileT)), + + %% Remove this test when ftp supports append. + case WhichType of + {'NATIVE', 'cosFileTransferNATIVE_file'} -> + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':append(FSS, FileS, FileT)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':insert(FSS, FileS2, FileT, 7)); + _-> + ok + end, + + %% Delete source and target files + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FSS, FileS2)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FST, FileT)), + + %% Should be back where we started. + timer:sleep(2000), + #any{value=Count3} = ?match({any, _, _}, 'CosPropertyService_PropertySet': + get_property_value(Dir, "num_children")), + ?match(true, (Count1 == Count3)), + + + ?line ?match(false, corba_object:non_existent(FSS)), + ?line ?match(false, corba_object:non_existent(FST)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FSS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FST)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(2000), + ?line ?match(true, corba_object:non_existent(FSS)), + ?line ?match(true, corba_object:non_existent(FST)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])), + stop_orber_remote(Node, normal), + ok + end. + +%%----------------------------------------------------------------- +%% FileTransferSession API tests +%%----------------------------------------------------------------- +fts_ftp_dir_api(doc) -> ["CosFileTransfer FTP FileTransferSession API tests.", ""]; +fts_ftp_dir_api(suite) -> []; +fts_ftp_dir_api(Config) -> + ?line {ok, Node} = create_node("ftp_dir_api", 4009, normal), + dir_helper(Config, 'FTP', ?TEST_DIR, Node, 4009, "ftp_dir_api"). + + +fts_native_dir_api(doc) -> ["CosFileTransfer NATIVE FileTransferSession API tests.", ""]; +fts_native_dir_api(suite) -> []; +fts_native_dir_api(Config) -> + ?line {ok, Node} = create_node("native_dir_api", 4010, normal), + {ok, Pwd} = file:get_cwd(), + dir_helper(Config, {'NATIVE', 'cosFileTransferNATIVE_file'}, + filename:split(Pwd), Node, 4010, "native_dir_api"). + +dir_helper(Config, WhichType, TEST_DIR, Node, Port, Name) -> + case ftp_host(Config) of + {skipped, SkippedReason} -> + {skipped, SkippedReason}; + Host -> + TEST_DIR_LEVEL1 = TEST_DIR ++ [create_name(remove_me_dir1)], + TEST_DIR_LEVEL2 = TEST_DIR_LEVEL1 ++ [create_name(remove_me_dir2)], + + io:format("<<<<<< CosFileTransfer Testing Configuration >>>>>>~n",[]), + io:format("Top Dir: ~p~nLevel2 Dir: ~p~n", [TEST_DIR_LEVEL1, TEST_DIR_LEVEL2]), + + ?line ?match(ok, remote_apply(Node, ?MODULE, install_data, + [tcp, {WhichType, Host, Name}])), + + ?line VFS = ?matchnopr({'IOP_IOR',"IDL:omg.org/CosFileTransfer/VirtualFileSystem:1.0",_}, + corba:string_to_object("corbaname::1.2@localhost:"++integer_to_list(Port)++"/NameService#"++Name)), + + %% Start two File Transfer Sessions (Source and Target). + ?line {FS, DirS} = ?matchnopr({{'IOP_IOR',_,_}, _}, + 'CosFileTransfer_VirtualFileSystem':login(VFS, + ?FTP_USER, + ?FTP_PASS, + ?FTP_ACC)), + + %% Do some basic test on one of the Directories attributes. + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_name'(DirS)), + ?line ?match([_H|_], 'CosFileTransfer_Directory':'_get_complete_file_name'(DirS)), + ?line ?match({'IOP_IOR',[],[]}, 'CosFileTransfer_Directory':'_get_parent'(DirS)), + ?line ?matchnopr(FS, 'CosFileTransfer_Directory':'_get_associated_session'(DirS)), + + %% Create a Root Directory. Currently we only need to create one but + %% later on, when supporting other protocols than FTP it's not enough. + ?line Dir1 = 'CosFileTransfer_FileTransferSession':create_directory(FS, + TEST_DIR_LEVEL1), + io:format("<<<<<< CosFileTransfer Testing Properties >>>>>>~n",[]), + ?line ?match({ok, [tk_long, tk_boolean]}, + 'CosFileTransfer_Directory':get_allowed_property_types(Dir1)), + ?line ?match({ok, [_,_]}, + 'CosFileTransfer_Directory':get_allowed_properties(Dir1)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_long, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "wrong", + #any{typecode=tk_long, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_short, value=0}, + fixed_readonly)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property_with_mode(Dir1, + "num_children", + #any{typecode=tk_long, value=0}, + fixed_normal)), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_properties_with_modes(Dir1, + [#'CosPropertyService_PropertyDef' + {property_name = "num_children", + property_value = #any{typecode=tk_long, value=0}, + property_mode = fixed_readonly}])), + ?line ?match(fixed_readonly, + 'CosFileTransfer_Directory':get_property_mode(Dir1, "num_children")), + ?line ?match({true, + [#'CosPropertyService_PropertyMode'{property_name = "num_children", + property_mode = fixed_readonly}]}, + 'CosFileTransfer_Directory':get_property_modes(Dir1, ["num_children"])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':set_property_mode(Dir1, "num_children", fixed_readonly)), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "num_children", + property_mode = fixed_readonly}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "wrong", + property_mode = fixed_readonly}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + set_property_modes(Dir1, + [#'CosPropertyService_PropertyMode' + {property_name = "num_children", + property_mode = fixed_normal}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_long, value=0})), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "wrong", + #any{typecode=tk_long, value=0})), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_short, value=0})), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':define_property(Dir1, + "num_children", + #any{typecode=tk_long, value=0})), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "num_children", + property_value = #any{typecode=tk_long, + value=0}}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "wrong", + property_value = #any{typecode=tk_long, + value=0}}])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory': + define_properties(Dir1, + [#'CosPropertyService_Property' + {property_name = "num_children", + property_value = #any{typecode=tk_short, + value=0}}])), + ?line ?match(2, 'CosFileTransfer_Directory':get_number_of_properties(Dir1)), + + ?line ?match({ok, ["num_children", "is_directory"], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_property_names(Dir1, 2)), + ?line ?match({ok, ["is_directory"], _}, + 'CosFileTransfer_Directory':get_all_property_names(Dir1, 1)), + + ?line ?match(#any{}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "num_children")), + ?line ?match(#any{}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "is_directory")), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':get_property_value(Dir1, "wrong")), + + ?line ?match({true, + [#'CosPropertyService_Property'{property_name = "num_children"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])), + ?line ?match({false, + [#'CosPropertyService_Property'{property_name = "wrong"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["wrong"])), + + ?line ?match({ok, [_],_}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)), + ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)), + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_property(Dir1, "num_children")), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_property(Dir1, "wrong")), + + + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_properties(Dir1, ["num_children"])), + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_Directory':delete_properties(Dir1, ["wrong"])), + ?line ?match(false, 'CosFileTransfer_Directory':delete_all_properties(Dir1)), + ?line ?match(true, + 'CosFileTransfer_Directory':is_property_defined(Dir1, "num_children")), + ?line ?match(false, + 'CosFileTransfer_Directory':is_property_defined(Dir1, "wrong")), + + %% The Top Dir should be empty and ... + ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)), + ?line ?match( #any{value=0}, + 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")), + %% Create a sub-directory. + ?line Dir2 = 'CosFileTransfer_FileTransferSession':create_directory(FS, + TEST_DIR_LEVEL2), + ?line ?match( #any{value=1}, + 'CosPropertyService_PropertySet':get_property_value(Dir1, "num_children")), + + ?line ?match({ok, [_,_], {'IOP_IOR',[],[]}}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 2)), + ?line {_,_,Iterator1} = ?match({ok, [_], _}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 1)), + ?line ?match({false, [_]}, + 'CosPropertyService_PropertiesIterator':next_n(Iterator1,4)), + + ?line {_,_,Iterator0} = ?match({ok, [], _}, + 'CosFileTransfer_Directory':get_all_properties(Dir1, 0)), + + ?line ?match({false, [_, {'CosPropertyService_Property', + "num_children",{any,tk_long,1}}]}, + 'CosPropertyService_PropertiesIterator':next_n(Iterator0,4)), + + ?line ?match({true, + [#'CosPropertyService_Property'{property_name = "num_children"}]}, + 'CosFileTransfer_Directory':get_properties(Dir1, ["num_children"])), + + %% The Top Directory is not emtpy any more and ... + ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef}],_} = + ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_}, + 'CosFileTransfer_Directory':list(Dir1, 1000)), + %% ... its name eq. to 'TEST_DIR_LEVEL2' + ?line ?match(TEST_DIR_LEVEL2, + 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef)), + + ?line #'CosFileTransfer_FileWrapper'{the_file = Dir3} = + ?matchnopr({'CosFileTransfer_FileWrapper', _, ndirectory}, + 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)), + + %% Must get the same result for the 'get_file' operation. + ?line {ok,[#'CosFileTransfer_FileWrapper'{the_file = DirRef2}],_} = + ?matchnopr({ok,[{'CosFileTransfer_FileWrapper', _, ndirectory}],_}, + 'CosFileTransfer_Directory':list(Dir3,1000)), + ?line ?match(TEST_DIR_LEVEL2, + 'CosFileTransfer_Directory':'_get_complete_file_name'(DirRef2)), + + %% Since the top directory isn't empty deleting it must fail. + ?line ?match({'EXCEPTION', _}, + 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)), + + %% Delete the sub-directory and ... + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir2)), + %% ... see if the top directory realyy is empty. + ?line ?match({ok,[],_}, 'CosFileTransfer_Directory':list(Dir1, 1000)), + + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':delete(FS, Dir1)), + %% Test if the top directory been removed as intended. + ?line ?match({'EXCEPTION', {'CosFileTransfer_FileNotFoundException', _, _}}, + 'CosFileTransfer_FileTransferSession':get_file(FS, TEST_DIR_LEVEL1)), + + ?line ?match(false, corba_object:non_existent(FS)), + ?line ?match(ok, 'CosFileTransfer_FileTransferSession':logout(FS)), + %% To make sure Orber can remove it from mnesia. + timer:sleep(1000), + ?line ?match(true, corba_object:non_existent(FS)), + ?line ?match(ok, remote_apply(Node, ?MODULE, uninstall_data, [Name])), + stop_orber_remote(Node, normal), + ok + end. + + +%%----------------------------------------------------------------- +%% Internal functions +%%----------------------------------------------------------------- +ftp_host(Config) -> + case ?config(ftp_remote_host, Config) of + undefined -> + {skipped, "The configuration parameter 'ftp_remote_host' not defined."}; + Host -> + Host + end. + +loop_files([]) -> + io:format("@@@ DONE @@@~n", []); +loop_files([#'CosFileTransfer_FileWrapper'{the_file = H}|T]) -> + FullName = 'CosFileTransfer_File':'_get_complete_file_name'(H), + Name = 'CosFileTransfer_File':'_get_name'(H), + io:format("FULL NAME: ~p SHORT NAME: ~p~n", [FullName, Name]), + loop_files(T). + + +create_file_on_source_node('FTP', _Config, Host, FileName, Path, Data) -> + io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]), + io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]), + {ok, Pid} = ?match({ok, _}, inets:start(ftpc, [{host, Host}], stand_alone)), + ?match(ok, ftp:user(Pid, ?FTP_USER, ?FTP_PASS)), + ?match(ok, ftp:cd(Pid, Path)), + ?match(ok, ftp:send_bin(Pid, list_to_binary(Data), FileName)), + ?match(ok, inets:stop(ftpc, Pid)); +create_file_on_source_node({'NATIVE', _}, _Config, Host, FileName, Path, Data) -> + io:format("<<<<<< CosFileTransfer Testing File >>>>>>~n",[]), + io:format("Host: ~p~nPath: ~p~nFile: ~p~n", [Host, Path, FileName]), + ?match(ok, file:write_file(FileName, list_to_binary(Data))). + +create_name(Type) -> + {MSec, Sec, USec} = erlang:now(), + lists:concat([Type,'_',MSec, '_', Sec, '_', USec]). + + + + +%%------------------------------------------------------------ +%% function : create_node/4 +%% Arguments: Name - the name of the new node (atom()) +%% Port - which iiop_port (integer()) +%% Domain - which domain. +%% Type - if /4 used the types defines the extra arguments +%% to be used. +%% Returns : {ok, Node} | {error, _} +%% Effect : Starts a new slave-node with given (optinally) +%% extra arguments. If fails it retries 'Retries' times. +%%------------------------------------------------------------ +create_node(Name, Port, normal) -> + Args = basic_args(Name), + create_node(Name, Port, 10, normal, Args, []); +create_node(Name, {Port, _Depth}, ssl) -> + Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]), + Args = basic_args(Name), + {ok, Node} = create_node(list_to_atom(Name), Port, 10, ssl, Args, []), + %% Client + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_certfile, + filename:join([Dir, "client", "cert.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_cacertfile, + filename:join([Dir, "client", "cacerts.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_keyfile, + filename:join([Dir, "client", "key.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_verify, 1]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_client_depth, 0]), + + %% Server + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_certfile, + filename:join([Dir, "server", "cert.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_cacertfile, + filename:join([Dir, "server", "cacerts.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_keyfile, + filename:join([Dir, "server", "key.pem"])]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_verify, 1]), + rpc:call(Node, application, set_env, [cosFileTransfer, ssl_server_depth, 0]), + {ok, Node}. + +%create_node(Name, {Port, Depth}, ssl) -> +% TestLibs = filename:join(filename:dirname(code:which(?MODULE)), "ssl_data"), +% Args = basic_args(Name), +% SArgs = basic_ssl_args(TestLibs, Args), +% LArgs = level_based_ssl(Depth, TestLibs, SArgs), +% create_node(list_to_atom(Name), Port, 10, ssl, LArgs, [{sslpath, TestLibs}]). + +create_node(Name, Port, Retries, Type, Args, Options) -> + [_, Host] = ?match([_,_],string:tokens(atom_to_list(node()), [$@])), + case starter(Host, Name, Args) of + {ok, NewNode} -> + ?line ?match(pong, net_adm:ping(NewNode)), + {ok, Cwd} = file:get_cwd(), + Path = code:get_path(), + ?line ?match(ok, rpc:call(NewNode, file, set_cwd, [Cwd])), + true = rpc:call(NewNode, code, set_path, [Path]), + ?match(ok, start_orber_remote(NewNode, Type, Options, Port)), + spawn_link(NewNode, ?MODULE, slave_sup, []), + rpc:multicall([node() | nodes()], global, sync, []), + {ok, NewNode}; + {error, Reason} when Retries == 0-> + {error, Reason}; + {error, Reason} -> + io:format("Could not start slavenode ~p ~p retrying~n", + [{Host, Name, Args}, Reason]), + timer:sleep(500), + create_node(Name, Port, Retries - 1, Type, Args, Options) + end. + +starter(Host, Name, Args) -> + case os:type() of + vxworks -> + test_server:start_node(Name, slave, [{args,Args}]); + _ -> + slave:start(Host, Name, Args) + end. + +slave_sup() -> + process_flag(trap_exit, true), + receive + {'EXIT', _, _} -> + case os:type() of + vxworks -> + erlang:halt(); + _ -> + ignore + end + end. + + +%%------------------------------------------------------------ +%% function : destroy_node +%% Arguments: Node - which node to destroy. +%% Type - normal | ssl +%% Returns : +%% Effect : +%%------------------------------------------------------------ +-ifdef(false). +destroy_node(Node, Type) -> + stopper(Node, Type). + +stopper(Node, Type) -> + catch stop_orber_remote(Node, Type), + case os:type() of + vxworks -> + test_server:stop_node(Node); + _ -> + slave:stop(Node) + end. +-endif. + +%%------------------------------------------------------------ +%% function : remote_apply +%% Arguments: N - Node, M - Module, +%% F - Function, A - Arguments (list) +%% Returns : +%% Effect : +%%------------------------------------------------------------ +remote_apply(N, M,F,A) -> + case rpc:call(N, M, F, A) of + {badrpc, Reason} -> + exit(Reason); + Other -> + Other + end. + +%%------------------------------------------------------------ +%% function : stop_orber_remote +%% Arguments: Node - which node to stop orber on. +%% Type - normal | ssl | light | ....... +%% Returns : ok +%% Effect : Stops orber on given node and, if specified, +%% other applications or programs. +%%------------------------------------------------------------ +stop_orber_remote(Node, ssl) -> + rpc:call(Node, ssl, stop, []), + rpc:call(Node, crypto, stop, []), + orb_rpc_blast(Node, ssl); +stop_orber_remote(Node, Type) -> + orb_rpc_blast(Node, Type). + +orb_rpc_blast(Node, _) -> + rpc:call(Node, cosFileTransferApp, stop, []), + rpc:call(Node, cosProperty, stop, []), + rpc:call(Node, cosFileTransferApp, uninstall, []), + rpc:call(Node, cosProperty, uninstall, []), + rpc:call(Node, orber, jump_stop, []). + +%%------------------------------------------------------------ +%% function : start_orber_remote +%% Arguments: Node - which node to start orber on. +%% Type - normal | ssl | light | ....... +%% Returns : ok +%% Effect : Starts orber on given node and, if specified, +%% other applications or programs. +%%------------------------------------------------------------ +start_orber_remote(Node, ssl, _Options, Port) -> + rpc:call(Node, ssl, start, []), + rpc:call(Node, crypto, start, []), + rpc:call(Node, ssl, seed, ["testing"]), + orb_rpc_setup(Node, ssl, Port); +start_orber_remote(Node, Type, _, Port) -> + orb_rpc_setup(Node, Type, Port). + +orb_rpc_setup(Node, _, Port) -> + rpc:call(Node, orber, jump_start, [Port]), + rpc:call(Node, cosProperty, install, []), + rpc:call(Node, cosProperty, start, []), + rpc:call(Node, cosFileTransferApp, install, []). + +%%--------------- MISC FUNCTIONS ----------------------------- +basic_args(_Name) -> + TestLibs = filename:dirname(code:which(?MODULE)), + " -orber orber_debug_level 10" ++ + " -pa " ++ + TestLibs ++ + " -pa " ++ + filename:join(TestLibs, "all_SUITE_data") ++ + " -pa " ++ + filename:dirname(code:which(cosFileTransferApp)). + +-ifdef(false). +basic_ssl_args(TestLibs, Args) -> +% Args ++ +% " -cosFileTransfer ssl_client_certfile \\\"" ++ +% filename:join(TestLibs, "ssl_client_cert.pem") ++ +% "\\\" -cosFileTransfer ssl_server_certfile \\\""++ +% filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"". + + io:format("<<<<<< SSL LIBS ~p >>>>>>~n",[TestLibs]), + NewArgs = Args ++ + " -cosFileTransfer ssl_client_certfile \\\"" ++ + filename:join(TestLibs, "ssl_client_cert.pem") ++ + "\\\" -cosFileTransfer ssl_server_certfile \\\""++ + filename:join(TestLibs, "ssl_server_cert.pem")++"\\\"", + io:format("<<<<<< SSL LIBS ARGS ~p >>>>>>~n",[NewArgs]), + NewArgs. + +level_based_ssl(1, _TestLibs, Args) -> + Args; +level_based_ssl(2, _TestLibs, Args) -> + Args.% ++ +% " -cosFileTransfer ssl_server_depth 2 " ++ +% " -cosFileTransfer ssl_client_depth 2 " ++ +% " -cosFileTransfer ssl_server_verify " ++ +% " -cosFileTransfer ssl_client_verify " ++ +% " -cosFileTransfer ssl_server_cacertfile " ++ +% " -cosFileTransfer ssl_client_cacertfile " ++ + +-endif. + +install_data(Protocol, {WhichType, Host, Name}) -> + io:format("<<<<<< Starting ~p/~p VFS at ~p/~p>>>>>>~n", + [Protocol, WhichType, Host, Name]), + %% Create a Virtual File System. + ?line VFS = ?match({_,_,_,_,_,_}, + cosFileTransferApp:create_VFS(WhichType, [], Host, ?FTP_PORT, + [{protocol, Protocol}])), + NS = corba:resolve_initial_references("NameService"), + NC1 = lname_component:set_id(lname_component:create(), Name), + N = lname:insert_component(lname:create(), 1, NC1), + 'CosNaming_NamingContext':rebind(NS, N, VFS). + +uninstall_data(Name) -> + ?line VFS = ?match({_,_,_,_,_,_}, + corba:string_to_object("corbaname:rir:/NameService#"++Name)), + ?line ?match(ok, corba:dispose(VFS)), + ok. + + + +%%------------------- EOF MODULE----------------------------------- diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml index de5a3e5f4c..04c0c2accd 100644 --- a/lib/cosNotification/doc/src/notes.xml +++ b/lib/cosNotification/doc/src/notes.xml @@ -31,6 +31,46 @@ <file>notes.xml</file> </header> + <section><title>cosNotification 1.1.15</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Switched from using the deprecated regexp to re instead.</p> + <p> + Own Id: OTP-8846</p> + </item> + </list> + </section> + +</section> + +<section> + <title>cosNotification 1.1.14</title> + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Test suites published.</p> + <p> + Own Id: OTP-8543 Aux Id:</p> + </item> + </list> + </section> + + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>Added missing trailing bracket to define in hrl-file.</p> + <p>Own Id: OTP-8489 Aux Id:</p> + </item> + </list> + </section> + </section> + <section> <title>cosNotification 1.1.14</title> <section> @@ -64,15 +104,15 @@ <list type="bulleted"> <item> <p>Removed superfluous VT in the documentation.</p> - <p>Own id: OTP-8353 Aux Id:</p> + <p>Own Id: OTP-8353 Aux Id:</p> </item> <item> <p>Removed superfluous backslash in the documentation.</p> - <p>Own id: OTP-8354 Aux Id:</p> + <p>Own Id: OTP-8354 Aux Id:</p> </item> <item> <p>The documentation EIX file was not generated.</p> - <p>Own id: OTP-8355 Aux Id:</p> + <p>Own Id: OTP-8355 Aux Id:</p> </item> </list> </section> @@ -104,7 +144,7 @@ <item> <p>Obsolete guards, e.g. record vs is_record, has been changed to avoid compiler warnings.</p> - <p>Own id: OTP-7987</p> + <p>Own Id: OTP-7987</p> </item> </list> </section> @@ -118,7 +158,7 @@ <list type="bulleted"> <item> <p>Updated file headers.</p> - <p>Own id: OTP-7837 Aux Id:</p> + <p>Own Id: OTP-7837 Aux Id:</p> </item> </list> </section> @@ -132,7 +172,7 @@ <list type="bulleted"> <item> <p>Documentation source included in open source releases.</p> - <p>Own id: OTP-7595 Aux Id:</p> + <p>Own Id: OTP-7595 Aux Id:</p> </item> </list> </section> @@ -147,7 +187,7 @@ <item> <p>The CosNotification proxy objects ignored the gcLimit option, instead the gcTime value was used.</p> - <p>Own id: OTP-7553 Aux Id:</p> + <p>Own Id: OTP-7553 Aux Id:</p> </item> </list> </section> @@ -161,7 +201,7 @@ <list type="bulleted"> <item> <p>Updated file headers.</p> - <p>Own id: OTP-7011</p> + <p>Own Id: OTP-7011</p> </item> </list> </section> @@ -175,7 +215,7 @@ <list type="bulleted"> <item> <p>The documentation source has been converted from SGML to XML.</p> - <p>Own id: OTP-6754</p> + <p>Own Id: OTP-6754</p> </item> </list> </section> @@ -189,7 +229,7 @@ <list type="bulleted"> <item> <p>Minor Makefile changes.</p> - <p>Own id: OTP-6701</p> + <p>Own Id: OTP-6701</p> </item> </list> </section> @@ -203,7 +243,7 @@ <list type="bulleted"> <item> <p>Removed some unused code.</p> - <p>Own id: OTP-6527</p> + <p>Own Id: OTP-6527</p> </item> </list> </section> @@ -219,7 +259,7 @@ <p>A user can now define the QoS EventReliability to be Persistent. Note, this is only a lightweight version and events will be lost if a proxy is terminated.</p> - <p>Own id: OTP-5923</p> + <p>Own Id: OTP-5923</p> </item> </list> </section> @@ -235,7 +275,7 @@ <p>Possible to configure cosNotification not to type check, by invoking corba_object:is_a/2, supplied IOR:s. When a type check fails, the feedback has been improved.</p> - <p>Own id: OTP-5823 Aux Id: seq10143</p> + <p>Own Id: OTP-5823 Aux Id: seq10143</p> </item> </list> </section> @@ -249,7 +289,7 @@ <list type="bulleted"> <item> <p>The app-file contained duplicated modules.</p> - <p>Own id: OTP-4976</p> + <p>Own Id: OTP-4976</p> </item> </list> </section> @@ -268,7 +308,7 @@ Interface Repository. It is necessary to re-compile all IDL-files and use COS-applications, including Orber, compiled with IC-4.2.</p> - <p>Own id: OTP-4576</p> + <p>Own Id: OTP-4576</p> </item> </list> </section> diff --git a/lib/cosNotification/src/cosNotification_Filter.erl b/lib/cosNotification/src/cosNotification_Filter.erl index dd3b5beb93..7201f7d6e2 100644 --- a/lib/cosNotification/src/cosNotification_Filter.erl +++ b/lib/cosNotification/src/cosNotification_Filter.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -877,9 +877,9 @@ check_wildcard(Types, Which, WC, Domain, Type) -> end, check_types(Types, Which, NewWC). -%% Change '*' to '.*', see regexp:parse/2 documentation. +%% Change '*' to '.*', see re:compile/1 documentation. convert_wildcard([], Acc) -> - case regexp:parse(lists:reverse(Acc)) of + case re:compile(lists:reverse(Acc)) of {ok, Expr} -> Expr; _ -> @@ -900,37 +900,37 @@ match_types(_, _, []) -> false; match_types(Domain, Type, [{domain, WCDomain, Type}|T]) -> L=length(Domain), - case catch regexp:matches(Domain, WCDomain) of - {match, []} -> + case catch re:run(Domain, WCDomain) of + nomatch -> match_types(Domain, Type, T); - {match, [{1, L}]} -> + {match, [{0, L}]} -> true; _-> match_types(Domain, Type, T) end; match_types(Domain, Type, [{type, Domain, WCType}|T]) -> L=length(Type), - case catch regexp:matches(Type, WCType) of - {match, []} -> + case catch re:run(Type, WCType) of + nomatch -> match_types(Domain, Type, T); - {match, [{1, L}]} -> + {match, [{0, L}]} -> true; _-> match_types(Domain, Type, T) end; match_types(Domain, Type, [{both, WCDomain, WCType}|T]) -> L1=length(Domain), - case catch regexp:matches(Domain, WCDomain) of - {match, []} -> + case catch re:run(Domain, WCDomain) of + nomatch -> match_types(Domain, Type, T); - {match, [{1, L1}]} -> + {match, [{0, L1}]} -> L2=length(Type), - case catch regexp:matches(Type, WCType) of - {match, []} -> + case catch re:run(Type, WCType) of + nomatch -> match_types(Domain, Type, T); - {match, [{1, L2}]} -> + {match, [{0, L2}]} -> true; - _-> + _ -> match_types(Domain, Type, T) end; _-> diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk index c03f0ef161..cfd5948dfc 100644 --- a/lib/cosNotification/vsn.mk +++ b/lib/cosNotification/vsn.mk @@ -1 +1 @@ -COSNOTIFICATION_VSN = 1.1.14 +COSNOTIFICATION_VSN = 1.1.15 diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 85614a84c2..92cc2b4dd9 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -126,6 +126,7 @@ static ERL_NIF_TERM des_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a static ERL_NIF_TERM des_ecb_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM des_ede3_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rand_bytes_3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); static ERL_NIF_TERM rand_uniform_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); @@ -194,6 +195,8 @@ static ErlNifFunc nif_funcs[] = { {"des_ecb_crypt", 3, des_ecb_crypt}, {"des_ede3_cbc_crypt", 6, des_ede3_cbc_crypt}, {"aes_cfb_128_crypt", 4, aes_cfb_128_crypt}, + {"aes_ctr_encrypt", 3, aes_ctr_encrypt}, + {"aes_ctr_decrypt", 3, aes_ctr_encrypt}, {"rand_bytes", 1, rand_bytes_1}, {"rand_bytes", 3, rand_bytes_3}, {"rand_uniform_nif", 2, rand_uniform_nif}, @@ -654,6 +657,34 @@ static ERL_NIF_TERM aes_cfb_128_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE return ret; } +/* Common for both encrypt and decrypt +*/ +static ERL_NIF_TERM aes_ctr_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{/* (Key, IVec, Data) */ + ErlNifBinary key, ivec, text; + AES_KEY aes_key; + unsigned char ivec_clone[16]; /* writable copy */ + unsigned char ecount_buf[AES_BLOCK_SIZE]; + unsigned int num = 0; + ERL_NIF_TERM ret; + + if (!enif_inspect_iolist_as_binary(env, argv[0], &key) + || AES_set_encrypt_key(key.data, key.size*8, &aes_key) != 0 + || !enif_inspect_binary(env, argv[1], &ivec) || ivec.size != 16 + || !enif_inspect_iolist_as_binary(env, argv[2], &text)) { + return enif_make_badarg(env); + } + memcpy(ivec_clone, ivec.data, 16); + memset(ecount_buf, 0, sizeof(ecount_buf)); + AES_ctr128_encrypt((unsigned char *) text.data, + enif_make_new_binary(env, text.size, &ret), + text.size, &aes_key, ivec_clone, ecount_buf, &num); + + /* To do an incremental {en|de}cryption, the state to to keep between calls + must include ivec_clone, ecount_buf and num. */ + return ret; +} + static ERL_NIF_TERM rand_bytes_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {/* (Bytes) */ unsigned bytes; diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index e1431cfd81..c407350c47 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -53,7 +53,7 @@ <p>aes: Advanced Encryption Standard (AES) (FIPS 197) </p> </item> <item> - <p>ecb, cbc, cfb, ofb: Recommendation for Block Cipher Modes + <p>ecb, cbc, cfb, ofb, ctr: Recommendation for Block Cipher Modes of Operation (NIST SP 800-38A).</p> </item> <item> @@ -557,6 +557,34 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> </desc> </func> <func> + <name>aes_ctr_encrypt(Key, IVec, Text) -> Cipher</name> + <fsummary>Encrypt <c>Text</c>according to AES in Counter mode</fsummary> + <type> + <v>Key = Text = iolist() | binary()</v> + <v>IVec = Cipher = binary()</v> + </type> + <desc> + <p>Encrypts <c>Text</c> according to AES in Counter mode (CTR). <c>Text</c> + can be any number of bytes. <c>Key</c> is the AES key and must be either + 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits + (16 bytes).</p> + </desc> + </func> + <func> + <name>aes_ctr_decrypt(Key, IVec, Cipher) -> Text</name> + <fsummary>Decrypt <c>Cipher</c>according to AES in Counter mode</fsummary> + <type> + <v>Key = Cipher = iolist() | binary()</v> + <v>IVec = Text = binary()</v> + </type> + <desc> + <p>Decrypts <c>Cipher</c> according to AES in Counter mode (CTR). <c>Cipher</c> + can be any number of bytes. <c>Key</c> is the AES key and must be either + 128, 192 or 256 bits long. <c>IVec</c> is an arbitrary initializing vector of 128 bits + (16 bytes).</p> + </desc> + </func> + <func> <name>erlint(Mpint) -> N</name> <name>mpint(N) -> Mpint</name> <fsummary>Convert between binary multi-precision integer and erlang big integer</fsummary> diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 71fd91cafd..d6e2e033c0 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -51,6 +51,7 @@ -export([aes_cbc_128_encrypt/3, aes_cbc_128_decrypt/3]). -export([aes_cbc_256_encrypt/3, aes_cbc_256_decrypt/3]). -export([aes_cbc_ivec/1]). +-export([aes_ctr_encrypt/3, aes_ctr_decrypt/3]). -export([dh_generate_parameters/2, dh_check/1]). %% Testing see below @@ -80,6 +81,7 @@ rc2_40_cbc_encrypt, rc2_40_cbc_decrypt, %% idea_cbc_encrypt, idea_cbc_decrypt, aes_cbc_256_encrypt, aes_cbc_256_decrypt, + aes_ctr_encrypt, aes_ctr_decrypt, info_lib]). -type rsa_digest_type() :: 'md5' | 'sha'. @@ -542,6 +544,16 @@ aes_cbc_ivec(Data) when is_binary(Data) -> aes_cbc_ivec(Data) when is_list(Data) -> aes_cbc_ivec(list_to_binary(Data)). +%% +%% AES - in counter mode (CTR) +%% +-spec aes_ctr_encrypt(iodata(), binary(), iodata()) -> + binary(). +-spec aes_ctr_decrypt(iodata(), binary(), iodata()) -> + binary(). + +aes_ctr_encrypt(_Key, _IVec, _Data) -> ?nif_stub. +aes_ctr_decrypt(_Key, _IVec, _Cipher) -> ?nif_stub. %% %% XOR - xor to iolists and return a binary diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl index 06b284d50d..19e10081d8 100644 --- a/lib/crypto/test/crypto_SUITE.erl +++ b/lib/crypto/test/crypto_SUITE.erl @@ -44,6 +44,7 @@ aes_cfb/1, aes_cbc/1, aes_cbc_iter/1, + aes_ctr/1, mod_exp_test/1, rand_uniform_test/1, rsa_verify_test/1, @@ -79,6 +80,7 @@ all(suite) -> aes_cfb, aes_cbc, aes_cbc_iter, + aes_ctr, des_cbc_iter, des_ecb, rand_uniform_test, @@ -619,6 +621,65 @@ aes_cbc_decrypt_iter(Key,IVec,Data, Acc) -> aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>). +aes_ctr(doc) -> "CTR"; +aes_ctr(Config) when is_list(Config) -> + %% Sample data from NIST Spec.Publ. 800-38A + %% F.5.1 CTR-AES128.Encrypt + Key128 = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"), + Samples128 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block + "6bc1bee22e409f96e93d7e117393172a", % Plaintext + "874d6191b620e3261bef6864990db6ce"},% Ciphertext + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "ae2d8a571e03ac9c9eb76fac45af8e51", + "9806f66b7970fdff8617187bb9fffdff"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "30c81c46a35ce411e5fbc1191a0a52ef", + "5ae4df3edbd5d35e5b4f09020db03eab"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "f69f2445df4f9b17ad2b417be66c3710", + "1e031dda2fbe03d1792170a0f3009cee"}], + lists:foreach(fun(S) -> aes_ctr_do(Key128,S) end, Samples128), + + %% F.5.3 CTR-AES192.Encrypt + Key192 = hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"), + Samples192 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block + "6bc1bee22e409f96e93d7e117393172a", % Plaintext + "1abc932417521ca24f2b0459fe7e6e0b"},% Ciphertext + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "ae2d8a571e03ac9c9eb76fac45af8e51", + "090339ec0aa6faefd5ccc2c6f4ce8e94"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "30c81c46a35ce411e5fbc1191a0a52ef", + "1e36b26bd1ebc670d1bd1d665620abf7"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "f69f2445df4f9b17ad2b417be66c3710", + "4f78a7f6d29809585a97daec58c6b050"}], + lists:foreach(fun(S) -> aes_ctr_do(Key192,S) end, Samples192), + + %% F.5.5 CTR-AES256.Encrypt + Key256 = hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"), + Samples256 = [{"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", % Input Block + "6bc1bee22e409f96e93d7e117393172a", % Plaintext + "601ec313775789a5b7a7f504bbf3d228"},% Ciphertext + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff00", + "ae2d8a571e03ac9c9eb76fac45af8e51", + "f443e3ca4d62b59aca84e990cacaf5c5"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff01", + "30c81c46a35ce411e5fbc1191a0a52ef", + "2b0930daa23de94ce87017ba2d84988d"}, + {"f0f1f2f3f4f5f6f7f8f9fafbfcfdff02", + "f69f2445df4f9b17ad2b417be66c3710", + "dfc9c58db67aada613c2dd08457941a6"}], + lists:foreach(fun(S) -> aes_ctr_do(Key256,S) end, Samples256). + + +aes_ctr_do(Key,{IVec, Plain, Cipher}) -> + ?line I = hexstr2bin(IVec), + ?line P = hexstr2bin(Plain), + ?line C = crypto:aes_ctr_encrypt(Key, I, P), + ?line m(C, hexstr2bin(Cipher)), + ?line m(P, crypto:aes_ctr_decrypt(Key, I, C)). + %% %% mod_exp_test(doc) -> diff --git a/lib/debugger/test/int_eval_SUITE.erl b/lib/debugger/test/int_eval_SUITE.erl index 19b006e750..1628ca69b1 100644 --- a/lib/debugger/test/int_eval_SUITE.erl +++ b/lib/debugger/test/int_eval_SUITE.erl @@ -65,10 +65,7 @@ bifs_outside_erlang(Config) when is_list(Config) -> Self = self(), ok = io:format("Self: ~p", [Self]), Info = ets:info(Id), - {owner,Self} = lists:nth(2, Info), - %% Was - %% {owner,Self} = element(2, Info), - %% in R10B. + Self = proplists:get_value(owner, Info), ?IM:ets_delete(Id), ok end, diff --git a/lib/dialyzer/RELEASE_NOTES b/lib/dialyzer/RELEASE_NOTES index 62b0c92f97..08f274a996 100644 --- a/lib/dialyzer/RELEASE_NOTES +++ b/lib/dialyzer/RELEASE_NOTES @@ -3,8 +3,26 @@ (in reversed chronological order) ============================================================================== -Version 2.3.0 (in Erlang/OTP R14) ---------------------------------- +Version 2.x.x (in Erlang/OTP R14B01) +------------------------------------ + - Fixed pretty rare infinite loop when refining the types of an SCC whose + functions all returned none() (thanks to Stavros Aronis). + - Fixed pretty rare crash when taking the infimum of two tuple_sets. + - Fixed pretty rare crash when using parameterized types containing unbound + variables (thanks to Nicolas Trangez for reporting it). + - Deeper unfolding of recursive types (thanks to Maria Christakis). + - Fixed some incomplete and erroneous specs in modules of kernel and stdlib. + - Fixed problems in the handling of remote types in records used as types + (thanks to Nico Kruber for the report and to Maria Christakis for the fix). + - Fixed handling of nested opaque types (thanks to Thorsten Schuett for + reporting it and to Maria Christakis for fixing it). + +Version 2.3.1 (in Erlang/OTP R14B) +---------------------------------- + - Eliminated warnings for auto-imported BIF clashes. + +Version 2.3.0 (in Erlang/OTP R14A) +---------------------------------- - Dialyzer properly supports the new attribute -export_type and checks that remote types only refer to exported types. A warning is produced if some files/applications refer to types defined in modules which are diff --git a/lib/dialyzer/doc/manual.txt b/lib/dialyzer/doc/manual.txt index 470ddd6c73..d9cb52f722 100644 --- a/lib/dialyzer/doc/manual.txt +++ b/lib/dialyzer/doc/manual.txt @@ -123,9 +123,10 @@ The exit status of the command line version is: Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose] - [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]* - [--output_plt file] [-Wwarn]* [--src] [--gui | --wx] - [files_or_dirs] [-r dirs] [--apps applications] [-o outfile] + [-pa dir]* [--plt plt] [--plts plts] [-Ddefine]* + [-I include_dir]* [--output_plt file] [-Wwarn]* + [--src] [--gui | --wx] [files_or_dirs] [-r dirs] + [--apps applications] [-o outfile] [--build_plt] [--add_to_plt] [--remove_from_plt] [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings] [--no_native] @@ -167,6 +168,10 @@ Options: --plt plt Use the specified plt as the initial plt (if the plt was built during setup the files will be checked for consistency) + --plts plts + Merges the specified plts to create the initial plt -- requires + that the plts are disjoint (i.e., do not have any module + appearing in more than one plt) -Wwarn A family of options which selectively turn on/off warnings (for help on the names of warnings use dialyzer -Whelp) @@ -294,6 +299,7 @@ Option :: {files, [Filename :: string()]} | {defines, [{Macro :: atom(), Value :: term()}]} | {from, src_code | byte_code} %% Defaults to byte_code | {init_plt, FileName :: string()} %% If changed from default + | {plts, [FileName :: string()]} %% If changed from default | {include_dirs, [DirName :: string()]} | {output_file, FileName :: string()} | {output_plt, FileName :: string()} diff --git a/lib/dialyzer/doc/src/dialyzer.xml b/lib/dialyzer/doc/src/dialyzer.xml index 1ec2ce830a..29308885fd 100644 --- a/lib/dialyzer/doc/src/dialyzer.xml +++ b/lib/dialyzer/doc/src/dialyzer.xml @@ -101,9 +101,9 @@ <tag><c><![CDATA[--output_plt file]]></c></tag> <item>Store the PLT at the specified location after building it.</item> <tag><c><![CDATA[--plt plt]]></c></tag> - <item>Use the specified plt as the initial persistent lookup table.</item> + <item>Use the specified PLT as the initial persistent lookup table.</item> <tag><c><![CDATA[-Wwarn]]></c></tag> - <item>a family of option which selectively turn on/off warnings. + <item>a family of options which selectively turn on/off warnings. (for help on the names of warnings use <c><![CDATA[dialyzer -Whelp]]></c>)</item> <tag><c><![CDATA[--shell]]></c></tag> <item>do not disable the Erlang shell while running the GUI</item> @@ -158,9 +158,16 @@ <tag><c><![CDATA[-Wno_match]]></c></tag> <item>Suppress warnings for patterns that are unused or cannot match.</item> + <tag><c><![CDATA[-Wno_opaque]]></c></tag> + <item>Suppress warnings for violations of opaqueness of data types.</item> <tag><c><![CDATA[-Werror_handling]]></c>***</tag> <item>Include warnings for functions that only return by means of an exception.</item> + <tag><c><![CDATA[-Wrace_conditions]]></c>***</tag> + <item>Include warnings for possible race conditions.</item> + <tag><c><![CDATA[-Wbehaviours]]></c>***</tag> + <item>Include warnings about behaviour callbacks which drift from the + published recommended interfaces.</item> <tag><c><![CDATA[-Wunmatched_returns]]></c>***</tag> <item>Include warnings for function calls which ignore a structured return value or do not match against one of many possible return value(s).</item> @@ -215,8 +222,11 @@ WarnOpts : no_return | no_improper_lists | no_fun_app | no_match + | no_opaque | no_fail_call | error_handling + | race_conditions + | behaviours | unmatched_returns | overspecs | underspecs diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index d8fd073ca6..471f9fccd2 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -106,27 +106,35 @@ cl_print_plt_info(Opts) -> end, doit(F). -print_plt_info(#options{init_plt = PLT, output_file = OutputFile}) -> +print_plt_info(#options{init_plts = PLTs, output_file = OutputFile}) -> + PLTInfo = get_plt_info(PLTs), + do_print_plt_info(PLTInfo, OutputFile). + +get_plt_info([PLT|PLTs]) -> String = case dialyzer_plt:included_files(PLT) of {ok, Files} -> - io_lib:format("The PLT ~s includes the following files:\n~p\n", + io_lib:format("The PLT ~s includes the following files:\n~p\n\n", [PLT, Files]); {error, read_error} -> - Msg = io_lib:format("Could not read the PLT file ~p\n", [PLT]), + Msg = io_lib:format("Could not read the PLT file ~p\n\n", [PLT]), throw({dialyzer_error, Msg}); {error, no_such_file} -> - Msg = io_lib:format("The PLT file ~p does not exist\n", [PLT]), + Msg = io_lib:format("The PLT file ~p does not exist\n\n", [PLT]), throw({dialyzer_error, Msg}) end, + String ++ get_plt_info(PLTs); +get_plt_info([]) -> "". + +do_print_plt_info(PLTInfo, OutputFile) -> case OutputFile =:= none of true -> - io:format("~s", [String]), + io:format("~s", [PLTInfo]), ?RET_NOTHING_SUSPICIOUS; false -> case file:open(OutputFile, [write]) of {ok, FileDesc} -> - io:format(FileDesc, "~s", [String]), + io:format(FileDesc, "~s", [PLTInfo]), ok = file:close(FileDesc), ?RET_NOTHING_SUSPICIOUS; {error, Reason} -> @@ -225,6 +233,8 @@ plt_info(Plt) -> %% Machinery %%----------- +-type doit_ret() :: {'ok', dial_ret()} | {'error', string()}. + doit(F) -> try {ok, F()} @@ -233,13 +243,17 @@ doit(F) -> {error, lists:flatten(Msg)} end. +-spec cl_error(string()) -> no_return(). + cl_error(Msg) -> cl_halt({error, Msg}, #options{}). +-spec gui_halt(doit_ret(), #options{}) -> no_return(). + gui_halt(R, Opts) -> cl_halt(R, Opts#options{report_mode = quiet}). --spec cl_halt({'ok',dial_ret()} | {'error',string()}, #options{}) -> no_return(). +-spec cl_halt(doit_ret(), #options{}) -> no_return(). cl_halt({ok, R = ?RET_NOTHING_SUSPICIOUS}, #options{report_mode = quiet}) -> halt(R); @@ -379,7 +393,7 @@ message_to_string({spec_missing_fun, [M, F, A]}) -> [M, F, A]); %%----- Warnings for opaque type violations ------------------- message_to_string({call_with_opaque, [M, F, Args, ArgNs, ExpArgs]}) -> - io_lib:format("The call ~w:~w~s contains ~s argument when ~s\n", + io_lib:format("The call ~w:~w~s contains ~s when ~s\n", [M, F, Args, form_positions(ArgNs), form_expected(ExpArgs)]); message_to_string({call_without_opaque, [M, F, Args, ExpectedTriples]}) -> io_lib:format("The call ~w:~w~s does not have ~s\n", diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl index 2da8ed2e5d..1d98574585 100644 --- a/lib/dialyzer/src/dialyzer.hrl +++ b/lib/dialyzer/src/dialyzer.hrl @@ -129,7 +129,7 @@ defines = [] :: [dial_define()], from = byte_code :: start_from(), get_warnings = maybe :: boolean() | 'maybe', - init_plt = none :: 'none' | file:filename(), + init_plts = [] :: [file:filename()], include_dirs = [] :: [file:filename()], output_plt = none :: 'none' | file:filename(), legal_warnings = ordsets:new() :: ordset(dial_warn_tag()), diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 3438cc8c7e..abad1f3a75 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -21,7 +21,7 @@ %%%------------------------------------------------------------------- %%% File : dialyzer_analysis_callgraph.erl %%% Author : Tobias Lindahl <[email protected]> -%%% Description : +%%% Description : %%% %%% Created : 5 Apr 2005 by Tobias Lindahl <[email protected]> %%%------------------------------------------------------------------- @@ -32,7 +32,7 @@ -include("dialyzer.hrl"). --record(analysis_state, +-record(analysis_state, { codeserver :: dialyzer_codeserver:codeserver(), analysis_type = succ_typings :: anal_type(), @@ -44,7 +44,7 @@ plt :: dialyzer_plt:plt(), start_from = byte_code :: start_from(), use_contracts = true :: boolean(), - behaviours = {false,[]} :: {boolean(),[atom()]} + behaviours = {false,[]} :: {boolean(),[atom()]} }). -record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}). @@ -83,10 +83,10 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State, send_warnings(Parent, SendWarnings) end, loop(State, Analysis, ExtCalls); - {AnalPid, cserver, CServer, Plt} -> + {AnalPid, cserver, CServer, Plt} -> send_codeserver_plt(Parent, CServer, Plt), loop(State, Analysis, ExtCalls); - {AnalPid, done, Plt, DocPlt} -> + {AnalPid, done, Plt, DocPlt} -> case ExtCalls =:= none of true -> send_analysis_done(Parent, Plt, DocPlt); @@ -176,7 +176,7 @@ analysis_start(Parent, Analysis) -> NonExportsList = sets:to_list(NonExports), Plt3 = dialyzer_plt:delete_list(State3#analysis_state.plt, NonExportsList), Plt4 = dialyzer_plt:delete_contract_list(Plt3, NonExportsList), - send_codeserver_plt(Parent, CServer, State3#analysis_state.plt), + send_codeserver_plt(Parent, CServer, State3#analysis_state.plt), send_analysis_done(Parent, Plt4, State3#analysis_state.doc_plt). analyze_callgraph(Callgraph, State) -> @@ -229,24 +229,24 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, {error, Reason} -> {TmpCG, TmpCServer, [{File, Reason}|TmpFailed], TmpNoWarn, TmpMods}; - {ok, NewCG, NoWarn, NewCServer, Mod} -> + {ok, NewCG, NoWarn, NewCServer, Mod} -> {NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn, [Mod|TmpMods]} end end; byte_code -> - fun(File, {TmpCG, TmpCServer, TmpFailed, TmpNoWarn, TmpMods}) -> + fun(File, {TmpCG, TmpCServer, TmpFailed, TmpNoWarn, TmpMods}) -> case compile_byte(File, TmpCG, TmpCServer, UseContracts) of {error, Reason} -> {TmpCG, TmpCServer, [{File, Reason}|TmpFailed], TmpNoWarn, TmpMods}; - {ok, NewCG, NoWarn, NewCServer, Mod} -> + {ok, NewCG, NoWarn, NewCServer, Mod} -> {NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn, [Mod|TmpMods]} end end end, - {NewCallgraph1, NewCServer, Failed, NoWarn, Modules} = + {NewCallgraph1, NewCServer, Failed, NoWarn, Modules} = lists:foldl(Fun, {Callgraph, CServer, [], [], []}, Files), case Failed =:= [] of true -> @@ -255,7 +255,7 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, lists:foldl(fun({Mod, F}, Dict) -> dict:append(Mod, F, Dict) end, dict:new(), NewFiles), check_for_duplicate_modules(ModDict); - false -> + false -> Msg = io_lib:format("Could not scan the following file(s): ~p", [lists:flatten(Failed)]), exit({error, Msg}) @@ -268,14 +268,14 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, if UnknownBehaviours =:= [] -> ok; true -> send_unknown_behaviours(Parent, UnknownBehaviours) end, - State1 = State#analysis_state{behaviours = {BehChk,KnownBehaviours}}, + State1 = State#analysis_state{behaviours = {BehChk, KnownBehaviours}}, NewCallgraph2 = cleanup_callgraph(State1, NewCServer, NewCallgraph1, Modules), {T3, _} = statistics(runtime), Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]), - send_log(Parent, Msg2), + send_log(Parent, Msg2), {NewCallgraph2, sets:from_list(NoWarn), NewCServer}. -cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent, +cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent, codeserver = CodeServer, behaviours = {BehChk, KnownBehaviours} }, @@ -298,9 +298,9 @@ cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent, not dialyzer_plt:contains_mfa(InitPlt, To)], {BadCalls1, RealExtCalls} = if ExtCalls1 =:= [] -> {[], []}; - true -> + true -> ModuleSet = sets:from_list(Modules), - lists:partition(fun({_From, {M, _F, _A}}) -> + lists:partition(fun({_From, {M, _F, _A}}) -> sets:is_element(M, ModuleSet) orelse dialyzer_plt:contains_module(InitPlt, M) end, ExtCalls1) @@ -367,14 +367,14 @@ compile_byte(File, Callgraph, CServer, UseContracts) -> case dialyzer_utils:get_record_and_type_info(AbstrCode) of {error, _} = Error -> Error; {ok, RecInfo} -> - CServer1 = + CServer1 = dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer), case UseContracts of true -> case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of {error, _} = Error -> Error; {ok, SpecInfo} -> - CServer2 = + CServer2 = dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo, CServer1), store_core(Mod, Core, NoWarn, Callgraph, CServer2) @@ -455,8 +455,12 @@ expand_files([File|Left], Ext, FileAcc) -> case filelib:is_dir(File) of true -> {ok, List} = file:list_dir(File), - NewFiles = - [filename:join(File, X) || X <- List, filename:extension(X) =:= Ext], + NewFiles = lists:foldl(fun (X, Acc) -> + case filename:extension(X) =:= Ext of + true -> [filename:join(File, X)|Acc]; + false -> Acc + end + end, FileAcc, List), expand_files(Left, Ext, NewFiles); false -> expand_files(Left, Ext, [File|FileAcc]) diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index 616e2465dc..1987c1732c 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -81,11 +81,15 @@ build_plt(Opts) -> init_opts_for_build(Opts) -> case Opts#options.output_plt =:= none of true -> - case Opts#options.init_plt of - none -> Opts#options{init_plt = none, output_plt = get_default_plt()}; - Plt -> Opts#options{init_plt = none, output_plt = Plt} + case Opts#options.init_plts of + [] -> Opts#options{output_plt = get_default_output_plt()}; + [Plt] -> Opts#options{init_plts = [], output_plt = Plt}; + Plts -> + Msg = io_lib:format("Could not build multiple PLT files: ~s\n", + [format_plts(Plts)]), + error(Msg) end; - false -> Opts#options{init_plt = none} + false -> Opts#options{init_plts = []} end. %%-------------------------------------------------------------------- @@ -98,39 +102,58 @@ add_to_plt(Opts) -> init_opts_for_add(Opts) -> case Opts#options.output_plt =:= none of true -> - case Opts#options.init_plt of - none -> Opts#options{output_plt = get_default_plt(), - init_plt = get_default_plt()}; - Plt -> Opts#options{output_plt = Plt} + case Opts#options.init_plts of + [] -> Opts#options{output_plt = get_default_output_plt(), + init_plts = get_default_init_plt()}; + [Plt] -> Opts#options{output_plt = Plt}; + Plts -> + Msg = io_lib:format("Could not add to multiple PLT files: ~s\n", + [format_plts(Plts)]), + error(Msg) end; false -> - case Opts#options.init_plt =:= none of - true -> Opts#options{init_plt = get_default_plt()}; + case Opts#options.init_plts =:= [] of + true -> Opts#options{init_plts = get_default_init_plt()}; false -> Opts end end. %%-------------------------------------------------------------------- -check_plt(Opts) -> +check_plt(#options{init_plts = []} = Opts) -> Opts1 = init_opts_for_check(Opts), - report_check(Opts), - plt_common(Opts1, [], []). + report_check(Opts1), + plt_common(Opts1, [], []); +check_plt(#options{init_plts = Plts} = Opts) -> + check_plt_aux(Plts, Opts). + +check_plt_aux([_] = Plt, Opts) -> + Opts1 = Opts#options{init_plts = Plt}, + Opts2 = init_opts_for_check(Opts1), + report_check(Opts2), + plt_common(Opts2, [], []); +check_plt_aux([Plt|Plts], Opts) -> + Opts1 = Opts#options{init_plts = [Plt]}, + Opts2 = init_opts_for_check(Opts1), + report_check(Opts2), + plt_common(Opts2, [], []), + check_plt_aux(Plts, Opts). init_opts_for_check(Opts) -> - Plt = - case Opts#options.init_plt of - none -> get_default_plt(); - Plt0 -> Plt0 + InitPlt = + case Opts#options.init_plts of + []-> get_default_init_plt(); + Plt -> Plt end, + [OutputPlt] = InitPlt, Opts#options{files = [], files_rec = [], analysis_type = plt_check, defines = [], from = byte_code, - init_plt = Plt, + init_plts = InitPlt, include_dirs = [], - output_plt = Plt, + output_plt = OutputPlt, use_contracts = true }. @@ -144,21 +167,25 @@ remove_from_plt(Opts) -> init_opts_for_remove(Opts) -> case Opts#options.output_plt =:= none of true -> - case Opts#options.init_plt of - none -> Opts#options{output_plt = get_default_plt(), - init_plt = get_default_plt()}; - Plt -> Opts#options{output_plt = Plt} + case Opts#options.init_plts of + [] -> Opts#options{output_plt = get_default_output_plt(), + init_plts = get_default_init_plt()}; + [Plt] -> Opts#options{output_plt = Plt}; + Plts -> + Msg = io_lib:format("Could not remove from multiple PLT files: ~s\n", + [format_plts(Plts)]), + error(Msg) end; false -> - case Opts#options.init_plt =:= none of - true -> Opts#options{init_plt = get_default_plt()}; + case Opts#options.init_plts =:= [] of + true -> Opts#options{init_plts = get_default_init_plt()}; false -> Opts end end. %%-------------------------------------------------------------------- -plt_common(Opts, RemoveFiles, AddFiles) -> +plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) -> case check_plt(Opts, RemoveFiles, AddFiles) of ok -> case Opts#options.report_mode of @@ -174,7 +201,7 @@ plt_common(Opts, RemoveFiles, AddFiles) -> report_failed_plt_check(Opts, DiffMd5), {AnalFiles, RemovedMods, ModDeps1} = expand_dependent_modules(Md5, DiffMd5, ModDeps), - Plt = clean_plt(Opts#options.init_plt, RemovedMods), + Plt = clean_plt(InitPlt, RemovedMods), case AnalFiles =:= [] of true -> %% Only removed stuff. Just write the PLT. @@ -186,19 +213,19 @@ plt_common(Opts, RemoveFiles, AddFiles) -> end; {error, no_such_file} -> Msg = io_lib:format("Could not find the PLT: ~s\n~s", - [Opts#options.init_plt, default_plt_error_msg()]), + [InitPlt, default_plt_error_msg()]), error(Msg); {error, not_valid} -> Msg = io_lib:format("The file: ~s is not a valid PLT file\n~s", - [Opts#options.init_plt, default_plt_error_msg()]), + [InitPlt, default_plt_error_msg()]), error(Msg); {error, read_error} -> Msg = io_lib:format("Could not read the PLT: ~s\n~s", - [Opts#options.init_plt, default_plt_error_msg()]), + [InitPlt, default_plt_error_msg()]), error(Msg); {error, {no_file_to_remove, F}} -> Msg = io_lib:format("Could not remove the file ~s from the PLT: ~s\n", - [F, Opts#options.init_plt]), + [F, InitPlt]), error(Msg) end. @@ -218,8 +245,7 @@ default_plt_error_msg() -> %%-------------------------------------------------------------------- -check_plt(Opts, RemoveFiles, AddFiles) -> - Plt = Opts#options.init_plt, +check_plt(#options{init_plts = [Plt]} = Opts, RemoveFiles, AddFiles) -> case dialyzer_plt:check_plt(Plt, RemoveFiles, AddFiles) of {old_version, _MD5} = OldVersion -> report_old_version(Opts), @@ -234,14 +260,14 @@ check_plt(Opts, RemoveFiles, AddFiles) -> %%-------------------------------------------------------------------- -report_check(#options{report_mode = ReportMode, init_plt = InitPlt}) -> +report_check(#options{report_mode = ReportMode, init_plts = [InitPlt]}) -> case ReportMode of quiet -> ok; _ -> io:format(" Checking whether the PLT ~s is up-to-date...", [InitPlt]) end. -report_old_version(#options{report_mode = ReportMode, init_plt = InitPlt}) -> +report_old_version(#options{report_mode = ReportMode, init_plts = [InitPlt]}) -> case ReportMode of quiet -> ok; _ -> @@ -264,7 +290,7 @@ report_failed_plt_check(#options{analysis_type = AnalType, report_analysis_start(#options{analysis_type = Type, report_mode = ReportMode, - init_plt = InitPlt, + init_plts = InitPlts, output_plt = OutputPlt}) -> case ReportMode of quiet -> ok; @@ -272,6 +298,7 @@ report_analysis_start(#options{analysis_type = Type, io:format(" "), case Type of plt_add -> + [InitPlt] = InitPlts, case InitPlt =:= OutputPlt of true -> io:format("Adding information to ~s...", [OutputPlt]); false -> io:format("Adding information from ~s to ~s...", @@ -282,6 +309,7 @@ report_analysis_start(#options{analysis_type = Type, plt_check -> io:format("Rebuilding the information in ~s...", [OutputPlt]); plt_remove -> + [InitPlt] = InitPlts, case InitPlt =:= OutputPlt of true -> io:format("Removing information from ~s...", [OutputPlt]); false -> io:format("Removing information from ~s to ~s...", @@ -320,16 +348,28 @@ report_md5_diff(List) -> %%-------------------------------------------------------------------- -get_default_plt() -> +get_default_init_plt() -> + [dialyzer_plt:get_default_plt()]. + +get_default_output_plt() -> dialyzer_plt:get_default_plt(). %%-------------------------------------------------------------------- +format_plts([Plt]) -> Plt; +format_plts([Plt|Plts]) -> + Plt ++ ", " ++ format_plts(Plts). + +%%-------------------------------------------------------------------- + do_analysis(Options) -> Files = get_files_from_opts(Options), - case Options#options.init_plt of - none -> do_analysis(Files, Options, dialyzer_plt:new(), none); - File -> do_analysis(Files, Options, dialyzer_plt:from_file(File), none) + case Options#options.init_plts of + [] -> do_analysis(Files, Options, dialyzer_plt:new(), none); + PltFiles -> + Plts = [dialyzer_plt:from_file(F) || F <- PltFiles], + Plt = dialyzer_plt:merge_plts_or_report_conflicts(PltFiles, Plts), + do_analysis(Files, Options, Plt, none) end. do_analysis(Files, Options, Plt, PltInfo) -> @@ -559,7 +599,7 @@ cl_loop(State, LogCache) -> cl_loop(State, LogCache) end. --spec failed_anal_msg(string(), [_]) -> string(). +-spec failed_anal_msg(string(), [_]) -> nonempty_string(). failed_anal_msg(Reason, LogCache) -> Msg = "Analysis failed with error: " ++ Reason ++ "\n", diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl index 0160b84abc..2f9e577544 100644 --- a/lib/dialyzer/src/dialyzer_cl_parse.erl +++ b/lib/dialyzer/src/dialyzer_cl_parse.erl @@ -138,11 +138,17 @@ cl(["-pa", Path|T]) -> true -> cl(T); {error, _} -> error("Bad directory for -pa: "++Path) end; -cl(["--plt", PLT|T]) -> - put(dialyzer_init_plt, PLT), - cl(T); cl(["--plt"]) -> error("No plt specified for --plt"); +cl(["--plt", PLT|T]) -> + put(dialyzer_init_plts, [PLT]), + cl(T); +cl(["--plts"]) -> + error("No plts specified for --plts"); +cl(["--plts"|T]) -> + {PLTs, NewT} = get_plts(T, []), + put(dialyzer_init_plts, PLTs), + cl(NewT); cl(["-q"|T]) -> put(dialyzer_options_report_mode, quiet), cl(T); @@ -284,7 +290,7 @@ common_options() -> [{defines, get(dialyzer_options_defines)}, {from, get(dialyzer_options_from)}, {include_dirs, get(dialyzer_include)}, - {init_plt, get(dialyzer_init_plt)}, + {plts, get(dialyzer_init_plts)}, {output_plt, get(dialyzer_output_plt)}, {report_mode, get(dialyzer_options_report_mode)}, {use_spec, get(dialyzer_options_use_contracts)}, @@ -309,6 +315,13 @@ get_lib_dir([], Acc) -> %%----------------------------------------------------------------------- +get_plts(["--"|T], Acc) -> {lists:reverse(Acc), T}; +get_plts(["-"++_Opt = H|T], Acc) -> {lists:reverse(Acc), [H|T]}; +get_plts([H|T], Acc) -> get_plts(T, [H|Acc]); +get_plts([], Acc) -> {lists:reverse(Acc), []}. + +%%----------------------------------------------------------------------- + help_warnings() -> S = warning_options_msg(), io:put_chars(S), @@ -316,9 +329,10 @@ help_warnings() -> help_message() -> S = "Usage: dialyzer [--help] [--version] [--shell] [--quiet] [--verbose] - [-pa dir]* [--plt plt] [-Ddefine]* [-I include_dir]* - [--output_plt file] [-Wwarn]* [--src] [--gui | --wx] - [files_or_dirs] [-r dirs] [--apps applications] [-o outfile] + [-pa dir]* [--plt plt] [--plts plts] [-Ddefine]* + [-I include_dir]* [--output_plt file] [-Wwarn]* + [--src] [--gui | --wx] [files_or_dirs] [-r dirs] + [--apps applications] [-o outfile] [--build_plt] [--add_to_plt] [--remove_from_plt] [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings] [--no_native] @@ -362,6 +376,10 @@ Options: --plt plt Use the specified plt as the initial plt (if the plt was built during setup the files will be checked for consistency) + --plts plts + Merges the specified plts to create the initial plt -- requires + that the plts are disjoint (i.e., do not have any module + appearing in more than one plt) -Wwarn A family of options which selectively turn on/off warnings (for help on the names of warnings use dialyzer -Whelp) @@ -378,12 +396,12 @@ Options: --build_plt The analysis starts from an empty plt and creates a new one from the files specified with -c and -r. Only works for beam files. - Use --plt or --output_plt to override the default plt location. + Use --plt(s) or --output_plt to override the default plt location. --add_to_plt The plt is extended to also include the files specified with -c and -r. - Use --plt to specify wich plt to start from, and --output_plt to - specify where to put the plt. Note that the analysis might include - files from the plt if they depend on the new files. + Use --plt(s) to specify wich plt to start from, and --output_plt to + specify where to put the plt. Note that the analysis might include + files from the plt if they depend on the new files. This option only works with beam files. --remove_from_plt The information from the files specified with -c and -r is removed @@ -396,8 +414,8 @@ Options: Skip the plt check when running Dialyzer. Useful when working with installed plts that never change. --plt_info - Makes Dialyzer print information about the plt and then quit. The plt - can be specified with --plt. + Makes Dialyzer print information about the plt and then quit. The plt + can be specified with --plt(s). --get_warnings Makes Dialyzer emit warnings even when manipulating the plt. Only emits warnings for files that are actually analyzed. diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index bf80c6f470..bcdcf2685d 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -163,20 +163,23 @@ process_contract_remote_types(CodeServer) -> check_contracts(Contracts, Callgraph, FunTypes) -> FoldFun = fun(Label, Type, NewContracts) -> - {ok, {M,F,A} = MFA} = dialyzer_callgraph:lookup_name(Label, Callgraph), - case orddict:find(MFA, Contracts) of - {ok, {_FileLine, Contract}} -> - case check_contract(Contract, Type) of - ok -> - case erl_bif_types:is_known(M, F, A) of - true -> - %% Disregard the contracts since - %% this is a known function. - NewContracts; - false -> - [{MFA, Contract}|NewContracts] + case dialyzer_callgraph:lookup_name(Label, Callgraph) of + {ok, {M,F,A} = MFA} -> + case orddict:find(MFA, Contracts) of + {ok, {_FileLine, Contract}} -> + case check_contract(Contract, Type) of + ok -> + case erl_bif_types:is_known(M, F, A) of + true -> + %% Disregard the contracts since + %% this is a known function. + NewContracts; + false -> + [{MFA, Contract}|NewContracts] + end; + {error, _Error} -> NewContracts end; - {error, _Error} -> NewContracts + error -> NewContracts end; error -> NewContracts end diff --git a/lib/dialyzer/src/dialyzer_gui.erl b/lib/dialyzer/src/dialyzer_gui.erl index f353638cdf..4436330f7f 100644 --- a/lib/dialyzer/src/dialyzer_gui.erl +++ b/lib/dialyzer/src/dialyzer_gui.erl @@ -88,8 +88,8 @@ -spec start(#options{}) -> ?RET_NOTHING_SUSPICIOUS. -start(DialyzerOptions = #options{from = From, init_plt = InitPltFile, - legal_warnings = LegalWarnings}) -> +start(#options{from = From, init_plts = InitPltFiles, + legal_warnings = LegalWarnings} = DialyzerOptions) -> process_flag(trap_exit, true), GS = gs:start(), @@ -336,9 +336,13 @@ start(DialyzerOptions = #options{from = From, init_plt = InitPltFile, gs:config(Packer, WH), {ok, CWD} = file:get_cwd(), - InitPlt = try dialyzer_plt:from_file(InitPltFile) - catch throw:{dialyzer_error, _} -> dialyzer_plt:new() - end, + InitPlt = + case InitPltFiles of + [] -> dialyzer_plt:new(); + _ -> + Plts = [dialyzer_plt:from_file(F) || F <- InitPltFiles], + dialyzer_plt:merge_plts_or_report_conflicts(InitPltFiles, Plts) + end, State = #gui_state{add_all = AddAll, add_file = AddFile, diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl index 2e309d7ec1..e711c15ea7 100644 --- a/lib/dialyzer/src/dialyzer_gui_wx.erl +++ b/lib/dialyzer/src/dialyzer_gui_wx.erl @@ -88,7 +88,7 @@ start(DialyzerOptions) -> State = wx:batch(fun() -> create_window(Wx, DialyzerOptions) end), gui_loop(State). -create_window(Wx, DialyzerOptions) -> +create_window(Wx, #options{init_plts = InitPltFiles} = DialyzerOptions) -> {ok, Host} = inet:gethostname(), %%---------- initializing frame --------- @@ -258,11 +258,15 @@ create_window(Wx, DialyzerOptions) -> plt = PltMenu, options =OptionsMenu, help = HelpMenu}, - - InitPlt = try dialyzer_plt:from_file(DialyzerOptions#options.init_plt) - catch throw:{dialyzer_error, _} -> dialyzer_plt:new() - end, + InitPlt = + case InitPltFiles of + [] -> dialyzer_plt:new(); + _ -> + Plts = [dialyzer_plt:from_file(F) || F <- InitPltFiles], + dialyzer_plt:merge_plts_or_report_conflicts(InitPltFiles, Plts) + end, + #gui_state{add = AddButton, add_dir = AddDirButton, add_rec = AddRecButton, diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index 010625b7bd..2c0afa6e2b 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -53,14 +53,21 @@ build(Opts) -> InitPlt = dialyzer_plt:get_default_plt(), DefaultOpts = #options{}, DefaultOpts1 = DefaultOpts#options{legal_warnings = DefaultWarns1, - init_plt = InitPlt}, - try - NewOpts = build_options(Opts, DefaultOpts1), + init_plts = [InitPlt]}, + try + Opts1 = preprocess_opts(Opts), + NewOpts = build_options(Opts1, DefaultOpts1), postprocess_opts(NewOpts) catch throw:{dialyzer_options_error, Msg} -> {error, Msg} end. +preprocess_opts([]) -> []; +preprocess_opts([{init_plt, File}|Opts]) -> + [{plts, [File]}|preprocess_opts(Opts)]; +preprocess_opts([Opt|Opts]) -> + [Opt|preprocess_opts(Opts)]. + postprocess_opts(Opts = #options{}) -> Opts1 = check_output_plt(Opts), adapt_get_warnings(Opts1). @@ -144,9 +151,9 @@ build_options([{OptionName, Value} = Term|Rest], Options) -> build_options(Rest, Options#options{from = Value}); get_warnings -> build_options(Rest, Options#options{get_warnings = Value}); - init_plt -> - assert_filenames([Term], [Value]), - build_options(Rest, Options#options{init_plt = Value}); + plts -> + assert_filenames(Term, Value), + build_options(Rest, Options#options{init_plts = Value}); include_dirs -> assert_filenames(Term, Value), OldVal = Options#options.include_dirs, diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl index 0f5be3b7f2..a7ba270c41 100644 --- a/lib/dialyzer/src/dialyzer_plt.erl +++ b/lib/dialyzer/src/dialyzer_plt.erl @@ -51,6 +51,7 @@ lookup_contract/2, lookup_module/2, merge_plts/1, + merge_plts_or_report_conflicts/2, new/0, plt_and_info_from_file/1, get_specs/1, @@ -244,9 +245,10 @@ from_file(FileName, ReturnInfo) -> [FileName, Reason])) end. --type inc_file_err_rsn() :: 'no_such_file' | 'read_error'. +-type err_rsn() :: 'not_valid' | 'no_such_file' | 'read_error'. + -spec included_files(file:filename()) -> {'ok', [file:filename()]} - | {'error', inc_file_err_rsn()}. + | {'error', err_rsn()}. included_files(FileName) -> case get_record_from_file(FileName) of @@ -291,6 +293,38 @@ merge_plts(List) -> exported_types = sets_merge(ExpTypesList), contracts = table_merge(ContractsList)}. +-spec merge_disj_plts([plt()]) -> plt(). + +merge_disj_plts(List) -> + InfoList = [Info || #plt{info = Info} <- List], + TypesList = [Types || #plt{types = Types} <- List], + ExpTypesList = [ExpTypes || #plt{exported_types = ExpTypes} <- List], + ContractsList = [Contracts || #plt{contracts = Contracts} <- List], + #plt{info = table_disj_merge(InfoList), + types = table_disj_merge(TypesList), + exported_types = sets_disj_merge(ExpTypesList), + contracts = table_disj_merge(ContractsList)}. + +-spec merge_plts_or_report_conflicts([file:filename()], [plt()]) -> plt(). + +merge_plts_or_report_conflicts(PltFiles, Plts) -> + try + merge_disj_plts(Plts) + catch throw:{dialyzer_error, not_disjoint_plts} -> + IncFiles = lists:append([begin {ok, Fs} = included_files(F), Fs end + || F <- PltFiles]), + ConfFiles = find_duplicates(IncFiles), + Msg = io_lib:format("Could not merge PLTs since they are not disjoint\n" + "The following files are included in more than one " + "PLTs:\n~p\n", [ConfFiles]), + error(Msg) + end. + +find_duplicates(List) -> + ModList = [filename:basename(E) || E <- List], + SortedList = lists:usort(ModList), + lists:usort(ModList -- SortedList). + -spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'. to_file(FileName, @@ -320,8 +354,7 @@ to_file(FileName, end. -type md5_diff() :: [{'differ', atom()} | {'removed', atom()}]. --type check_error() :: 'not_valid' | 'no_such_file' | 'read_error' - | {'no_file_to_remove', file:filename()}. +-type check_error() :: err_rsn() | {'no_file_to_remove', file:filename()}. -spec check_plt(file:filename(), [file:filename()], [file:filename()]) -> 'ok' @@ -556,6 +589,25 @@ table_merge([Plt|Plts], Acc) -> NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc), table_merge(Plts, NewAcc). +table_disj_merge([H|T]) -> + table_disj_merge(T, H). + +table_disj_merge([], Acc) -> + Acc; +table_disj_merge([Plt|Plts], Acc) -> + case table_is_disjoint(Plt, Acc) of + true -> + NewAcc = dict:merge(fun(_Key, _Val1, _Val2) -> gazonk end, + Plt, Acc), + table_disj_merge(Plts, NewAcc); + false -> throw({dialyzer_error, not_disjoint_plts}) + end. + +table_is_disjoint(T1, T2) -> + K1 = dict:fetch_keys(T1), + K2 = dict:fetch_keys(T2), + lists:all(fun(E) -> not lists:member(E, K2) end, K1). + sets_merge([H|T]) -> sets_merge(T, H). @@ -565,6 +617,19 @@ sets_merge([Plt|Plts], Acc) -> NewAcc = sets:union(Plt, Acc), sets_merge(Plts, NewAcc). +sets_disj_merge([H|T]) -> + sets_disj_merge(T, H). + +sets_disj_merge([], Acc) -> + Acc; +sets_disj_merge([Plt|Plts], Acc) -> + case sets:is_disjoint(Plt, Acc) of + true -> + NewAcc = sets:union(Plt, Acc), + sets_disj_merge(Plts, NewAcc); + false -> throw({dialyzer_error, not_disjoint_plts}) + end. + %%--------------------------------------------------------------------------- %% Debug utilities. diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl index ec8d613b96..ee9d5e88a3 100644 --- a/lib/dialyzer/src/dialyzer_races.erl +++ b/lib/dialyzer/src/dialyzer_races.erl @@ -118,7 +118,7 @@ var_map :: dict()}). -type case_tags() :: 'beg_case' | #beg_clause{} | #end_clause{} | #end_case{}. --type code() :: [#dep_call{} | #warn_call{} | #fun_call{} | +-type code() :: [#dep_call{} | #fun_call{} | #warn_call{} | #curr_fun{} | #let_tag{} | case_tags() | race_tag()]. -type table_var() :: label() | ?no_label. @@ -479,23 +479,11 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, _Other -> {RaceList, [], NestingLevel, false} end; - #dep_call{call_name = ets_lookup, args = DepCallArgs} -> + #dep_call{call_name = ets_lookup} -> case RaceWarnTag of ?WARN_ETS_LOOKUP_INSERT -> - [Tab, Names, _, _] = DepCallArgs, - case compare_var_list(Tab, - dialyzer_callgraph:get_public_tables(Callgraph), - RaceVarMap) - orelse - length(Names -- - dialyzer_callgraph:get_named_tables(Callgraph)) < - length(Names) of - true -> - {[Head#dep_call{var_map = RaceVarMap}|RaceList], - [], NestingLevel, false}; - false -> - {RaceList, [], NestingLevel, false} - end; + {[Head#dep_call{var_map = RaceVarMap}|RaceList], + [], NestingLevel, false}; _Other -> {RaceList, [], NestingLevel, false} end; @@ -517,23 +505,11 @@ fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, _Other -> {RaceList, [], NestingLevel, false} end; - #warn_call{call_name = ets_insert, args = WarnCallArgs} -> + #warn_call{call_name = ets_insert} -> case RaceWarnTag of ?WARN_ETS_LOOKUP_INSERT -> - [Tab, Names, _, _] = WarnCallArgs, - case compare_var_list(Tab, - dialyzer_callgraph:get_public_tables(Callgraph), - RaceVarMap) - orelse - length(Names -- - dialyzer_callgraph:get_named_tables(Callgraph)) < - length(Names) of - true -> - {[Head#warn_call{var_map = RaceVarMap}|RaceList], - [], NestingLevel, false}; - false -> - {RaceList, [], NestingLevel, false} - end; + {[Head#warn_call{var_map = RaceVarMap}|RaceList], + [], NestingLevel, false}; _Other -> {RaceList, [], NestingLevel, false} end; diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index 3effb1c2e6..f68472d2fc 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -314,6 +314,7 @@ traverse(Tree, DefinedVars, State) -> error -> t_fun(length(Vars), t_none()); {ok, Dom} -> t_fun(Dom, t_none()) end, + TreeVar = mk_var(Tree), State2 = try State1 = case state__add_prop_constrs(Tree, State0) of @@ -321,20 +322,21 @@ traverse(Tree, DefinedVars, State) -> PropState -> PropState end, {BodyState, BodyVar} = traverse(Body, DefinedVars1, State1), - state__store_conj(mk_var(Tree), eq, + state__store_conj(TreeVar, eq, t_fun(mk_var_list(Vars), BodyVar), BodyState) catch throw:error -> - state__store_conj(mk_var(Tree), eq, FunFailType, State0) + state__store_conj(TreeVar, eq, FunFailType, State0) end, Cs = state__cs(State2), - State3 = state__store_constrs(mk_var(Tree), Cs, State2), - Ref = mk_constraint_ref(mk_var(Tree), get_deps(Cs)), + State3 = state__store_constrs(TreeVar, Cs, State2), + Ref = mk_constraint_ref(TreeVar, get_deps(Cs)), OldCs = state__cs(State), State4 = state__new_constraint_context(State3), State5 = state__store_conj_list([OldCs, Ref], State4), State6 = state__store_fun_arity(Tree, State5), - {State6, mk_var(Tree)}; + State7 = state__add_fun_to_scc(TreeVar, State6), + {State7, TreeVar}; 'let' -> Vars = cerl:let_vars(Tree), Arg = cerl:let_arg(Tree), @@ -580,7 +582,7 @@ handle_try(Tree, DefinedVars, State) -> mk_conj_constraint_list([HandlerCs, mk_constraint(TreeVar, eq, HandlerVar)]), Disj = mk_disj_constraint_list([Conj1, Conj2]), - {Disj, mk_var(Tree)}; + {Disj, TreeVar}; {false, true} -> {mk_conj_constraint_list([ArgBodyCs, mk_constraint(TreeVar, eq, BodyVar)]), @@ -2070,7 +2072,7 @@ new_state(SCC0, NextLabel, CallGraph, Plt, PropTypes) -> NameMap = dict:from_list([{MFA, Var} || {MFA, {Var, _Fun}, _Rec} <- SCC0]), SCC = [mk_var(Fun) || {_MFA, {_Var, Fun}, _Rec} <- SCC0], #state{callgraph = CallGraph, name_map = NameMap, next_label = NextLabel, - prop_types = PropTypes, plt = Plt, scc = SCC}. + prop_types = PropTypes, plt = Plt, scc = ordsets:from_list(SCC)}. state__set_rec_dict(State, RecDict) -> State#state{records = RecDict}. @@ -2161,6 +2163,9 @@ get_apply_constr(FunLabels, Dst, ArgTypes, #state{callgraph = CG} = State) -> state__scc(#state{scc = SCC}) -> SCC. +state__add_fun_to_scc(Fun, #state{scc = SCC} = State) -> + State#state{scc = ordsets:add_element(Fun, SCC)}. + state__plt(#state{plt = PLT}) -> PLT. diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index a9da229061..248fdf6835 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -66,7 +66,7 @@ print_types1([{opaque, _Name} = Key|T], RecDict) -> io:format("\n~w: ~w\n", [Key, erl_types:t_from_form(Form, RecDict)]), print_types1(T, RecDict); print_types1([{record, _Name} = Key|T], RecDict) -> - {ok, [{Arity, Fields} = AF]} = dict:find(Key, RecDict), + {ok, [{_Arity, _Fields} = AF]} = dict:find(Key, RecDict), io:format("~w: ~w\n\n", [Key, AF]), print_types1(T, RecDict). -define(debug(D_), print_types(D_)). @@ -211,9 +211,9 @@ get_record_and_type_info([_Other|Left], Module, Records, RecDict) -> get_record_and_type_info([], _Module, Records, RecDict) -> case type_record_fields(lists:reverse(Records), RecDict) of {ok, _NewRecDict} = Ok -> - ?debug(NewRecDict), + ?debug(_NewRecDict), Ok; - {Name, {error, Error}} -> + {error, Name, Error} -> {error, lists:flatten(io_lib:format(" Error while parsing #~w{}: ~s\n", [Name, Error]))} end. @@ -269,9 +269,9 @@ type_record_fields([RecKey|Recs], RecDict) -> RecDict2 = dict:update(RecKey, Fun, RecDict1), type_record_fields(Recs, RecDict2) catch - throw:{error, _} = Error -> + throw:{error, Error} -> {record, Name} = RecKey, - {Name, Error} + {error, Name, Error} end. -spec process_record_remote_types(dialyzer_codeserver:codeserver()) -> dialyzer_codeserver:codeserver(). @@ -378,7 +378,7 @@ sets_filter([Mod|Mods], ExpTypes) -> -spec src_compiler_opts() -> [compile:option(),...]. src_compiler_opts() -> - [no_copt, to_core, binary, return_errors, + [no_copt, to_core, binary, return_errors, no_inline, strict_record_tests, strict_record_updates, no_is_record_optimization]. diff --git a/lib/docbuilder/src/docb_main.erl b/lib/docbuilder/src/docb_main.erl index 87a1401a02..4f5f035a65 100644 --- a/lib/docbuilder/src/docb_main.erl +++ b/lib/docbuilder/src/docb_main.erl @@ -34,14 +34,23 @@ %% Parses the source file File and transforms the result to html, %% latex and/or man page format. process(File, Opts) -> - - File1 = File ++ ".tmpconv", - os:cmd("sed -e 's/xi:include[ \t]*href/include file/g' -e 's/xmlns:xi=\"http:\\/\\/www.w3.org\\/2001\\/XInclude\"//g' < " ++ - File ++ ".xml > " ++ File1 ++ ".xml"), %LATH + + SrcType = docb_util:lookup_option(src_type, Opts), + + File1 = + case SrcType of + ".xml" -> + FileTmp = File ++ ".tmpconv", + os:cmd("sed -e 's/xi:include[ \t]*href/include file/g' -e 's/xmlns:xi=\"http:\\/\\/www.w3.org\\/2001\\/XInclude\"//g' < " ++ + File ++ ".xml > " ++ FileTmp ++ ".xml"), + FileTmp; + ".sgml" -> + File + end, case parse1(File1, Opts) of errors -> - file:delete(File1 ++ ".xml"), + delete_tmp_file(SrcType, File1), errors; {ok, Tree} -> From = element(1, Tree), @@ -62,15 +71,21 @@ process(File, Opts) -> Result = [transform(From, To, Opts, File, Tree)||To <- Tos], case lists:member(transformation_error,Result) of true -> - file:delete(File1 ++ ".xml"), + delete_tmp_file(SrcType, File1), errors; _ -> - file:delete(File1 ++ ".xml"), + delete_tmp_file(SrcType, File1), ok end end. + +delete_tmp_file(".xml", File) -> + file:delete(File ++ ".xml"); +delete_tmp_file(_, _) -> + ok. + %%---------------------------------------------------------------------- %% parse(File, Opts) -> {ok, Tree} | errors diff --git a/lib/edoc/src/edoc.erl b/lib/edoc/src/edoc.erl index ec452a5929..75b3bb451a 100644 --- a/lib/edoc/src/edoc.erl +++ b/lib/edoc/src/edoc.erl @@ -58,6 +58,8 @@ read_comments/1, read_comments/2, read_source/1, read_source/2]). +-compile({no_auto_import,[error/1]}). + -import(edoc_report, [report/2, report/3, error/1, error/3]). -include("edoc.hrl"). diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl index 900f0b3040..6cc2f5cd9b 100644 --- a/lib/edoc/src/edoc_layout.erl +++ b/lib/edoc/src/edoc_layout.erl @@ -482,7 +482,7 @@ local_defs([]) -> []; local_defs(Es) -> [?NL, {ul, [{class, "definitions"}], - lists:concat([[{li, [{tt, localdef(E)}]}, ?NL] || E <- Es])}]. + lists:append([[{li, [{tt, localdef(E)}]}, ?NL] || E <- Es])}]. localdef(E = #xmlElement{content = Es}) -> (case get_elem(typevar, Es) of diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl index 5b7fb1e0d2..c1f95a7a67 100644 --- a/lib/edoc/src/edoc_lib.erl +++ b/lib/edoc/src/edoc_lib.erl @@ -288,11 +288,13 @@ parse_expr(S, L) -> %% content in e.g. %% <a href="overview-summary.html#mtag-author">`@author'</a> tags. -%% @type info() = #info{name = string(), -%% mail = string(), -%% uri = string()} +%% @type info() = #info{name = string(), +%% email = string(), +%% uri = string()} --record(info, {name = "", email = "", uri = ""}). +-record(info, {name = "" :: string(), + email = "" :: string(), + uri = "" :: string()}). parse_contact(S, L) -> I = scan_name(S, L, #info{}, []), @@ -988,6 +990,14 @@ get_plugin(Key, Default, Opts) -> %% --------------------------------------------------------------------- %% Error handling +-type line() :: erl_scan:line(). +-type err() :: 'eof' + | {'missing', char()} + | {line(), atom(), string()} + | string(). + +-spec throw_error(err(), line()) -> no_return(). + throw_error({missing, C}, L) -> throw_error({"missing '~c'.", [C]}, L); throw_error(eof, L) -> diff --git a/lib/edoc/src/edoc_macros.erl b/lib/edoc/src/edoc_macros.erl index 2874e2940c..5b512cb53a 100644 --- a/lib/edoc/src/edoc_macros.erl +++ b/lib/edoc/src/edoc_macros.erl @@ -14,8 +14,6 @@ %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 %% USA %% -%% $Id$ -%% %% @private %% @copyright 2001-2005 Richard Carlsson %% @author Richard Carlsson <[email protected]> @@ -317,6 +315,14 @@ macro_content([C | Cs], As, L, N) -> macro_content([], _As, _L, _N) -> throw('end'). +-type line() :: erl_scan:line(). +-type err() :: 'unterminated_macro' + | 'macro_name' + | {'macro_name', string()} + | {string(), [string()]}. + +-spec throw_error(line(), err()) -> no_return(). + throw_error(L, unterminated_macro) -> throw_error(L, {"unexpected end of macro.", []}); throw_error(L, macro_name) -> diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl index 0eea8ae66f..91ee5a1b2b 100644 --- a/lib/edoc/src/edoc_parser.yrl +++ b/lib/edoc/src/edoc_parser.yrl @@ -404,6 +404,8 @@ parse_throws(S, L) -> %% --------------------------------------------------------------------- +-spec throw_error(term(), erl_scan:line()) -> no_return(). + throw_error({L, M, D}, _L0) -> throw({error,L,{format_error,M,D}}); throw_error({parse_spec, E}, L) -> diff --git a/lib/edoc/src/edoc_refs.erl b/lib/edoc/src/edoc_refs.erl index c2146bbe02..edc30674c0 100644 --- a/lib/edoc/src/edoc_refs.erl +++ b/lib/edoc/src/edoc_refs.erl @@ -14,8 +14,6 @@ %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 %% USA %% -%% $Id$ -%% %% @private %% @copyright 2003 Richard Carlsson %% @author Richard Carlsson <[email protected]> diff --git a/lib/edoc/src/edoc_run.erl b/lib/edoc/src/edoc_run.erl index 37025d6621..96e5ea4631 100644 --- a/lib/edoc/src/edoc_run.erl +++ b/lib/edoc/src/edoc_run.erl @@ -42,6 +42,8 @@ -export([file/1, application/1, packages/1, files/1, toc/1]). +-compile({no_auto_import,[error/1]}). + -import(edoc_report, [report/2, error/1]). diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl index 1f2cb99c75..c0b861e08a 100644 --- a/lib/edoc/src/edoc_tags.erl +++ b/lib/edoc/src/edoc_tags.erl @@ -330,6 +330,10 @@ parse_typedef(Data, Line, _Env, _Where) -> Def end. +-type line() :: erl_scan:line(). + +-spec parse_file(_, line(), _, _) -> no_return(). + parse_file(Data, Line, Env, _Where) -> case edoc_lib:parse_expr(Data, Line) of {string, _, File0} -> @@ -344,6 +348,8 @@ parse_file(Data, Line, Env, _Where) -> throw_error(Line, file_not_string) end. +-spec parse_header(_, line(), _, _) -> no_return(). + parse_header(Data, Line, Env, {Where, _}) -> parse_header(Data, Line, Env, Where); parse_header(Data, Line, Env, Where) when is_list(Where) -> @@ -362,6 +368,13 @@ parse_header(Data, Line, Env, Where) when is_list(Where) -> throw_error(Line, file_not_string) end. +-type err() :: 'file_not_string' + | {'file_not_found', file:filename()} + | {'read_file', file:filename(), term()} + | string(). + +-spec throw_error(line(), err()) -> no_return(). + throw_error(L, {read_file, File, R}) -> throw_error(L, {"error reading file '~s': ~w", [edoc_lib:filename(File), R]}); diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl index 85c9ee6f2a..b0255f793d 100644 --- a/lib/edoc/src/edoc_types.erl +++ b/lib/edoc/src/edoc_types.erl @@ -14,8 +14,6 @@ %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 %% USA %% -%% $Id$ -%% %% @private %% @copyright 2001-2003 Richard Carlsson %% @author Richard Carlsson <[email protected]> diff --git a/lib/erl_docgen/Makefile b/lib/erl_docgen/Makefile index c5bed632a5..93a6353cac 100644 --- a/lib/erl_docgen/Makefile +++ b/lib/erl_docgen/Makefile @@ -1,19 +1,20 @@ -# ``The contents of this file are subject to the Erlang Public License, +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1996-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 via the world wide web at http://www.erlang.org/. +# 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. # -# The Initial Developer of the Original Code is Ericsson Utvecklings AB. -# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings -# AB. All Rights Reserved.'' -# -# $Id$ +# %CopyrightEnd% # include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk @@ -22,9 +23,11 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # Macros # -SUB_DIRECTORIES = priv +SUB_DIRECTORIES = src priv #doc/src +include vsn.mk +VSN = $(ERL_DOCGEN_VSN) SPECIAL_TARGETS = diff --git a/lib/erl_docgen/ebin/.gitignore b/lib/erl_docgen/ebin/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/lib/erl_docgen/ebin/.gitignore diff --git a/lib/erl_docgen/priv/bin/specs_gen.escript b/lib/erl_docgen/priv/bin/specs_gen.escript new file mode 100644 index 0000000000..840fed6dd5 --- /dev/null +++ b/lib/erl_docgen/priv/bin/specs_gen.escript @@ -0,0 +1,129 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +%%% <script> [-I<dir>]... [-o<dir>] [-module Module] [File] +%%% +%%% Use EDoc and the layout module 'otp_specs' to create an XML file +%%% containing Dialyzer types and specifications (-type, -spec). +%%% +%%% Options: +%%% +%%% "-o<dir>" The output directory for the created file. +%%% Default is ".". +%%% "-I<dir>" Directory to be searched when including a file. +%%% "-module Module" +%%% Module name to use when there is no File argument. +%%% A temporary file will be created. +%%% Exactly one of -module Module and File must be given. +%%% +%%% The name of the generated file is "specs_<module>.xml". Its exact +%%% format is not further described here. + +main(Args) -> + case catch parse(Args, [], ".", no_module) of + {ok, FileSpec, InclFs, Dir} -> + call_edoc(FileSpec, InclFs, Dir); + {error, Msg} -> + io:format("~s\n", [Msg]), + usage() + end. + +parse(["-o"++Dir | Opts], InclFs, _, Module) -> + parse(Opts, InclFs, Dir, Module); +parse(["-I"++I | Opts], InclFs, Dir, Module) -> + parse(Opts, [I | InclFs], Dir, Module); +parse(["-module", Module | Opts], InclFs, Dir, _) -> + parse(Opts, InclFs, Dir, Module); +parse([File], InclFs, Dir, no_module) -> + {ok, {file, File}, lists:reverse(InclFs), Dir}; +parse([_], _, _, _) -> + {error, io_lib:format("Cannot have both -module option and file", [])}; +parse([], _, _, no_module) -> + {error, io_lib:format("Missing -module option or file", [])}; +parse([], InclFs, Dir, Module) -> + {ok, {module, Module}, lists:reverse(InclFs), Dir}; +parse(Args, _, _, _) -> + {error, io_lib:format("Bad arguments: ~p", [Args])}. + +usage() -> + io:format("usage: ~s [-I<include_dir>]... [-o<out_dir>] " + "[-module <module>] [file]\n", [escript:script_name()]), + halt(1). + +call_edoc(FileSpec, InclFs, Dir) -> + Incl = [{includes, InclFs}], + Pre = [{preprocess, true}], + Choice = [{dialyzer_specs, all}], + DirOpt = [{dir, Dir}], + Pretty = [{pretty_print, erl_pp}], + Layout = [{layout, otp_specs}, + {file_suffix, ".specs"}, + {stylesheet, ""}], + Warn = [{report_missing_type, false}, + {report_type_mismatch, false}], + OptionList = (DirOpt ++ Choice ++ Pre ++ Warn ++ Pretty ++ Layout ++ Incl), + {File, TmpFile} = case FileSpec of + {file, File0} -> + {File0, false}; + {module, Module} -> + {create_tmp_file(Dir, Module), true} + end, + try edoc:files([File], OptionList) of + ok -> + clean_up(Dir, File, TmpFile), + rename(Dir, File) + catch + _:_ -> + io:format("EDoc could not process file '~s'\n", [File]), + clean_up(Dir, File, TmpFile), + halt(3) + end. + +rename(Dir, F) -> + Mod = filename:basename(F, ".erl"), + Old = filename:join(Dir, Mod ++ ".specs"), + New = filename:join(Dir, "specs_" ++ Mod ++ ".xml"), + case file:rename(Old, New) of + ok -> + ok; + {error, R} -> + R1 = file:format_error(R), + io:format("could not rename file '~s': ~s\n", [New, R1]), + halt(2) + end. + +clean_up(Dir, File, TmpFile) -> + [file:delete(File) || TmpFile], + _ = [file:delete(filename:join(Dir, F)) || + F <- ["packages-frame.html", + "overview-summary.html", + "modules-frame.html", + "index.html", "erlang.png", "edoc-info"]], + ok. + +create_tmp_file(Dir, Module) -> + TmpFile = filename:join(Dir, Module++".erl"), + case file:write_file(TmpFile, "-module(" ++ Module ++ ").\n") of + ok -> + TmpFile; + {error, R} -> + R1 = file:format_error(R), + io:format("could not write file '~s': ~s\n", [TmpFile, R1]), + halt(2) + end. diff --git a/lib/erl_docgen/priv/bin/xref_mod_app.escript b/lib/erl_docgen/priv/bin/xref_mod_app.escript new file mode 100755 index 0000000000..fcc3a96ada --- /dev/null +++ b/lib/erl_docgen/priv/bin/xref_mod_app.escript @@ -0,0 +1,107 @@ +#!/usr/bin/env escript +%% -*- erlang -*- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% + +%%% Find all applications and all modules given a root directory. +%%% Output an XML file that can be used for finding which application +%%% a given module belongs to. +%%% +%%% Options: +%%% +%%% "-topdir <D>" Applications are found under D/lib/. +%%% The default value is $ERL_TOP. +%%% +%%% "-outfile <F>" Output is written onto F. +%%% The default value is "mod2app.xml". +%%% +%%% The output file has the following format: +%%% +%%% <?xml version="1.0"?> +%%% <mod2app> +%%% <module name="ModName1">AppName1</module> +%%% ... +%%% <mod2app> +%%% +%%% meaning that module ModName1 resides in application AppName1. + +main(Args) -> + case catch parse(Args, os:getenv("ERL_TOP"), "mod2app.xml") of + {ok, TopDir, OutFile} -> + case modapp(TopDir) of + [] -> + io:format("no applications found\n"), + halt(3); + MA -> + Layout = layout(MA), + XML = xmerl:export_simple(Layout, xmerl_xml), + write_file(XML, OutFile) + end; + {error, Msg} -> + io:format("~s\n", [Msg]), + usage() + end. + +parse(["-topdir", TopDir | Opts], _, OutFile) -> + parse(Opts, TopDir, OutFile); +parse(["-outfile", OutFile | Opts], TopDir, _) -> + parse(Opts, TopDir, OutFile); +parse([], TopDir, OutFile) -> + {ok, TopDir, OutFile}; +parse([Opt | _], _, _) -> + {error, io_lib:format("Bad option: ~p", [Opt])}. + +usage() -> + io:format("usage: ~s [-topdir <dir>] [-outfile <file>]\n", + [escript:script_name()]), + halt(1). + +modapp(TopDir) -> + AppDirs = filelib:wildcard(filename:join([TopDir,"lib","*"])), + AM = [appmods(D) || D <- AppDirs], + lists:keysort(1, [{M,A} || {A,Ms} <- AM, M <- Ms]). + +%% It's OK if too much data is generated as long as all applications +%% and all modules are mentioned. +appmods(D) -> + ErlFiles = filelib:wildcard(filename:join([D,"src","*.erl"])), + AppV = filename:basename(D), + App = case string:rstr(AppV, "-") of + 0 -> AppV; + P -> string:sub_string(AppV, 1, P-1) + end, + {App, [filename:basename(EF, ".erl") || EF <- ErlFiles]}. + +-include_lib("xmerl/include/xmerl.hrl"). + +-define(IND(N), lists:duplicate(N, $\s)). +-define(NL, "\n"). + +layout(MAL) -> + ML = lists:append([[?IND(2),{module,[{name,M}],[A]},?NL] || {M,A} <- MAL]), + [?NL,{mod2app,[?NL|ML]},?NL]. + +write_file(Text, File) -> + case file:open(File, [write]) of + {ok, FD} -> + io:put_chars(FD, Text), + ok = file:close(FD); + {error, R} -> + R1 = file:format_error(R), + io:format("could not write file '~s': ~s\n", [File, R1]), + halt(2) + end. diff --git a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd b/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd index 7b9974fbda..c1237766e1 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd +++ b/lib/erl_docgen/priv/docbuilder_dtd/common.refs.dtd @@ -26,15 +26,18 @@ <!ELEMENT description (%block;|quote|br|marker|warning|note)* > <!ELEMENT funcs (func)+ > -<!ELEMENT func (name+,fsummary,type?,desc?) > +<!ELEMENT func (name+,type_desc+,fsummary,type?,desc?) > <!-- ELEMENT name is defined in each ref dtd --> <!ELEMENT fsummary (#PCDATA|c|em)* > <!ELEMENT type (v,d?)+ > <!ELEMENT v (#PCDATA) > <!ELEMENT d (#PCDATA|c|em)* > -<!ELEMENT desc (%block;|quote|br|marker|warning|note)* > +<!ELEMENT desc (%block;|quote|br|marker|warning|note|anno)* > <!ELEMENT authors (aname,email)+ > <!ELEMENT aname (#PCDATA) > <!ELEMENT email (#PCDATA) > <!ELEMENT section (marker*,title,(%block;|quote|br|marker| warning|note)*) > +<!ELEMENT datatypes (datatype)+ > +<!ELEMENT datatype (name+,desc?) > +<!ELEMENT type_desc (#PCDATA) > diff --git a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd b/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd index 21656a1446..9905086ff4 100644 --- a/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd +++ b/lib/erl_docgen/priv/docbuilder_dtd/erlref.dtd @@ -22,7 +22,7 @@ %common.refs; <!ELEMENT erlref (header,module,modulesummary,description, - (section|funcs)*,authors?) > + (section|funcs|datatypes)*,authors?) > <!ELEMENT module (#PCDATA) > <!ELEMENT modulesummary (#PCDATA) > diff --git a/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent b/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent index 3df9970a43..7a07e2c406 100644 --- a/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent +++ b/lib/erl_docgen/priv/dtd_man_entities/xhtml-lat1.ent @@ -21,26 +21,26 @@ <!ENTITY sect "§"> <!-- section sign, U+00A7 ISOnum --> <!ENTITY uml "¨"> <!-- diaeresis = spacing diaeresis, U+00A8 ISOdia --> -<!ENTITY copy "©"> <!-- copyright sign, U+00A9 ISOnum --> +<!ENTITY copy "(C)"> <!-- copyright sign, U+00A9 ISOnum --> <!ENTITY ordf "ª"> <!-- feminine ordinal indicator, U+00AA ISOnum --> -<!ENTITY laquo "«"> <!-- left-pointing double angle quotation mark - = left pointing guillemet, U+00AB ISOnum --> +<!ENTITY laquo """> <!-- left-pointing double angle quotation mark + = left pointing guillemetn = " in man pages, U+00AB ISOnum --> <!ENTITY not "¬"> <!-- not sign = discretionary hyphen, U+00AC ISOnum --> -<!ENTITY shy "­"> <!-- soft hyphen = discretionary hyphen, +<!ENTITY shy ""> <!-- soft hyphen = discretionary hyphen, U+00AD ISOnum --> -<!ENTITY reg "®"> <!-- registered sign = registered trade mark sign, +<!ENTITY reg "(R)"> <!-- registered sign = registered trade mark sign, U+00AE ISOnum --> <!ENTITY macr "¯"> <!-- macron = spacing macron = overline = APL overbar, U+00AF ISOdia --> <!ENTITY deg "°"> <!-- degree sign, U+00B0 ISOnum --> -<!ENTITY plusmn "±"> <!-- plus-minus sign = plus-or-minus sign, +<!ENTITY plusmn "+/-"> <!-- plus-minus sign = plus-or-minus sign, U+00B1 ISOnum --> <!ENTITY sup2 "²"> <!-- superscript two = superscript digit two = squared, U+00B2 ISOnum --> <!ENTITY sup3 "³"> <!-- superscript three = superscript digit three = cubed, U+00B3 ISOnum --> -<!ENTITY acute "´"> <!-- acute accent = spacing acute, +<!ENTITY acute "'"> <!-- acute accent = spacing acute, U+00B4 ISOdia --> <!ENTITY micro "µ"> <!-- micro sign, U+00B5 ISOnum --> <!ENTITY para "¶"> <!-- pilcrow sign = paragraph sign, @@ -62,134 +62,134 @@ = fraction three quarters, U+00BE ISOnum --> <!ENTITY iquest "¿"> <!-- inverted question mark = turned question mark, U+00BF ISOnum --> -<!ENTITY Agrave "À"> <!-- latin capital letter A with grave +<!ENTITY Agrave "A"> <!-- latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 --> -<!ENTITY Aacute "Á"> <!-- latin capital letter A with acute, +<!ENTITY Aacute "A"> <!-- latin capital letter A with acute, U+00C1 ISOlat1 --> -<!ENTITY Acirc "Â"> <!-- latin capital letter A with circumflex, +<!ENTITY Acirc "A"> <!-- latin capital letter A with circumflex, U+00C2 ISOlat1 --> -<!ENTITY Atilde "Ã"> <!-- latin capital letter A with tilde, +<!ENTITY Atilde "A"> <!-- latin capital letter A with tilde, U+00C3 ISOlat1 --> -<!ENTITY Auml "Ä"> <!-- latin capital letter A with diaeresis, +<!ENTITY Auml "A"> <!-- latin capital letter A with diaeresis, U+00C4 ISOlat1 --> -<!ENTITY Aring "Å"> <!-- latin capital letter A with ring above +<!ENTITY Aring "A"> <!-- latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 --> -<!ENTITY AElig "Æ"> <!-- latin capital letter AE +<!ENTITY AElig "AE"> <!-- latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 --> -<!ENTITY Ccedil "Ç"> <!-- latin capital letter C with cedilla, +<!ENTITY Ccedil "C"> <!-- latin capital letter C with cedilla, U+00C7 ISOlat1 --> -<!ENTITY Egrave "È"> <!-- latin capital letter E with grave, +<!ENTITY Egrave "E"> <!-- latin capital letter E with grave, U+00C8 ISOlat1 --> -<!ENTITY Eacute "É"> <!-- latin capital letter E with acute, +<!ENTITY Eacute "E"> <!-- latin capital letter E with acute, U+00C9 ISOlat1 --> -<!ENTITY Ecirc "Ê"> <!-- latin capital letter E with circumflex, +<!ENTITY Ecirc "E"> <!-- latin capital letter E with circumflex, U+00CA ISOlat1 --> -<!ENTITY Euml "Ë"> <!-- latin capital letter E with diaeresis, +<!ENTITY Euml "E"> <!-- latin capital letter E with diaeresis, U+00CB ISOlat1 --> -<!ENTITY Igrave "Ì"> <!-- latin capital letter I with grave, +<!ENTITY Igrave "I"> <!-- latin capital letter I with grave, U+00CC ISOlat1 --> -<!ENTITY Iacute "Í"> <!-- latin capital letter I with acute, +<!ENTITY Iacute "I"> <!-- latin capital letter I with acute, U+00CD ISOlat1 --> -<!ENTITY Icirc "Î"> <!-- latin capital letter I with circumflex, +<!ENTITY Icirc "I"> <!-- latin capital letter I with circumflex, U+00CE ISOlat1 --> -<!ENTITY Iuml "Ï"> <!-- latin capital letter I with diaeresis, +<!ENTITY Iuml "I"> <!-- latin capital letter I with diaeresis, U+00CF ISOlat1 --> <!ENTITY ETH "Ð"> <!-- latin capital letter ETH, U+00D0 ISOlat1 --> -<!ENTITY Ntilde "Ñ"> <!-- latin capital letter N with tilde, +<!ENTITY Ntilde "N"> <!-- latin capital letter N with tilde, U+00D1 ISOlat1 --> -<!ENTITY Ograve "Ò"> <!-- latin capital letter O with grave, +<!ENTITY Ograve "O"> <!-- latin capital letter O with grave, U+00D2 ISOlat1 --> -<!ENTITY Oacute "Ó"> <!-- latin capital letter O with acute, +<!ENTITY Oacute "O"> <!-- latin capital letter O with acute, U+00D3 ISOlat1 --> -<!ENTITY Ocirc "Ô"> <!-- latin capital letter O with circumflex, +<!ENTITY Ocirc "O"> <!-- latin capital letter O with circumflex, U+00D4 ISOlat1 --> -<!ENTITY Otilde "Õ"> <!-- latin capital letter O with tilde, +<!ENTITY Otilde "O"> <!-- latin capital letter O with tilde, U+00D5 ISOlat1 --> -<!ENTITY Ouml "Ö"> <!-- latin capital letter O with diaeresis, +<!ENTITY Ouml "O"> <!-- latin capital letter O with diaeresis, U+00D6 ISOlat1 --> -<!ENTITY times "×"> <!-- multiplication sign, U+00D7 ISOnum --> +<!ENTITY times "x"> <!-- multiplication sign, U+00D7 ISOnum --> <!ENTITY Oslash "Ø"> <!-- latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 --> -<!ENTITY Ugrave "Ù"> <!-- latin capital letter U with grave, +<!ENTITY Ugrave "U"> <!-- latin capital letter U with grave, U+00D9 ISOlat1 --> -<!ENTITY Uacute "Ú"> <!-- latin capital letter U with acute, +<!ENTITY Uacute "U"> <!-- latin capital letter U with acute, U+00DA ISOlat1 --> -<!ENTITY Ucirc "Û"> <!-- latin capital letter U with circumflex, +<!ENTITY Ucirc "U"> <!-- latin capital letter U with circumflex, U+00DB ISOlat1 --> -<!ENTITY Uuml "Ü"> <!-- latin capital letter U with diaeresis, +<!ENTITY Uuml "U"> <!-- latin capital letter U with diaeresis, U+00DC ISOlat1 --> -<!ENTITY Yacute "Ý"> <!-- latin capital letter Y with acute, +<!ENTITY Yacute "Y"> <!-- latin capital letter Y with acute, U+00DD ISOlat1 --> <!ENTITY THORN "Þ"> <!-- latin capital letter THORN, U+00DE ISOlat1 --> <!ENTITY szlig "ß"> <!-- latin small letter sharp s = ess-zed, U+00DF ISOlat1 --> -<!ENTITY agrave "à"> <!-- latin small letter a with grave +<!ENTITY agrave "a"> <!-- latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 --> -<!ENTITY aacute "á"> <!-- latin small letter a with acute, +<!ENTITY aacute "a"> <!-- latin small letter a with acute, U+00E1 ISOlat1 --> -<!ENTITY acirc "â"> <!-- latin small letter a with circumflex, +<!ENTITY acirc "a"> <!-- latin small letter a with circumflex, U+00E2 ISOlat1 --> -<!ENTITY atilde "ã"> <!-- latin small letter a with tilde, +<!ENTITY atilde "a"> <!-- latin small letter a with tilde, U+00E3 ISOlat1 --> -<!ENTITY auml "ä"> <!-- latin small letter a with diaeresis, +<!ENTITY auml "a"> <!-- latin small letter a with diaeresis, U+00E4 ISOlat1 --> -<!ENTITY aring "å"> <!-- latin small letter a with ring above +<!ENTITY aring "a"> <!-- latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 --> -<!ENTITY aelig "æ"> <!-- latin small letter ae +<!ENTITY aelig "ae"> <!-- latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 --> -<!ENTITY ccedil "ç"> <!-- latin small letter c with cedilla, +<!ENTITY ccedil "c"> <!-- latin small letter c with cedilla, U+00E7 ISOlat1 --> -<!ENTITY egrave "è"> <!-- latin small letter e with grave, +<!ENTITY egrave "e"> <!-- latin small letter e with grave, U+00E8 ISOlat1 --> -<!ENTITY eacute "é"> <!-- latin small letter e with acute, +<!ENTITY eacute "e"> <!-- latin small letter e with acute, U+00E9 ISOlat1 --> -<!ENTITY ecirc "ê"> <!-- latin small letter e with circumflex, +<!ENTITY ecirc "e"> <!-- latin small letter e with circumflex, U+00EA ISOlat1 --> -<!ENTITY euml "ë"> <!-- latin small letter e with diaeresis, +<!ENTITY euml "e"> <!-- latin small letter e with diaeresis, U+00EB ISOlat1 --> -<!ENTITY igrave "ì"> <!-- latin small letter i with grave, +<!ENTITY igrave "i"> <!-- latin small letter i with grave, U+00EC ISOlat1 --> -<!ENTITY iacute "í"> <!-- latin small letter i with acute, +<!ENTITY iacute "i"> <!-- latin small letter i with acute, U+00ED ISOlat1 --> -<!ENTITY icirc "î"> <!-- latin small letter i with circumflex, +<!ENTITY icirc "i"> <!-- latin small letter i with circumflex, U+00EE ISOlat1 --> -<!ENTITY iuml "ï"> <!-- latin small letter i with diaeresis, +<!ENTITY iuml "i"> <!-- latin small letter i with diaeresis, U+00EF ISOlat1 --> <!ENTITY eth "ð"> <!-- latin small letter eth, U+00F0 ISOlat1 --> -<!ENTITY ntilde "ñ"> <!-- latin small letter n with tilde, +<!ENTITY ntilde "n"> <!-- latin small letter n with tilde, U+00F1 ISOlat1 --> -<!ENTITY ograve "ò"> <!-- latin small letter o with grave, +<!ENTITY ograve "o"> <!-- latin small letter o with grave, U+00F2 ISOlat1 --> -<!ENTITY oacute "ó"> <!-- latin small letter o with acute, +<!ENTITY oacute "o"> <!-- latin small letter o with acute, U+00F3 ISOlat1 --> -<!ENTITY ocirc "ô"> <!-- latin small letter o with circumflex, +<!ENTITY ocirc "o"> <!-- latin small letter o with circumflex, U+00F4 ISOlat1 --> -<!ENTITY otilde "õ"> <!-- latin small letter o with tilde, +<!ENTITY otilde "o"> <!-- latin small letter o with tilde, U+00F5 ISOlat1 --> -<!ENTITY ouml "ö"> <!-- latin small letter o with diaeresis, +<!ENTITY ouml "o"> <!-- latin small letter o with diaeresis, U+00F6 ISOlat1 --> <!ENTITY divide "÷"> <!-- division sign, U+00F7 ISOnum --> -<!ENTITY oslash "ø"> <!-- latin small letter o with stroke, +<!ENTITY oslash "o"> <!-- latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 --> -<!ENTITY ugrave "ù"> <!-- latin small letter u with grave, +<!ENTITY ugrave "u"> <!-- latin small letter u with grave, U+00F9 ISOlat1 --> -<!ENTITY uacute "ú"> <!-- latin small letter u with acute, +<!ENTITY uacute "u"> <!-- latin small letter u with acute, U+00FA ISOlat1 --> -<!ENTITY ucirc "û"> <!-- latin small letter u with circumflex, +<!ENTITY ucirc "u"> <!-- latin small letter u with circumflex, U+00FB ISOlat1 --> -<!ENTITY uuml "ü"> <!-- latin small letter u with diaeresis, +<!ENTITY uuml "u"> <!-- latin small letter u with diaeresis, U+00FC ISOlat1 --> -<!ENTITY yacute "ý"> <!-- latin small letter y with acute, +<!ENTITY yacute "y"> <!-- latin small letter y with acute, U+00FD ISOlat1 --> <!ENTITY thorn "þ"> <!-- latin small letter thorn with, U+00FE ISOlat1 --> -<!ENTITY yuml "ÿ"> <!-- latin small letter y with diaeresis, +<!ENTITY yuml "y"> <!-- latin small letter y with diaeresis, U+00FF ISOlat1 --> diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl index bba0f97645..732560e303 100644 --- a/lib/erl_docgen/priv/xsl/db_html.xsl +++ b/lib/erl_docgen/priv/xsl/db_html.xsl @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- +<!-- # # %CopyrightBegin% # @@ -17,15 +17,315 @@ # under the License. # # %CopyrightEnd% - + --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> + xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <xsl:include href="db_html_params.xsl"/> + <!-- Start of Dialyzer type/spec tags. + See also the template matching "name" and the template "menu.funcs" + --> + + <xsl:param name="specs_file" select="''"/> + <xsl:variable name="i" select="document($specs_file)"></xsl:variable> + + <xsl:param name="mod2app_file" select="''"/> + <xsl:variable name="m2a" select="document($mod2app_file)"></xsl:variable> + <xsl:key name="mod2app" match="module" use="@name"/> + + <xsl:template name="err"> + <xsl:param name="m"/> + <xsl:param name="n"/> + <xsl:param name="a"/> + <xsl:param name="s"/> + <xsl:message terminate="yes"> + Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if> + <xsl:value-of + select="$n"/>/<xsl:value-of + select="$a"/>: <xsl:value-of select="$s"/> + </xsl:message> + </xsl:template> + + <xsl:template name="spec_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="arity" select="@arity"/> + <xsl:variable name="clause" select="@clause"/> + <xsl:variable name="spec0" select= + "$i/specs/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec" select="$spec0[string-length($clause) = 0 + or position() = $clause]"/> + <xsl:if test="count($spec) = 0"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$arity"/> + <xsl:with-param name="s">unknown spec</xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:variable name="arity_clause"> + <xsl:choose> + <xsl:when test="string-length(@clause) > 0"> + <xsl:value-of select="@arity"/>/<xsl:value-of select="@clause"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@arity"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="ancestor::cref"> + <xsl:message terminate="yes"> + Error: did not expect a 'name' tag with name/arity attributes here! + </xsl:message> + </xsl:when> + <xsl:when test="ancestor::erlref"> + <a name="{$name}-{$arity_clause}"></a> + <xsl:choose> + <xsl:when test="string(@with_guards) = 'no'"> + <xsl:apply-templates select="$spec/contract/clause/head"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="contract"> + <xsl:with-param name="contract" select="$spec/contract"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + </xsl:choose> + </xsl:template> + + <xsl:template name="contract"> + <xsl:param name="contract"/> + <xsl:call-template name="clause"> + <xsl:with-param name="clause" select="$contract/clause"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="clause"> + <xsl:param name="clause"/> + <xsl:variable name="type_desc" select="../type_desc"/> + <xsl:for-each select="$clause"> + <xsl:apply-templates select="head"/> + <xsl:if test="count(guard) > 0"> + <xsl:call-template name="guard"> + <xsl:with-param name="guard" select="guard"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + </xsl:if> + </xsl:for-each> + </xsl:template> + + <xsl:template match="head"> + <span class="bold_code"> + <xsl:apply-templates/> + </span> + <br/> + </xsl:template> + + <xsl:template name="guard"> + <xsl:param name="guard"/> + <xsl:param name="type_desc"/> + <div class="REFBODY"><p>Types:</p> + <xsl:call-template name="subtype"> + <xsl:with-param name="subtype" select="$guard/subtype"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + </div> + </xsl:template> + + <xsl:template name="subtype"> + <xsl:param name="subtype"/> + <xsl:param name="type_desc"/> + <xsl:for-each select="$subtype"> + <xsl:variable name="tname" select="typename"/> + <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/> + <div class="REFTYPES"> + <span class="bold_code"> + <xsl:apply-templates select="string"/> + </span> + </div> + <xsl:apply-templates select="$type_desc[@name = $tname]"/> + </xsl:for-each> + </xsl:template> + + <!-- Note: <type_desc> has not been implemented for data types. --> + + <!-- Similar to <d> --> + <xsl:template match="type_desc"> + <div class="REFBODY"> + <xsl:apply-templates/> + </div> + </xsl:template> + + <!-- This is for debugging. All modules! --> + <xsl:template match="all_etypes"> + <xsl:for-each select= "$i//type"> + <pre> + <span class="bold_code"> + <xsl:apply-templates select="typedecl"/> + </span><xsl:text> +</xsl:text> + </pre> + </xsl:for-each> + </xsl:template> + + <!-- Datatypes --> + <xsl:template match="datatypes"> + <h3> + <xsl:text>DATA TYPES</xsl:text> + </h3> + <xsl:apply-templates/> + </xsl:template> + + <!-- Datatype --> + <xsl:template match="datatype"> + <p><xsl:apply-templates select="name"/></p> + <xsl:apply-templates select="desc"/> + </xsl:template> + + <xsl:template match="typehead"> + <span class="bold_code"> + <xsl:apply-templates/> + </span><br/> + </xsl:template> + + <!-- local_defs --> + <xsl:template match="local_defs"> + <div class="REFBODY"> + <xsl:apply-templates> + </xsl:apply-templates> + </div> + </xsl:template> + + <xsl:template match="local_def"> + <div class="REFTYPES"> + <span class="bold_code"> + <xsl:apply-templates/> + </span> + </div> + </xsl:template> + + <xsl:template name="type_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length(@n_vars) > 0"> + <xsl:value-of select="@n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="string-length($name) > 0"> + <xsl:variable name="type" select= + "$i/specs/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]"/> + + <xsl:if test="count($type) != 1"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n_vars"/> + <xsl:with-param name="s">unknown type</xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:apply-templates select="$type/typedecl"/> + </xsl:when> + <xsl:otherwise> + <span class="bold_code"> + <xsl:value-of select="."/> + </span> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Used both in <datatype> and in <func>! --> + <xsl:template match="anno"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="anno" select="normalize-space(text())"/> + <xsl:variable name="namespec" + select="ancestor::desc/preceding-sibling::name"/> + <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0"> + <xsl:call-template name="err"> + <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>) + </xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:variable name="mod" select="$namespec/@mod"/> + <xsl:variable name="name" select="$namespec/@name"/> + <xsl:variable name="arity" select="$namespec/@arity"/> + <xsl:variable name="clause" select="$namespec/@clause"/> + <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length($tmp_n_vars) > 0"> + <xsl:value-of select="$tmp_n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="spec0" select= + "$i/specs/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec_annos" select= + "$spec0[string-length($clause) = 0 + or position() = $clause]/anno[.=$anno]"/> + <xsl:variable name="type_annos" select= + "$i/specs/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/> + + <xsl:if test="count($spec_annos) = 0 + and count($type_annos) = 0 + and string-length($specs_file) > 0"> + <xsl:variable name="n"> + <xsl:choose> + <xsl:when test="string-length($arity) = 0"> + <xsl:value-of select="$n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$arity"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n"/> + <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/> + </xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:value-of select="$anno"/> + </xsl:template> + + <!-- Used for indentation of formatted types and specs --> + <xsl:template match="nbsp"> + <xsl:text> </xsl:text> + </xsl:template> + + <!-- End of Dialyzer type/spec tags --> + <!-- Page layout --> <xsl:template name="pagelayout"> <xsl:param name="chapnum"/> @@ -36,19 +336,19 @@ <title>Erlang -- <xsl:value-of select="header/title"/></title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"> - + <div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/> <script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script> <script language="JavaScript" type="text/javascript"> <xsl:text disable-output-escaping="yes"><![CDATA[ - <!-- + <!-- function getWinHeight() { var myHeight = 0; if( typeof( window.innerHeight ) == 'number' ) { //Non-IE myHeight = window.innerHeight; - } else if( document.documentElement && ( document.documentElement.clientWidth || + } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode' myHeight = document.documentElement.clientHeight; @@ -56,7 +356,7 @@ //IE 4 compatible myHeight = document.body.clientHeight; } - return myHeight; + return myHeight; } function setscrollpos() { @@ -64,16 +364,16 @@ document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2; } - function addEvent(obj, evType, fn){ - if (obj.addEventListener){ - obj.addEventListener(evType, fn, true); - return true; - } else if (obj.attachEvent){ - var r = obj.attachEvent("on"+evType, fn); - return r; - } else { - return false; - } + function addEvent(obj, evType, fn){ + if (obj.addEventListener){ + obj.addEventListener(evType, fn, true); + return true; + } else if (obj.attachEvent){ + var r = obj.attachEvent("on"+evType, fn); + return r; + } else { + return false; + } } addEvent(window, 'load', setscrollpos); @@ -85,7 +385,7 @@ <xsl:with-param name="chapnum" select="$chapnum"/> <xsl:with-param name="curModule" select="$curModule"/> </xsl:call-template> - + <div id="content"> <div class="innertube"> @@ -124,17 +424,17 @@ <xsl:if test="$lname = 'releasenotes'"> <!-- .../part --> <xsl:call-template name="releasenotes.content" /> - </xsl:if> + </xsl:if> <xsl:if test="$lname = 'part'"> <!-- .../part --> <xsl:call-template name="part.content" /> - </xsl:if> + </xsl:if> <xsl:if test="$lname = 'chapter'"> <!-- .../part/chapter --> <xsl:call-template name="chapter.content"> <xsl:with-param name="chapnum" select="$chapnum"/> </xsl:call-template> - </xsl:if> + </xsl:if> <xsl:if test="$lname = 'application'"> <!-- .../application --> <xsl:call-template name="app.content" /> @@ -178,37 +478,37 @@ <small> <xsl:if test="boolean(/book/parts/part)"> <a href="users_guide.html">User's Guide</a><br/> - </xsl:if> + </xsl:if> <xsl:if test="boolean(/book/applications)"> <a href="index.html">Reference Manual</a><br/> - </xsl:if> + </xsl:if> <xsl:if test="boolean(/book/releasenotes)"> <a href="release_notes.html">Release Notes</a><br/> - </xsl:if> + </xsl:if> <a href="{$pdfdir}/{$appname}-{$appver}.pdf">PDF</a><br/> <a href="{$topdocdir}/index.html">Top</a> </small> </xsl:template> - + <xsl:template name="menu_middle"> <!-- small> <xsl:choose> <xsl:when test="ancestor::parts"> <a href="users_guide_bibliography.html">Bibliography</a><br/> <a href="users_guide_glossary.html">Glossary</a><br/> - </xsl:when> - <xsl:when test="ancestor::applications"> + </xsl:when> + <xsl:when test="ancestor::applications"> <a href="ref_man_bibliography.html">Bibliography</a><br/> <a href="ref_man_glossary.html">Glossary</a><br/> - </xsl:when> + </xsl:when> </xsl:choose> </small --> <br/> <a href="javascript:openAllFlips()">Expand All</a><br/> <a href="javascript:closeAllFlips()">Contract All</a> - </xsl:template> - + </xsl:template> + <!-- Book --> <xsl:template match="/book"> @@ -243,7 +543,7 @@ <!-- Chapter/Section --> <xsl:template match="chapter/section"> - <xsl:param name="chapnum"/> + <xsl:param name="chapnum"/> <h3> <a name="{generate-id(title)}"> <xsl:value-of select="$chapnum"/>.<xsl:number/>  @@ -302,7 +602,7 @@ <!-- Lists --> - + <xsl:template match="list"> <xsl:param name="chapnum"/> <ul> @@ -330,7 +630,7 @@ </xsl:apply-templates> </dl> </xsl:template> - + <xsl:template match="taglist/tag"> <xsl:param name="chapnum"/> <dt> @@ -377,7 +677,7 @@ </xsl:apply-templates> </p> </div> - </div> + </div> </xsl:template> <!-- Paragraph --> @@ -402,7 +702,7 @@ </xsl:template> <xsl:template match="em"> - <strong><xsl:apply-templates/></strong> + <strong><xsl:apply-templates/></strong> </xsl:template> <!-- Code --> @@ -507,7 +807,7 @@ <!-- Part --> <xsl:template match="part"> <!-- Generate Glossary for Users Guide --> - <!--xsl:call-template name="glossary"> + <!--xsl:call-template name="glossary"> <xsl:with-param name="type">users_guide</xsl:with-param> </xsl:call-template--> @@ -530,9 +830,9 @@ <center><h4>Version <xsl:value-of select="$appver"/></h4></center> <center><h4><xsl:value-of select="$gendate"/></h4></center> - + <xsl:apply-templates select="chapter"/> - + </xsl:template> <!-- Menu.ug --> @@ -565,10 +865,10 @@ </xsl:call-template> </ul> </div> - </div> + </div> </xsl:template> - - + + <xsl:template name="menu.chapter"> <xsl:param name="entries"/> <xsl:param name="chapnum"/> @@ -596,7 +896,7 @@ <a href="{$chapter_file}.html"> Top of chapter </a> - </li> + </li> <xsl:call-template name="menu.section"> <xsl:with-param name="entries" select="section[title]"/> @@ -623,7 +923,7 @@ <!-- Chapter (if top tag)--> <xsl:template match="/chapter"> - <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes" + <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"> <xsl:call-template name="pagelayout"> @@ -635,7 +935,7 @@ <!-- Chapter --> <xsl:template match="chapter"> - <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes" + <xsl:document href="{substring-before(header/file, '.xml')}.html" method="html" encoding="UTF-8" indent="yes" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"> <xsl:call-template name="pagelayout"> @@ -670,7 +970,7 @@ <xsl:template match="application"> <!-- Generate Glossary for Ref. Manual --> - <!--xsl:call-template name="glossary"> + <!--xsl:call-template name="glossary"> <xsl:with-param name="type">ref_man</xsl:with-param> </xsl:call-template--> @@ -678,7 +978,7 @@ <!--xsl:call-template name="bibliography"> <xsl:with-param name="type">ref_man</xsl:with-param> </xsl:call-template--> - + <xsl:document href="{$outdir}/index.html" method="html" encoding="UTF-8" indent="yes" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"> @@ -695,9 +995,9 @@ <center><h4>Version <xsl:value-of select="$appver"/></h4></center> <center><h4><xsl:value-of select="$gendate"/></h4></center> - + <xsl:apply-templates select="erlref|cref|comref|fileref|appref"/> - + </xsl:template> <!-- Menu.ref --> @@ -730,16 +1030,16 @@ </xsl:call-template> </ul> </div> - </div> + </div> </xsl:template> - - + + <xsl:template name="menu.ref2"> <xsl:param name="entries"/> <!--xsl:param name="genFuncMenu"/--> <xsl:param name="curModule"/> <xsl:for-each select="$entries"> - + <xsl:variable name="cval"> <xsl:choose> <xsl:when test="local-name() = 'erlref'"> @@ -767,9 +1067,9 @@ <xsl:when test="local-name() = 'fileref'">false</xsl:when> <xsl:when test="descendant::funcs">true</xsl:when> <xsl:otherwise>false</xsl:otherwise> - </xsl:choose> + </xsl:choose> </xsl:variable> - + <xsl:variable name="expanded"> <xsl:choose> <xsl:when test="$curModule = $cval">true</xsl:when> @@ -796,7 +1096,7 @@ <a href="{$link_cval}.html"> Top of manual page </a> - </li> + </li> <xsl:call-template name="menu.funcs"> <xsl:with-param name="entries" select="funcs/func/name"/> @@ -823,7 +1123,7 @@ </xsl:otherwise> </xsl:choose> </xsl:otherwise> - </xsl:choose> + </xsl:choose> </xsl:for-each> </xsl:template> @@ -831,7 +1131,7 @@ <xsl:template name="menu.funcs"> <xsl:param name="entries"/> <xsl:param name="basename"/> - + <xsl:for-each select="$entries"> <xsl:choose> @@ -840,74 +1140,97 @@ <xsl:choose> <xsl:when test="string-length($fname) > 0"> <li title="{$fname}"> - <a href="{$basename}.html#{$fname}"> + <a href="{$basename}.html#{$fname}"> <xsl:value-of select="$fname"/>() </a> - </li> + </li> </xsl:when> <xsl:otherwise> <li title="{name/nametext}"> - <a href="{$basename}.html#{name/nametext}"> + <a href="{$basename}.html#{name/nametext}"> <xsl:value-of select="nametext"/>() - </a> - </li> + </a> + </li> </xsl:otherwise> - </xsl:choose> + </xsl:choose> </xsl:when> - + <xsl:when test="ancestor::erlref"> - + <xsl:variable name="tmpstring"> <xsl:value-of select="substring-before(substring-after(., '('), '->')"/> - </xsl:variable> - + </xsl:variable> + <xsl:variable name="ustring"> <xsl:choose> <xsl:when test="string-length($tmpstring) > 0"> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="$tmpstring"/> - </xsl:call-template> + </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="substring-after(., '(')"/> - </xsl:call-template> + </xsl:call-template> </xsl:otherwise> </xsl:choose> - </xsl:variable> - + </xsl:variable> + <xsl:variable name="arity"> - <xsl:call-template name="calc-arity"> - <xsl:with-param name="string" select="substring-before($ustring, ')')"/> - <xsl:with-param name="no-of-pars" select="0"/> - </xsl:call-template> - </xsl:variable> - + <xsl:choose> + <xsl:when test="string-length(@arity) > 0"> + <!-- Dialyzer spec --> + <xsl:choose> + <xsl:when test="string-length(@clause) > 0"> + <xsl:value-of select="@arity"/>/<xsl:value-of select="@clause"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="@arity"/> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="calc-arity"> + <xsl:with-param name="string" select="substring-before($ustring, ')')"/> + <xsl:with-param name="no-of-pars" select="0"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="fname"> - <xsl:variable name="fname1"> - <xsl:value-of select="substring-before(., '(')"/> - </xsl:variable> - <xsl:variable name="fname2"> - <xsl:value-of select="substring-after($fname1, 'erlang:')"/> - </xsl:variable> <xsl:choose> - <xsl:when test="string-length($fname2) > 0"> - <xsl:value-of select="$fname2"/> + <xsl:when test="string-length(@name) > 0"> + <!-- Dialyzer spec --> + <xsl:value-of select="@name"/> </xsl:when> <xsl:otherwise> - <xsl:value-of select="$fname1"/> + <xsl:variable name="fname1"> + <xsl:value-of select="substring-before(., '(')"/> + </xsl:variable> + <xsl:variable name="fname2"> + <xsl:value-of select="substring-after($fname1, 'erlang:')"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="string-length($fname2) > 0"> + <xsl:value-of select="$fname2"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$fname1"/> + </xsl:otherwise> + </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:variable> - + <li title="{$fname}-{$arity}"> - <a href="{$basename}.html#{$fname}-{$arity}"> + <a href="{$basename}.html#{$fname}-{$arity}"> <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/> </a> - </li> + </li> </xsl:when> </xsl:choose> - + </xsl:for-each> </xsl:template> @@ -1148,7 +1471,7 @@ <!-- Func --> <xsl:template match="func"> <xsl:param name="partnum"/> - + <p><xsl:apply-templates select="name"/></p> <xsl:apply-templates select="fsummary|type|desc"> @@ -1159,33 +1482,48 @@ <xsl:template match="name"> + <xsl:choose> + <!-- @arity is mandatory when referring to a specification --> + <xsl:when test="string-length(@arity) > 0"> + <xsl:call-template name="spec_name"/> + </xsl:when> + <xsl:when test="ancestor::datatype"> + <xsl:call-template name="type_name"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="name"> <xsl:variable name="tmpstring"> <xsl:value-of select="substring-before(substring-after(., '('), '->')"/> - </xsl:variable> + </xsl:variable> <xsl:variable name="ustring"> <xsl:choose> <xsl:when test="string-length($tmpstring) > 0"> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="$tmpstring"/> - </xsl:call-template> + </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="substring-after(., '(')"/> - </xsl:call-template> + </xsl:call-template> </xsl:otherwise> </xsl:choose> - </xsl:variable> - + </xsl:variable> + <xsl:variable name="arity"> <xsl:call-template name="calc-arity"> <xsl:with-param name="string" select="substring-before($ustring, ')')"/> - <xsl:with-param name="no-of-pars" select="0"/> + <xsl:with-param name="no-of-pars" select="0"/> </xsl:call-template> - </xsl:variable> - + </xsl:variable> + <xsl:choose> <xsl:when test="ancestor::cref"> <a name="{substring-before(nametext, '(')}"><span class="bold_code"><xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/></span></a><br/> @@ -1199,7 +1537,7 @@ <xsl:value-of select="substring-after($fname1, 'erlang:')"/> </xsl:variable> <xsl:choose> - <xsl:when test="string-length($fname2) > 0"> + <xsl:when test="string-length($fname2) > 0"> <xsl:value-of select="$fname2"/> </xsl:when> <xsl:otherwise> @@ -1213,21 +1551,20 @@ <span class="bold_code"><xsl:value-of select="."/></span> </xsl:otherwise> </xsl:choose> - - </xsl:template> + </xsl:template> <!-- Type --> <xsl:template match="type"> <xsl:param name="partnum"/> - <div class="REFBODY"><p>Types:</p> + <div class="REFBODY"><p>Types:</p> <xsl:apply-templates> <xsl:with-param name="partnum" select="$partnum"/> </xsl:apply-templates> </div> - + </xsl:template> @@ -1286,16 +1623,37 @@ <xsl:variable name="modulepart"><xsl:value-of select="substring-before($filepart, ':')"/></xsl:variable> <xsl:choose> <xsl:when test="string-length($modulepart) > 0"> - <xsl:variable name="filepart1"><xsl:value-of select="substring-after($filepart, ':')"/></xsl:variable> + <xsl:variable name="filepart1"><xsl:value-of select="substring-after($filepart, ':')"/></xsl:variable> <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$modulepart}','{$filepart1}.html#{$linkpart}');"><xsl:apply-templates/></a></span> </xsl:when> <xsl:otherwise> <xsl:choose> + <!-- Dialyzer seealso (the application is unknown) --> + <xsl:when test="string-length($specs_file) > 0 + and count($i/specs/module[@name=$filepart]) = 0"> + <!-- Deemed to slow; use key() instead + <xsl:variable name="app" + select="$m2a/mod2app/module[@name=$filepart]"/> + --> + <xsl:variable name="reftext" select="text()"/> + <xsl:for-each select="$m2a"> + <xsl:variable name="app" select="key('mod2app', $filepart)"/> + <xsl:choose> + <xsl:when test="string-length($app) > 0"> + <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$app}','{$filepart}.html');"><xsl:value-of select="$reftext"/></a></span> + </xsl:when> + <xsl:otherwise> + <!-- Unknown application; no link --> + <xsl:value-of select="$reftext"/> + </xsl:otherwise> + </xsl:choose> + </xsl:for-each> + </xsl:when> <xsl:when test="string-length($linkpart) > 0"> <span class="bold_code"><a href="{$filepart}.html#{$linkpart}"><xsl:apply-templates/></a></span> </xsl:when> - <xsl:otherwise> - <span class="bold_code"><a href="{$filepart}.html"><xsl:apply-templates/></a></span> + <xsl:otherwise> + <span class="bold_code"><a href="{$filepart}.html"><xsl:apply-templates/></a></span> </xsl:otherwise> </xsl:choose> </xsl:otherwise> @@ -1308,16 +1666,16 @@ </xsl:when> <xsl:otherwise> <xsl:variable name="modulepart"><xsl:value-of select="substring-before(@marker, ':')"/></xsl:variable> - + <xsl:choose> <xsl:when test="string-length($modulepart) > 0"> - <xsl:variable name="filepart1"><xsl:value-of select="substring-after(@marker, ':')"/></xsl:variable> + <xsl:variable name="filepart1"><xsl:value-of select="substring-after(@marker, ':')"/></xsl:variable> <span class="bold_code"><a href="javascript:erlhref('{$topdocdir}/../','{$modulepart}','{$filepart1}.html');"><xsl:apply-templates/></a></span> </xsl:when> <xsl:otherwise> - <span class="bold_code"><a href="{@marker}.html"><xsl:apply-templates/></a></span> + <span class="bold_code"><a href="{@marker}.html"><xsl:apply-templates/></a></span> </xsl:otherwise> - </xsl:choose> + </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:otherwise> @@ -1342,16 +1700,16 @@ <xsl:choose> <xsl:when test="ancestor::parts"> <a href="users_guide_glossary.html#{@id}"><xsl:value-of select="@id"/></a> - </xsl:when> - <xsl:when test="ancestor::applications"> + </xsl:when> + <xsl:when test="ancestor::applications"> <a href="ref_man_glossary.html#{@id}"><xsl:value-of select="@id"/></a> - </xsl:when> + </xsl:when> </xsl:choose> </xsl:when> <xsl:otherwise> <a href="{$topdocdir}/glossary.html#{@id}"><xsl:value-of select="@id"/></a> </xsl:otherwise> - </xsl:choose --> + </xsl:choose --> </xsl:template> <xsl:template match="cite"> @@ -1375,9 +1733,9 @@ <center><h4>Version <xsl:value-of select="$appver"/></h4></center> <center><h4><xsl:value-of select="$gendate"/></h4></center> - + <xsl:apply-templates select="chapter"/> - + </xsl:template> <!-- Menu.rn --> @@ -1410,7 +1768,7 @@ </xsl:call-template> </ul> </div> - </div> + </div> </xsl:template> <!-- Glossary --> @@ -1423,14 +1781,14 @@ <title>Erlang Documentation -- <xsl:value-of select="header/title"/></title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"> - + <div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/> <script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script> <!-- Generate menu --> <xsl:call-template name="menu"/> - + <div id="content"> <div class="innertube"> <h1>Glossary</h1> @@ -1478,14 +1836,14 @@ <title>Erlang Documentation -- <xsl:value-of select="header/title"/></title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"> - + <div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="{$topdocdir}/js/flipmenu/flipmenu.js"/> <script id="js2" type="text/javascript" src="{$topdocdir}/js/erlresolvelinks.js"></script> <!-- Generate menu --> <xsl:call-template name="menu"/> - + <div id="content"> <div class="innertube"> <h1>Bibliography</h1> @@ -1498,8 +1856,8 @@ <tr> <td><xsl:value-of select="@id"/></td> <td><xsl:value-of select="citedef"/></td> - </tr> - </xsl:if> + </tr> + </xsl:if> </xsl:for-each> </table> @@ -1529,7 +1887,7 @@ <xsl:template name="calc-arity"> <xsl:param name="string"/> <xsl:param name="no-of-pars"/> - + <xsl:variable name="length"> <xsl:value-of select="string-length($string)"/> </xsl:variable> @@ -1538,8 +1896,8 @@ <xsl:when test="$length > 0"> <xsl:call-template name="calc-arity"> <xsl:with-param name="string" select="substring-after($string, ',')"/> - <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/> - </xsl:call-template> + <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/> + </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$no-of-pars"/> @@ -1554,9 +1912,9 @@ <xsl:variable name="str1"> <xsl:call-template name="remove-paren-1"> <xsl:with-param name="string" select="$string"/> - <xsl:with-param name="start">(</xsl:with-param> - <xsl:with-param name="end">)</xsl:with-param> - </xsl:call-template> + <xsl:with-param name="start">(</xsl:with-param> + <xsl:with-param name="end">)</xsl:with-param> + </xsl:call-template> </xsl:variable> <xsl:variable name="str2"> @@ -1564,7 +1922,7 @@ <xsl:with-param name="string" select="$str1"/> <xsl:with-param name="start">{</xsl:with-param> <xsl:with-param name="end">}</xsl:with-param> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:variable name="str3"> @@ -1572,7 +1930,7 @@ <xsl:with-param name="string" select="$str2"/> <xsl:with-param name="start">[</xsl:with-param> <xsl:with-param name="end">]</xsl:with-param> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:value-of select="$str3"/> @@ -1584,7 +1942,7 @@ <xsl:param name="string"/> <xsl:param name="start"/> <xsl:param name="end"/> - + <xsl:variable name="tmp1"> <xsl:value-of select="substring-before($string, $start)"/> </xsl:variable> @@ -1597,7 +1955,7 @@ <xsl:variable name="retstring"> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="$tmp2"/> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/> </xsl:when> diff --git a/lib/erl_docgen/priv/xsl/db_man.xsl b/lib/erl_docgen/priv/xsl/db_man.xsl index 71c4a66707..2a8fb9fe3e 100644 --- a/lib/erl_docgen/priv/xsl/db_man.xsl +++ b/lib/erl_docgen/priv/xsl/db_man.xsl @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- +<!-- # # %CopyrightBegin% # @@ -17,24 +17,294 @@ # under the License. # # %CopyrightEnd% - + --> <xsl:stylesheet version="1.0" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:preserve-space elements="code pre"/> <xsl:strip-space elements="*"/> <xsl:output method="text" encoding="UTF-8" indent="no"/> + <!-- Start of Dialyzer type/spec tags. See also the template matching "name" + --> + + <!-- Note: specs data for *one* module (as opposed to html and pdf) --> + <xsl:param name="specs_file" select="''"/> + <xsl:variable name="i" select="document($specs_file)"></xsl:variable> + + <xsl:template name="err"> + <xsl:param name="m"/> + <xsl:param name="n"/> + <xsl:param name="a"/> + <xsl:param name="s"/> + <xsl:message terminate="yes"> + Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if> + <xsl:value-of + select="$n"/>/<xsl:value-of + select="$a"/>: <xsl:value-of select="$s"/> + </xsl:message> + </xsl:template> + + <xsl:template name="spec_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="arity" select="@arity"/> + <xsl:variable name="clause" select="@clause"/> + <xsl:variable name="spec0" select= + "$i/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec" select="$spec0[string-length($clause) = 0 + or position() = $clause]"/> + <xsl:if test="count($spec) = 0"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$arity"/> + <xsl:with-param name="s">unknown spec</xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:choose> + <xsl:when test="ancestor::cref"> + <xsl:message terminate="yes"> + Error: did not expect a 'name' tag with name/arity attributes here! + </xsl:message> + </xsl:when> + <xsl:when test="ancestor::erlref"> + <xsl:choose> + <xsl:when test="string(@with_guards) = 'no'"> + <xsl:apply-templates select="$spec/contract/clause/head"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="contract"> + <xsl:with-param name="contract" select="$spec/contract"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + <xsl:text> .br</xsl:text> + </xsl:when> + </xsl:choose> + </xsl:template> + + <xsl:template name="contract"> + <xsl:param name="contract"/> + <xsl:call-template name="clause"> + <xsl:with-param name="clause" select="$contract/clause"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="clause"> + <xsl:param name="clause"/> + <xsl:variable name="type_desc" select="../type_desc"/> + <xsl:for-each select="$clause"> + <xsl:apply-templates select="head"/> + <xsl:if test="count(guard) > 0"> + <xsl:call-template name="guard"> + <xsl:with-param name="guard" select="guard"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + </xsl:if> + </xsl:for-each> + </xsl:template> + + <xsl:template match="head"> + <xsl:text> .nf </xsl:text> + <xsl:text> .B </xsl:text> + <xsl:apply-templates/> + <xsl:text> .br</xsl:text> + <xsl:text> .fi</xsl:text> + </xsl:template> + + <xsl:template name="guard"> + <xsl:param name="guard"/> + <xsl:param name="type_desc"/> + <xsl:text> .RS</xsl:text> + <xsl:text> .TP</xsl:text> + <xsl:text> Types</xsl:text> + <xsl:call-template name="subtype"> + <xsl:with-param name="subtype" select="$guard/subtype"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + <xsl:text> .RE</xsl:text> + </xsl:template> + + <xsl:template name="subtype"> + <xsl:param name="subtype"/> + <xsl:param name="type_desc"/> + <xsl:for-each select="$subtype"> + <xsl:variable name="tname" select="typename"/> + <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/> + <xsl:text> </xsl:text> + <xsl:apply-templates select="string"/> + <xsl:text> .br</xsl:text> + <xsl:apply-templates select="$type_desc[@name = $tname]"/> + </xsl:for-each> + </xsl:template> + + <!-- Note: <type_desc> has not been implemented for data types. --> + + <!-- Similar to <d> --> + <xsl:template match="type_desc"> + <xsl:text> </xsl:text><xsl:apply-templates/> + <xsl:text> .br</xsl:text> + </xsl:template> + + <!-- Datatypes --> + <xsl:template match="datatypes"> + <xsl:text> .SH DATA TYPES</xsl:text> + <xsl:apply-templates/> + </xsl:template> + + <!-- Datatype --> + <xsl:template match="datatype"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="typehead"> + <xsl:text> .nf </xsl:text> + <xsl:text> .B </xsl:text> + <xsl:apply-templates/> + <xsl:text> .br</xsl:text> + <xsl:text> .fi</xsl:text> + </xsl:template> + + <xsl:template match="local_defs"> + <xsl:text> .RS</xsl:text> + <xsl:apply-templates/> + <xsl:text> .RE</xsl:text> + </xsl:template> + + <xsl:template match="local_def"> + <xsl:text> </xsl:text> + <xsl:apply-templates/> + <xsl:text> .br</xsl:text> + </xsl:template> + + <xsl:template name="type_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length(@n_vars) > 0"> + <xsl:value-of select="@n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="string-length($name) > 0"> + <xsl:variable name="type" select= + "$i/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]"/> + + <xsl:if test="count($type) != 1"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n_vars"/> + <xsl:with-param name="s">unknown type</xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:apply-templates select="$type/typedecl"/> + </xsl:when> + <xsl:otherwise> + <xsl:text> .nf </xsl:text> + <xsl:text> .B </xsl:text> + <xsl:apply-templates/> + <xsl:text> .br</xsl:text> + <xsl:text> .fi</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Used both in <datatype> and in <func>! --> + <xsl:template match="anno"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="anno" select="normalize-space(text())"/> + <xsl:variable name="namespec" + select="ancestor::desc/preceding-sibling::name"/> + <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0"> + <xsl:call-template name="err"> + <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>) + </xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:variable name="mod" select="$namespec/@mod"/> + <xsl:variable name="name" select="$namespec/@name"/> + <xsl:variable name="arity" select="$namespec/@arity"/> + <xsl:variable name="clause" select="$namespec/@clause"/> + <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length($tmp_n_vars) > 0"> + <xsl:value-of select="$tmp_n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="spec0" select= + "$i/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec_annos" select= + "$spec0[string-length($clause) = 0 + or position() = $clause]/anno[.=$anno]"/> + <xsl:variable name="type_annos" select= + "$i/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/> + + <xsl:if test="count($spec_annos) = 0 + and count($type_annos) = 0 + and string-length($specs_file) > 0"> + <xsl:variable name="n"> + <xsl:choose> + <xsl:when test="string-length($arity) = 0"> + <xsl:value-of select="$n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$arity"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n"/> + <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/> + </xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:value-of select="$anno"/> + </xsl:template> + + <!-- Used for indentation of formatted types and specs --> + <xsl:template match="nbsp"> + <xsl:text> </xsl:text> + </xsl:template> + + <!-- End of Dialyzer type/spec tags --> + <!-- Header --> <xsl:template match="header"> </xsl:template> - + <!-- Section/Title --> <xsl:template match="section/title"> </xsl:template> - + <!-- *ref/Section --> <xsl:template match="erlref/section|comref/section|cref/section|fileref/section|appref/section"> <xsl:text> .SH "</xsl:text><xsl:value-of select="translate(title, 'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text>" </xsl:text> @@ -49,11 +319,11 @@ <!-- Lists --> - + <xsl:template match="list"> <xsl:text> .RS 2</xsl:text> <xsl:apply-templates/> - <xsl:text> .RE</xsl:text> + <xsl:text> .RE </xsl:text> </xsl:template> <xsl:template match="list/item"> @@ -66,9 +336,9 @@ <xsl:template match="taglist"> <xsl:text> .RS 2</xsl:text> <xsl:apply-templates select="tag|item"/> - <xsl:text> .RE</xsl:text> + <xsl:text> .RE </xsl:text> </xsl:template> - + <xsl:template match="taglist/tag"> <xsl:text> .TP 2 </xsl:text> <xsl:text>.B </xsl:text> @@ -76,7 +346,7 @@ </xsl:template> <xsl:template match="taglist/item"> - <xsl:apply-templates/> + <xsl:apply-templates/> </xsl:template> <xsl:template match="item/p"> @@ -88,10 +358,10 @@ <xsl:value-of select="$content"/> </xsl:when> <xsl:otherwise> - <xsl:text> .RS 2</xsl:text> - <xsl:text> .LP .LP </xsl:text> + <xsl:text> .RS 2</xsl:text> + <xsl:text> .LP .LP </xsl:text> <xsl:value-of select="$content"/> - <xsl:text> .RE</xsl:text> + <xsl:text> .RE</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -171,7 +441,7 @@ <xsl:template match="application"> <xsl:apply-templates/> </xsl:template> - + <!-- Erlref --> <xsl:template match="/erlref"> <xsl:variable name="companyname"> @@ -184,7 +454,7 @@ <xsl:text>.TH </xsl:text><xsl:value-of select="module"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Module Definition" </xsl:text> <xsl:text>.SH NAME </xsl:text> - <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text> </xsl:text> + <xsl:value-of select="module"/><xsl:text> \- </xsl:text><xsl:value-of select="modulesummary"/><xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template> @@ -199,7 +469,7 @@ </xsl:variable> <xsl:text>.TH </xsl:text><xsl:value-of select="com"/><xsl:text> 1 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "User Commands" </xsl:text> <xsl:text>.SH NAME </xsl:text> - <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text> </xsl:text> + <xsl:value-of select="com"/><xsl:text> \- </xsl:text><xsl:value-of select="comsummary"/><xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template> @@ -214,7 +484,7 @@ </xsl:variable> <xsl:text>.TH </xsl:text><xsl:value-of select="lib"/><xsl:text> 3 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "C Library Functions" </xsl:text> <xsl:text>.SH NAME </xsl:text> - <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text> </xsl:text> + <xsl:value-of select="lib"/><xsl:text> \- </xsl:text><xsl:value-of select="libsummary"/><xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template> @@ -229,7 +499,7 @@ </xsl:variable> <xsl:text>.TH </xsl:text><xsl:value-of select="file"/><xsl:text> 5 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Files" </xsl:text> <xsl:text>.SH NAME </xsl:text> - <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text> </xsl:text> + <xsl:value-of select="file"/><xsl:text> \- </xsl:text><xsl:value-of select="filesummary"/><xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template> @@ -244,7 +514,7 @@ </xsl:variable> <xsl:text>.TH </xsl:text><xsl:value-of select="app"/><xsl:text> 7 "</xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/><xsl:text>" "</xsl:text><xsl:value-of select="$companyname"/><xsl:text>" "Erlang Application Definition" </xsl:text> <xsl:text>.SH NAME </xsl:text> - <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text> </xsl:text> + <xsl:value-of select="app"/><xsl:text> \- </xsl:text><xsl:value-of select="appsummary"/><xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:template> @@ -271,10 +541,26 @@ <!-- Func --> <xsl:template match="func"> <xsl:text> .LP</xsl:text> - <xsl:apply-templates/> + <xsl:apply-templates select="name"/> + <xsl:apply-templates select="fsummary|type|desc"/> </xsl:template> <xsl:template match="name"> + <xsl:choose> + <!-- @arity is mandatory when referring to a specification --> + <xsl:when test="string-length(@arity) > 0"> + <xsl:call-template name="spec_name"/> + </xsl:when> + <xsl:when test="ancestor::datatype"> + <xsl:call-template name="type_name"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="name"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="name"> <xsl:text> .B </xsl:text> <xsl:apply-templates/> <xsl:text> .br</xsl:text> @@ -296,7 +582,7 @@ <xsl:text> </xsl:text><xsl:value-of select="normalize-space(text())"/> <xsl:text> .br</xsl:text> </xsl:template> - + <!-- D --> <xsl:template match="d"> <xsl:text> </xsl:text><xsl:apply-templates/> @@ -316,7 +602,7 @@ <!-- This tag is skipped for now. --> </xsl:template> - + <!-- Authors --> <xsl:template match="authors"> <xsl:text> .SH AUTHORS</xsl:text> @@ -338,19 +624,26 @@ <!-- Do not noramlize any text within pre and code tags. --> <xsl:template match="pre/text()"> - <xsl:value-of select="."/> + <xsl:call-template name="replace-string"> + <xsl:with-param name="text" select="." /> + <xsl:with-param name="replace" select=""\"" /> + <xsl:with-param name="with" select=""\\"" /> + </xsl:call-template> </xsl:template> <xsl:template match="code/text()"> - <xsl:value-of select="."/> + <xsl:call-template name="replace-string"> + <xsl:with-param name="text" select="." /> + <xsl:with-param name="replace" select=""\"" /> + <xsl:with-param name="with" select=""\\"" /> + </xsl:call-template> </xsl:template> - <!-- Replace ' by \&' ans . by \&. --> <xsl:template match="text()"> <xsl:variable name="startstring"> <xsl:value-of select="normalize-space()"/><xsl:text> </xsl:text> - </xsl:variable> + </xsl:variable> <xsl:variable name="rep1"> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="$startstring" /> diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl index e12b4d219a..1e80c360b8 100644 --- a/lib/erl_docgen/priv/xsl/db_pdf.xsl +++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- +<!-- # # %CopyrightBegin% # @@ -17,7 +17,7 @@ # under the License. # # %CopyrightEnd% - + --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" @@ -27,16 +27,310 @@ <xsl:include href="db_pdf_params.xsl"/> + <!-- Start of Dialyzer type/spec tags. + See also the template matching "name" and the template "bookmarks6" + --> + + <xsl:param name="specs_file" select="''"/> + <xsl:variable name="i" select="document($specs_file)"></xsl:variable> + + <xsl:template name="err"> + <xsl:param name="m"/> + <xsl:param name="n"/> + <xsl:param name="a"/> + <xsl:param name="s"/> + <xsl:message terminate="yes"> + Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if> + <xsl:value-of + select="$n"/>/<xsl:value-of + select="$a"/>: <xsl:value-of select="$s"/> + </xsl:message> + </xsl:template> + + <xsl:template name="spec_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="arity" select="@arity"/> + <xsl:variable name="clause" select="@clause"/> + <xsl:variable name="spec0" select= + "$i/specs/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec" select="$spec0[string-length($clause) = 0 + or position() = $clause]"/> + <xsl:if test="count($spec) = 0"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$arity"/> + <xsl:with-param name="s">unknown spec</xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:choose> + <xsl:when test="ancestor::cref"> + <xsl:message terminate="yes"> + Error: did not expect a 'name' tag with name/arity attributes here! + </xsl:message> + </xsl:when> + <xsl:when test="ancestor::erlref"> + <fo:block id="{generate-id()}"> + <xsl:choose> + <xsl:when test="string(@with_guards) = 'no'"> + <xsl:apply-templates select="$spec/contract/clause/head"/> + </xsl:when> + <xsl:otherwise> + <xsl:call-template name="contract"> + <xsl:with-param name="contract" select="$spec/contract"/> + </xsl:call-template> + </xsl:otherwise> + </xsl:choose> + </fo:block> + </xsl:when> + </xsl:choose> + </xsl:template> + + <xsl:template name="contract"> + <xsl:param name="contract"/> + <xsl:call-template name="clause"> + <xsl:with-param name="clause" select="$contract/clause"/> + </xsl:call-template> + </xsl:template> + + <xsl:template name="clause"> + <xsl:param name="clause"/> + <xsl:variable name="type_desc" select="../type_desc"/> + <xsl:for-each select="$clause"> + <xsl:apply-templates select="head"/> + <xsl:if test="count(guard) > 0"> + <xsl:call-template name="guard"> + <xsl:with-param name="guard" select="guard"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + </xsl:if> + </xsl:for-each> + </xsl:template> + + <xsl:template match="head"> + <fo:block xsl:use-attribute-sets="function-name"> + <xsl:apply-templates/> + </fo:block> + </xsl:template> + + <xsl:template name="guard"> + <fo:block> + <xsl:text>Types:</xsl:text> + </fo:block> + <fo:list-block xsl:use-attribute-sets="type-listblock"> + <xsl:call-template name="subtype"> + <xsl:with-param name="subtype" select="$guard/subtype"/> + <xsl:with-param name="type_desc" select="$type_desc"/> + </xsl:call-template> + </fo:list-block> + </xsl:template> + + <xsl:template name="subtype"> + <xsl:param name="subtype"/> + <xsl:param name="type_desc"/> + <xsl:for-each select="$subtype"> + <xsl:variable name="tname" select="typename"/> + <xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/> + <fo:list-item xsl:use-attribute-sets="type-listitem"> + <fo:list-item-label end-indent="label-end()"> + <fo:block> + </fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()" format="justify"> + <fo:block font-weight="bold"> + <xsl:apply-templates select="string"/> + </fo:block> + </fo:list-item-body> + </fo:list-item> + <xsl:apply-templates select="$type_desc[@name = $tname]"/> + </xsl:for-each> + </xsl:template> + + <!-- Note: <type_desc> has not been implemented for data types. --> + + <!-- Similar to <d> --> + <xsl:template match="type_desc"> + <fo:list-item xsl:use-attribute-sets="type-listitem"> + <fo:list-item-label end-indent="label-end()"><fo:block></fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()" format="justify"> + <fo:block> + <xsl:apply-templates/> + </fo:block> + </fo:list-item-body> + </fo:list-item> + </xsl:template> + + <!-- Datatypes --> + <xsl:template match="datatypes"> + <fo:block xsl:use-attribute-sets="h3"> + <xsl:text>Data Types</xsl:text> + </fo:block> + <xsl:apply-templates/> + </xsl:template> + + <!-- Datatype --> + <xsl:template match="datatype"> + <fo:block xsl:use-attribute-sets="function-name"> + <xsl:apply-templates select="name"/> + </fo:block> + <xsl:apply-templates select="desc"/> + </xsl:template> + + <!-- Like <head>... --> + <xsl:template match="typehead"> + <fo:block xsl:use-attribute-sets="function-name"> + <xsl:apply-templates/> + </fo:block> + </xsl:template> + + <!-- Like <guard>, except "Types:"... --> + <xsl:template match="local_defs"> + <fo:list-block xsl:use-attribute-sets="type-listblock"> + <xsl:apply-templates/> + </fo:list-block> + </xsl:template> + + <!-- Like <subtype>... --> + <xsl:template match="local_def"> + <fo:list-item xsl:use-attribute-sets="type-listitem"> + <fo:list-item-label end-indent="label-end()"> + <fo:block> + </fo:block> + </fo:list-item-label> + <fo:list-item-body start-indent="body-start()" format="justify"> + <fo:block font-weight="bold"> + <xsl:apply-templates/> + </fo:block> + </fo:list-item-body> + </fo:list-item> + </xsl:template> + + <xsl:template name="type_name"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="mod" select="@mod"/> + <xsl:variable name="name" select="@name"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length(@n_vars) > 0"> + <xsl:value-of select="@n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="string-length($name) > 0"> + <xsl:variable name="type" select= + "$i/specs/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]"/> + + <xsl:if test="count($type) != 1"> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n_vars"/> + <xsl:with-param name="s">unknown type</xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:apply-templates select="$type/typedecl"/> + </xsl:when> + <xsl:otherwise> + <fo:inline font-weight="bold" xsl:use-attribute-sets="type-listitem"> + <xsl:value-of select="."/> + </fo:inline> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- Used both in <datatype> and in <func>! --> + <xsl:template match="anno"> + <xsl:variable name="curModule" select="ancestor::erlref/module"/> + <xsl:variable name="anno" select="normalize-space(text())"/> + <xsl:variable name="namespec" + select="ancestor::desc/preceding-sibling::name"/> + <xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0"> + <xsl:call-template name="err"> + <xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>) + </xsl:with-param> + </xsl:call-template> + </xsl:if> + + <xsl:variable name="mod" select="$namespec/@mod"/> + <xsl:variable name="name" select="$namespec/@name"/> + <xsl:variable name="arity" select="$namespec/@arity"/> + <xsl:variable name="clause" select="$namespec/@clause"/> + <xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/> + <xsl:variable name="n_vars"> + <xsl:choose> + <xsl:when test="string-length($tmp_n_vars) > 0"> + <xsl:value-of select="$tmp_n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="0"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:variable name="spec0" select= + "$i/specs/module[@name=$curModule]/spec + [name=$name and arity=$arity + and (string-length($mod) = 0 or module = $mod)]"/> + <xsl:variable name="spec_annos" select= + "$spec0[string-length($clause) = 0 + or position() = $clause]/anno[.=$anno]"/> + <xsl:variable name="type_annos" select= + "$i/specs/module[@name=$curModule]/type + [name=$name and n_vars=$n_vars + and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/> + + <xsl:if test="count($spec_annos) = 0 + and count($type_annos) = 0 + and string-length($specs_file) > 0"> + <xsl:variable name="n"> + <xsl:choose> + <xsl:when test="string-length($arity) = 0"> + <xsl:value-of select="$n_vars"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$arity"/> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <xsl:call-template name="err"> + <xsl:with-param name="m" select="$mod"/> + <xsl:with-param name="n" select="$name"/> + <xsl:with-param name="a" select="$n"/> + <xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/> + </xsl:with-param> + </xsl:call-template> + </xsl:if> + <xsl:value-of select="$anno"/> + </xsl:template> + + <!-- Used for indentation of formatted types and specs --> + <xsl:template match="nbsp"> + <xsl:text> </xsl:text> + </xsl:template> + + <!-- End of Dialyzer type/spec tags --> <xsl:template match="/"> <xsl:apply-templates select="book"/> </xsl:template> - + <xsl:template match="book"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> - <!-- Master pages --> + <!-- Master pages --> <fo:layout-master-set> <fo:simple-page-master master-name="cover" @@ -47,7 +341,7 @@ <xsl:attribute name="page-width"> <xsl:value-of select="$page-width"/> </xsl:attribute> - <fo:region-body + <fo:region-body margin="0mm"/> </fo:simple-page-master> @@ -63,7 +357,7 @@ <xsl:attribute name="page-width"> <xsl:value-of select="$page-width"/> </xsl:attribute> - <fo:region-body + <fo:region-body margin-top="15mm" margin-bottom="20mm"/> <fo:region-before @@ -100,10 +394,10 @@ <fo:page-sequence-master master-name="document"> <fo:repeatable-page-master-alternatives> - <fo:conditional-page-master-reference + <fo:conditional-page-master-reference master-reference="left-page" odd-or-even="even"/> - <fo:conditional-page-master-reference + <fo:conditional-page-master-reference master-reference="right-page" odd-or-even="odd"/> </fo:repeatable-page-master-alternatives> @@ -166,7 +460,7 @@ <fo:flow flow-name="xsl-region-body"> <fo:block> - + </fo:block> <xsl:apply-templates select="parts"/> @@ -189,7 +483,7 @@ <!-- Cover page --> <xsl:template match="header/title"> - <fo:page-sequence + <fo:page-sequence font-family="sans-serif" force-page-count="even" master-reference="cover"> @@ -242,7 +536,7 @@ the License for the specific language governing rights and limitations under the License. - The Initial Developer of the Original Code is + The Initial Developer of the Original Code is --> <xsl:value-of select="$companyname"/>. </fo:block> @@ -281,22 +575,22 @@ <xsl:template name="bookmarks1"> <xsl:param name="entries"/> <xsl:if test="$entries != ''"> - + <fo:bookmark internal-destination="{generate-id(/book/parts/part)}" starting-state="hide"> <fo:bookmark-title>User's Guide</fo:bookmark-title> - + <xsl:for-each select="$entries"> <xsl:call-template name="bookmarks2"> <xsl:with-param name="entries" select="chapter[header/title]"/> </xsl:call-template> </xsl:for-each> - + </fo:bookmark> </xsl:if> </xsl:template> - + <xsl:template name="bookmarks2"> <xsl:param name="entries"/> <xsl:for-each select="$entries"> @@ -341,7 +635,7 @@ starting-state="hide"> <fo:bookmark-title>Reference Manual</fo:bookmark-title> <xsl:for-each select="$entries"> - + <xsl:call-template name="bookmarks5"> <xsl:with-param name="entries" select="erlref[module]|comref[com]|cref[lib]|fileref[file]|appref[app]"/> @@ -387,7 +681,7 @@ <fo:bookmark internal-destination="{generate-id(nametext)}" starting-state="hide"> <xsl:variable name="fname"> <xsl:value-of select="substring-before(nametext, '(')"/> - </xsl:variable> + </xsl:variable> <fo:bookmark-title> <xsl:choose> <xsl:when test="string-length($fname) > 0"> @@ -396,7 +690,7 @@ <xsl:otherwise> <xsl:value-of select="nametext"/>() </xsl:otherwise> - </xsl:choose> + </xsl:choose> </fo:bookmark-title> </fo:bookmark> </xsl:when> @@ -404,60 +698,76 @@ <fo:bookmark internal-destination="{generate-id(.)}" starting-state="hide"> <xsl:variable name="tmpstring"> <xsl:value-of select="substring-before(substring-after(., '('), '->')"/> - </xsl:variable> + </xsl:variable> <xsl:variable name="ustring"> <xsl:choose> <xsl:when test="string-length($tmpstring) > 0"> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="$tmpstring"/> - </xsl:call-template> + </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="substring-after(., '(')"/> - </xsl:call-template> + </xsl:call-template> </xsl:otherwise> </xsl:choose> - </xsl:variable> + </xsl:variable> <xsl:variable name="arity"> - <xsl:call-template name="calc-arity"> - <xsl:with-param name="string" select="substring-before($ustring, ')')"/> - <xsl:with-param name="no-of-pars" select="0"/> - </xsl:call-template> - </xsl:variable> - - <xsl:variable name="fname"> - <xsl:variable name="fname1"> - <xsl:value-of select="substring-before(., '(')"/> - </xsl:variable> - <xsl:variable name="fname2"> - <xsl:value-of select="substring-after($fname1, 'erlang:')"/> - </xsl:variable> - <xsl:choose> - <xsl:when test="string-length($fname2) > 0"> - <xsl:value-of select="$fname2"/> - </xsl:when> + <xsl:choose> + <xsl:when test="string-length(@arity) > 0"> + <!-- Dialyzer spec --> + <xsl:value-of select="@arity"/> + </xsl:when> <xsl:otherwise> - <xsl:value-of select="$fname1"/> + <xsl:call-template name="calc-arity"> + <xsl:with-param name="string" select="substring-before($ustring, ')')"/> + <xsl:with-param name="no-of-pars" select="0"/> + </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:variable> + <xsl:variable name="fname"> + <xsl:choose> + <xsl:when test="string-length(@name) > 0"> + <!-- Dialyzer spec --> + <xsl:value-of select="@name"/> + </xsl:when> + <xsl:otherwise> + <xsl:variable name="fname1"> + <xsl:value-of select="substring-before(., '(')"/> + </xsl:variable> + <xsl:variable name="fname2"> + <xsl:value-of select="substring-after($fname1, 'erlang:')"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="string-length($fname2) > 0"> + <xsl:value-of select="$fname2"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$fname1"/> + </xsl:otherwise> + </xsl:choose> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + <fo:bookmark-title> <xsl:value-of select="$fname"/>/<xsl:value-of select="$arity"/> </fo:bookmark-title> </fo:bookmark> </xsl:when> </xsl:choose> - + </xsl:for-each> </xsl:template> <!-- UG part --> - + <!-- Parts --> <xsl:template match="parts"> <xsl:apply-templates select="part"/> @@ -491,7 +801,7 @@ <xsl:value-of select="$partnum"/>.<xsl:number/>  <xsl:value-of select="header/title"/> </fo:marker> <xsl:value-of select="$partnum"/>.<xsl:number/>  <xsl:value-of select="header/title"/> - + </fo:block> <xsl:apply-templates select="section|quote|warning|note|br|image|marker|table|p|pre|code|list|taglist|codeinclude|erleval"> @@ -567,7 +877,7 @@ </xsl:template> <!-- Lists --> - + <xsl:template match="list"> <xsl:param name="partnum"/> <fo:list-block xsl:use-attribute-sets="listblock"> @@ -692,7 +1002,7 @@ </xsl:variable> <fo:block xsl:use-attribute-sets="code"> - <xsl:apply-templates select="text()"/> + <xsl:apply-templates select="text()"/> </fo:block> <xsl:if test="@caption"> @@ -711,7 +1021,7 @@ </xsl:variable> <fo:block xsl:use-attribute-sets="code"> - <xsl:apply-templates/> + <xsl:apply-templates/> </fo:block> <xsl:if test="@caption"> @@ -734,23 +1044,23 @@ <xsl:variable name="partnum"> <xsl:number level="any" from="book" count="part|application"/> </xsl:variable> - - <fo:block xsl:use-attribute-sets="h1" id="{generate-id()}"> + + <fo:block xsl:use-attribute-sets="h1" id="{generate-id()}"> <xsl:if test="/book/header/title"> <xsl:value-of select="$partnum"/>    <xsl:text>Reference Manual</xsl:text> - </xsl:if> + </xsl:if> </fo:block> - - + + <xsl:apply-templates select="description"> <xsl:with-param name="partnum" select="$partnum"/> </xsl:apply-templates> - + <xsl:apply-templates select="erlref|comref|cref|fileref|appref"> <xsl:with-param name="partnum" select="$partnum"/> </xsl:apply-templates> - + </xsl:template> <!-- Erlref --> @@ -763,7 +1073,7 @@ <fo:marker marker-class-name="chapter-title"> <xsl:value-of select="module"/> </fo:marker> - <xsl:value-of select="module"/> + <xsl:value-of select="module"/> </fo:block> <xsl:text>Erlang module</xsl:text> </fo:block> @@ -784,7 +1094,7 @@ <fo:marker marker-class-name="chapter-title"> <xsl:value-of select="com"/> </fo:marker> - <xsl:value-of select="com"/> + <xsl:value-of select="com"/> </fo:block> <xsl:text>Command</xsl:text> </fo:block> @@ -805,7 +1115,7 @@ <fo:marker marker-class-name="chapter-title"> <xsl:value-of select="lib"/> </fo:marker> - <xsl:value-of select="lib"/> + <xsl:value-of select="lib"/> </fo:block> <xsl:text>C Library</xsl:text> </fo:block> @@ -826,7 +1136,7 @@ <fo:marker marker-class-name="chapter-title"> <xsl:value-of select="file"/> </fo:marker> - <xsl:value-of select="file"/> + <xsl:value-of select="file"/> </fo:block> <xsl:text>Name</xsl:text> </fo:block> @@ -847,7 +1157,7 @@ <fo:marker marker-class-name="chapter-title"> <xsl:value-of select="app"/> </fo:marker> - <xsl:value-of select="app"/> + <xsl:value-of select="app"/> </fo:block> <xsl:text>Application</xsl:text> </fo:block> @@ -900,9 +1210,7 @@ <xsl:template match="func"> <xsl:param name="partnum"/> - <fo:block xsl:use-attribute-sets="function-name"> - <xsl:apply-templates select="name"/> - </fo:block> + <xsl:apply-templates select="name"/> <xsl:apply-templates select="fsummary|type|desc"> <xsl:with-param name="partnum" select="$partnum"/> @@ -914,15 +1222,35 @@ <xsl:template match="name"> <xsl:param name="partnum"/> <xsl:choose> + <!-- @arity is mandatory when referring to a specification --> + <xsl:when test="string-length(@arity) > 0"> + <xsl:call-template name="spec_name"/> + </xsl:when> + <xsl:when test="ancestor::datatype"> + <xsl:call-template name="type_name"/> + </xsl:when> + <xsl:otherwise> + <fo:block xsl:use-attribute-sets="function-name"> + <xsl:call-template name="name"> + <xsl:with-param name="partnum" select="$partnum"/> + </xsl:call-template> + </fo:block> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template name="name"> + <xsl:param name="partnum"/> + <xsl:choose> <xsl:when test="ancestor::cref"> <fo:block id="{generate-id(nametext)}"> - <xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/> - </fo:block> + <xsl:value-of select="ret"/><xsl:text> </xsl:text><xsl:value-of select="nametext"/> + </fo:block> </xsl:when> <xsl:otherwise> <fo:block id="{generate-id(.)}"> - <xsl:value-of select="."/> - </fo:block> + <xsl:value-of select="."/> + </fo:block> </xsl:otherwise> </xsl:choose> </xsl:template> @@ -931,9 +1259,9 @@ <!-- Type --> <xsl:template match="type"> <xsl:param name="partnum"/> - + <fo:block> - <xsl:text>Types:</xsl:text> + <xsl:text>Types:</xsl:text> </fo:block> <fo:list-block xsl:use-attribute-sets="type-listblock"> @@ -1001,9 +1329,9 @@ <xsl:param name="chapnum"/> <xsl:variable name="tabnum"> <xsl:number level="any" from="chapter" count="table"/> - </xsl:variable> + </xsl:variable> <fo:table xsl:use-attribute-sets="table"> - <fo:table-body> + <fo:table-body> <xsl:apply-templates select="row"> <xsl:with-param name="chapnum" select="$chapnum"/> <xsl:with-param name="tabnum" select="$tabnum"/> @@ -1107,7 +1435,7 @@ <xsl:template name="calc-arity"> <xsl:param name="string"/> <xsl:param name="no-of-pars"/> - + <xsl:variable name="length"> <xsl:value-of select="string-length($string)"/> </xsl:variable> @@ -1116,8 +1444,8 @@ <xsl:when test="$length > 0"> <xsl:call-template name="calc-arity"> <xsl:with-param name="string" select="substring-after($string, ',')"/> - <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/> - </xsl:call-template> + <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/> + </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$no-of-pars"/> @@ -1131,9 +1459,9 @@ <xsl:variable name="str1"> <xsl:call-template name="remove-paren-1"> <xsl:with-param name="string" select="$string"/> - <xsl:with-param name="start">(</xsl:with-param> - <xsl:with-param name="end">)</xsl:with-param> - </xsl:call-template> + <xsl:with-param name="start">(</xsl:with-param> + <xsl:with-param name="end">)</xsl:with-param> + </xsl:call-template> </xsl:variable> <xsl:variable name="str2"> @@ -1141,7 +1469,7 @@ <xsl:with-param name="string" select="$str1"/> <xsl:with-param name="start">{</xsl:with-param> <xsl:with-param name="end">}</xsl:with-param> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:variable name="str3"> @@ -1149,7 +1477,7 @@ <xsl:with-param name="string" select="$str2"/> <xsl:with-param name="start">[</xsl:with-param> <xsl:with-param name="end">]</xsl:with-param> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:value-of select="$str3"/> @@ -1161,7 +1489,7 @@ <xsl:param name="string"/> <xsl:param name="start"/> <xsl:param name="end"/> - + <xsl:variable name="tmp1"> <xsl:value-of select="substring-before($string, $start)"/> </xsl:variable> @@ -1174,7 +1502,7 @@ <xsl:variable name="retstring"> <xsl:call-template name="remove-paren"> <xsl:with-param name="string" select="$tmp2"/> - </xsl:call-template> + </xsl:call-template> </xsl:variable> <xsl:value-of select="concat(concat($tmp1, 'x'), $retstring)"/> </xsl:when> diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile new file mode 100644 index 0000000000..8e81bccd59 --- /dev/null +++ b/lib/erl_docgen/src/Makefile @@ -0,0 +1,96 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1996-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=$(ERL_DOCGEN_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/erl_docgen-$(VSN) + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- +MODULES = \ + otp_specs + +HRL_FILES = + +ERL_FILES = $(MODULES:%=%.erl) + +TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) + +APP_FILE = erl_docgen.app + +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +APPUP_FILE = erl_docgen.appup + +APPUP_SRC= $(APPUP_FILE).src +APPUP_TARGET= $(EBIN)/$(APPUP_FILE) + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_COMPILE_FLAGS += -I../../xmerl/include + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- + +debug opt: $(TARGET_FILES) + +clean: + rm -f $(TARGET_FILES) + rm -f core + +docs: + + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- + +$(APP_TARGET): $(APP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + +release_docs_spec: + diff --git a/lib/erl_docgen/src/erl_docgen.app.src b/lib/erl_docgen/src/erl_docgen.app.src new file mode 100644 index 0000000000..1720464b6d --- /dev/null +++ b/lib/erl_docgen/src/erl_docgen.app.src @@ -0,0 +1,12 @@ +{application, erl_docgen, + [{description, "Misc tools for building documentation"}, + {vsn, "%VSN%"}, + {modules, [otp_specs + ] + }, + {registered,[]}, + {applications, [kernel,stdlib]}, + {env, [] + } + ] +}. diff --git a/lib/erl_docgen/src/erl_docgen.appup.src b/lib/erl_docgen/src/erl_docgen.appup.src new file mode 100644 index 0000000000..54a63833e6 --- /dev/null +++ b/lib/erl_docgen/src/erl_docgen.appup.src @@ -0,0 +1 @@ +{"%VSN%",[],[]}. diff --git a/lib/erl_docgen/src/otp_specs.erl b/lib/erl_docgen/src/otp_specs.erl new file mode 100644 index 0000000000..728ddb2e6e --- /dev/null +++ b/lib/erl_docgen/src/otp_specs.erl @@ -0,0 +1,701 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-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(otp_specs). + +-export([module/2, package/2, overview/2, type/1]). + +-include("xmerl.hrl"). + +-define(XML_EXPORT, xmerl_xml). +-define(DEFAULT_XML_EXPORT, ?XML_EXPORT). +-define(DEFAULT_PP, erl_pp). +-define(IND(N), #xmlText{value="\n" ++ lists:duplicate(N, $\s)}). +-define(NL, "\n"). + +module(Element, Options) -> + XML = layout_module(Element, init_opts(Options)), + Export = proplists:get_value(xml_export, Options, + ?DEFAULT_XML_EXPORT), + xmerl:export_simple(XML, Export, [#xmlAttribute{name=prolog, + value=""}]). + +-record(opts, {pretty_print, file_suffix}). + +init_opts(Options) -> + #opts{pretty_print = proplists:get_value(pretty_print, + Options, ?DEFAULT_PP), + %% It *is* depending on edoc.hrl! + file_suffix = proplists:get_value(file_suffix, Options, ".html")}. + +layout_module(#xmlElement{name = module, content = Es}=E, Opts) -> + Name = get_attrval(name, E), + Functions = [{function_name(Elem), Elem} || + Elem <- get_content(functions, Es)], + Types = [{type_name(Elem), Elem} || Elem <- get_content(typedecls, Es)], + Body = [{module, + [{name,[Name]}], + ([?NL] ++ types(lists:sort(Types), Opts) + ++ functions(lists:sort(Functions), Opts) + ++ timestamp())}], + Body. + +timestamp() -> + [{timestamp, [io_lib:fwrite("Generated by EDoc, ~s, ~s.", + [edoc_lib:datestr(date()), + edoc_lib:timestr(time())])]},?NL]. + +functions(Fs, Opts) -> + lists:flatmap(fun ({Name, E}) -> function(Name, E, Opts) end, Fs). + +function(Name, #xmlElement{content = Es}, Opts) -> + TS = get_content(typespec, Es), + Spec = typespec(TS, Opts), + [{spec,(Name + ++ [?IND(2),{contract,Spec}] + ++ typespec_annos(TS))}, + ?NL]. + +function_name(E) -> + [] = get_attrval(module, E), + [?IND(2),{name,[atom(get_attrval(name, E))]}, + ?IND(2),{arity,[get_attrval(arity, E)]}]. + +label_anchor(Content, E) -> + case get_attrval(label, E) of + "" -> Content; + Ref -> [{marker, [{id, Ref}], Content}] + end. + +typespec([], _Opts) -> []; +typespec(Es, Opts) -> + {Head, LDefs} = collect_clause(Es, Opts), + clause(Head, LDefs) ++ [?IND(2)]. + +collect_clause(Es, Opts) -> + Name = t_name(get_elem(erlangName, Es)), + Defs = get_elem(localdef, Es), + [Type] = get_elem(type, Es), + {format_spec(Name, Type, Opts), collect_local_defs(Defs, Opts)}. + +clause(Head, LDefs) -> + FC = [?IND(6),{head,Head}] ++ local_clause_defs(LDefs), + [?IND(4),{clause,FC}]. + +local_clause_defs([]) -> []; +local_clause_defs(LDefs) -> + LocalDefs = [{subtype,T} || T <- coalesce_local_defs(LDefs, [])], + [?IND(6),{guard,margin(8, LocalDefs)}]. + +types(Ts, Opts) -> + lists:flatmap(fun ({Name, E}) -> typedecl(Name, E, Opts) end, Ts). + +typedecl(Name, E=#xmlElement{content = Es}, Opts) -> + TD = get_content(typedef, Es), + TypeDef = typedef(E, TD, Opts), + [{type,(Name + ++ [?IND(2),{typedecl, TypeDef}] + ++ typedef_annos(TD))}, + ?NL]. + +type_name(#xmlElement{content = Es}) -> + Typedef = get_content(typedef, Es), + [E] = get_elem(erlangName, Typedef), + Args = get_content(argtypes, Typedef), + [] = get_attrval(module, E), + [?IND(2),{name,[atom(get_attrval(name, E))]}, + ?IND(2),{n_vars,[integer_to_list(length(Args))]}]. + +typedef(E, Es, Opts) -> + Ns = get_elem(erlangName, Es), + Name = + ([t_name(Ns), "("] + ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), [")"])), + LDefs = collect_local_defs(get_elem(localdef, Es), Opts), + TypeHead = case get_elem(type, Es) of + [] -> label_anchor(Name, E); + Type -> (label_anchor(Name, E) + ++ format_type(Name, Type, Opts)) + end, + ([?IND(6),{typehead,TypeHead}] + ++ local_type_defs(LDefs, [])). + +local_type_defs([], _) -> []; +local_type_defs(LDefs, Last) -> + LocalDefs = [{local_def,T} || T <- coalesce_local_defs(LDefs, Last)], + [?IND(6),{local_defs,margin(8, LocalDefs)}]. + +collect_local_defs(Es, Opts) -> + [collect_localdef(E, Opts) || E <- Es]. + +collect_localdef(E = #xmlElement{content = Es}, Opts) -> + Name = case get_elem(typevar, Es) of + [] -> + label_anchor(N0 = t_abstype(get_content(abstype, Es)), E); + [V] -> + N0 = t_var(V) + end, + {Name,N0,format_type(N0, get_elem(type, Es), Opts)}. + +%% "A = t(), B = t()" is coalesced into "A = B = t()". +%% Names as B above are kept, but the formated string is empty. +coalesce_local_defs([], _Last) -> + []; +coalesce_local_defs([{Name,N0,TypeS} | L], Last) when Name =:= N0 -> + cld(L, [{Name,N0}], TypeS, Last); +coalesce_local_defs([{Name,N0,TypeS} | L], Last) -> + [local_def(N0, Name, TypeS, Last, L) | coalesce_local_defs(L, Last)]. + +cld([{Name,N0,TypeS} | L], Names, TypeS, Last) when Name =:= N0 -> + cld(L, [{Name,N0} | Names], TypeS, Last); +cld(L, Names0, TypeS, Last) -> + Names = [{_,Name0} | Names1] = lists:reverse(Names0), + NS = join([N || {N,_} <- Names], [" = "]), + ([local_def(Name0, NS, TypeS, Last, L) | + [local_def(N0, "", "", [], L) || {_,N0} <- Names1]] + ++ coalesce_local_defs(L, Last)). + +local_def(Name, NS, TypeS, Last, L) -> + [{typename,Name},{string,NS ++ TypeS ++ [Last || L =:= []]}]. + +%% join([], Sep) when is_list(Sep) -> +%% []; +join([H|T], Sep) -> + H ++ lists:append([Sep ++ X || X <- T]). + +%% Use the default formatting of EDoc, which creates references, and +%% then insert newlines and indentation according to erl_pp (the +%% (fast) Erlang pretty printer). +format_spec(Name, Type, #opts{pretty_print = erl_pp}=Opts) -> + try + L = t_clause(Name, Type), + O = pp_clause(Name, Type), + {R, ".\n"} = diaf(L, O, Opts), + R + catch _:_ -> + %% Example: "@spec ... -> record(a)" + format_spec(Name, Type, Opts#opts{pretty_print=default}) + end; +format_spec(Sep, Type, _Opts) -> + t_clause(Sep, Type). + +t_clause(Name, Type) -> + #xmlElement{content = [#xmlElement{name = 'fun', content = C}]} = Type, + [Name] ++ t_fun(C). + +pp_clause(Pre, Type) -> + Types = ot_utype([Type]), + Atom = lists:duplicate(iolist_size(Pre), $a), + L1 = erl_pp:attribute({attribute,0,spec,{{list_to_atom(Atom),0},[Types]}}), + "-spec " ++ L2 = lists:flatten(L1), + L3 = Pre ++ lists:nthtail(length(Atom), L2), + re:replace(L3, "\n ", "\n", [{return,list},global]). + +format_type(Name, Type, #opts{pretty_print = erl_pp}=Opts) -> + try + L = t_utype(Type), + O = pp_type(Name, Type), + {R, ".\n"} = diaf(L, O, Opts), + [" = "] ++ R + catch _:_ -> + %% Example: "t() = record(a)." + format_type(Name, Type, Opts#opts{pretty_print=default}) + end; +format_type(_Name, Type, _Opts) -> + [" = "] ++ t_utype(Type). + +pp_type(Prefix, Type) -> + Atom = list_to_atom(lists:duplicate(iolist_size(Prefix), $a)), + L1 = erl_pp:attribute({attribute,0,type,{Atom,ot_utype(Type),[]}}), + {L2,N} = case lists:dropwhile(fun(C) -> C =/= $: end, lists:flatten(L1)) of + ":: " ++ L3 -> {L3,9}; % compensation for extra "()" and ":" + "::\n" ++ L3 -> {"\n"++L3,6} + end, + Ss = lists:duplicate(N, $\s), + re:replace(L2, "\n"++Ss, "\n", [{return,list},global]). + +diaf(L, O0, Opts) -> + {R0, O} = diaf(L, [], O0, [], Opts), + R1 = rewrite_some_predefs(lists:reverse(R0)), + R = indentation(lists:flatten(R1)), + {R, O}. + +diaf([C | L], St, [C | O], R, Opts) -> + diaf(L, St, O, [[C] | R], Opts); +diaf(" "++L, St, O, R, Opts) -> + diaf(L, St, O, R, Opts); +diaf("", [Cs | St], O, R, Opts) -> + diaf(Cs, St, O, R, Opts); +diaf("", [], O, R, _Opts) -> + {R, O}; +diaf(L, St, " "++O, R, Opts) -> + diaf(L, St, O, [" " | R], Opts); +diaf(L, St, "\n"++O, R, Opts) -> + Ss = lists:takewhile(fun(C) -> C =:= $\s end, O), + diaf(L, St, lists:nthtail(length(Ss), O), ["\n"++Ss | R], Opts); +diaf([{seealso, HRef0, S0} | L], St, O0, R, Opts) -> + {S, O} = diaf(S0, app_fix(O0), Opts), + HRef = fix_mod_ref(HRef0, Opts), + diaf(L, St, O, [{seealso, HRef, S} | R], Opts); +diaf("="++L, St, "::"++O, R, Opts) -> + %% EDoc uses "=" for record field types; Dialyzer uses "::". Maybe + %% there should be an option for this, possibly affecting other + %% similar discrepancies. + diaf(L, St, O, ["=" | R], Opts); +diaf([Cs | L], St, O, R, Opts) -> + diaf(Cs, [L | St], O, R, Opts). + +rewrite_some_predefs(S) -> + xpredef(lists:flatten(S)). + +xpredef([]) -> + []; +xpredef("neg_integer()"++L) -> + ["integer() =< -1"] ++ xpredef(L); +xpredef("non_neg_integer()"++L) -> + ["integer() >= 0"] ++ xpredef(L); +xpredef("pos_integer()"++L) -> + ["integer() >= 1"] ++ xpredef(L); +xpredef([T | Es]) when is_tuple(T) -> + [T | xpredef(Es)]; +xpredef([E | Es]) -> + [[E] | xpredef(Es)]. + +indentation([]) -> + []; +indentation([$\n|L]) -> + [{br,[]}|indent(L)]; +indentation([T | Es]) when is_tuple(T) -> + [T | indentation(Es)]; +indentation([E|L]) -> + [[E]|indentation(L)]. + +indent([$\s|L]) -> + [{nbsp,[]}|indent(L)]; +indent(L) -> + indentation(L). + +app_fix(L) -> + try + {"//" ++ R1,L2} = app_fix(L, 1), + [App, Mod] = string:tokens(R1, "/"), + "//" ++ atom(App) ++ "/" ++ atom(Mod) ++ L2 + catch _:_ -> L + end. + +app_fix(L, I) -> % a bit slow + {L1, L2} = lists:split(I, L), + case erl_scan:tokens([], L1 ++ ". ", 1) of + {done, {ok,[{atom,_,Atom}|_],_}, _} -> {atom_to_list(Atom), L2}; + _ -> app_fix(L, I+1) + end. + +%% Remove the file suffix from module references. +fix_mod_ref(HRef, #opts{file_suffix = ""}) -> + HRef; +fix_mod_ref([{marker, S}]=HRef0, #opts{file_suffix = FS}) -> + {A, B} = lists:splitwith(fun(C) -> C =/= $# end, S), + case lists:member($:, A) of + true -> + HRef0; % should "save" most application references "http:" + false -> + case {lists:suffix(FS, A), B} of + {true, "#"++_} -> + [{marker, lists:sublist(A, length(A)-length(FS)) ++ B}]; + _ -> + HRef0 + end + end. + +see(E, Es) -> + case href(E) of + [] -> Es; + Ref -> + [{seealso, Ref, Es}] + end. + +href(E) -> + case get_attrval(href, E) of + "" -> []; + URI -> + [{marker, URI}] + end. + +atom(String) -> + io_lib:write_atom(list_to_atom(String)). + +t_name([E]) -> + N = get_attrval(name, E), + case get_attrval(module, E) of + "" -> atom(N); + M -> + S = atom(M) ++ ":" ++ atom(N), + case get_attrval(app, E) of + "" -> S; + A -> "//" ++ atom(A) ++ "/" ++ S + end + end. + +t_utype([E]) -> + t_utype_elem(E). + +t_utype_elem(E=#xmlElement{content = Es}) -> + case get_attrval(name, E) of + "" -> t_type(Es); + Name -> + T = t_type(Es), + case T of + [Name] -> T; % avoid generating "Foo::Foo" + T -> [Name] ++ ["::"] ++ T + end + end. + +t_type([E=#xmlElement{name = typevar}]) -> + t_var(E); +t_type([E=#xmlElement{name = atom}]) -> + t_atom(E); +t_type([E=#xmlElement{name = integer}]) -> + t_integer(E); +t_type([E=#xmlElement{name = range}]) -> + t_range(E); +t_type([E=#xmlElement{name = binary}]) -> + t_binary(E); +t_type([E=#xmlElement{name = float}]) -> + t_float(E); +t_type([#xmlElement{name = nil}]) -> + t_nil(); +t_type([#xmlElement{name = list, content = Es}]) -> + t_list(Es); +t_type([#xmlElement{name = nonempty_list, content = Es}]) -> + t_nonempty_list(Es); +t_type([#xmlElement{name = tuple, content = Es}]) -> + t_tuple(Es); +t_type([#xmlElement{name = 'fun', content = Es}]) -> + ["fun("] ++ t_fun(Es) ++ [")"]; +t_type([E = #xmlElement{name = record, content = Es}]) -> + t_record(E, Es); +t_type([E = #xmlElement{name = abstype, content = Es}]) -> + t_abstype(E, Es); +t_type([#xmlElement{name = union, content = Es}]) -> + t_union(Es). + +t_var(E) -> + [get_attrval(name, E)]. + +t_atom(E) -> + [get_attrval(value, E)]. + +t_integer(E) -> + [get_attrval(value, E)]. + +t_range(E) -> + [get_attrval(value, E)]. + +t_binary(E) -> + [get_attrval(value, E)]. + +t_float(E) -> + [get_attrval(value, E)]. + +t_nil() -> + ["[]"]. + +t_list(Es) -> + ["["] ++ t_utype(get_elem(type, Es)) ++ ["]"]. + +t_nonempty_list(Es) -> + ["["] ++ t_utype(get_elem(type, Es)) ++ [", ...]"]. + +t_tuple(Es) -> + ["{"] ++ seq(fun t_utype_elem/1, Es, ["}"]). + +t_fun(Es) -> + ["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es), + [") -> "] ++ t_utype(get_elem(type, Es))). + +t_record(E, Es) -> + Name = ["#"] ++ t_type(get_elem(atom, Es)), + case get_elem(field, Es) of + [] -> + see(E, [Name, "{}"]); + Fs -> + see(E, Name) ++ ["{"] ++ seq(fun t_field/1, Fs, ["}"]) + end. + +t_field(#xmlElement{content = Es}) -> + t_type(get_elem(atom, Es)) ++ [" = "] ++ t_utype(get_elem(type, Es)). + +t_abstype(E, Es) -> + Name = t_name(get_elem(erlangName, Es)), + case get_elem(type, Es) of + [] -> + see(E, [Name, "()"]); + Ts -> + see(E, [Name]) ++ ["("] ++ seq(fun t_utype_elem/1, Ts, [")"]) + end. + +t_abstype(Es) -> + ([t_name(get_elem(erlangName, Es)), "("] + ++ seq(fun t_utype_elem/1, get_elem(type, Es), [")"])). + +t_union(Es) -> + seq(fun t_utype_elem/1, Es, " | ", []). + +seq(F, Es, Tail) -> + seq(F, Es, ", ", Tail). + +seq(F, [E], _Sep, Tail) -> + F(E) ++ Tail; +seq(F, [E | Es], Sep, Tail) -> + F(E) ++ [Sep] ++ seq(F, Es, Sep, Tail); +seq(_F, [], _Sep, Tail) -> + Tail. + +get_elem(Name, [#xmlElement{name = Name} = E | Es]) -> + [E | get_elem(Name, Es)]; +get_elem(Name, [_ | Es]) -> + get_elem(Name, Es); +get_elem(_, []) -> + []. + +get_attr(Name, [#xmlAttribute{name = Name} = A | As]) -> + [A | get_attr(Name, As)]; +get_attr(Name, [_ | As]) -> + get_attr(Name, As); +get_attr(_, []) -> + []. + +get_attrval(Name, #xmlElement{attributes = As}) -> + case get_attr(Name, As) of + [#xmlAttribute{value = V}] -> + V; + [] -> "" + end. + +get_content(Name, Es) -> + case get_elem(Name, Es) of + [#xmlElement{content = Es1}] -> + Es1; + [] -> [] + end. + +overview(_, _Options) -> []. + +package(_, _Options) -> []. + +type(_) -> []. + +%% --------------------------------------------------------------------- + +ot_utype([E]) -> + ot_utype_elem(E). + +ot_utype_elem(E=#xmlElement{content = Es}) -> + case get_attrval(name, E) of + "" -> ot_type(Es); + N -> + Name = {var,0,list_to_atom(N)}, + T = ot_type(Es), + case T of + Name -> T; + T -> {ann_type,0,[Name, T]} + end + end. + +ot_type([E=#xmlElement{name = typevar}]) -> + ot_var(E); +ot_type([E=#xmlElement{name = atom}]) -> + ot_atom(E); +ot_type([E=#xmlElement{name = integer}]) -> + ot_integer(E); +ot_type([E=#xmlElement{name = range}]) -> + ot_range(E); +ot_type([E=#xmlElement{name = binary}]) -> + ot_binary(E); +ot_type([E=#xmlElement{name = float}]) -> + ot_float(E); +ot_type([#xmlElement{name = nil}]) -> + ot_nil(); +ot_type([#xmlElement{name = list, content = Es}]) -> + ot_list(Es); +ot_type([#xmlElement{name = nonempty_list, content = Es}]) -> + ot_nonempty_list(Es); +ot_type([#xmlElement{name = tuple, content = Es}]) -> + ot_tuple(Es); +ot_type([#xmlElement{name = 'fun', content = Es}]) -> + ot_fun(Es); +ot_type([#xmlElement{name = record, content = Es}]) -> + ot_record(Es); +ot_type([#xmlElement{name = abstype, content = Es}]) -> + ot_abstype(Es); +ot_type([#xmlElement{name = union, content = Es}]) -> + ot_union(Es). + +ot_var(E) -> + {var,0,list_to_atom(get_attrval(name, E))}. + +ot_atom(E) -> + {ok, [Atom], _} = erl_scan:string(get_attrval(value, E), 0), + Atom. + +ot_integer(E) -> + {integer,0,list_to_integer(get_attrval(value, E))}. + +ot_range(E) -> + [I1, I2] = string:tokens(get_attrval(value, E), "."), + {type,0,range,[{integer,0,list_to_integer(I1)}, + {integer,0,list_to_integer(I2)}]}. + +ot_binary(E) -> + {Base, Unit} = + case string:tokens(get_attrval(value, E), ",:*><") of + [] -> + {0, 0}; + ["_",B] -> + {list_to_integer(B), 0}; + ["_","_",U] -> + {0, list_to_integer(U)}; + ["_",B,_,"_",U] -> + {list_to_integer(B), list_to_integer(U)} + end, + {type,0,binary,[{integer,0,Base},{integer,0,Unit}]}. + +ot_float(E) -> + {float,0,list_to_float(get_attrval(value, E))}. + +ot_nil() -> + {nil,0}. + +ot_list(Es) -> + {type,0,list,[ot_utype(get_elem(type, Es))]}. + +ot_nonempty_list(Es) -> + {type,0,nonempty_list,[ot_utype(get_elem(type, Es))]}. + +ot_tuple(Es) -> + {type,0,tuple,[ot_utype_elem(E) || E <- Es]}. + +ot_fun(Es) -> + Range = ot_utype(get_elem(type, Es)), + Args = [ot_utype_elem(A) || A <- get_content(argtypes, Es)], + {type,0,'fun',[{type,0,product,Args},Range]}. + +ot_record(Es) -> + {type,0,record,[ot_type(get_elem(atom, Es)) | + [ot_field(F) || F <- get_elem(field, Es)]]}. + +ot_field(#xmlElement{content = Es}) -> + {type,0,field_type, + [ot_type(get_elem(atom, Es)), ot_utype(get_elem(type, Es))]}. + +ot_abstype(Es) -> + ot_name(get_elem(erlangName, Es), + [ot_utype_elem(Elem) || Elem <- get_elem(type, Es)]). + +ot_union(Es) -> + {type,0,union,[ot_utype_elem(E) || E <- Es]}. + +ot_name(Es, T) -> + case ot_name(Es) of + [Mod, ":", Atom] -> + {remote_type,0,[{atom,0,list_to_atom(Mod)}, + {atom,0,list_to_atom(Atom)},T]}; + "tuple" when T =:= [] -> + {type,0,tuple,any}; + Atom -> + {type,0,list_to_atom(Atom),T} + end. + +ot_name([E]) -> + Atom = get_attrval(name, E), + case get_attrval(module, E) of + "" -> Atom; + M -> + case get_attrval(app, E) of + "" -> + [M, ":", Atom]; + A -> + ["//"++A++"/" ++ M, ":", Atom] % EDoc only! + end + end. + +%% Returns exactly those annotations that can be referred to. Note +%% that a Dialyzer type/spec (currently) can have more annotations +%% than can be represented by EDoc types. Note also that edoc_dia +%% has annotated all type variables with themselves. +typespec_annos([]) -> [?NL]; +typespec_annos([_|Es]) -> + annotations(clause_annos(Es)). + +clause_annos(Es) -> + [annos(get_elem(type, Es)), local_defs_annos(get_elem(localdef, Es))]. + +typedef_annos(Es) -> + annotations([(case get_elem(type, Es) of + [] -> []; + T -> annos(T) + end + ++ lists:flatmap(fun annos_elem/1, + get_content(argtypes, Es))), + local_defs_annos(get_elem(localdef, Es))]). + +local_defs_annos(Es) -> + lists:flatmap(fun localdef_annos/1, Es). + +localdef_annos(#xmlElement{content = Es}) -> + annos(get_elem(type, Es)). + +annotations(AnnoL) -> + Annos = lists:usort(lists:flatten(AnnoL)), + margin(2, Annos). + +margin(N, L) -> + lists:append([[?IND(N),E] || E <- L]) ++ [?IND(N-2)]. + +annos([E]) -> + annos_elem(E). + +annos_elem(E=#xmlElement{content = Es}) -> + case get_attrval(name, E) of + "" -> annos_type(Es); + "..." -> annos_type(Es); % compensate for a kludge in edoc_dia.erl + N -> + [{anno,[N]} | annos_type(Es)] + end. + +annos_type([#xmlElement{name = list, content = Es}]) -> + annos(get_elem(type, Es)); +annos_type([#xmlElement{name = nonempty_list, content = Es}]) -> + annos(get_elem(type, Es)); +annos_type([#xmlElement{name = tuple, content = Es}]) -> + lists:flatmap(fun annos_elem/1, Es); +annos_type([#xmlElement{name = 'fun', content = Es}]) -> + (annos(get_elem(type, Es)) + ++ lists:flatmap(fun annos_elem/1, get_content(argtypes, Es))); +annos_type([#xmlElement{name = record, content = Es}]) -> + lists:append([annos(get_elem(type, Es1)) || + #xmlElement{content = Es1} <- get_elem(field, Es)]); +annos_type([#xmlElement{name = abstype, content = Es}]) -> + lists:flatmap(fun annos_elem/1, get_elem(type, Es)); +annos_type([#xmlElement{name = union, content = Es}]) -> + lists:flatmap(fun annos_elem/1, Es); +annos_type([E=#xmlElement{name = typevar}]) -> + annos_elem(E); +annos_type(_) -> + []. diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 8e379463ad..ff89802599 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -30,6 +30,20 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.7.1.1</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The <c>erl_interface</c> tracelevel for erlang messages was incorrect. This has now been fixed. + </p> + <p> + Own Id: OTP-8874</p> + </item> + </list> + </section> + +</section> <section><title>Erl_Interface 3.7.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/src/connect/eirecv.c b/lib/erl_interface/src/connect/eirecv.c index 51fc32d65c..7d72ddeeae 100644 --- a/lib/erl_interface/src/connect/eirecv.c +++ b/lib/erl_interface/src/connect/eirecv.c @@ -107,7 +107,7 @@ ei_recv_internal (int fd, switch (msg->msgtype) { case ERL_SEND: /* { SEND, Cookie, ToPid } */ - if (ei_tracelevel > 0) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_atom(header,&index,msg->cookie) || ei_decode_pid(header,&index,&msg->to)) { @@ -118,7 +118,7 @@ ei_recv_internal (int fd, break; case ERL_REG_SEND: /* { REG_SEND, From, Cookie, ToName } */ - if (ei_tracelevel > 0) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_pid(header,&index,&msg->from) || ei_decode_atom(header,&index,msg->cookie) || ei_decode_atom(header,&index,msg->toname)) @@ -133,7 +133,7 @@ ei_recv_internal (int fd, case ERL_LINK: /* { LINK, From, To } */ case ERL_UNLINK: /* { UNLINK, From, To } */ case ERL_GROUP_LEADER: /* { GROUP_LEADER, From, To } */ - if (ei_tracelevel > 1) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_pid(header,&index,&msg->from) || ei_decode_pid(header,&index,&msg->to)) { @@ -145,7 +145,7 @@ ei_recv_internal (int fd, case ERL_EXIT: /* { EXIT, From, To, Reason } */ case ERL_EXIT2: /* { EXIT2, From, To, Reason } */ - if (ei_tracelevel > 1) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_pid(header,&index,&msg->from) || ei_decode_pid(header,&index,&msg->to)) { @@ -156,7 +156,7 @@ ei_recv_internal (int fd, break; case ERL_SEND_TT: /* { SEND_TT, Cookie, ToPid, TraceToken } */ - if (ei_tracelevel > 0) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_atom(header,&index,msg->cookie) || ei_decode_pid(header,&index,&msg->to) || ei_decode_trace(header,&index,&msg->token)) @@ -169,7 +169,7 @@ ei_recv_internal (int fd, break; case ERL_REG_SEND_TT: /* { REG_SEND_TT, From, Cookie, ToName, TraceToken } */ - if (ei_tracelevel > 0) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_pid(header,&index,&msg->from) || ei_decode_atom(header,&index,msg->cookie) || ei_decode_atom(header,&index,msg->toname) @@ -184,7 +184,7 @@ ei_recv_internal (int fd, case ERL_EXIT_TT: /* { EXIT_TT, From, To, TraceToken, Reason } */ case ERL_EXIT2_TT: /* { EXIT2_TT, From, To, TraceToken, Reason } */ - if (ei_tracelevel > 1) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; if (ei_decode_pid(header,&index,&msg->from) || ei_decode_pid(header,&index,&msg->to) || ei_decode_trace(header,&index,&msg->token)) @@ -197,7 +197,7 @@ ei_recv_internal (int fd, break; case ERL_NODE_LINK: /* { NODE_LINK } */ - if (ei_tracelevel > 1) show_this_msg = 1; + if (ei_tracelevel >= 4) show_this_msg = 1; break; default: diff --git a/lib/erl_interface/src/connect/send.c b/lib/erl_interface/src/connect/send.c index cd832db4ea..57e32903cf 100644 --- a/lib/erl_interface/src/connect/send.c +++ b/lib/erl_interface/src/connect/send.c @@ -87,8 +87,7 @@ int ei_send_encoded_tmo(int fd, const erlang_pid *to, put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: 1070 */ - /* FIXME incorrect level */ - if (ei_tracelevel > 0) + if (ei_tracelevel >= 4) ei_show_sendmsg(stderr,header,msg); #ifdef HAVE_WRITEV diff --git a/lib/erl_interface/src/connect/send_exit.c b/lib/erl_interface/src/connect/send_exit.c index 098797c96d..d4e6605a2c 100644 --- a/lib/erl_interface/src/connect/send_exit.c +++ b/lib/erl_interface/src/connect/send_exit.c @@ -88,8 +88,7 @@ int ei_send_exit_tmo(int fd, const erlang_pid *from, const erlang_pid *to, put32be(s, index - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: len + 1080 */ - /* FIXME incorrect level */ - if (ei_tracelevel > 1) + if (ei_tracelevel >= 4) ei_show_sendmsg(stderr,msgbuf,NULL); ei_write_fill_t(fd,msgbuf,index,ms); diff --git a/lib/erl_interface/src/connect/send_reg.c b/lib/erl_interface/src/connect/send_reg.c index 8f0e40309c..779b1b8359 100644 --- a/lib/erl_interface/src/connect/send_reg.c +++ b/lib/erl_interface/src/connect/send_reg.c @@ -82,8 +82,7 @@ int ei_send_reg_encoded_tmo(int fd, const erlang_pid *from, put32be(s, index + msglen - 4); /* 4 */ put8(s, ERL_PASS_THROUGH); /* 1 */ /*** sum: 1336 */ - /* FIXME incorrect level.... */ - if (ei_tracelevel > 0) + if (ei_tracelevel >= 4) ei_show_sendmsg(stderr,header,msg); #ifdef HAVE_WRITEV diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c index efe9c6e5d9..b5e9b45a3b 100644 --- a/lib/erl_interface/src/decode/decode_big.c +++ b/lib/erl_interface/src/decode/decode_big.c @@ -74,7 +74,7 @@ erlang_big *ei_alloc_big(unsigned int digit_bytes) { memset(b,(char)0,sizeof(erlang_big)); if ( (b->digits = malloc(2*n)) == NULL) { free(b); - return 0; + return NULL; } b->arity = digit_bytes; diff --git a/lib/erl_interface/src/epmd/epmd_publish.c b/lib/erl_interface/src/epmd/epmd_publish.c index a9b8727747..d45fe644c0 100644 --- a/lib/erl_interface/src/epmd/epmd_publish.c +++ b/lib/erl_interface/src/epmd/epmd_publish.c @@ -69,6 +69,12 @@ static int ei_epmd_r4_publish (int port, const char *alive, unsigned ms) int n; int res, creation; + if (len > sizeof(buf)-2) + { + erl_errno = ERANGE; + return -1; + } + s = buf; put16be(s,len); diff --git a/lib/erl_interface/src/epmd/epmd_unpublish.c b/lib/erl_interface/src/epmd/epmd_unpublish.c index 08662fe1ec..495cbab44c 100644 --- a/lib/erl_interface/src/epmd/epmd_unpublish.c +++ b/lib/erl_interface/src/epmd/epmd_unpublish.c @@ -59,6 +59,11 @@ int ei_unpublish_tmo(const char *alive, unsigned ms) int len = 1 + strlen(alive); int fd, res; + if (len > sizeof(buf)-3) { + erl_errno = ERANGE; + return -1; + } + put16be(s,len); put8(s,EI_EPMD_STOP_REQ); strcpy(s, alive); diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c index 18315bfbd3..a6c2f64dd0 100644 --- a/lib/erl_interface/src/legacy/erl_marshal.c +++ b/lib/erl_interface/src/legacy/erl_marshal.c @@ -511,29 +511,28 @@ static int erl_term_len_helper(ETERM *ep, int dist) case ERL_INTEGER: i = ep->uval.ival.i; - if ((i > ERL_MAX) || (i < ERL_MIN)) len = 7; - else if ((i < 256) && (i >= 0)) len = 2; + if ((i < 256) && (i >= 0)) len = 2; else len = 5; break; case ERL_U_INTEGER: u = ep->uval.uival.u; - if (u > ERL_MAX) len = 7; + if ((int)u < 0) len = 7; else if (u < 256) len = 2; else len = 5; break; case ERL_LONGLONG: l = ep->uval.llval.i; - if ((l > ((long long) ERL_MAX)) || - (l < ((long long) ERL_MIN))) len = 11; + if ((l > ((long long) INT_MAX)) || + (l < ((long long) INT_MIN))) len = 11; else if ((l < 256) && (l >= 0)) len = 2; else len = 5; break; case ERL_U_LONGLONG: ul = ep->uval.ullval.u; - if (ul > ((unsigned long long) ERL_MAX)) len = 11; + if (ul > ((unsigned long long) INT_MAX)) len = 11; else if (ul < 256) len = 2; else len = 5; break; @@ -546,12 +545,7 @@ static int erl_term_len_helper(ETERM *ep, int dist) case ERL_REF: i = strlen((char *)ERL_REF_NODE(ep)); - if (dist >= 4 && ERL_REF_LEN(ep) > 1) { - len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4; - } else { - /* 1 + N + 4 + 1 where N = 3 + strlen */ - len = 9 + i; - } + len = 1 + 2 + (i+3) + 1 + ERL_REF_LEN(ep) * 4; break; case ERL_PORT: @@ -1890,8 +1884,11 @@ static int cmp_big_big(unsigned char**e1, unsigned char **e2) ei_get_type((char *)*e1,&i1,&t1,&n1); ei_get_type((char *)*e2,&i2,&t2,&n2); - b1 = ei_alloc_big(n1); - b2 = ei_alloc_big(n2); + if ( (b1 = ei_alloc_big(n1)) == NULL) return -1; + if ( (b2 = ei_alloc_big(n2)) == NULL) { + ei_free_big(b1); + return 1; + } ei_decode_big((char *)*e1,&i1,b1); ei_decode_big((char *)*e2,&i2,b2); diff --git a/lib/erl_interface/src/misc/ei_format.c b/lib/erl_interface/src/misc/ei_format.c index 08235d0ebe..b35421d4b2 100644 --- a/lib/erl_interface/src/misc/ei_format.c +++ b/lib/erl_interface/src/misc/ei_format.c @@ -106,6 +106,8 @@ static int eiformat(const char** fmt, union arg** args, ei_x_buff* x) default: if (isdigit((int)*p)) res = pdigit(&p, x); + else if ((*p == '-' || *p == '+') && isdigit((int)*(p+1))) + res = pdigit(&p, x); else if (islower((int)*p)) res = patom(&p, x); else @@ -149,6 +151,8 @@ static int pdigit(const char** fmt, ei_x_buff* x) double d; long l; + if (**fmt == '-' || **fmt == '+') + (*fmt)++; for (;;) { c = *(*fmt)++; if (isdigit((int)c)) diff --git a/lib/erl_interface/src/misc/ei_portio.c b/lib/erl_interface/src/misc/ei_portio.c index c4e397f1e0..a3f6f63fff 100644 --- a/lib/erl_interface/src/misc/ei_portio.c +++ b/lib/erl_interface/src/misc/ei_portio.c @@ -166,6 +166,9 @@ int ei_writev_fill_t(int fd, const struct iovec *iov, int iovcnt, unsigned if (done < sum) { if (iov_base == NULL) { iov_base = malloc(sizeof(struct iovec) * iovcnt); + if (iov_base == NULL) { + return -1; + } memcpy(iov_base, iov, sizeof(struct iovec) * iovcnt); current_iov = iov_base; } diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c index 98473f780e..5fc6b3542c 100644 --- a/lib/erl_interface/src/misc/ei_printterm.c +++ b/lib/erl_interface/src/misc/ei_printterm.c @@ -253,7 +253,8 @@ static int print_term(FILE* fp, ei_x_buff* x, erlang_big *b; char *ds; - b = ei_alloc_big(n); + if ( (b = ei_alloc_big(n)) == NULL) goto err; + if (ei_decode_big(buf, index, b) < 0) { ei_free_big(b); goto err; diff --git a/lib/erl_interface/src/prog/erl_call.c b/lib/erl_interface/src/prog/erl_call.c index 448de9aa23..33ff6da7c9 100644 --- a/lib/erl_interface/src/prog/erl_call.c +++ b/lib/erl_interface/src/prog/erl_call.c @@ -118,7 +118,6 @@ static void usage_arg(const char *progname, const char *switchname); static void usage_error(const char *progname, const char *switchname); static void usage(const char *progname); static int get_module(char **mbuf, char **mname); -static struct hostent* get_hostent(char *host); static int do_connect(ei_cnode *ec, char *nodename, struct call_flags *flags); static int read_stdin(char **buf); static void split_apply_string(char *str, char **mod, @@ -367,8 +366,8 @@ int erl_call(int argc, char **argv) * Expand name to a real name (may be ip-address) */ /* FIXME better error string */ - if ((hp = get_hostent(host)) == 0) { - fprintf(stderr,"erl_call: can't get_hostent(%s)\n", host); + if ((hp = ei_gethostbyname(host)) == 0) { + fprintf(stderr,"erl_call: can't ei_gethostbyname(%s)\n", host); exit(1); } /* If shortnames, cut off the name at first '.' */ @@ -604,32 +603,6 @@ int erl_call(int argc, char **argv) * ***************************************************************************/ -/* - * Get host entry (by address or name) - */ -/* FIXME: will fail on names like '2fun4you'. */ -static struct hostent* get_hostent(char *host) -{ - if (isdigit((int)*host)) { - struct in_addr ip_addr; - int b1, b2, b3, b4; - long addr; - - /* FIXME: Use inet_aton() (or inet_pton() and get v6 for free). */ - if (sscanf(host, "%d.%d.%d.%d", &b1, &b2, &b3, &b4) != 4) { - return NULL; - } - addr = inet_addr(host); - ip_addr.s_addr = htonl(addr); - - return ei_gethostbyaddr((char *)&ip_addr,sizeof(struct in_addr), AF_INET); - } - - return ei_gethostbyname(host); -} /* get_hostent */ - - - /* * This function does only return on success. diff --git a/lib/erl_interface/src/registry/reg_dump.c b/lib/erl_interface/src/registry/reg_dump.c index 50a6949177..dfec96b43c 100644 --- a/lib/erl_interface/src/registry/reg_dump.c +++ b/lib/erl_interface/src/registry/reg_dump.c @@ -157,7 +157,7 @@ static int mn_send_delete(int fd, erlang_pid *mnesia, const char *key) int len = strlen(key) + 32; /* 32 is a slight overestimate */ if (len > EISMALLBUF) - if (!(dbuf = malloc(index))) + if (!(dbuf = malloc(len))) return -1; msgbuf = (dbuf ? dbuf : sbuf); @@ -187,7 +187,7 @@ static int mn_send_write(int fd, erlang_pid *mnesia, const char *key, ei_reg_obj int len = 32 + keylen + obj->size; if (len > EISMALLBUF) - if (!(dbuf = malloc(index))) + if (!(dbuf = malloc(len))) return -1; msgbuf = (dbuf ? dbuf : sbuf); diff --git a/lib/erl_interface/src/registry/reg_restore.c b/lib/erl_interface/src/registry/reg_restore.c index 27918d2364..aeb33c784a 100644 --- a/lib/erl_interface/src/registry/reg_restore.c +++ b/lib/erl_interface/src/registry/reg_restore.c @@ -266,7 +266,7 @@ int ei_reg_restore(int fd, ei_reg *reg, const char *mntab) /* make sure receive buffer can handle largest expected message */ len = maxkey + maxobj + 512; if (len > EISMALLBUF) - if (!(dbuf = malloc(index))) { + if (!(dbuf = malloc(len))) { ei_send_exit(fd,&self,&mnesia,"cannot allocate space for incoming data"); return -1; } diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl index 09a37409f2..524a04a3b4 100644 --- a/lib/erl_interface/test/ei_decode_SUITE.erl +++ b/lib/erl_interface/test/ei_decode_SUITE.erl @@ -232,7 +232,7 @@ send_integers(P) -> ?line send_term_as_binary(P, 16#80000000), % SMALL_BIG_EXT new smallest pos(*) ?line send_term_as_binary(P,-16#80000001), % SMALL_BIG_EXT new largest neg (*) - case erlang:system_info(wordsize) of + case erlang:system_info({wordsize,external}) of 4 -> ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32 ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32 diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl index 7871f07ae9..cbe9fa52d7 100644 --- a/lib/erl_interface/test/ei_format_SUITE.erl +++ b/lib/erl_interface/test/ei_format_SUITE.erl @@ -155,7 +155,7 @@ format_wo_ver(suite) -> []; format_wo_ver(Config) when is_list(Config) -> ?line P = runner:start(?format_wo_ver), - ?line {term, [{a, "b"}, {c, 10}]} = get_term(P), + ?line {term, [-1, 2, {a, "b"}, {c, 10}]} = get_term(P), ?line runner:recv_eot(P), ok. diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c index a969ded3dc..ecdce402f5 100644 --- a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c +++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c @@ -176,7 +176,7 @@ TESTCASE(format_wo_ver) { ei_x_buff x; ei_x_new (&x); - ei_x_format(&x, "[{~a,~s},{~a,~i}]", "a", "b", "c", 10); + ei_x_format(&x, "[-1, +2, {~a,~s},{~a,~i}]", "a", "b", "c", 10); send_bin_term(&x); free(x.buff); diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c index f273efd532..80d7f69520 100644 --- a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c +++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. + * 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 @@ -98,14 +98,30 @@ static void encode_decode(ETERM* original, const char* text) { static unsigned char encoded[16*1024]; ETERM* new_terms; - int bytes = erl_encode(original, encoded); + ETERM* head; + int bytes; + int len; + + /* If a list, check the elements one by one first */ + head = erl_hd(original); + if (head != NULL) { + encode_decode(head, "CAR"); + encode_decode(erl_tl(original), "CDR"); + } + bytes = erl_encode(original, encoded); if (bytes == 0) { fail("failed to encode terms"); } else if (bytes > sizeof(encoded)) { fail("encoded terms buffer overflow"); } + else if (bytes != (len=erl_term_len(original))) { + fprintf(stderr, "bytes(%d) != len(%d) for term ", bytes, len); + erl_print_term(stderr, original); + fprintf(stderr, " [%s]\r\n", text); + fail("erl_encode and erl_term_len do not agree"); + } else if ((new_terms = erl_decode(encoded)) == NULL) { fail("failed to decode terms"); } diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index c642cc5002..6c664959a3 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1 +1 @@ -EI_VSN = 3.7.1 +EI_VSN = 3.7.1.1 diff --git a/lib/et/src/et_selector.erl b/lib/et/src/et_selector.erl index f39f21aa70..c8e9c907b2 100644 --- a/lib/et/src/et_selector.erl +++ b/lib/et/src/et_selector.erl @@ -115,13 +115,13 @@ change_pattern({Mod, Pattern}) when is_atom(Mod) -> old_ctp({Mod, _Fun, Args}) -> case Mod of - et -> ignore; + et -> {ok, ignore}; _ -> dbg:ctp({Mod, report_event, Args}) end. old_tp({Mod, _Fun, Args}, Pattern) -> case Mod of - et -> ignore; + et -> {ok, ignore}; _ -> dbg:tp({Mod, report_event, Args}, Pattern) end. diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile index 19be96d763..2cdc579275 100644 --- a/lib/eunit/doc/src/Makefile +++ b/lib/eunit/doc/src/Makefile @@ -146,7 +146,7 @@ debug opt: clean clean_docs: rm -rf $(HTMLDIR)/* rm -f $(MAN3DIR)/* - rm -f $(XML_CHAPTER_FILES) *.html + rm -f $(XML_REF3_FILES) $(XML_CHAPTER_FILES) *.html rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) rm -f errs core *~ diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl index 59084a52fb..4a86a108cf 100644 --- a/lib/eunit/src/eunit.erl +++ b/lib/eunit/src/eunit.erl @@ -16,7 +16,7 @@ %% $Id: eunit.erl 339 2009-04-05 14:10:47Z rcarlsson $ %% %% @copyright 2004-2009 Micka�l R�mond, Richard Carlsson -%% @author Micka�l R�mond <[email protected]> +%% @author Mickaël Rémond <[email protected]> %% [http://www.process-one.net/] %% @author Richard Carlsson <[email protected]> %% [http://user.it.uu.se/~richardc/] diff --git a/lib/eunit/src/eunit_surefire.erl b/lib/eunit/src/eunit_surefire.erl index aeda31d251..eb994a990a 100644 --- a/lib/eunit/src/eunit_surefire.erl +++ b/lib/eunit/src/eunit_surefire.erl @@ -15,7 +15,7 @@ %% %% $Id: $ %% -%% @author Micka�l R�mond <[email protected]> +%% @author Mickaël Rémond <[email protected]> %% @copyright 2009 Micka�l R�mond, Paul Guyot %% @see eunit %% @doc Surefire reports for EUnit (Format used by Maven and Atlassian diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 6eeeab3610..ed5bf03804 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -192,7 +192,7 @@ type(binary, referenced_byte_size, 1, Xs) -> type(code, add_path, 1, Xs) -> strict(arg_types(code, add_path, 1), Xs, fun (_) -> - t_sup(t_boolean(), + t_sup(t_atom('true'), t_tuple([t_atom('error'), t_atom('bad_directory')])) end); type(code, add_patha, 1, Xs) -> @@ -1219,7 +1219,7 @@ type(erlang, monitor_node, 3, Xs) -> strict(arg_types(erlang, monitor_node, 3), Xs, fun (_) -> t_atom('true') end); type(erlang, nif_error, 1, _) -> - t_any(); + t_any(); % this BIF and the next one are stubs for NIFs and never return type(erlang, nif_error, 2, Xs) -> strict(arg_types(erlang, nif_error, 2), Xs, fun (_) -> t_any() end); type(erlang, node, 0, _) -> t_node(); @@ -1970,38 +1970,40 @@ type(ets, slot, 2, Xs) -> strict(arg_types(ets, slot, 2), Xs, fun (_) -> t_sup(t_list(t_tuple()), t_atom('$end_of_table')) end); type(ets, update_counter, 3, Xs) -> - strict(arg_types(ets, update_counter, 3), Xs, fun (_) -> t_integer() end); + strict(arg_types(ets, update_counter, 3), Xs, + fun ([_, _, Op]) -> + case t_is_integer(Op) of + true -> t_integer(); + false -> + case t_is_tuple(Op) of + true -> t_integer(); + false -> + case t_is_list(Op) of + true -> t_list(t_integer()); + false -> + case t_is_nil(Op) of + true -> t_nil(); + false -> t_sup([t_integer(), t_list(t_integer())]) + end + end + end + end + end); type(ets, update_element, 3, Xs) -> strict(arg_types(ets, update_element, 3), Xs, fun (_) -> t_boolean() end); %%-- file --------------------------------------------------------------------- -type(file, close, 1, Xs) -> - strict(arg_types(file, close, 1), Xs, fun (_) -> t_file_return() end); -type(file, delete, 1, Xs) -> - strict(arg_types(file, delete, 1), Xs, fun (_) -> t_file_return() end); -type(file, get_cwd, 0, _) -> - t_sup(t_tuple([t_atom('ok'), t_string()]), - t_tuple([t_atom('error'), t_file_posix_error()])); -type(file, make_dir, 1, Xs) -> - strict(arg_types(file, make_dir, 1), Xs, fun (_) -> t_file_return() end); -type(file, open, 2, Xs) -> - strict(arg_types(file, open, 2), Xs, - fun (_) -> - t_sup([t_tuple([t_atom('ok'), t_file_io_device()]), - t_tuple([t_atom('error'), t_file_posix_error()])]) - end); -type(file, read_file, 1, Xs) -> - strict(arg_types(file, read_file, 1), Xs, - fun (_) -> - t_sup([t_tuple([t_atom('ok'), t_binary()]), - t_tuple([t_atom('error'), t_file_posix_error()])]) - end); -type(file, set_cwd, 1, Xs) -> - strict(arg_types(file, set_cwd, 1), Xs, - fun (_) -> t_sup(t_atom('ok'), - t_tuple([t_atom('error'), t_file_posix_error()])) - end); -type(file, write_file, 2, Xs) -> - strict(arg_types(file, write_file, 2), Xs, fun (_) -> t_file_return() end); +type(file, native_name_encoding, 0, _) -> + t_file_encoding(); +%%-- prim_file ---------------------------------------------------------------- +type(prim_file, internal_name2native, 1, Xs) -> + strict(arg_types(prim_file, internal_name2native, 1), Xs, + fun (_) -> t_binary() end); +type(prim_file, internal_native2name, 1, Xs) -> + strict(arg_types(prim_file, internal_native2name, 1), Xs, + fun (_) -> t_prim_file_name() end); +type(prim_file, internal_normalize_utf8, 1, Xs) -> + strict(arg_types(prim_file, internal_normalize_utf8, 1), Xs, + fun (_) -> t_binary() end); %%-- gen_tcp ------------------------------------------------------------------ %% NOTE: All type information for this module added to avoid loss of precision type(gen_tcp, accept, 1, Xs) -> @@ -3345,7 +3347,7 @@ arg_types(code, all_loaded, 0) -> arg_types(code, compiler_dir, 0) -> []; arg_types(code, del_path, 1) -> - [t_sup(t_string(), t_atom())]; % OBS: doc differs from add_path/1 - why? + [t_sup(t_string(), t_atom())]; % OBS: differs from add_path/1 arg_types(code, delete, 1) -> [t_atom()]; arg_types(code, ensure_loaded, 1) -> @@ -3393,7 +3395,7 @@ arg_types(code, replace_path, 2) -> arg_types(code, root_dir, 0) -> []; arg_types(code, set_path, 1) -> - [t_string()]; + [t_list(t_string())]; arg_types(code, soft_purge, 1) -> arg_types(code, delete, 1); arg_types(code, stick_mod, 1) -> @@ -4181,32 +4183,22 @@ arg_types(ets, setopts, 2) -> t_tuple([t_atom('heir'), t_atom('none')])), [t_tab(), t_sup(Opt, t_list(Opt))]; arg_types(ets, update_counter, 3) -> - [t_tab(), t_any(), t_sup(t_integer(), - t_sup(t_tuple([t_integer(), t_integer()]), - t_tuple([t_integer(), t_integer(), - t_integer(), t_integer()])))]; + Int = t_integer(), + UpdateOp = t_sup(t_tuple([Int, Int]), t_tuple([Int, Int, Int, Int])), + [t_tab(), t_any(), t_sup([UpdateOp, t_list(UpdateOp), Int])]; arg_types(ets, update_element, 3) -> PosValue = t_tuple([t_integer(), t_any()]), [t_tab(), t_any(), t_sup(PosValue, t_list(PosValue))]; %%------- file ---------------------------------------------------------------- -arg_types(file, close, 1) -> - [t_file_io_device()]; -arg_types(file, delete, 1) -> - [t_file_name()]; -arg_types(file, get_cwd, 0) -> +arg_types(file, native_name_encoding, 0) -> []; -arg_types(file, make_dir, 1) -> - [t_file_name()]; -arg_types(file, open, 2) -> - [t_file_name(), t_list(t_file_open_option())]; -arg_types(file, read_file, 1) -> - [t_file_name()]; -arg_types(file, set_cwd, 1) -> - [t_file_name()]; -arg_types(file, write, 2) -> - [t_file_io_device(), t_iodata()]; -arg_types(file, write_file, 2) -> - [t_file_name(), t_sup(t_binary(), t_list())]; +%%-- prim_file ---------------------------------------------------------------- +arg_types(prim_file, internal_name2native, 1) -> + [t_prim_file_name()]; +arg_types(prim_file, internal_native2name, 1) -> + [t_binary()]; +arg_types(prim_file, internal_normalize_utf8, 1) -> + [t_binary()]; %%------- gen_tcp ------------------------------------------------------------- arg_types(gen_tcp, accept, 1) -> [t_socket()]; @@ -4638,7 +4630,7 @@ t_httppacket() -> t_HttpHeader(), t_atom('http_eoh'), t_HttpError()]). t_endian() -> - t_sup([t_atom('big'), t_atom('little')]). + t_sup(t_atom('big'), t_atom('little')). %% ===================================================================== %% Types for the binary module @@ -4669,16 +4661,16 @@ t_HttpRequest() -> t_tuple([t_atom('http_request'), t_HttpMethod(), t_HttpUri(), t_HttpVersion()]). t_HttpResponse() -> - t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_string()]). + t_tuple([t_atom('http_response'), t_HttpVersion(), t_integer(), t_HttpString()]). t_HttpHeader() -> - t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_string()]). + t_tuple([t_atom('http_header'), t_integer(), t_HttpField(), t_any(), t_HttpString()]). t_HttpError() -> - t_tuple([t_atom('http_error'), t_string()]). + t_tuple([t_atom('http_error'), t_HttpString()]). t_HttpMethod() -> - t_sup(t_HttpMethodAtom(), t_string()). + t_sup(t_HttpMethodAtom(), t_HttpString()). t_HttpMethodAtom() -> t_atoms(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE']). @@ -4687,18 +4679,18 @@ t_HttpUri() -> t_sup([t_atom('*'), t_tuple([t_atom('absoluteURI'), t_sup(t_atom('http'), t_atom('https')), - t_string(), + t_HttpString(), t_sup(t_non_neg_integer(), t_atom('undefined')), - t_string()]), - t_tuple([t_atom('scheme'), t_string(), t_string()]), - t_tuple([t_atom('abs_path'), t_string()]), - t_string()]). + t_HttpString()]), + t_tuple([t_atom('scheme'), t_HttpString(), t_HttpString()]), + t_tuple([t_atom('abs_path'), t_HttpString()]), + t_HttpString()]). t_HttpVersion() -> t_tuple([t_non_neg_integer(), t_non_neg_integer()]). t_HttpField() -> - t_sup(t_HttpFieldAtom(), t_string()). + t_sup(t_HttpFieldAtom(), t_HttpString()). t_HttpFieldAtom() -> t_atoms(['Cache-Control', 'Connection', 'Date', 'Pragma', 'Transfer-Encoding', @@ -4715,6 +4707,9 @@ t_HttpFieldAtom() -> 'Set-Cookie', 'Set-Cookie2', 'X-Forwarded-For', 'Cookie', 'Keep-Alive', 'Proxy-Connection']). +t_HttpString() -> + t_sup(t_string(),t_binary()). + %% ===================================================================== %% These are used for the built-in functions of 'code' %% ===================================================================== @@ -4979,68 +4974,12 @@ t_ets_info_items() -> t_atom('type')]). %% ===================================================================== -%% These are used for the built-in functions of 'file' +%% These are used for the built-in functions of 'prim_file' %% ===================================================================== -t_file_io_device() -> - t_sup(t_pid(), t_tuple([t_atom('file_descriptor'), t_atom(), t_any()])). - -t_file_name() -> - t_sup([t_atom(), - t_string(), - %% DeepList = [char() | atom() | DeepList] -- approximation below - t_list(t_sup([t_atom(), t_string(), t_list()]))]). - -t_file_open_option() -> - t_sup([t_atom('read'), - t_atom('write'), - t_atom('append'), - t_atom('raw'), - t_atom('binary'), - t_atom('delayed_write'), - t_atom('read_ahead'), - t_atom('compressed'), - t_tuple([t_atom('delayed_write'), - t_pos_integer(), t_non_neg_integer()]), - t_tuple([t_atom('read_ahead'), t_pos_integer()])]). - -%% This lists all Posix errors that can occur in file:*/* functions -t_file_posix_error() -> - t_sup([t_atom('eacces'), - t_atom('eagain'), - t_atom('ebadf'), - t_atom('ebusy'), - t_atom('edquot'), - t_atom('eexist'), - t_atom('efault'), - t_atom('efbig'), - t_atom('eintr'), - t_atom('einval'), - t_atom('eio'), - t_atom('eisdir'), - t_atom('eloop'), - t_atom('emfile'), - t_atom('emlink'), - t_atom('enametoolong'), - t_atom('enfile'), - t_atom('enodev'), - t_atom('enoent'), - t_atom('enomem'), - t_atom('enospc'), - t_atom('enotblk'), - t_atom('enotdir'), - t_atom('enotsup'), - t_atom('enxio'), - t_atom('eperm'), - t_atom('epipe'), - t_atom('erofs'), - t_atom('espipe'), - t_atom('esrch'), - t_atom('estale'), - t_atom('exdev')]). - -t_file_return() -> - t_sup(t_atom('ok'), t_tuple([t_atom('error'), t_file_posix_error()])). +t_prim_file_name() -> + t_sup([t_string(), + t_binary()]). %% ===================================================================== %% These are used for the built-in functions of 'gen_tcp' @@ -5242,7 +5181,12 @@ t_ML() -> % a binary or a possibly deep list of integers or binaries t_sup(t_list(t_sup([t_integer(), t_binary(), t_list()])), t_binary()). t_encoding() -> - t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']). + t_sup([t_atoms(['latin1', 'unicode', 'utf8', 'utf16', 'utf32']), + t_tuple([t_atom('utf16'), t_endian()]), + t_tuple([t_atom('utf32'), t_endian()])]). + +t_file_encoding() -> + t_atoms(['latin1', 'utf8']). t_encoding_a2b() -> % for the 2nd arg of atom_to_binary/2 and binary_to_atom/2 t_atoms(['latin1', 'unicode', 'utf8']). diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 9a40be6d14..1ed85af172 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -29,7 +29,7 @@ %% In late 2008, Manouk Manoukian and Kostis Sagonas added support for %% opaque types to the structure-based representation of types. %% During February and March 2009, Kostis Sagonas significantly -%% cleaned up the type representation added spec declarations. +%% cleaned up the type representation and added spec declarations. %% %% ====================================================================== @@ -714,12 +714,13 @@ t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType, case lookup_type(Name, RemDict) of {type, {_Mod, Type, ArgNames}} when ArgsLen =:= length(ArgNames) -> {NewType, NewCycle, NewRR} = - case unfold(RemType, C) of + case can_unfold_more(RemType, C) of true -> List = lists:zip(ArgNames, Args), TmpVarDict = dict:from_list(List), {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; - false -> {t_any(), C, [RemType]} + false -> + {t_any(), C, [RemType]} end, {RT, RR} = t_solve_remote(NewType, ET, R, NewCycle), RetRR = NewRR ++ RR, @@ -733,9 +734,11 @@ t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType, List = lists:zip(ArgNames, Args), TmpVarDict = dict:from_list(List), {Rep, NewCycle, NewRR} = - case unfold(RemType, C) of - true -> {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; - false -> {t_any(), C, [RemType]} + case can_unfold_more(RemType, C) of + true -> + {t_from_form(Type, RemDict, TmpVarDict), [RemType|C], []}; + false -> + {t_any(), C, [RemType]} end, {NewRep, RR} = t_solve_remote(Rep, ET, R, NewCycle), RetRR = NewRR ++ RR, @@ -2124,7 +2127,8 @@ t_elements(?identifier(IDs)) -> t_elements(?list(_, _, _) = T) -> [T]; t_elements(?number(_, _) = T) -> case T of - ?number(?any, ?unknown_qual) -> [T]; + ?number(?any, ?unknown_qual) -> + [?float, ?integer(?any)]; ?float -> [T]; ?integer(?any) -> [T]; ?int_range(_, _) -> [T]; @@ -2171,10 +2175,10 @@ t_inf(?var(_), T, _Mode) -> subst_all_vars_to_any(T); t_inf(T, ?var(_), _Mode) -> subst_all_vars_to_any(T); t_inf(?any, T, _Mode) -> subst_all_vars_to_any(T); t_inf(T, ?any, _Mode) -> subst_all_vars_to_any(T); -t_inf(?unit, _, _Mode) -> ?unit; -t_inf(_, ?unit, _Mode) -> ?unit; t_inf(?none, _, _Mode) -> ?none; t_inf(_, ?none, _Mode) -> ?none; +t_inf(?unit, _, _Mode) -> ?unit; % ?unit cases should appear below ?none +t_inf(_, ?unit, _Mode) -> ?unit; t_inf(T, T, _Mode) -> subst_all_vars_to_any(T); t_inf(?atom(Set1), ?atom(Set2), _) -> case set_intersection(Set1, Set2) of @@ -2383,14 +2387,16 @@ inf_tuple_sets(L1, L2, Mode) -> List -> ?tuple_set(List) end. -inf_tuple_sets([{Arity, Tuples1}|Left1], [{Arity, Tuples2}|Left2], Acc, Mode) -> +inf_tuple_sets([{Arity, Tuples1}|Ts1], [{Arity, Tuples2}|Ts2], Acc, Mode) -> case inf_tuples_in_sets(Tuples1, Tuples2, Mode) of - [] -> inf_tuple_sets(Left1, Left2, Acc, Mode); - NewTuples -> inf_tuple_sets(Left1, Left2, [{Arity, NewTuples}|Acc], Mode) + [] -> inf_tuple_sets(Ts1, Ts2, Acc, Mode); + [?tuple_set([{Arity, NewTuples}])] -> + inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode); + NewTuples -> inf_tuple_sets(Ts1, Ts2, [{Arity, NewTuples}|Acc], Mode) end; -inf_tuple_sets(L1 = [{Arity1, _}|Left1], L2 = [{Arity2, _}|Left2], Acc, Mode) -> - if Arity1 < Arity2 -> inf_tuple_sets(Left1, L2, Acc, Mode); - Arity1 > Arity2 -> inf_tuple_sets(L1, Left2, Acc, Mode) +inf_tuple_sets([{Arity1, _}|Ts1] = L1, [{Arity2, _}|Ts2] = L2, Acc, Mode) -> + if Arity1 < Arity2 -> inf_tuple_sets(Ts1, L2, Acc, Mode); + Arity1 > Arity2 -> inf_tuple_sets(L1, Ts2, Acc, Mode) end; inf_tuple_sets([], _, Acc, _Mode) -> lists:reverse(Acc); inf_tuple_sets(_, [], Acc, _Mode) -> lists:reverse(Acc). @@ -2406,17 +2412,17 @@ inf_tuples_in_sets(L1, [?tuple(Elements2, _, ?any)], Mode) -> inf_tuples_in_sets(L1, L2, Mode) -> inf_tuples_in_sets(L1, L2, [], Mode). -inf_tuples_in_sets([?tuple(Elements1, Arity, Tag)|Left1], - [?tuple(Elements2, Arity, Tag)|Left2], Acc, Mode) -> +inf_tuples_in_sets([?tuple(Elements1, Arity, Tag)|Ts1], + [?tuple(Elements2, Arity, Tag)|Ts2], Acc, Mode) -> case t_inf_lists_strict(Elements1, Elements2, Mode) of - bottom -> inf_tuples_in_sets(Left1, Left2, Acc, Mode); - NewElements -> - inf_tuples_in_sets(Left1, Left2, [?tuple(NewElements, Arity, Tag)|Acc], Mode) + bottom -> inf_tuples_in_sets(Ts1, Ts2, Acc, Mode); + NewElements -> + inf_tuples_in_sets(Ts1, Ts2, [?tuple(NewElements, Arity, Tag)|Acc], Mode) end; -inf_tuples_in_sets([?tuple(_, _, Tag1)|Left1] = L1, - [?tuple(_, _, Tag2)|Left2] = L2, Acc, Mode) -> - if Tag1 < Tag2 -> inf_tuples_in_sets(Left1, L2, Acc, Mode); - Tag1 > Tag2 -> inf_tuples_in_sets(L1, Left2, Acc, Mode) +inf_tuples_in_sets([?tuple(_, _, Tag1)|Ts1] = L1, + [?tuple(_, _, Tag2)|Ts2] = L2, Acc, Mode) -> + if Tag1 < Tag2 -> inf_tuples_in_sets(Ts1, L2, Acc, Mode); + Tag1 > Tag2 -> inf_tuples_in_sets(L1, Ts2, Acc, Mode) end; inf_tuples_in_sets([], _, Acc, _Mode) -> lists:reverse(Acc); inf_tuples_in_sets(_, [], Acc, _Mode) -> lists:reverse(Acc). @@ -2763,7 +2769,9 @@ t_subtract_list(T, []) -> -spec t_subtract(erl_type(), erl_type()) -> erl_type(). t_subtract(_, ?any) -> ?none; +t_subtract(_, ?var(_)) -> ?none; t_subtract(?any, _) -> ?any; +t_subtract(?var(_) = T, _) -> T; t_subtract(T, ?unit) -> T; t_subtract(?unit, _) -> ?unit; t_subtract(?none, _) -> ?none; @@ -2791,13 +2799,13 @@ t_subtract(?opaque(Set1), ?opaque(Set2)) -> Set -> ?opaque(Set) end; t_subtract(?matchstate(Pres1, Slots1), ?matchstate(Pres2, _Slots2)) -> - Pres = t_subtract(Pres1,Pres2), + Pres = t_subtract(Pres1, Pres2), case t_is_none(Pres) of true -> ?none; - false -> ?matchstate(Pres,Slots1) + false -> ?matchstate(Pres, Slots1) end; -t_subtract(?matchstate(Present,Slots),_) -> - ?matchstate(Present,Slots); +t_subtract(?matchstate(Present, Slots), _) -> + ?matchstate(Present, Slots); t_subtract(?nil, ?nil) -> ?none; t_subtract(?nil, ?nonempty_list(_, _)) -> @@ -2919,7 +2927,7 @@ t_subtract(T, ?product(_)) -> T; t_subtract(?union(U1), ?union(U2)) -> subtract_union(U1, U2); -t_subtract(T1, T2) -> +t_subtract(T1, T2) -> ?union(U1) = force_union(T1), ?union(U2) = force_union(T2), subtract_union(U1, U2). @@ -3390,211 +3398,263 @@ t_from_form(Form, RecDict) -> -spec t_from_form(parse_form(), dict(), dict()) -> erl_type(). t_from_form(Form, RecDict, VarDict) -> - {T, _R} = t_from_form(Form, [], RecDict, VarDict), + {T, _R} = t_from_form(Form, [], false, RecDict, VarDict), T. -type type_names() :: [{'type' | 'opaque' | 'record', atom()}]. --spec t_from_form(parse_form(), type_names(), dict(), dict()) -> +-spec t_from_form(parse_form(), type_names(), boolean(), dict(), dict()) -> {erl_type(), type_names()}. -t_from_form({var, _L, '_'}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({var, _L, '_'}, _TypeNames, _InOpaque, _RecDict, _VarDict) -> {t_any(), []}; -t_from_form({var, _L, Name}, _TypeNames, _RecDict, VarDict) -> +t_from_form({var, _L, Name}, _TypeNames, _InOpaque, _RecDict, VarDict) -> case dict:find(Name, VarDict) of error -> {t_var(Name), []}; {ok, Val} -> {Val, []} end; -t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, RecDict, VarDict) -> - t_from_form(Type, TypeNames, RecDict, VarDict); -t_from_form({paren_type, _L, [Type]}, TypeNames, RecDict, VarDict) -> - t_from_form(Type, TypeNames, RecDict, VarDict); +t_from_form({ann_type, _L, [_Var, Type]}, TypeNames, InOpaque, RecDict, + VarDict) -> + t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict); +t_from_form({paren_type, _L, [Type]}, TypeNames, InOpaque, RecDict, + VarDict) -> + t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict); t_from_form({remote_type, _L, [{atom, _, Module}, {atom, _, Type}, Args]}, - TypeNames, RecDict, VarDict) -> - {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict), + TypeNames, InOpaque, RecDict, VarDict) -> + {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict), {t_remote(Module, Type, L), R}; -t_from_form({atom, _L, Atom}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({atom, _L, Atom}, _TypeNames, _InOpaque, _RecDict, _VarDict) -> {t_atom(Atom), []}; -t_from_form({integer, _L, Int}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({integer, _L, Int}, _TypeNames, _InOpaque, _RecDict, _VarDict) -> {t_integer(Int), []}; -t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _RecDict, _VarDict) -> +t_from_form({op, _L, _Op, _Arg} = Op, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> case erl_eval:partial_eval(Op) of {integer, _, Val} -> {t_integer(Val), []}; - _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])}) + _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])}) end; -t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames, _RecDict, _VarDict) -> +t_from_form({op, _L, _Op, _Arg1, _Arg2} = Op, _TypeNames, _InOpaque, + _RecDict, _VarDict) -> case erl_eval:partial_eval(Op) of {integer, _, Val} -> {t_integer(Val), []}; - _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Op])}) + _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Op])}) end; -t_from_form({type, _L, any, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, any, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_any(), []}; -t_from_form({type, _L, arity, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, arity, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_arity(), []}; -t_from_form({type, _L, array, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, array, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_array(), []}; -t_from_form({type, _L, atom, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, atom, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_atom(), []}; -t_from_form({type, _L, binary, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, binary, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_binary(), []}; t_from_form({type, _L, binary, [Base, Unit]} = Type, - _TypeNames, _RecDict, _VarDict) -> + _TypeNames, _InOpaque, _RecDict, _VarDict) -> case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of {{integer, _, BaseVal}, {integer, _, UnitVal}} when BaseVal >= 0, UnitVal >= 0 -> {t_bitstr(UnitVal, BaseVal), []}; - _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])}) + _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])}) end; -t_from_form({type, _L, bitstring, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, bitstring, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_bitstr(), []}; -t_from_form({type, _L, bool, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, bool, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_boolean(), []}; % XXX: Temporarily -t_from_form({type, _L, boolean, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, boolean, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_boolean(), []}; -t_from_form({type, _L, byte, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, byte, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_byte(), []}; -t_from_form({type, _L, char, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, char, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_char(), []}; -t_from_form({type, _L, dict, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, dict, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_dict(), []}; -t_from_form({type, _L, digraph, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, digraph, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_digraph(), []}; -t_from_form({type, _L, float, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, float, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_float(), []}; -t_from_form({type, _L, function, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, function, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_fun(), []}; -t_from_form({type, _L, 'fun', []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, 'fun', []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_fun(), []}; t_from_form({type, _L, 'fun', [{type, _, any, []}, Range]}, TypeNames, - RecDict, VarDict) -> - {T, R} = t_from_form(Range, TypeNames, RecDict, VarDict), + InOpaque, RecDict, VarDict) -> + {T, R} = t_from_form(Range, TypeNames, InOpaque, RecDict, VarDict), {t_fun(T), R}; t_from_form({type, _L, 'fun', [{type, _, product, Domain}, Range]}, - TypeNames, RecDict, VarDict) -> - {L, R1} = list_from_form(Domain, TypeNames, RecDict, VarDict), - {T, R2} = t_from_form(Range, TypeNames, RecDict, VarDict), + TypeNames, InOpaque, RecDict, VarDict) -> + {L, R1} = list_from_form(Domain, TypeNames, InOpaque, RecDict, VarDict), + {T, R2} = t_from_form(Range, TypeNames, InOpaque, RecDict, VarDict), {t_fun(L, T), R1 ++ R2}; -t_from_form({type, _L, gb_set, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, gb_set, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_gb_set(), []}; -t_from_form({type, _L, gb_tree, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, gb_tree, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_gb_tree(), []}; -t_from_form({type, _L, identifier, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, identifier, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_identifier(), []}; -t_from_form({type, _L, integer, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, integer, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_integer(), []}; -t_from_form({type, _L, iodata, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, iodata, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_iodata(), []}; -t_from_form({type, _L, iolist, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, iolist, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_iolist(), []}; -t_from_form({type, _L, list, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, list, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_list(), []}; -t_from_form({type, _L, list, [Type]}, TypeNames, RecDict, VarDict) -> - {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict), +t_from_form({type, _L, list, [Type]}, TypeNames, InOpaque, RecDict, + VarDict) -> + {T, R} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict), {t_list(T), R}; -t_from_form({type, _L, mfa, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, mfa, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_mfa(), []}; -t_from_form({type, _L, module, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, module, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_module(), []}; -t_from_form({type, _L, nil, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, nil, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_nil(), []}; -t_from_form({type, _L, neg_integer, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, neg_integer, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_neg_integer(), []}; -t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, non_neg_integer, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_non_neg_integer(), []}; -t_from_form({type, _L, no_return, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, no_return, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_unit(), []}; -t_from_form({type, _L, node, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, node, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_node(), []}; -t_from_form({type, _L, none, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, none, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_none(), []}; -t_from_form({type, _L, nonempty_list, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, nonempty_list, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_nonempty_list(), []}; -t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, RecDict, VarDict) -> - {T, R} = t_from_form(Type, TypeNames, RecDict, VarDict), +t_from_form({type, _L, nonempty_list, [Type]}, TypeNames, InOpaque, RecDict, + VarDict) -> + {T, R} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict), {t_nonempty_list(T), R}; t_from_form({type, _L, nonempty_improper_list, [Cont, Term]}, TypeNames, - RecDict, VarDict) -> - {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict), - {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict), + InOpaque, RecDict, VarDict) -> + {T1, R1} = t_from_form(Cont, TypeNames, InOpaque, RecDict, VarDict), + {T2, R2} = t_from_form(Term, TypeNames, InOpaque, RecDict, VarDict), {t_cons(T1, T2), R1 ++ R2}; t_from_form({type, _L, nonempty_maybe_improper_list, []}, _TypeNames, - _RecDict, _VarDict) -> + _InOpaque, _RecDict, _VarDict) -> {t_cons(?any, ?any), []}; -t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]}, TypeNames, - RecDict, VarDict) -> - {T1, R1} = t_from_form(Cont, TypeNames, RecDict, VarDict), - {T2, R2} = t_from_form(Term, TypeNames, RecDict, VarDict), +t_from_form({type, _L, nonempty_maybe_improper_list, [Cont, Term]}, + TypeNames, InOpaque, RecDict, VarDict) -> + {T1, R1} = t_from_form(Cont, TypeNames, InOpaque, RecDict, VarDict), + {T2, R2} = t_from_form(Term, TypeNames, InOpaque, RecDict, VarDict), {t_cons(T1, T2), R1 ++ R2}; -t_from_form({type, _L, nonempty_string, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, nonempty_string, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_nonempty_string(), []}; -t_from_form({type, _L, number, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, number, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_number(), []}; -t_from_form({type, _L, pid, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, pid, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_pid(), []}; -t_from_form({type, _L, port, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, port, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_port(), []}; -t_from_form({type, _L, pos_integer, []}, _TypeNames, _RecDict, _VarDict) -> - {t_pos_integer(), []}; -t_from_form({type, _L, maybe_improper_list, []}, _TypeNames, _RecDict, +t_from_form({type, _L, pos_integer, []}, _TypeNames, _InOpaque, _RecDict, _VarDict) -> + {t_pos_integer(), []}; +t_from_form({type, _L, maybe_improper_list, []}, _TypeNames, _InOpaque, + _RecDict, _VarDict) -> {t_maybe_improper_list(), []}; -t_from_form({type, _L, maybe_improper_list, [Content, Termination]}, TypeNames, - RecDict, VarDict) -> - {T1, R1} = t_from_form(Content, TypeNames, RecDict, VarDict), - {T2, R2} = t_from_form(Termination, TypeNames, RecDict, VarDict), +t_from_form({type, _L, maybe_improper_list, [Content, Termination]}, + TypeNames, InOpaque, RecDict, VarDict) -> + {T1, R1} = t_from_form(Content, TypeNames, InOpaque, RecDict, VarDict), + {T2, R2} = t_from_form(Termination, TypeNames, InOpaque, RecDict, VarDict), {t_maybe_improper_list(T1, T2), R1 ++ R2}; -t_from_form({type, _L, product, Elements}, TypeNames, RecDict, VarDict) -> - {L, R} = list_from_form(Elements, TypeNames, RecDict, VarDict), +t_from_form({type, _L, product, Elements}, TypeNames, InOpaque, RecDict, + VarDict) -> + {L, R} = list_from_form(Elements, TypeNames, InOpaque, RecDict, VarDict), {t_product(L), R}; -t_from_form({type, _L, queue, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, queue, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_queue(), []}; t_from_form({type, _L, range, [From, To]} = Type, - _TypeNames, _RecDict, _VarDict) -> + _TypeNames, _InOpaque, _RecDict, _VarDict) -> case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of - {{integer, _, FromVal}, - {integer, _, ToVal}} -> + {{integer, _, FromVal}, {integer, _, ToVal}} -> {t_from_range(FromVal, ToVal), []}; - _ -> throw({error, io_lib:format("Unable evaluate type ~w\n", [Type])}) + _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])}) end; -t_from_form({type, _L, record, [Name|Fields]}, TypeNames, RecDict, VarDict) -> - record_from_form(Name, Fields, TypeNames, RecDict, VarDict); -t_from_form({type, _L, reference, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, record, [Name|Fields]}, TypeNames, InOpaque, RecDict, + VarDict) -> + record_from_form(Name, Fields, TypeNames, InOpaque, RecDict, VarDict); +t_from_form({type, _L, reference, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_reference(), []}; -t_from_form({type, _L, set, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, set, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_set(), []}; -t_from_form({type, _L, string, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, string, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_string(), []}; -t_from_form({type, _L, term, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, term, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_any(), []}; -t_from_form({type, _L, tid, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, tid, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_tid(), []}; -t_from_form({type, _L, timeout, []}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, timeout, []}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_timeout(), []}; -t_from_form({type, _L, tuple, any}, _TypeNames, _RecDict, _VarDict) -> +t_from_form({type, _L, tuple, any}, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {t_tuple(), []}; -t_from_form({type, _L, tuple, Args}, TypeNames, RecDict, VarDict) -> - {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict), +t_from_form({type, _L, tuple, Args}, TypeNames, InOpaque, RecDict, VarDict) -> + {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict), {t_tuple(L), R}; -t_from_form({type, _L, union, Args}, TypeNames, RecDict, VarDict) -> - {L, R} = list_from_form(Args, TypeNames, RecDict, VarDict), +t_from_form({type, _L, union, Args}, TypeNames, InOpaque, RecDict, VarDict) -> + {L, R} = list_from_form(Args, TypeNames, InOpaque, RecDict, VarDict), {t_sup(L), R}; -t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) -> +t_from_form({type, _L, Name, Args}, TypeNames, InOpaque, RecDict, VarDict) -> case lookup_type(Name, RecDict) of {type, {_Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) -> - case unfold({type, Name}, TypeNames) of + case can_unfold_more({type, Name}, TypeNames) of true -> List = lists:zipwith( fun(ArgName, ArgType) -> {Ttemp, _R} = t_from_form(ArgType, TypeNames, - RecDict, VarDict), + InOpaque, RecDict, + VarDict), {ArgName, Ttemp} end, ArgNames, Args), TmpVarDict = dict:from_list(List), - {T, R} = t_from_form(Type, [{type, Name}|TypeNames], RecDict, - TmpVarDict), + {T, R} = t_from_form(Type, [{type, Name}|TypeNames], InOpaque, + RecDict, TmpVarDict), case lists:member({type, Name}, R) of true -> {t_limit(T, ?REC_TYPE_LIMIT), R}; false -> {T, R} @@ -3603,26 +3663,32 @@ t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) -> end; {opaque, {Module, Type, ArgNames}} when length(Args) =:= length(ArgNames) -> {Rep, Rret} = - case unfold({opaque, Name}, TypeNames) of + case can_unfold_more({opaque, Name}, TypeNames) of true -> List = lists:zipwith( fun(ArgName, ArgType) -> - {Ttemp, _R} = t_from_form(ArgType, TypeNames, - RecDict, VarDict), + {Ttemp, _R} = t_from_form(ArgType, TypeNames, + InOpaque, RecDict, + VarDict), {ArgName, Ttemp} end, ArgNames, Args), TmpVarDict = dict:from_list(List), - {T, R} = t_from_form(Type, [{opaque, Name}|TypeNames], RecDict, - TmpVarDict), + {T, R} = t_from_form(Type, [{opaque, Name}|TypeNames], true, + RecDict, TmpVarDict), case lists:member({opaque, Name}, R) of true -> {t_limit(T, ?REC_TYPE_LIMIT), R}; false -> {T, R} end; false -> {t_any(), [{opaque, Name}]} end, - Tret = t_from_form({opaque, -1, Name, {Module, Args, Rep}}, - RecDict, VarDict), + Tret = + case InOpaque of + true -> Rep; + false -> + t_from_form({opaque, -1, Name, {Module, Args, Rep}}, + RecDict, VarDict) + end, {Tret, Rret}; {type, _} -> throw({error, io_lib:format("Unknown type ~w\n", [Name])}); @@ -3631,15 +3697,16 @@ t_from_form({type, _L, Name, Args}, TypeNames, RecDict, VarDict) -> error -> throw({error, io_lib:format("Unable to find type ~w\n", [Name])}) end; -t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _RecDict, - _VarDict) -> +t_from_form({opaque, _L, Name, {Mod, Args, Rep}}, _TypeNames, _InOpaque, + _RecDict, _VarDict) -> case Args of [] -> {t_opaque(Mod, Name, Args, Rep), []}; _ -> throw({error, "Polymorphic opaque types not supported yet"}) end. -record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) -> - case unfold({record, Name}, TypeNames) of +record_from_form({atom, _, Name}, ModFields, TypeNames, InOpaque, RecDict, + VarDict) -> + case can_unfold_more({record, Name}, TypeNames) of true -> case lookup_record(Name, RecDict) of {ok, DeclFields} -> @@ -3649,14 +3716,15 @@ record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) -> {DeclFields1, R1} = case lists:all(fun(Elem) -> Elem end, AreTyped) of true -> {DeclFields, []}; - false -> fields_from_form(DeclFields, TypeNames1, + false -> fields_from_form(DeclFields, TypeNames1, InOpaque, RecDict, dict:new()) end, {GetModRec, R2} = get_mod_record(ModFields, DeclFields1, - TypeNames1, RecDict, VarDict), + TypeNames1, InOpaque, + RecDict, VarDict), case GetModRec of {error, FieldName} -> - throw({error, io_lib:format("Illegal declaration of ~w#{~w}\n", + throw({error, io_lib:format("Illegal declaration of #~w{~w}\n", [Name, FieldName])}); {ok, NewFields} -> {t_tuple( @@ -3664,17 +3732,18 @@ record_from_form({atom, _, Name}, ModFields, TypeNames, RecDict, VarDict) -> R1 ++ R2} end; error -> - throw({error, erlang:error(io_lib:format("Unknown record #~w{}\n", - [Name]))}) + throw({error, io_lib:format("Unknown record #~w{}\n", [Name])}) end; false -> {t_any(), []} end. -get_mod_record([], DeclFields, _TypeNames, _RecDict, _VarDict) -> +get_mod_record([], DeclFields, _TypeNames, _InOpaque, _RecDict, + _VarDict) -> {{ok, DeclFields}, []}; -get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) -> +get_mod_record(ModFields, DeclFields, TypeNames, InOpaque, RecDict, + VarDict) -> DeclFieldsDict = orddict:from_list(DeclFields), - {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames, + {ModFieldsDict, R} = build_field_dict(ModFields, TypeNames, InOpaque, RecDict, VarDict), case get_mod_record(DeclFieldsDict, ModFieldsDict, []) of {error, _FieldName} = Error -> {Error, R}; @@ -3684,21 +3753,23 @@ get_mod_record(ModFields, DeclFields, TypeNames, RecDict, VarDict) -> R} end. -build_field_dict(FieldTypes, TypeNames, RecDict, VarDict) -> - build_field_dict(FieldTypes, TypeNames, RecDict, VarDict, []). +build_field_dict(FieldTypes, TypeNames, InOpaque, RecDict, VarDict) -> + build_field_dict(FieldTypes, TypeNames, InOpaque, RecDict, VarDict, []). build_field_dict([{type, _, field_type, [{atom, _, Name}, Type]}|Left], - TypeNames, RecDict, VarDict, Acc) -> - {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict), + TypeNames, InOpaque, RecDict, VarDict, Acc) -> + {T, R1} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict), NewAcc = [{Name, T}|Acc], - {D, R2} = build_field_dict(Left, TypeNames, RecDict, VarDict, NewAcc), + {D, R2} = build_field_dict(Left, TypeNames, InOpaque, RecDict, VarDict, + NewAcc), {D, R1 ++ R2}; -build_field_dict([], _TypeNames, _RecDict, _VarDict, Acc) -> +build_field_dict([], _TypeNames, _InOpaque, _RecDict, _VarDict, Acc) -> {orddict:from_list(Acc), []}. get_mod_record([{FieldName, DeclType}|Left1], [{FieldName, ModType}|Left2], Acc) -> - case t_is_var(ModType) orelse t_is_subtype(ModType, DeclType) of + case t_is_var(ModType) orelse t_is_remote(ModType) orelse + t_is_subtype(ModType, DeclType) of false -> {error, FieldName}; true -> get_mod_record(Left1, Left2, [{FieldName, ModType}|Acc]) end; @@ -3711,18 +3782,19 @@ get_mod_record(DeclFields, [], Acc) -> get_mod_record(_, [{FieldName2, _ModType}|_], _Acc) -> {error, FieldName2}. -fields_from_form([], _TypeNames, _RecDict, _VarDict) -> +fields_from_form([], _TypeNames, _InOpaque, _RecDict, _VarDict) -> {[], []}; -fields_from_form([{Name, Type}|Tail], TypeNames, RecDict, VarDict) -> - {T, R1} = t_from_form(Type, TypeNames, RecDict, VarDict), - {F, R2} = fields_from_form(Tail, TypeNames, RecDict, VarDict), +fields_from_form([{Name, Type}|Tail], TypeNames, InOpaque, RecDict, + VarDict) -> + {T, R1} = t_from_form(Type, TypeNames, InOpaque, RecDict, VarDict), + {F, R2} = fields_from_form(Tail, TypeNames, InOpaque, RecDict, VarDict), {[{Name, T}|F], R1 ++ R2}. -list_from_form([], _TypeNames, _RecDict, _VarDict) -> +list_from_form([], _TypeNames, _InOpaque, _RecDict, _VarDict) -> {[], []}; -list_from_form([H|Tail], TypeNames, RecDict, VarDict) -> - {T, R1} = t_from_form(H, TypeNames, RecDict, VarDict), - {L, R2} = list_from_form(Tail, TypeNames, RecDict, VarDict), +list_from_form([H|Tail], TypeNames, InOpaque, RecDict, VarDict) -> + {T, R1} = t_from_form(H, TypeNames, InOpaque, RecDict, VarDict), + {L, R2} = list_from_form(Tail, TypeNames, InOpaque, RecDict, VarDict), {[T|L], R1 ++ R2}. -spec t_form_to_string(parse_form()) -> string(). @@ -3881,8 +3953,9 @@ lookup_type(Name, RecDict) -> type_is_defined(TypeOrOpaque, Name, RecDict) -> dict:is_key({TypeOrOpaque, Name}, RecDict). -unfold(TypeName, TypeNames) -> - not lists:member(TypeName, TypeNames). +can_unfold_more(TypeName, TypeNames) -> + Fun = fun(E, Acc) -> case E of TypeName -> Acc + 1; _ -> Acc end end, + lists:foldl(Fun, 0, TypeNames) < ?REC_TYPE_LIMIT. %% ----------------------------------- %% Set diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl index 1f8be4040e..920c94d85c 100644 --- a/lib/hipe/icode/hipe_beam_to_icode.erl +++ b/lib/hipe/icode/hipe_beam_to_icode.erl @@ -369,6 +369,10 @@ trans_fun([{bif,BifName,{f,Lbl},[_] = Args,Reg}|Instructions], Env) -> trans_fun([{bif,BifName,{f,Lbl},[_,_] = Args,Reg}|Instructions], Env) -> {BifInsts,Env1} = trans_bif(2,BifName,Lbl,Args,Reg,Env), [hipe_icode:mk_comment({bif2,BifName})|BifInsts] ++ trans_fun(Instructions,Env1); +%%--- bif3 --- +trans_fun([{bif,BifName,{f,Lbl},[_,_,_] = Args,Reg}|Instructions], Env) -> + {BifInsts,Env1} = trans_bif(3,BifName,Lbl,Args,Reg,Env), + [hipe_icode:mk_comment({bif3,BifName})|BifInsts] ++ trans_fun(Instructions,Env1); %%--- allocate trans_fun([{allocate,StackSlots,_}|Instructions], Env) -> trans_allocate(StackSlots) ++ trans_fun(Instructions,Env); diff --git a/lib/hipe/icode/hipe_icode_callgraph.erl b/lib/hipe/icode/hipe_icode_callgraph.erl index 95182fc002..3dba8e1071 100644 --- a/lib/hipe/icode/hipe_icode_callgraph.erl +++ b/lib/hipe/icode/hipe_icode_callgraph.erl @@ -25,8 +25,6 @@ %% in hipe_icode_type.erl. %% %% Created : 7 Jun 2004 by Tobias Lindahl <[email protected]> -%% -%% $Id$ %%----------------------------------------------------------------------- -module(hipe_icode_callgraph). @@ -48,7 +46,7 @@ -type mfa_icode() :: {mfa(), #icode{}}. --record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[atom()]]}). +-record(icode_callgraph, {codedict :: dict(), ordered_sccs :: [[mfa()]]}). %%------------------------------------------------------------------------ %% Exported functions @@ -78,7 +76,7 @@ construct_callgraph(List) -> to_list(#icode_callgraph{codedict = Dict, ordered_sccs = SCCs}) -> FlatList = lists:flatten(SCCs), - [{Mod, dict:fetch(Mod, Dict)} || Mod <- FlatList]. + [{MFA, dict:fetch(MFA, Dict)} || MFA <- FlatList]. %%------------------------------------------------------------------------ diff --git a/lib/hipe/icode/hipe_icode_range.erl b/lib/hipe/icode/hipe_icode_range.erl index bcc857acf4..c7e6a451af 100644 --- a/lib/hipe/icode/hipe_icode_range.erl +++ b/lib/hipe/icode/hipe_icode_range.erl @@ -843,7 +843,7 @@ compare_with_integer(N, OldVarRange) -> %%== Ranges ================================================================== --spec pp_ann(#ann{} | erl_types:erl_type()) -> [string()]. +-spec pp_ann(#ann{} | erl_types:erl_type()) -> string(). pp_ann(#ann{range=#range{range=R, other=false}}) -> pp_range(R); @@ -1365,7 +1365,7 @@ range_bnot(Range) -> Minus_one = range_init({-1,-1}, false), range_add(range_mult(Range, Minus_one), Minus_one). --spec width(range_rep() | integer()) -> 'pos_inf' | non_neg_integer(). +-spec width(range_rep() | inf_integer()) -> 'pos_inf' | non_neg_integer(). width({Min, Max}) -> inf_max([width(Min), width(Max)]); width(pos_inf) -> pos_inf; diff --git a/lib/hipe/icode/hipe_icode_type.erl b/lib/hipe/icode/hipe_icode_type.erl index 28198467f7..3f9488d7c3 100644 --- a/lib/hipe/icode/hipe_icode_type.erl +++ b/lib/hipe/icode/hipe_icode_type.erl @@ -2,19 +2,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2009. All Rights Reserved. -%% +%% 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% %% %%%-------------------------------------------------------------------- @@ -23,8 +23,6 @@ %%% Description : Propagate type information. %%% %%% Created : 25 Feb 2003 by Tobias Lindahl <[email protected]> -%%% -%%% $Id$ %%%-------------------------------------------------------------------- -module(hipe_icode_type). @@ -78,7 +76,7 @@ %-define(server_debug, fun(X, Y) -> io:format("~p server: ~s ~p~n", [self(), X, Y]) end). -define(server_debug, fun(_, _) -> ok end). --import(erl_types, [min/2, max/2, number_min/1, number_max/1, +-import(erl_types, [number_min/1, number_max/1, t_any/0, t_atom/1, t_atom/0, t_atom_vals/1, t_binary/0, t_bitstr/0, t_bitstr_base/1, t_bitstr_unit/1, t_boolean/0, t_cons/0, t_constant/0, @@ -494,10 +492,10 @@ integer_range_less_then_propagator(IntArg1, IntArg2) -> Min2 = number_min(IntArg2), Max2 = number_max(IntArg2), %% is this the same as erl_types:t_subtract?? no ... ?? - TrueMax1 = min(Max1, erl_bif_types:infinity_add(Max2, -1)), - TrueMin2 = max(erl_bif_types:infinity_add(Min1, 1), Min2), - FalseMin1 = max(Min1, Min2), - FalseMax2 = min(Max1, Max2), + TrueMax1 = erl_types:min(Max1, erl_bif_types:infinity_add(Max2, -1)), + TrueMin2 = erl_types:max(erl_bif_types:infinity_add(Min1, 1), Min2), + FalseMin1 = erl_types:max(Min1, Min2), + FalseMax2 = erl_types:min(Max1, Max2), {t_from_range(Min1, TrueMax1), t_from_range(TrueMin2, Max2), t_from_range(FalseMin1, Max1), diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index c80fb6a0a2..570e4d9d17 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% 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% %% %% ==================================================================== @@ -25,7 +25,6 @@ %% Purpose : %% Notes : %% History : * 1998-01-28 Erik Johansson ([email protected]): Created. -%% CVS : $Id$ %% ==================================================================== %% @doc This is the direct interface to the HiPE compiler. %% @@ -506,7 +505,7 @@ compile(Name, File, Opts0) -> run_compiler(Name, DisasmFun, IcodeFun, NewOpts) end. --spec compile_core(mod(), _, compile_file(), comp_options()) -> +-spec compile_core(mod(), cerl:c_module(), compile_file(), comp_options()) -> {'ok', compile_ret()} | {'error', term()}. compile_core(Name, Core0, File, Opts) -> @@ -535,7 +534,7 @@ compile_core(Name, Core0, File, Opts) -> %% %% @see compile/3 --spec compile(mod(), _, compile_file(), comp_options()) -> +-spec compile(mod(), cerl:c_module() | [], compile_file(), comp_options()) -> {'ok', compile_ret()} | {'error', term()}. compile(Name, [], File, Opts) -> @@ -790,7 +789,7 @@ finalize_fun(MfaIcodeList, Exports, Opts) -> FalseVal when (FalseVal =:= undefined) orelse (FalseVal =:= false) -> [finalize_fun_sequential(MFAIcode, Opts, #comp_servers{}) || {_MFA, _Icode} = MFAIcode <- MfaIcodeList]; - TrueVal when (TrueVal =:= true) or (TrueVal =:= debug) -> + TrueVal when (TrueVal =:= true) orelse (TrueVal =:= debug) -> finalize_fun_concurrent(MfaIcodeList, Exports, Opts) end. @@ -939,6 +938,8 @@ assemble(CompiledCode, Closures, Exports, Options) -> hipe_sparc_assemble:assemble(CompiledCode, Closures, Exports, Options); powerpc -> hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options); + ppc64 -> + hipe_ppc_assemble:assemble(CompiledCode, Closures, Exports, Options); arm -> hipe_arm_assemble:assemble(CompiledCode, Closures, Exports, Options); x86 -> @@ -1048,7 +1049,7 @@ post(Res, Icode, Options) -> %% -------------------------------------------------------------------- %% @doc Returns the current HiPE version as a string(). --spec version() -> string(). +-spec version() -> nonempty_string(). version() -> ?VERSION_STRING(). @@ -1390,6 +1391,8 @@ o1_opts() -> Common; powerpc -> Common; + ppc64 -> + Common; arm -> Common -- [inline_fp]; % Pointless optimising for absent hardware x86 -> @@ -1411,6 +1414,8 @@ o2_opts() -> Common; powerpc -> Common; + ppc64 -> + Common; arm -> Common; x86 -> @@ -1429,6 +1434,8 @@ o3_opts() -> Common; powerpc -> Common; + ppc64 -> + Common; arm -> Common; x86 -> diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl index fe9bc83fd2..e81642fb33 100644 --- a/lib/hipe/main/hipe_main.erl +++ b/lib/hipe/main/hipe_main.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% 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% %% %% @doc This is the HiPE compiler's main "loop". @@ -102,7 +102,7 @@ compile_icode(MFA, LinearIcode0, Options, Servers, DebugState) -> ?opt_start_timer("Icode"), LinearIcode1 = icode_no_comment(LinearIcode0, Options), IcodeCfg0 = icode_linear_to_cfg(LinearIcode1, Options), - %%hipe_icode_cfg:pp(IcodeCfg1), + %% hipe_icode_cfg:pp(IcodeCfg0), IcodeCfg1 = icode_handle_exceptions(IcodeCfg0, MFA, Options), IcodeCfg3 = icode_inline_bifs(IcodeCfg1, Options), pp(IcodeCfg3, MFA, icode, pp_icode, Options, Servers), diff --git a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl index ac555b933c..ce33af453a 100644 --- a/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl +++ b/lib/hipe/regalloc/hipe_graph_coloring_regalloc.erl @@ -389,23 +389,23 @@ decrement_each([N|Ns], OldLow, IG, Vis, K) -> %% {Spilled_node, Low_degree_neighbors, New_interference_graph} spill(IG, Vis, Spill, K, SpillLimit, Target) -> - Ns = list_ig(IG), - Costs = spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target), - ?report3("spill costs are ~p~n",[Costs]), - ActualCosts = lists:sort(Costs), - ?report3("actual costs are ~p~n",[ActualCosts]), + Ns = list_ig(IG), + Costs = spill_costs(Ns, IG, Vis, Spill, SpillLimit, Target), + ?report3("spill costs are ~p~n", [Costs]), + ActualCosts = lists:sort(Costs), + ?report3("actual costs are ~p~n", [ActualCosts]), case ActualCosts of - [] -> - ?error_msg("There is no node to spill",[]), + [] -> + ?error_msg("There is no node to spill", []), ?EXIT('no node to spill'); [{_Cost,N}|_] -> {Low, NewIG} = decrement_neighbors(N, [], IG, Vis, K), - %?report("spilled node ~p at cost ~p (~p now ready)~n",[N,Cost,Low]), + %% ?report("spilled node ~p at cost ~p (~p now ready)~n", [N,Cost,Low]), {N, Low, NewIG} end. spill_costs([], _IG, _Vis, _Spill, _SpillLimit, _Target) -> - []; + []; spill_costs([{N,Info}|Ns], IG, Vis, Spill, SpillLimit, Target) -> case degree(Info) of 0 -> spill_costs(Ns,IG,Vis,Spill, SpillLimit, Target); @@ -451,28 +451,28 @@ select_colors([{X,colorable}|Xs], IG, Cols, PhysRegs, K) -> {Reg,NewCols} = select_color(X, IG, Cols, PhysRegs), ?report("~p~n",[Reg]), [{X,{reg,Reg}} | select_colors(Xs, IG, NewCols, PhysRegs, K)]; -%select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) -> -% ?report('spilled: ~p~n',[X]), -% %% Check if optimistic coloring could have found a color -% case catch select_color(X,IG,Cols,K) of -% {'EXIT',_} -> % no color possible -% ?report('(no optimistic color)~n',[]), -% [{X,{spill,M}}|select_colors(Xs, IG, Cols, PhysRegs, K)]; -% {Reg,NewCols} -> -% ?report('(optimistic color: ~p)~n',[Reg]), -% [{X,{reg,Reg}}|select_colors(Xs, IG, Cols, PhysRegs, K)] -% end. +%%select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) -> +%% ?report('spilled: ~p~n',[X]), +%% %% Check if optimistic coloring could have found a color +%% case catch select_color(X,IG,Cols,K) of +%% {'EXIT',_} -> % no color possible +%% ?report('(no optimistic color)~n',[]), +%% [{X,{spill,M}}|select_colors(Xs, IG, Cols, PhysRegs, K)]; +%% {Reg,NewCols} -> +%% ?report('(optimistic color: ~p)~n',[Reg]), +%% [{X,{reg,Reg}}|select_colors(Xs, IG, Cols, PhysRegs, K)] +%% end. %% Old code / pessimistic coloring: select_colors([{X,{spill,M}}|Xs], IG, Cols, PhysRegs, K) -> ?report("spilled: ~p~n",[X]), %% Check if optimistic coloring could have found a color -% case catch select_color(X,IG,Cols,K) of -% {'EXIT',_} -> % no color possible -% ?report('(no optimistic color)~n',[]); -% {Reg,NewCols} -> -% ?report('(optimistic color: ~p)~n',[Reg]) -% end, +%% case catch select_color(X,IG,Cols,K) of +%% {'EXIT',_} -> % no color possible +%% ?report('(no optimistic color)~n',[]); +%% {Reg,NewCols} -> +%% ?report('(optimistic color: ~p)~n',[Reg]) +%% end, [{X,{spill,M}} | select_colors(Xs, IG, Cols, PhysRegs, K)]. select_color(X, IG, Cols, PhysRegs) -> diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index ef06b2abf8..d93f423f0c 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -354,6 +354,8 @@ phi_arglist_update/2, phi_redirect_pred/3]). +-export_type([alub_cond/0]). + %% %% RTL %% @@ -590,6 +592,9 @@ branch_pred(#branch{p=P}) -> P. %% alub %% +-type alub_cond() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le' + | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'. + mk_alub(Dst, Src1, Op, Src2, Cond, True, False) -> mk_alub(Dst, Src1, Op, Src2, Cond, True, False, 0.5). mk_alub(Dst, Src1, Op, Src2, Cond, True, False, P) -> diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc index 31fedd927e..9e80fa5e13 100644 --- a/lib/hipe/rtl/hipe_rtl_arith.inc +++ b/lib/hipe/rtl/hipe_rtl_arith.inc @@ -119,7 +119,8 @@ eval_alu(Op, Arg1, Arg2) -> %% there are cases where we can evaluate a subset of the bits, but can %% not do a full eval-alub call (eg. a + 0 gives no carry) %% --spec eval_cond_bits(atom(), boolean(), boolean(), boolean(), boolean()) -> boolean(). +-spec eval_cond_bits(hipe_rtl:alub_cond(), boolean(), + boolean(), boolean(), boolean()) -> boolean(). eval_cond_bits(Cond, N, Z, V, C) -> case Cond of @@ -146,9 +147,7 @@ eval_cond_bits(Cond, N, Z, V, C) -> 'overflow' -> V; 'not_overflow' -> - not V; - _ -> - ?EXIT({'condition code not handled',Cond}) + not V end. eval_alub(Op, Cond, Arg1, Arg2) -> diff --git a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl index 76c0a88933..64d723d15d 100644 --- a/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl +++ b/lib/hipe/rtl/hipe_rtl_ssa_const_prop.erl @@ -93,8 +93,6 @@ -include("../ssa/hipe_ssa_const_prop.inc"). -type bool_lattice() :: 'true' | 'false' | 'top' | 'bottom'. --type conditional() :: 'eq' | 'ne' | 'ge' | 'geu' | 'gt' | 'gtu' | 'le' - | 'leu' | 'lt' | 'ltu' | 'overflow' | 'not_overflow'. %%----------------------------------------------------------------------------- %% Procedure : visit_expression/2 @@ -400,7 +398,7 @@ maybe_top_or_bottom([top | Rest], _) -> maybe_top_or_bottom(Rest, top); maybe_top_or_bottom([bottom | _], _) -> bottom; maybe_top_or_bottom([_ | Rest], TB) -> maybe_top_or_bottom(Rest, TB). --spec partial_eval_branch(conditional(), bool_lattice(), bool_lattice(), +-spec partial_eval_branch(hipe_rtl:alub_cond(), bool_lattice(), bool_lattice(), bool_lattice() | 0, bool_lattice() | 0) -> bool_lattice(). partial_eval_branch(Cond, N0, Z0, V0, C0) -> @@ -441,14 +439,14 @@ visit_alub(Inst, Env) -> hipe_rtl:alub_false_label(Inst)]; top -> []; _ -> - %if the partial branch cannot be evaluated we must execute the - % instruction at runtime. + %% if the partial branch cannot be evaluated we must execute the + %% instruction at runtime. case partial_eval_branch(hipe_rtl:alub_cond(Inst), N, Z, C, V) of bottom -> [hipe_rtl:alub_true_label(Inst), hipe_rtl:alub_false_label(Inst)]; top -> []; - true -> [hipe_rtl:alub_true_label(Inst) ]; - false -> [hipe_rtl:alub_false_label(Inst) ] + true -> [hipe_rtl:alub_true_label(Inst)]; + false -> [hipe_rtl:alub_false_label(Inst)] end end, {[], NewSSA, NewEnv} = set_to(hipe_rtl:alub_dst(Inst), NewVal, Env), @@ -944,8 +942,8 @@ update_branch(Inst, Env) -> %% some small helpers. alub_to_move(Inst, Res, Lab) -> - [ hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res), - hipe_rtl:mk_goto(Lab) ]. + [hipe_rtl:mk_move(hipe_rtl:alub_dst(Inst), Res), + hipe_rtl:mk_goto(Lab)]. make_alub_subst_list(bottom, _, Tail) -> Tail; make_alub_subst_list(top, Src, _) -> @@ -970,13 +968,13 @@ update_alub(Inst, Env) -> %% move and the branch. We can however replace variable with constants: S1 = make_alub_subst_list(Val1, Src1, []), S2 = make_alub_subst_list(Val2, Src2, S1), - [ hipe_rtl:subst_uses(S2, Inst) ]; - _ -> % we know where we will be going, let's find out what Dst should be. - % knowing where we are going means that at most one of the values is - % bottom, hence we can replace the alu-instr with a move. - % remember, a = b + 0 can give us enough info to know what jump to - % do without knowing the value of a. (I wonder if this will ever - % actualy happen ;) + [hipe_rtl:subst_uses(S2, Inst)]; + _ -> %% we know where we will be going, let's find out what Dst should be. + %% knowing where we are going means that at most one of the values is + %% bottom, hence we can replace the alu-instr with a move. + %% remember, a = b + 0 can give us enough info to know what jump to + %% do without knowing the value of a. (I wonder if this will ever + %% actualy happen ;) Res = case ResVal of bottom -> % something nonconstant. if (Val1 =:= bottom) -> Src1; @@ -985,11 +983,12 @@ update_alub(Inst, Env) -> _ -> hipe_rtl:mk_imm(ResVal) end, case CondRes of - top -> io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n", - [Inst, {ResVal, N, Z, C, V} , Val1, Val2]), - [Inst ]; - true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst)); - false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst)) + top -> + io:format("oops. something VERY bad: ~w ~w V1 & 2 ~w ~w\n", + [Inst, {ResVal, N, Z, C, V} , Val1, Val2]), + [Inst]; + true -> alub_to_move(Inst, Res, hipe_rtl:alub_true_label(Inst)); + false -> alub_to_move(Inst, Res, hipe_rtl:alub_false_label(Inst)) end end. @@ -1050,7 +1049,7 @@ update_phi(Instruction, Environment) -> %%----------------------------------------------------------------------------- -%% make sure that all precoloured rgisters are taken out of the equation. +%% make sure that all precoloured registers are taken out of the equation. lookup_lattice_value(X, Environment) -> case hipe_rtl_arch:is_precoloured(X) or hipe_rtl:is_const_label(X) of true -> diff --git a/lib/hipe/tools/hipe_tool.erl b/lib/hipe/tools/hipe_tool.erl index a1bd79895d..990805ceca 100644 --- a/lib/hipe/tools/hipe_tool.erl +++ b/lib/hipe/tools/hipe_tool.erl @@ -56,9 +56,9 @@ -record(state, {win_created = false :: boolean(), mindex = 0 :: integer(), - mod :: module(), + mod :: atom(), funs = [] :: [fa()], - mods = [] :: [module()], + mods = [] :: [atom()], options = [o2] :: comp_options(), compiling = false :: 'false' | pid() }). @@ -291,8 +291,7 @@ update_code_listbox(State) -> integer_to_list(length(Mods))++")"), catch gs:config(code_listbox, [{data, Mods}, {items, Mods}, - {selection, 0} - ]), + {selection, 0}]), update_module_box(State#state{mods = Mods}, 0, Mods, "") end end. @@ -367,7 +366,7 @@ update_text(Lab, Text) -> %% @doc Returns a list of all loaded modules. %%--------------------------------------------------------------------- --spec mods() -> [module()]. +-spec mods() -> [atom()]. mods() -> [Mod || {Mod,_File} <- code:all_loaded()]. @@ -382,25 +381,26 @@ funs(Mod) -> native_code(Mod) -> Mod:module_info(native_addresses). --spec mfas(module(), [fa()]) -> [mfa()]. +-spec mfas(atom(), [fa()]) -> [mfa()]. mfas(Mod, Funs) -> [{Mod,F,A} || {F,A} <- Funs]. --spec fun_names(module(), [fa()], [fa_address()], boolean()) -> string(). +-spec fun_names(atom(), [fa()], [fa_address()], boolean()) -> [string()]. fun_names(M, Funs, NativeCode, Prof) -> - [list_to_atom(atom_to_list(F) ++ "/" ++ integer_to_list(A) ++ - (case in_native(F, A, NativeCode) of - true -> " [native] "; - false -> "" - end) - ++ - if Prof -> - (catch integer_to_list(hipe_bifs:call_count_get({M,F,A}))); - true -> "" - end) || - {F,A} <- Funs]. + [atom_to_list(F) ++ "/" ++ integer_to_list(A) + ++ + (case in_native(F, A, NativeCode) of + true -> " [native] "; + false -> "" + end) + ++ + if Prof -> + (catch integer_to_list(hipe_bifs:call_count_get({M,F,A}))); + true -> "" + end + || {F,A} <- Funs]. -spec in_native(atom(), arity(), [fa_address()]) -> boolean(). @@ -461,7 +461,7 @@ get_compile(Info) -> false -> [] end. --spec is_profiled(module()) -> boolean(). +-spec is_profiled(atom()) -> boolean(). is_profiled(Mod) -> case hipe_bifs:call_count_get({Mod,module_info,0}) of @@ -478,7 +478,7 @@ compile(State) -> P = spawn(fun() -> c(Parent, State#state.mod, State#state.options) end), State#state{compiling = P}. --spec c(pid(), module(), comp_options()) -> 'ok'. +-spec c(pid(), atom(), comp_options()) -> 'ok'. c(Parent, Mod, Options) -> Res = hipe:c(Mod, Options), diff --git a/lib/hipe/x86/hipe_x86_spill_restore.erl b/lib/hipe/x86/hipe_x86_spill_restore.erl index e60c446e17..cd927669fb 100644 --- a/lib/hipe/x86/hipe_x86_spill_restore.erl +++ b/lib/hipe/x86/hipe_x86_spill_restore.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2008-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% %% %% ==================================================================== @@ -71,9 +71,9 @@ firstPass(Defun) -> case hipe_x86_cfg:reverse_postorder(CFG0) of [Label1, Label2|_] -> SaveTreeElement = saveTreeLookup(Label2, SaveTree), - %% FilteredSaveTreeElement is the to be spilled temps around the function call. - %% They are spilled just before move formals - FilteredSaveTreeElement = [Temp || Temp <- SaveTreeElement, temp_is_pseudo(Temp)], + %% FilteredSaveTreeElement is the to be spilled temps around the + %% function call. They are spilled just before move formals. + FilteredSaveTreeElement = [T || T <- SaveTreeElement, temp_is_pseudo(T)], Block = hipe_x86_cfg:bb(CFG1, Label1), Code = hipe_bb:code(Block), %% The following statements are tedious but work ok. @@ -83,7 +83,7 @@ firstPass(Defun) -> %% Another solution may be to introduce another block. MoveCodes = lists:sublist(Code, length(Code)-1), JumpCode = lists:last(Code), - hipe_x86_cfg:bb_add(CFG1, Label1, hipe_bb:mk_bb(MoveCodes ++ [hipe_x86:mk_pseudo_spill(FilteredSaveTreeElement)] ++ [JumpCode])); + hipe_x86_cfg:bb_add(CFG1, Label1, hipe_bb:mk_bb(MoveCodes ++ [hipe_x86:mk_pseudo_spill(FilteredSaveTreeElement), JumpCode])); _ -> CFG1 end. @@ -110,13 +110,12 @@ firstPassHelper([Label|Labels], Liveness, CFG, SaveTree) -> NewBlock = hipe_bb:code_update(Block, NewCode), NewCFG = hipe_x86_cfg:bb_add(CFG, Label, NewBlock), SizeOfSet = setSize(NewIntersectedList), - %% if the Intersected Save List is not empty, insert it in the save tree. if SizeOfSet =/= 0 -> - UpdatedSaveTree = gb_trees:insert(Label,NewIntersectedList,SaveTree), - firstPassHelper(Labels, Liveness, NewCFG,UpdatedSaveTree); + UpdatedSaveTree = gb_trees:insert(Label, NewIntersectedList, SaveTree), + firstPassHelper(Labels, Liveness, NewCFG, UpdatedSaveTree); true -> - firstPassHelper(Labels, Liveness, NewCFG,SaveTree) + firstPassHelper(Labels, Liveness, NewCFG, SaveTree) end; firstPassHelper([], _, CFG, SaveTree) -> {CFG, SaveTree}. @@ -125,17 +124,15 @@ firstPassHelper([], _, CFG, SaveTree) -> firstPassDoBlock(Insts, LiveOut, IntersectedSaveList) -> lists:foldr(fun firstPassDoInsn/2, {LiveOut,IntersectedSaveList,[]}, Insts). -firstPassDoInsn(I, {LiveOut,IntersectedSaveList,PrevInsts} ) -> +firstPassDoInsn(I, {LiveOut,IntersectedSaveList,PrevInsts}) -> case I of #pseudo_call{} -> do_pseudo_call(I, {LiveOut,IntersectedSaveList,PrevInsts}); _ -> % other instructions DefinedList = from_list( ?HIPE_X86_LIVENESS:defines(I)), UsedList = from_list(?HIPE_X86_LIVENESS:uses(I)), - NewLiveOut = subtract(union(LiveOut, UsedList), DefinedList), - NewIntersectedSaveList = subtract(IntersectedSaveList, DefinedList), - + NewIntersectedSaveList = subtract(IntersectedSaveList, DefinedList), {NewLiveOut, NewIntersectedSaveList, [I|PrevInsts]} end. @@ -162,7 +159,7 @@ saveTreeLookup(Label, SaveTree) -> [] end. -%% Performs the second pass of the algoritm. +%% Performs the second pass of the algorithm. %% It basically eliminates the unnecessary spills and introduces restores. %% Works top down secondPass(CFG0) -> @@ -306,7 +303,8 @@ addRestoreBlockToEdge(PseudoCall, ContLabel, CFG, TempArgsList) -> NewCFG = hipe_x86_cfg:bb_add(CFG, NextLabel, NewBlock), {NewCFG, NewPseudoCall}. -%% used instead of hipe_x86_cfg:redirect_jmp since it does not handle pseudo_call calls. +%% used instead of hipe_x86_cfg:redirect_jmp since it does not handle +%% pseudo_call calls. redirect_pseudo_call(I = #pseudo_call{contlab=ContLabel}, Old, New) -> case Old =:= ContLabel of true -> I#pseudo_call{contlab=New}; @@ -323,8 +321,8 @@ temp_is_pseudo(Temp) -> %% Set operations where the module name is an easily changeable macro %%--------------------------------------------------------------------- -union(Set1,Set2) -> - ?SET_MODULE:union(Set1,Set2). +union(Set1, Set2) -> + ?SET_MODULE:union(Set1, Set2). setSize(Set) -> ?SET_MODULE:size(Set). diff --git a/lib/inets/doc/src/ftp.xml b/lib/inets/doc/src/ftp.xml index 25dfe716fc..ca902d8d9d 100644 --- a/lib/inets/doc/src/ftp.xml +++ b/lib/inets/doc/src/ftp.xml @@ -107,7 +107,7 @@ <tag>{mode, Mode}</tag> <item> <marker id="mode"></marker> - <p>Mode = <c>active | passive</c> </p>> + <p>Mode = <c>active | passive</c> </p> <p>Default is <c>passive</c>. </p> </item> diff --git a/lib/inets/doc/src/http_client.xml b/lib/inets/doc/src/http_client.xml index ea8053cafa..672ea3fa98 100644 --- a/lib/inets/doc/src/http_client.xml +++ b/lib/inets/doc/src/http_client.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -57,7 +57,7 @@ [{inets, [{services, [{httpc, PropertyList}]}]}] </pre> <p>For valid properties see - <seealso marker="http">httpc(3)</seealso>. </p> + <seealso marker="httpc">httpc(3)</seealso>. </p> </section> <section> diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml index 9c8df28fec..c20358178b 100644 --- a/lib/inets/doc/src/httpc.xml +++ b/lib/inets/doc/src/httpc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -172,7 +172,8 @@ ssl_options() = {verify, code()} | {autoredirect, boolean()} | {proxy_auth, {userstring(), passwordstring()}} | {version, http_version()} | - {relaxed, boolean()}</v> + {relaxed, boolean()} | + {url_encode, boolean()}</v> <v>timeout() = integer() >= 0 | infinity</v> <v>Options = options()</v> <v>options() = [option()]</v> @@ -276,6 +277,11 @@ ssl_options() = {verify, code()} | <p>Defaults to <c>false</c>. </p> </item> + <tag><c><![CDATA[url_encode]]></c></tag> + <item> + <p>Will apply Percent-encoding, also known as URL encoding on the URL.</p> + <p>Defaults to <c>false</c>. </p> + </item> </taglist> <p>Option (<c>option()</c>) details: </p> @@ -342,7 +348,7 @@ ssl_options() = {verify, code()} | <p>Socket options to be used for this and subsequent request(s). </p> <p>Overrides any value set by the - <seealso marker="set_options">set_options</seealso> + <seealso marker="#set_options">set_options</seealso> function. </p> <p>Note that the validity of the options are <em>not</em> checked in any way. </p> @@ -632,4 +638,3 @@ apply(Module, Function, [ReplyInfo | Args]) </section> </erlref> - diff --git a/lib/inets/doc/src/httpd.xml b/lib/inets/doc/src/httpd.xml index 847605fe93..62f4e18f82 100644 --- a/lib/inets/doc/src/httpd.xml +++ b/lib/inets/doc/src/httpd.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -421,7 +421,7 @@ bytes Beware of trailing space in Replacement that will be used. If you must have a space in Re use e.g the character encoding - <code>\040</code> see <seealso marker="re">re(3)</seealso>. + <code>\040</code> see <seealso marker="stdlib:re">re(3)</seealso>. </item> <tag>{directory_index, [string()]}</tag> @@ -931,6 +931,10 @@ bytes connection }). </code> + + <p>To acess the record in your callback-module use </p> + <code> -include_lib("inets/include/httpd.hrl"). </code> + <p>The fields of the <c>mod</c> record has the following meaning: </p> <taglist> @@ -978,10 +982,10 @@ bytes <c>parsed_header</c> contains all HTTP header fields from the HTTP-request stored in a list as key-value tuples. See RFC 2616 for a listing of all header fields. For example the date field - would be stored as: <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"}. + would be stored as: <c>{"date","Wed, 15 Oct 1997 14:35:17 GMT"} </c>. RFC 2616 defines that HTTP is a case insensitive protocol and the header fields may be in lower case or upper case. Httpd will - ensure that all header field names are in lower case. </c>. + ensure that all header field names are in lower case. </item> <tag><c>entity_body</c></tag> <item>The <c>Entity-Body</c> as defined diff --git a/lib/inets/doc/src/mod_auth.xml b/lib/inets/doc/src/mod_auth.xml index f3628c8297..9503add2e0 100644 --- a/lib/inets/doc/src/mod_auth.xml +++ b/lib/inets/doc/src/mod_auth.xml @@ -111,7 +111,8 @@ </desc> </func> <func> - <name>list_users(Options) -> {ok, Users} | {error, Reason} <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name> + <name>list_users(Options) -> {ok, Users} | {error, Reason}</name> + <name>list_users(Port, Dir) -> {ok, Users} | {error, Reason}</name> <name>list_users(Address, Port, Dir) -> {ok, Users} | {error, Reason}</name> <fsummary>List users in the user database.</fsummary> <type> diff --git a/lib/inets/include/httpd.hrl b/lib/inets/include/httpd.hrl new file mode 100644 index 0000000000..a7e63ca670 --- /dev/null +++ b/lib/inets/include/httpd.hrl @@ -0,0 +1,41 @@ +%% +%% %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% +%% +%% + +-ifndef(httpd_hrl). +-define(httpd_hrl, true). + +-include_lib("kernel/include/file.hrl"). + +-record(init_data,{peername,resolve}). + +-record(mod,{init_data, + data=[], + socket_type=ip_comm, + socket, + config_db, + method, + absolute_uri=[], + request_uri, + http_version, + request_line, + parsed_header=[], + entity_body, + connection}). +-endif. % -ifdef(httpd_hrl). diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile index 575c6efaec..0397b48ab2 100644 --- a/lib/inets/src/http_client/Makefile +++ b/lib/inets/src/http_client/Makefile @@ -51,7 +51,6 @@ MODULES = \ httpc_profile_sup \ httpc_response \ httpc_request \ - http_uri \ HRL_FILES = httpc_internal.hrl diff --git a/lib/inets/src/http_client/httpc.erl b/lib/inets/src/http_client/httpc.erl index 851364001c..ae754fab94 100644 --- a/lib/inets/src/http_client/httpc.erl +++ b/lib/inets/src/http_client/httpc.erl @@ -442,18 +442,23 @@ handle_request(Method, Url, HeadersRecord = header_record(NewHeaders, Host2, HTTPOptions), Receiver = proplists:get_value(receiver, Options), SocketOpts = proplists:get_value(socket_opts, Options), + UrlEncodeBool = HTTPOptions#http_options.url_encode, + MaybeEscPath = url_encode(Path, UrlEncodeBool), + MaybeEscQuery = url_encode(Query, UrlEncodeBool), + AbsUri = url_encode(Url, UrlEncodeBool), + Request = #request{from = Receiver, scheme = Scheme, address = {Host, Port}, - path = Path, - pquery = Query, + path = MaybeEscPath, + pquery = MaybeEscQuery, method = Method, headers = HeadersRecord, content = {ContentType, Body}, settings = HTTPOptions, - abs_uri = Url, + abs_uri = AbsUri, userinfo = UserInfo, - stream = Stream, + stream = Stream, headers_as_is = headers_as_is(Headers, Options), socket_opts = SocketOpts, started = Started}, @@ -471,6 +476,10 @@ handle_request(Method, Url, Error end. +url_encode(URI, true) -> + http_uri:encode(URI); +url_encode(URI, false) -> + URI. handle_answer(RequestId, false, _) -> {ok, RequestId}; @@ -578,12 +587,8 @@ http_options_default() -> (_) -> error end, - AutoRedirectPost = fun(Value) when (Value =:= true) orelse - (Value =:= false) -> - {ok, Value}; - (_) -> - error - end, + AutoRedirectPost = boolfun(), + SslPost = fun(Value) when is_list(Value) -> {ok, {?HTTP_DEFAULT_SSL_KIND, Value}}; ({ssl, SslOptions}) when is_list(SslOptions) -> @@ -601,12 +606,8 @@ http_options_default() -> (_) -> error end, - RelaxedPost = fun(Value) when (Value =:= true) orelse - (Value =:= false) -> - {ok, Value}; - (_) -> - error - end, + RelaxedPost = boolfun(), + ConnTimeoutPost = fun(Value) when is_integer(Value) andalso (Value >= 0) -> {ok, Value}; @@ -615,6 +616,8 @@ http_options_default() -> (_) -> error end, + + UrlDecodePost = boolfun(), [ {version, {value, "HTTP/1.1"}, #http_options.version, VersionPost}, {timeout, {value, ?HTTP_REQUEST_TIMEOUT}, #http_options.timeout, TimeoutPost}, @@ -622,18 +625,21 @@ http_options_default() -> {ssl, {value, {?HTTP_DEFAULT_SSL_KIND, []}}, #http_options.ssl, SslPost}, {proxy_auth, {value, undefined}, #http_options.proxy_auth, ProxyAuthPost}, {relaxed, {value, false}, #http_options.relaxed, RelaxedPost}, + {url_encode, {value, false}, #http_options.url_encode, UrlDecodePost}, %% this field has to be *after* the timeout option (as that field is used for the default value) {connect_timeout, {field, #http_options.timeout}, #http_options.connect_timeout, ConnTimeoutPost} ]. +boolfun() -> + fun(Value) when (Value =:= true) orelse + (Value =:= false) -> + {ok, Value}; + (_) -> + error + end. request_options_defaults() -> - VerifyBoolean = - fun(Value) when ((Value =:= true) orelse (Value =:= false)) -> - ok; - (_) -> - error - end, + VerifyBoolean = boolfun(), VerifySync = VerifyBoolean, diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 8af6613fa2..cb6f3e2841 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -713,33 +713,38 @@ terminate(normal, profile_name = ProfileName, request = Request, timers = Timers, - pipeline = Pipeline}) -> + pipeline = Pipeline, + keep_alive = KeepAlive} = State) -> ?hcrt("terminate(normal) - remote close", [{id, Id}, {profile, ProfileName}]), %% Clobber session (catch httpc_manager:delete_session(Id, ProfileName)), + maybe_retry_queue(Pipeline, State), + maybe_retry_queue(KeepAlive, State), + %% Cancel timers - #timers{request_timers = ReqTmrs, queue_timer = QTmr} = Timers, - cancel_timer(QTmr, timeout_queue), - lists:foreach(fun({_, Timer}) -> cancel_timer(Timer, timeout) end, - ReqTmrs), + cancel_timers(Timers), %% Maybe deliver answers to requests - deliver_answers([Request | queue:to_list(Pipeline)]), + deliver_answer(Request), %% And, just in case, close our side (**really** overkill) http_transport:close(SocketType, Socket); -terminate(_, #state{session = #session{id = Id, - socket = Socket, - socket_type = SocketType}, +terminate(Reason, #state{session = #session{id = Id, + socket = Socket, + socket_type = SocketType}, request = undefined, profile_name = ProfileName, timers = Timers, pipeline = Pipeline, keep_alive = KeepAlive} = State) -> + ?hcrt("terminate", + [{id, Id}, {profile, ProfileName}, {reason, Reason}]), + + %% Clobber session (catch httpc_manager:delete_session(Id, ProfileName)), maybe_retry_queue(Pipeline, State), @@ -772,59 +777,55 @@ maybe_send_answer(#request{from = answer_sent}, _Reason, State) -> maybe_send_answer(Request, Answer, State) -> answer_request(Request, Answer, State). -deliver_answers([]) -> - ?hcrd("deliver answer done", []), - ok; -deliver_answers([#request{id = Id, from = From} = Request | Requests]) +deliver_answer(#request{id = Id, from = From} = Request) when is_pid(From) -> Response = httpc_response:error(Request, socket_closed_remotely), ?hcrd("deliver answer", [{id, Id}, {from, From}, {response, Response}]), - httpc_response:send(From, Response), - deliver_answers(Requests); -deliver_answers([Request|Requests]) -> + httpc_response:send(From, Response); +deliver_answer(Request) -> ?hcrd("skip deliver answer", [{request, Request}]), - deliver_answers(Requests). + ok. %%-------------------------------------------------------------------- %% Func: code_change(_OldVsn, State, Extra) -> {ok, NewState} %% Purpose: Convert process state when code is changed %%-------------------------------------------------------------------- -code_change(_, #state{request = Request, pipeline = Queue} = State, - [{from, '5.0.1'}, {to, '5.0.2'}]) -> - Settings = new_http_options(Request#request.settings), - NewRequest = Request#request{settings = Settings}, - NewQueue = new_queue(Queue, fun new_http_options/1), - {ok, State#state{request = NewRequest, pipeline = NewQueue}}; - -code_change(_, #state{request = Request, pipeline = Queue} = State, - [{from, '5.0.2'}, {to, '5.0.1'}]) -> - Settings = old_http_options(Request#request.settings), - NewRequest = Request#request{settings = Settings}, - NewQueue = new_queue(Queue, fun old_http_options/1), - {ok, State#state{request = NewRequest, pipeline = NewQueue}}; +%% code_change(_, #state{request = Request, pipeline = Queue} = State, +%% [{from, '5.0.1'}, {to, '5.0.2'}]) -> +%% Settings = new_http_options(Request#request.settings), +%% NewRequest = Request#request{settings = Settings}, +%% NewQueue = new_queue(Queue, fun new_http_options/1), +%% {ok, State#state{request = NewRequest, pipeline = NewQueue}}; + +%% code_change(_, #state{request = Request, pipeline = Queue} = State, +%% [{from, '5.0.2'}, {to, '5.0.1'}]) -> +%% Settings = old_http_options(Request#request.settings), +%% NewRequest = Request#request{settings = Settings}, +%% NewQueue = new_queue(Queue, fun old_http_options/1), +%% {ok, State#state{request = NewRequest, pipeline = NewQueue}}; code_change(_, State, _) -> {ok, State}. -new_http_options({http_options, TimeOut, AutoRedirect, SslOpts, - Auth, Relaxed}) -> - {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts, - Auth, Relaxed}. - -old_http_options({http_options, _, TimeOut, AutoRedirect, - SslOpts, Auth, Relaxed}) -> - {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}. - -new_queue(Queue, Fun) -> - List = queue:to_list(Queue), - NewList = - lists:map(fun(Request) -> - Settings = - Fun(Request#request.settings), - Request#request{settings = Settings} - end, List), - queue:from_list(NewList). +%% new_http_options({http_options, TimeOut, AutoRedirect, SslOpts, +%% Auth, Relaxed}) -> +%% {http_options, "HTTP/1.1", TimeOut, AutoRedirect, SslOpts, +%% Auth, Relaxed}. + +%% old_http_options({http_options, _, TimeOut, AutoRedirect, +%% SslOpts, Auth, Relaxed}) -> +%% {http_options, TimeOut, AutoRedirect, SslOpts, Auth, Relaxed}. + +%% new_queue(Queue, Fun) -> +%% List = queue:to_list(Queue), +%% NewList = +%% lists:map(fun(Request) -> +%% Settings = +%% Fun(Request#request.settings), +%% Request#request{settings = Settings} +%% end, List), +%% queue:from_list(NewList). %%%-------------------------------------------------------------------- @@ -854,12 +855,18 @@ connect(SocketType, ToAddress, inet6fb4 -> Opts3 = [inet6 | Opts2], case http_transport:connect(SocketType, ToAddress, Opts3, Timeout) of - {error, Reason} when ((Reason =:= nxdomain) orelse - (Reason =:= eafnosupport)) -> + {error, _Reason} = Error -> Opts4 = [inet | Opts2], - http_transport:connect(SocketType, ToAddress, Opts4, Timeout); - Other -> - Other + case http_transport:connect(SocketType, + ToAddress, Opts4, Timeout) of + {error, _} -> + %% Reply with the "original" error + Error; + OK -> + OK + end; + OK -> + OK end; _ -> Opts3 = [IpFamily | Opts2], @@ -1440,6 +1447,12 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg, timers = Timers#timers{request_timers = lists:delete(Timer, RequestTimers)}}. + +cancel_timers(#timers{request_timers = ReqTmrs, queue_timer = QTmr}) -> + cancel_timer(QTmr, timeout_queue), + CancelTimer = fun({_, Timer}) -> cancel_timer(Timer, timeout) end, + lists:foreach(CancelTimer, ReqTmrs). + cancel_timer(undefined, _) -> ok; cancel_timer(Timer, TimeoutMsg) -> diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl index 3cdd95a02b..1d8a5b6a92 100644 --- a/lib/inets/src/http_client/httpc_internal.hrl +++ b/lib/inets/src/http_client/httpc_internal.hrl @@ -60,7 +60,11 @@ relaxed = false, %% integer() - ms before a connect times out - connect_timeout = ?HTTP_REQUEST_CTIMEOUT + connect_timeout = ?HTTP_REQUEST_CTIMEOUT, + + %% bool() - Use %-encoding rfc 2396 + url_encode + } ). diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index 1e1bde220b..591cb78c29 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -734,10 +734,11 @@ handle_connect_and_send(_StarterPid, ReqId, HandlerPid, Result, ok; [] -> - error_report(Profile, - "handler (~p) successfully started " - "for unknown request ~p => canceling", - [HandlerPid, ReqId]), + ?hcri("handler successfully started " + "for unknown request => canceling", + [{profile, Profile}, + {handler, HandlerPid}, + {request, ReqId}]), httpc_handler:cancel(ReqId, HandlerPid) end. diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile index 5dac3b0c00..aaf3cfb995 100644 --- a/lib/inets/src/http_lib/Makefile +++ b/lib/inets/src/http_lib/Makefile @@ -45,7 +45,8 @@ MODULES = \ http_transport\ http_util \ http_request \ - http_response + http_response \ + http_uri HRL_FILES = http_internal.hrl diff --git a/lib/inets/src/http_lib/http_transport.erl b/lib/inets/src/http_lib/http_transport.erl index b8121852b8..0024d19fc1 100644 --- a/lib/inets/src/http_lib/http_transport.erl +++ b/lib/inets/src/http_lib/http_transport.erl @@ -192,24 +192,31 @@ listen_ip_comm(Addr, Port) -> case IpFamily of inet6fb4 -> Opts2 = [inet6 | Opts], + ?hlrt("try ipv6 listen", [{port, NewPort}, {opts, Opts2}]), case (catch gen_tcp:listen(NewPort, Opts2)) of {error, Reason} when ((Reason =:= nxdomain) orelse (Reason =:= eafnosupport)) -> Opts3 = [inet | Opts], + ?hlrt("ipv6 listen failed - try ipv4 instead", + [{reason, Reason}, {port, NewPort}, {opts, Opts3}]), gen_tcp:listen(NewPort, Opts3); %% This is when a given hostname has resolved to a %% IPv4-address. The inet6-option together with a %% {ip, IPv4} option results in badarg - {'EXIT', _} -> + {'EXIT', Reason} -> Opts3 = [inet | Opts], + ?hlrt("ipv6 listen exit - try ipv4 instead", + [{reason, Reason}, {port, NewPort}, {opts, Opts3}]), gen_tcp:listen(NewPort, Opts3); Other -> + ?hlrt("ipv6 listen done", [{other, Other}]), Other end; _ -> Opts2 = [IpFamily | Opts], + ?hlrt("listen", [{port, NewPort}, {opts, Opts2}]), gen_tcp:listen(NewPort, Opts2) end. diff --git a/lib/inets/src/http_client/http_uri.erl b/lib/inets/src/http_lib/http_uri.erl index 615a0d8ec4..44b9face0b 100644 --- a/lib/inets/src/http_client/http_uri.erl +++ b/lib/inets/src/http_lib/http_uri.erl @@ -1,26 +1,26 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2006-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(http_uri). --export([parse/1]). +-export([parse/1, encode/1, decode/1]). %%%========================================================================= %%% API @@ -34,10 +34,25 @@ parse(AbsURI) -> {UserInfo, Host, Port, Path, Query} -> {Scheme, UserInfo, Host, Port, Path, Query}; _ -> - {error, {malformed_url, AbsURI}} + {error, {malformed_url, AbsURI}} end end. +encode(URI) -> + Reserved = sets:from_list([$;, $:, $@, $&, $=, $+, $,, $/, $?, + $#, $[, $], $<, $>, $\", ${, $}, $|, + $\\, $', $^, $%, $ ]), + lists:append(lists:map(fun(Char) -> + uri_encode(Char, Reserved) + end, URI)). + +decode([$%,Hex1,Hex2|Rest]) -> + [hex2dec(Hex1)*16+hex2dec(Hex2)|decode(Rest)]; +decode([First|Rest]) -> + [First|decode(Rest)]; +decode([]) -> + []. + %%%======================================================================== %%% Internal functions %%%======================================================================== @@ -56,7 +71,7 @@ parse_scheme(AbsURI) -> parse_uri_rest(Scheme, "//" ++ URIPart) -> - {Authority, PathQuery} = + {Authority, PathQuery} = case split_uri(URIPart, "/", URIPart, 1, 0) of Split = {_, _} -> Split; @@ -68,7 +83,7 @@ parse_uri_rest(Scheme, "//" ++ URIPart) -> {URIPart,""} end end, - + {UserInfo, HostPort} = split_uri(Authority, "@", {"", Authority}, 1, 1), {Host, Port} = parse_host_port(Scheme, HostPort), {Path, Query} = parse_path_query(PathQuery), @@ -78,7 +93,6 @@ parse_uri_rest(Scheme, "//" ++ URIPart) -> parse_path_query(PathQuery) -> {Path, Query} = split_uri(PathQuery, "\\?", {PathQuery, ""}, 1, 0), {path(Path), Query}. - parse_host_port(Scheme,"[" ++ HostPort) -> %ipv6 DefaultPort = default_port(Scheme), @@ -90,12 +104,12 @@ parse_host_port(Scheme, HostPort) -> DefaultPort = default_port(Scheme), {Host, Port} = split_uri(HostPort, ":", {HostPort, DefaultPort}, 1, 1), {Host, int_port(Port)}. - + split_uri(UriPart, SplitChar, NoMatchResult, SkipLeft, SkipRight) -> case inets_regexp:first_match(UriPart, SplitChar) of {match, Match, _} -> {string:substr(UriPart, 1, Match - SkipLeft), - string:substr(UriPart, Match + SkipRight, length(UriPart))}; + string:substr(UriPart, Match + SkipRight, length(UriPart))}; nomatch -> NoMatchResult end. @@ -114,3 +128,15 @@ path("") -> "/"; path(Path) -> Path. + +uri_encode(Char, Reserved) -> + case sets:is_element(Char, Reserved) of + true -> + [ $% | http_util:integer_to_hexlist(Char)]; + false -> + [Char] + end. + +hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0; +hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10; +hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10. diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile index 879e605217..bdd8c5ee3c 100644 --- a/lib/inets/src/http_server/Makefile +++ b/lib/inets/src/http_server/Makefile @@ -82,7 +82,9 @@ MODULES = \ mod_security \ mod_security_server -HRL_FILES = httpd.hrl httpd_internal.hrl mod_auth.hrl +INCLUDE = ../../include + +HRL_FILES = $(INCLUDE)/httpd.hrl httpd_internal.hrl mod_auth.hrl ERL_FILES = $(MODULES:%=%.erl) @@ -98,9 +100,9 @@ include ../inets_app/inets.mk ERL_COMPILE_FLAGS += \ $(INETS_FLAGS) \ $(INETS_ERL_COMPILE_FLAGS) \ - -I../../include \ + -I$(INCLUDE) \ -I../inets_app \ - -I../http_lib + -I../http_lib \ # ---------------------------------------------------- diff --git a/lib/inets/src/http_server/httpd.erl b/lib/inets/src/http_server/httpd.erl index fb5fa1c758..93608dbf96 100644 --- a/lib/inets/src/http_server/httpd.erl +++ b/lib/inets/src/http_server/httpd.erl @@ -24,7 +24,6 @@ -include("httpd.hrl"). - %% Behavior callbacks -export([ start_standalone/1, @@ -271,8 +270,8 @@ foreach([KeyValue|Rest]) -> {ok, Plus2Space, _} = inets_regexp:gsub(KeyValue,"[\+]"," "), case inets_regexp:split(Plus2Space,"=") of {ok,[Key|Value]} -> - [{httpd_util:decode_hex(Key), - httpd_util:decode_hex(lists:flatten(Value))}|foreach(Rest)]; + [{http_uri:decode(Key), + http_uri:decode(lists:flatten(Value))}|foreach(Rest)]; {ok,_} -> foreach(Rest) end. diff --git a/lib/inets/src/http_server/httpd.hrl b/lib/inets/src/http_server/httpd.hrl deleted file mode 100644 index 0db8a029bb..0000000000 --- a/lib/inets/src/http_server/httpd.hrl +++ /dev/null @@ -1,82 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-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_lib("kernel/include/file.hrl"). - --ifndef(SERVER_SOFTWARE). --define(SERVER_SOFTWARE,"inets/develop"). % Define in Makefile! --endif. --define(SERVER_PROTOCOL,"HTTP/1.1"). --define(DEFAULT_MODS, [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, - mod_dir, mod_get, mod_head, mod_log, mod_disk_log]). --define(SOCKET_CHUNK_SIZE,8192). --define(SOCKET_MAX_POLL,25). --define(FILE_CHUNK_SIZE,64*1024). --define(GATEWAY_INTERFACE,"CGI/1.1"). --define(NICE(Reason),lists:flatten(atom_to_list(?MODULE)++": "++Reason)). --define(DEFAULT_CONTEXT, - [{errmsg,"[an error occurred while processing this directive]"}, - {timefmt,"%A, %d-%b-%y %T %Z"}, - {sizefmt,"abbrev"}]). - - --ifdef(inets_error). --define(ERROR(Format, Args), io:format("E(~p:~p:~p) : "++Format++"~n", - [self(),?MODULE,?LINE]++Args)). --else. --define(ERROR(F,A),[]). --endif. - --ifdef(inets_log). --define(LOG(Format, Args), io:format("L(~p:~p:~p) : "++Format++"~n", - [self(),?MODULE,?LINE]++Args)). --else. --define(LOG(F,A),[]). --endif. - --ifdef(inets_debug). --define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n", - [self(),?MODULE,?LINE]++Args)). --else. --define(DEBUG(F,A),[]). --endif. - --ifdef(inets_cdebug). --define(CDEBUG(Format, Args), io:format("C(~p:~p:~p) : "++Format++"~n", - [self(),?MODULE,?LINE]++Args)). --else. --define(CDEBUG(F,A),[]). --endif. - - --record(init_data,{peername,resolve}). --record(mod,{init_data, - data=[], - socket_type=ip_comm, - socket, - config_db, - method, - absolute_uri=[], - request_uri, - http_version, - request_line, - parsed_header=[], - entity_body, - connection}). diff --git a/lib/inets/src/http_server/httpd_acceptor.erl b/lib/inets/src/http_server/httpd_acceptor.erl index c261eff6b2..bcebb6a9e3 100644 --- a/lib/inets/src/http_server/httpd_acceptor.erl +++ b/lib/inets/src/http_server/httpd_acceptor.erl @@ -21,6 +21,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). %% Internal application API -export([start_link/5, start_link/6]). diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl index 8438c4037e..f4d8a6c09f 100644 --- a/lib/inets/src/http_server/httpd_conf.erl +++ b/lib/inets/src/http_server/httpd_conf.erl @@ -31,8 +31,8 @@ validate_properties/1]). -define(VMODULE,"CONF"). --include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("httpd.hrl"). -include_lib("inets/src/http_lib/http_internal.hrl"). diff --git a/lib/inets/src/http_server/httpd_file.erl b/lib/inets/src/http_server/httpd_file.erl index 5fd529100e..7e21d9e158 100644 --- a/lib/inets/src/http_server/httpd_file.erl +++ b/lib/inets/src/http_server/httpd_file.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. +%% Copyright Ericsson AB 2006-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 @@ -22,11 +22,13 @@ -export([handle_error/4]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). + handle_error(eacces, Op, ModData, Path) -> - handle_error(403, Op, ModData, Path,""); + handle_error(403, Op, ModData, Path,"Forbidden"); handle_error(enoent, Op, ModData, Path) -> - handle_error(404, Op, ModData, Path,""); + handle_error(404, Op, ModData, Path,"File not found"); handle_error(enotdir, Op, ModData, Path) -> handle_error(404, Op, ModData, Path, ": A component of the file name is not a directory"); @@ -34,8 +36,8 @@ handle_error(emfile, Op, _ModData, Path) -> handle_error(500, Op, none, Path, ": To many open files"); handle_error({enfile,_}, Op, _ModData, Path) -> handle_error(500, Op, none, Path, ": File table overflow"); -handle_error(_Reason, Op, _ModData, Path) -> - handle_error(500, Op, none, Path, ""). +handle_error(_Reason, Op, ModData, Path) -> + handle_error(404, Op, ModData, Path, "File not found"). handle_error(StatusCode, Op, none, Path, Reason) -> {StatusCode, none, ?NICE("Can't " ++ Op ++ Path ++ Reason)}; diff --git a/lib/inets/src/http_server/httpd_internal.hrl b/lib/inets/src/http_server/httpd_internal.hrl index 38b0ddefd3..108469ea0a 100644 --- a/lib/inets/src/http_server/httpd_internal.hrl +++ b/lib/inets/src/http_server/httpd_internal.hrl @@ -21,7 +21,50 @@ -ifndef(httpd_internal_hrl). -define(httpd_internal_hrl, true). --include_lib("inets/src/inets_app/inets_internal.hrl"). +-ifndef(SERVER_SOFTWARE). +-define(SERVER_SOFTWARE,"inets/develop"). % Define in Makefile! +-endif. +-define(SERVER_PROTOCOL,"HTTP/1.1"). +-define(DEFAULT_MODS, [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, + mod_dir, mod_get, mod_head, mod_log, mod_disk_log]). +-define(SOCKET_CHUNK_SIZE,8192). +-define(SOCKET_MAX_POLL,25). +-define(FILE_CHUNK_SIZE,64*1024). +-define(GATEWAY_INTERFACE,"CGI/1.1"). +-define(NICE(Reason),lists:flatten(atom_to_list(?MODULE)++": "++Reason)). +-define(DEFAULT_CONTEXT, + [{errmsg,"[an error occurred while processing this directive]"}, + {timefmt,"%A, %d-%b-%y %T %Z"}, + {sizefmt,"abbrev"}]). + + +-ifdef(inets_error). +-define(ERROR(Format, Args), io:format("E(~p:~p:~p) : "++Format++"~n", + [self(),?MODULE,?LINE]++Args)). +-else. +-define(ERROR(F,A),[]). +-endif. + +-ifdef(inets_log). +-define(LOG(Format, Args), io:format("L(~p:~p:~p) : "++Format++"~n", + [self(),?MODULE,?LINE]++Args)). +-else. +-define(LOG(F,A),[]). +-endif. + +-ifdef(inets_debug). +-define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n", + [self(),?MODULE,?LINE]++Args)). +-else. +-define(DEBUG(F,A),[]). +-endif. + +-ifdef(inets_cdebug). +-define(CDEBUG(Format, Args), io:format("C(~p:~p:~p) : "++Format++"~n", + [self(),?MODULE,?LINE]++Args)). +-else. +-define(CDEBUG(F,A),[]). +-endif. -define(SERVICE, httpd). -define(hdri(Label, Content), ?report_important(Label, ?SERVICE, Content)). diff --git a/lib/inets/src/http_server/httpd_request.erl b/lib/inets/src/http_server/httpd_request.erl index 883acbf585..7084d9824a 100644 --- a/lib/inets/src/http_server/httpd_request.erl +++ b/lib/inets/src/http_server/httpd_request.erl @@ -304,9 +304,9 @@ validate_uri(RequestURI) -> UriNoQueryNoHex = case string:str(RequestURI, "?") of 0 -> - (catch httpd_util:decode_hex(RequestURI)); + (catch http_uri:decode(RequestURI)); Ndx -> - (catch httpd_util:decode_hex(string:left(RequestURI, Ndx))) + (catch http_uri:decode(string:left(RequestURI, Ndx))) end, case UriNoQueryNoHex of {'EXIT',_Reason} -> diff --git a/lib/inets/src/http_server/httpd_script_env.erl b/lib/inets/src/http_server/httpd_script_env.erl index a742cbef76..d3115150b0 100644 --- a/lib/inets/src/http_server/httpd_script_env.erl +++ b/lib/inets/src/http_server/httpd_script_env.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. +%% Copyright Ericsson AB 2005-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 @@ -23,6 +23,7 @@ -export([create_env/3]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). %%%========================================================================= %%% Internal application API diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl index 1507c6852a..f94e5459c1 100644 --- a/lib/inets/src/http_server/httpd_sup.erl +++ b/lib/inets/src/http_server/httpd_sup.erl @@ -37,7 +37,7 @@ -define(TIMEOUT, 15000). -include("httpd_internal.hrl"). - +-include("inets_internal.hrl"). %%%========================================================================= %%% API diff --git a/lib/inets/src/http_server/httpd_util.erl b/lib/inets/src/http_server/httpd_util.erl index cfad79638f..789f12652b 100644 --- a/lib/inets/src/http_server/httpd_util.erl +++ b/lib/inets/src/http_server/httpd_util.erl @@ -21,7 +21,7 @@ -export([ip_address/2, lookup/2, lookup/3, multi_lookup/2, lookup_mime/2, lookup_mime/3, lookup_mime_default/2, lookup_mime_default/3, reason_phrase/1, message/3, rfc1123_date/0, - rfc1123_date/1, day/1, month/1, decode_hex/1, + rfc1123_date/1, day/1, month/1, flatlength/1, split_path/1, split_script_path/1, suffix/1, split/3, uniq/1, make_name/2,make_name/3,make_name/4,strip/1, @@ -32,7 +32,7 @@ dir_validate/2, file_validate/2, mime_type_validate/1, mime_types_validate/1, custom_date/0]). --export([encode_hex/1]). +-export([encode_hex/1, decode_hex/1]). -include_lib("kernel/include/file.hrl"). ip_address({_,_,_,_} = Address, _IpFamily) -> @@ -175,13 +175,13 @@ reason_phrase(_) -> "Internal Server Error". %% message message(301,URL,_) -> - "The document has moved <A HREF=\""++URL++"\">here</A>."; + "The document has moved <A HREF=\""++ maybe_encode(URL) ++"\">here</A>."; message(304, _URL,_) -> "The document has not been changed."; message(400,none,_) -> "Your browser sent a query that this server could not understand."; message(400,Msg,_) -> - "Your browser sent a query that this server could not understand. "++Msg; + "Your browser sent a query that this server could not understand. "++ maybe_encode(Msg); message(401,none,_) -> "This server could not verify that you are authorized to access the document you @@ -190,9 +190,9 @@ credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required."; message(403,RequestURI,_) -> - "You don't have permission to access "++RequestURI++" on this server."; + "You don't have permission to access "++ maybe_encode(RequestURI) ++" on this server."; message(404,RequestURI,_) -> - "The requested URL "++RequestURI++" was not found on this server."; + "The requested URL " ++ maybe_encode(RequestURI) ++ " was not found on this server."; message(408, Timeout, _) -> Timeout; message(412,none,_) -> @@ -200,7 +200,7 @@ message(412,none,_) -> message(413, Reason,_) -> "Entity: " ++ Reason; message(414,ReasonPhrase,_) -> - "Message "++ReasonPhrase++"."; + "Message "++ ReasonPhrase ++"."; message(416,ReasonPhrase,_) -> ReasonPhrase; @@ -216,15 +216,23 @@ message(501,{Method, RequestURI, HTTPVersion}, _ConfigDB) -> if is_atom(Method) -> atom_to_list(Method)++ - " to "++RequestURI++" ("++HTTPVersion++") not supported."; + " to "++ maybe_encode(RequestURI)++" ("++HTTPVersion++") not supported."; is_list(Method) -> Method++ - " to "++RequestURI++" ("++HTTPVersion++") not supported." + " to "++ maybe_encode(RequestURI)++" ("++HTTPVersion++") not supported." end; message(503, String, _ConfigDB) -> "This service in unavailable due to: "++String. +maybe_encode(URI) -> + case lists:member($%, URI) of + true -> + URI; + false -> + http_uri:encode(URI) + end. + %%convert_rfc_date(Date)->{{YYYY,MM,DD},{HH,MIN,SEC}} convert_request_date([D,A,Y,DateType| Rest])-> @@ -381,16 +389,11 @@ month(12) -> "Dec". %% decode_hex -decode_hex([$%,Hex1,Hex2|Rest]) -> - [hex2dec(Hex1)*16+hex2dec(Hex2)|decode_hex(Rest)]; -decode_hex([First|Rest]) -> - [First|decode_hex(Rest)]; -decode_hex([]) -> - []. +decode_hex(URI) -> + http_uri:decode(URI). -hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0; -hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10; -hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10. +encode_hex(URI) -> + http_uri:encode(URI). %% flatlength flatlength(List) -> @@ -411,7 +414,7 @@ split_path(Path) -> case inets_regexp:match(Path,"[\?].*\$") of %% A QUERY_STRING exists! {match,Start,Length} -> - {httpd_util:decode_hex(string:substr(Path,1,Start-1)), + {http_uri:decode(string:substr(Path,1,Start-1)), string:substr(Path,Start,Length)}; %% A possible PATH_INFO exists! nomatch -> @@ -419,9 +422,9 @@ split_path(Path) -> end. split_path([],SoFar) -> - {httpd_util:decode_hex(lists:reverse(SoFar)),[]}; + {http_uri:decode(lists:reverse(SoFar)),[]}; split_path([$/|Rest],SoFar) -> - Path=httpd_util:decode_hex(lists:reverse(SoFar)), + Path=http_uri:decode(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type =:= regular -> {Path,[$/|Rest]}; @@ -454,7 +457,7 @@ pathinfo_querystring([C|Rest], SoFar) -> pathinfo_querystring(Rest, [C|SoFar]). split_script_path([$?|QueryString], SoFar) -> - Path = httpd_util:decode_hex(lists:reverse(SoFar)), + Path = http_uri:decode(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type =:= regular -> {Path, [$?|QueryString]}; @@ -464,7 +467,7 @@ split_script_path([$?|QueryString], SoFar) -> not_a_script end; split_script_path([], SoFar) -> - Path = httpd_util:decode_hex(lists:reverse(SoFar)), + Path = http_uri:decode(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok,FileInfo} when FileInfo#file_info.type =:= regular -> {Path, []}; @@ -474,7 +477,7 @@ split_script_path([], SoFar) -> not_a_script end; split_script_path([$/|Rest], SoFar) -> - Path = httpd_util:decode_hex(lists:reverse(SoFar)), + Path = http_uri:decode(lists:reverse(SoFar)), case file:read_file_info(Path) of {ok, FileInfo} when FileInfo#file_info.type =:= regular -> {Path, [$/|Rest]}; @@ -608,9 +611,6 @@ hexlist_to_integer(List)-> %%---------------------------------------------------------------------- %%Converts an integer to an hexlist %%---------------------------------------------------------------------- -encode_hex(Num)-> - integer_to_hexlist(Num). - integer_to_hexlist(Num) when is_integer(Num) -> http_util:integer_to_hexlist(Num). @@ -735,7 +735,6 @@ valid_accept_timeout(A) -> valid_config(_) -> ok. - %%---------------------------------------------------------------------- %% Enable debugging, %%---------------------------------------------------------------------- diff --git a/lib/inets/src/http_server/mod_actions.erl b/lib/inets/src/http_server/mod_actions.erl index d50ed4b16c..c3946ff9b4 100644 --- a/lib/inets/src/http_server/mod_actions.erl +++ b/lib/inets/src/http_server/mod_actions.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -21,6 +21,7 @@ -export([do/1,load/2, store/2]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). %% do diff --git a/lib/inets/src/http_server/mod_alias.erl b/lib/inets/src/http_server/mod_alias.erl index 9c5a8cc1c6..0b9fe4cfe0 100644 --- a/lib/inets/src/http_server/mod_alias.erl +++ b/lib/inets/src/http_server/mod_alias.erl @@ -29,6 +29,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -define(VMODULE,"ALIAS"). diff --git a/lib/inets/src/http_server/mod_auth.erl b/lib/inets/src/http_server/mod_auth.erl index 07cafb4726..85a87ab884 100644 --- a/lib/inets/src/http_server/mod_auth.erl +++ b/lib/inets/src/http_server/mod_auth.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -38,6 +38,7 @@ -include("httpd.hrl"). -include("mod_auth.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -define(VMODULE,"AUTH"). diff --git a/lib/inets/src/http_server/mod_auth_dets.erl b/lib/inets/src/http_server/mod_auth_dets.erl index bc6c2b70a0..a48725d5d9 100644 --- a/lib/inets/src/http_server/mod_auth_dets.erl +++ b/lib/inets/src/http_server/mod_auth_dets.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% 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 @@ -35,6 +35,7 @@ -export([store_directory_data/3]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). -include("mod_auth.hrl"). store_directory_data(_Directory, DirData, Server_root) -> diff --git a/lib/inets/src/http_server/mod_auth_plain.erl b/lib/inets/src/http_server/mod_auth_plain.erl index d88859d28a..c0a83711ba 100644 --- a/lib/inets/src/http_server/mod_auth_plain.erl +++ b/lib/inets/src/http_server/mod_auth_plain.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% 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 @@ -22,6 +22,8 @@ -include("httpd.hrl"). -include("mod_auth.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). + -define(VMODULE,"AUTH_PLAIN"). diff --git a/lib/inets/src/http_server/mod_auth_server.erl b/lib/inets/src/http_server/mod_auth_server.erl index 5f9e59be9d..947273bd9e 100644 --- a/lib/inets/src/http_server/mod_auth_server.erl +++ b/lib/inets/src/http_server/mod_auth_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -22,6 +22,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -behaviour(gen_server). diff --git a/lib/inets/src/http_server/mod_cgi.erl b/lib/inets/src/http_server/mod_cgi.erl index 33605b9698..c854166c29 100644 --- a/lib/inets/src/http_server/mod_cgi.erl +++ b/lib/inets/src/http_server/mod_cgi.erl @@ -27,6 +27,7 @@ -export([do/1, load/2, store/2]). -include("http_internal.hrl"). +-include("httpd_internal.hrl"). -include("httpd.hrl"). -define(VMODULE,"CGI"). diff --git a/lib/inets/src/http_server/mod_dir.erl b/lib/inets/src/http_server/mod_dir.erl index cdc7cc01e4..d791ee28e9 100644 --- a/lib/inets/src/http_server/mod_dir.erl +++ b/lib/inets/src/http_server/mod_dir.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -18,9 +18,11 @@ %% %% -module(mod_dir). --export([do/1]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). + +-export([do/1]). %% do @@ -57,7 +59,7 @@ do_dir(Info) -> case file:read_file_info(DefaultPath) of {ok,FileInfo} when FileInfo#file_info.type == directory -> DecodedRequestURI = - httpd_util:decode_hex(Info#mod.request_uri), + http_uri:decode(Info#mod.request_uri), ?DEBUG("do_dir -> ~n" " Path: ~p~n" " DefaultPath: ~p~n" diff --git a/lib/inets/src/http_server/mod_disk_log.erl b/lib/inets/src/http_server/mod_disk_log.erl index 95e0d00c70..5a3766de66 100644 --- a/lib/inets/src/http_server/mod_disk_log.erl +++ b/lib/inets/src/http_server/mod_disk_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -28,7 +28,7 @@ -define(VMODULE,"DISK_LOG"). -include("httpd.hrl"). - +-include("httpd_internal.hrl"). %%%========================================================================= %%% API diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl index f7877aa9e2..929185a67a 100644 --- a/lib/inets/src/http_server/mod_esi.erl +++ b/lib/inets/src/http_server/mod_esi.erl @@ -30,6 +30,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -define(VMODULE,"ESI"). -define(DEFAULT_ERL_TIMEOUT,15000). diff --git a/lib/inets/src/http_server/mod_get.erl b/lib/inets/src/http_server/mod_get.erl index 9fd1fcec47..5cb30e3d97 100644 --- a/lib/inets/src/http_server/mod_get.erl +++ b/lib/inets/src/http_server/mod_get.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -20,7 +20,7 @@ -module(mod_get). -export([do/1]). -include("httpd.hrl"). - +-include("httpd_internal.hrl"). %% do do(Info) -> diff --git a/lib/inets/src/http_server/mod_head.erl b/lib/inets/src/http_server/mod_head.erl index 8b08d61651..c346fd4d23 100644 --- a/lib/inets/src/http_server/mod_head.erl +++ b/lib/inets/src/http_server/mod_head.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 diff --git a/lib/inets/src/http_server/mod_htaccess.erl b/lib/inets/src/http_server/mod_htaccess.erl index d8835198f5..e1f66d01c8 100644 --- a/lib/inets/src/http_server/mod_htaccess.erl +++ b/lib/inets/src/http_server/mod_htaccess.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -23,6 +23,7 @@ -export([do/1, load/2, store/2]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Public methods that interface the eswapi %% diff --git a/lib/inets/src/http_server/mod_include.erl b/lib/inets/src/http_server/mod_include.erl index 534eba8a36..35f45bdd33 100644 --- a/lib/inets/src/http_server/mod_include.erl +++ b/lib/inets/src/http_server/mod_include.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -21,6 +21,7 @@ -export([do/1,parse/2,config/6,include/6,echo/6,fsize/6,flastmod/6,exec/6]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). -define(VMODULE,"INCLUDE"). @@ -186,9 +187,9 @@ document_uri(ConfigDB, RequestURI) -> FileName = string:substr(Path,Start,Length), case inets_regexp:match(VirtualPath, FileName++"\$") of {match, _, _} -> - httpd_util:decode_hex(VirtualPath)++AfterPath; + http_uri:decode(VirtualPath)++AfterPath; nomatch -> - string:strip(httpd_util:decode_hex(VirtualPath),right,$/)++ + string:strip(http_uri:decode(VirtualPath),right,$/)++ "/"++FileName++AfterPath end. diff --git a/lib/inets/src/http_server/mod_log.erl b/lib/inets/src/http_server/mod_log.erl index de24d5a569..c8a2ec0dc4 100644 --- a/lib/inets/src/http_server/mod_log.erl +++ b/lib/inets/src/http_server/mod_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -26,6 +26,7 @@ -export([do/1, load/2, store/2, remove/1]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). -define(VMODULE,"LOG"). %%%========================================================================= diff --git a/lib/inets/src/http_server/mod_range.erl b/lib/inets/src/http_server/mod_range.erl index 0698fb9099..a0408cba79 100644 --- a/lib/inets/src/http_server/mod_range.erl +++ b/lib/inets/src/http_server/mod_range.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -20,7 +20,7 @@ -module(mod_range). -export([do/1]). -include("httpd.hrl"). - +-include("httpd_internal.hrl"). %% do do(Info) -> diff --git a/lib/inets/src/http_server/mod_responsecontrol.erl b/lib/inets/src/http_server/mod_responsecontrol.erl index 79e2e1bdba..5d5b60cdbd 100644 --- a/lib/inets/src/http_server/mod_responsecontrol.erl +++ b/lib/inets/src/http_server/mod_responsecontrol.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -22,6 +22,7 @@ -export([do/1]). -include("httpd.hrl"). +-include("httpd_internal.hrl"). do(Info) -> ?DEBUG("do -> response_control",[]), diff --git a/lib/inets/src/http_server/mod_security.erl b/lib/inets/src/http_server/mod_security.erl index 95793e1cfb..41988732ad 100644 --- a/lib/inets/src/http_server/mod_security.erl +++ b/lib/inets/src/http_server/mod_security.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% 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 @@ -32,6 +32,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -define(VMODULE,"SEC"). diff --git a/lib/inets/src/http_server/mod_security_server.erl b/lib/inets/src/http_server/mod_security_server.erl index 58060686b3..784b3eba70 100644 --- a/lib/inets/src/http_server/mod_security_server.erl +++ b/lib/inets/src/http_server/mod_security_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -45,6 +45,7 @@ -include("httpd.hrl"). -include("httpd_internal.hrl"). +-include("inets_internal.hrl"). -behaviour(gen_server). diff --git a/lib/inets/src/http_server/mod_trace.erl b/lib/inets/src/http_server/mod_trace.erl index df482228d8..7233925783 100644 --- a/lib/inets/src/http_server/mod_trace.erl +++ b/lib/inets/src/http_server/mod_trace.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index 84d8c9278d..0194c65db9 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -18,6 +18,11 @@ {"%VSN%", [ + {"5.5", + [ + {restart_application, inets} + ] + }, {"5.4", [ {restart_application, inets} @@ -29,6 +34,11 @@ [ {restart_application, inets} ] + }, + {"5.4", + [ + {restart_application, inets} + ] } ] }. diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index bb7f2186af..0492d33eab 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -288,16 +288,20 @@ release_spec: opt $(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test @for d in $(DATADIRS); do \ echo "installing data dir $$d"; \ - echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \ - cat $$d/TAR.exclude >> $$d/TAR.exclude2; \ - find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \ - find $$d -name '*.keep*' >> $$d/TAR.exclude2; \ - find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \ - find $$d -name '*~' >> $$d/TAR.exclude2; \ - find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \ - find $$d -name 'core' >> $$d/TAR.exclude2; \ - find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \ - tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \ + if test -f $$d/TAR.exclude; then \ + echo $$d/TAR.exclude2 > $$d/TAR.exclude2; \ + cat $$d/TAR.exclude >> $$d/TAR.exclude2; \ + find $$d -name '*.contrib*' >> $$d/TAR.exclude2; \ + find $$d -name '*.keep*' >> $$d/TAR.exclude2; \ + find $$d -name '*.mkelem*' >> $$d/TAR.exclude2; \ + find $$d -name '*~' >> $$d/TAR.exclude2; \ + find $$d -name 'erl_crash.dump' >> $$d/TAR.exclude2; \ + find $$d -name 'core' >> $$d/TAR.exclude2; \ + find $$d -name '.cmake.state' >> $$d/TAR.exclude2; \ + tar cfX - $$d/TAR.exclude2 $$d | (cd $(RELSYSDIR)/test; tar xf -); \ + else \ + tar cf - $$d | (cd $(RELSYSDIR)/test; tar xf -); \ + fi; \ done release_tests_spec: opt diff --git a/lib/inets/test/httpc_SUITE.erl b/lib/inets/test/httpc_SUITE.erl index 902e440c80..94d5a48ef6 100644 --- a/lib/inets/test/httpc_SUITE.erl +++ b/lib/inets/test/httpc_SUITE.erl @@ -254,9 +254,14 @@ init_per_testcase(Case, Timeout, Config) -> [{watchdog, Dog}, {local_server, Server} | TmpConfig2] end, + %% httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, + %% ["localhost", ?IPV6_LOCAL_HOST]}}]), + httpc:set_options([{proxy, {{?PROXY, ?PROXY_PORT}, - ["localhost", ?IPV6_LOCAL_HOST]}}]), - %% snmp:set_trace([gen_tcp, inet_tcp, prim_inet]), + ["localhost", ?IPV6_LOCAL_HOST]}}, + {ipfamily, inet6fb4}]), + + %% snmp:set_trace([gen_tcp]), NewConfig. @@ -471,7 +476,7 @@ http_relaxed(Config) when is_list(Config) -> DummyServerPid ! stop, ok = httpc:set_options([{ipv6, enabled}]), - %% ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + %% ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -489,7 +494,7 @@ http_dummy_pipe(Config) when is_list(Config) -> test_pipeline(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. http_inets_pipe(doc) -> @@ -851,7 +856,7 @@ http_headers_dummy(Config) when is_list(Config) -> ], "text/plain", FooBar}, [], []), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -875,7 +880,7 @@ http_bad_response(Config) when is_list(Config) -> test_server:format("Wrong Statusline: ~p~n", [Reason]), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1157,7 +1162,7 @@ http_redirect(Config) when is_list(Config) -> tsp("http_redirect -> stop dummy server"), DummyServerPid ! stop, tsp("http_redirect -> reset ipfamily option (to inet6fb4)"), - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), tsp("http_redirect -> done"), ok; @@ -1181,7 +1186,7 @@ http_redirect_loop(Config) when is_list(Config) -> {ok, {{_,300,_}, [_ | _], _}} = httpc:request(get, {URL, []}, [], []), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. %%------------------------------------------------------------------------- @@ -1215,7 +1220,7 @@ http_internal_server_error(Config) when is_list(Config) -> ets:delete(unavailable), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1242,7 +1247,7 @@ http_userinfo(Config) when is_list(Config) -> httpc:request(get, {URLUnAuth, []}, [], []), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1271,9 +1276,9 @@ http_cookie(Config) when is_list(Config) -> ets:delete(cookie), - ok = httpc:set_options([{cookies, disabled}, {ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{cookies, disabled}]), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6************ + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. %%------------------------------------------------------------------------- @@ -1643,7 +1648,7 @@ http_stream_once(Config) when is_list(Config) -> p("http_stream_once -> stop dummy server", []), DummyServerPid ! stop, p("http_stream_once -> set ipfamily to inet6fb4", []), - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), p("http_stream_once -> done", []), ok. @@ -1847,7 +1852,7 @@ http_invalid_http(Config) when is_list(Config) -> test_server:format("Parse error: ~p ~n", [Reason]), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1901,7 +1906,7 @@ transfer_encoding_otp_6807(Config) when is_list(Config) -> "/capital_transfer_encoding.html", {ok, {{_,200,_}, [_|_], [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1933,7 +1938,7 @@ empty_response_header_otp_6830(Config) when is_list(Config) -> URL = ?URL_START ++ integer_to_list(Port) ++ "/no_headers.html", {ok, {{_,200,_}, [], [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1950,7 +1955,7 @@ no_content_204_otp_6982(Config) when is_list(Config) -> URL = ?URL_START ++ integer_to_list(Port) ++ "/no_content.html", {ok, {{_,204,_}, [], []}} = httpc:request(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1968,7 +1973,7 @@ missing_CR_otp_7304(Config) when is_list(Config) -> URL = ?URL_START ++ integer_to_list(Port) ++ "/missing_CR.html", {ok, {{_,200,_}, _, [_ | _]}} = httpc:request(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. @@ -1990,7 +1995,7 @@ otp_7883_1(Config) when is_list(Config) -> {error, socket_closed_remotely} = httpc:request(URL), DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. otp_7883_2(doc) -> @@ -2017,7 +2022,7 @@ otp_7883_2(Config) when is_list(Config) -> end, DummyServerPid ! stop, - ok = httpc:set_options([{ipfamily, inet6fb4}]), % ********** ipfamily = inet6 ************* + ok = httpc:set_options([{ipfamily, inet6fb4}]), ok. diff --git a/lib/inets/test/httpd_basic_SUITE.erl b/lib/inets/test/httpd_basic_SUITE.erl index f86c1fcb49..9ba2e73942 100644 --- a/lib/inets/test/httpd_basic_SUITE.erl +++ b/lib/inets/test/httpd_basic_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-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 @@ -25,13 +25,16 @@ %% Note: This directive should only be used in test suites. -compile(export_all). +-define(URL_START, "http://localhost:"). + all(doc) -> ["Basic test of httpd."]; all(suite) -> [ uri_too_long_414, - header_too_long_413 + header_too_long_413, + escaped_url_in_error_body ]. %%-------------------------------------------------------------------- @@ -131,6 +134,31 @@ header_too_long_413(Config) when is_list(Config) -> {version, "HTTP/1.1"}]), inets:stop(httpd, Pid). +escaped_url_in_error_body(doc) -> + ["Test Url-encoding see OTP-8940"]; +escaped_url_in_error_body(suite) -> + []; +escaped_url_in_error_body(Config) when is_list(Config) -> + HttpdConf = ?config(httpd_conf, Config), + {ok, Pid} = inets:start(httpd, [{port, 0} | HttpdConf]), + Info = httpd:info(Pid), + Port = proplists:get_value(port, Info), + Address = proplists:get_value(bind_address, Info), + Path = "/<b>this_is_bold<b>", + URL = ?URL_START ++ integer_to_list(Port) ++ Path, + EscapedPath = http_uri:encode(Path), + {ok, {404, Body}} = httpc:request(get, {URL, []}, + [{url_encode, true}], + [{version, "HTTP/1.0"}, {full_result, false}]), + EscapedPath = find_URL_path(string:tokens(Body, " ")), + {ok, {404, Body1}} = httpc:request(get, {URL, []}, [], + [{version, "HTTP/1.0"}, {full_result, false}]), + EscapedPath = find_URL_path(string:tokens(Body1, " ")), + inets:stop(httpd, Pid). - - +find_URL_path([]) -> + ""; +find_URL_path(["URL", URL | _]) -> + URL; +find_URL_path([_ | Rest]) -> + find_URL_path(Rest). diff --git a/lib/inets/test/inets_appup_test.erl b/lib/inets/test/inets_appup_test.erl index d580c6c4c5..2c9c687c91 100644 --- a/lib/inets/test/inets_appup_test.erl +++ b/lib/inets/test/inets_appup_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. +%% 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 @@ -18,11 +18,12 @@ %% %% %%---------------------------------------------------------------------- -%% Purpose: Verify the application specifics of the Megaco application +%% Purpose: Verify the application specifics of the Inets application %%---------------------------------------------------------------------- -module(inets_appup_test). -compile(export_all). +-compile({no_auto_import,[error/1]}). -include("inets_test_lib.hrl"). diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl index 86fc2d1a32..c56a714f5a 100644 --- a/lib/inets/test/inets_test_lib.erl +++ b/lib/inets/test/inets_test_lib.erl @@ -329,6 +329,9 @@ connect(ip_comm, Host, Port, Opts) -> {error, eafnosupport} -> tsp("eafnosupport opts: ~p", [Opts]), connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); + {error, enetunreach} -> + tsp("eafnosupport opts: ~p", [Opts]), + connect(ip_comm, Host, Port, lists:delete(inet6, Opts)); {error, {enfile,_}} -> tsp("Error enfile"), {error, enfile}; diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 5eff9e4e3f..f462290a99 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -1,5 +1,24 @@ +#-*-makefile-*- ; force emacs to enter makefile-mode + +# %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% + APPLICATION = inets -INETS_VSN = 5.5 +INETS_VSN = 5.5.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java index 4146bd3ced..a9712aa2ba 100644 --- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpMbox.java @@ -678,6 +678,11 @@ public class OtpMbox { return m.self.equals(self); } + @Override + public int hashCode() { + return self.hashCode(); + } + /* * called by OtpNode to deliver message to this mailbox. * diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml index 2044b074ee..d3441d3623 100644 --- a/lib/kernel/doc/src/file.xml +++ b/lib/kernel/doc/src/file.xml @@ -36,6 +36,61 @@ other Erlang processes to continue executing in parallel with the file operations. See the command line flag <c>+A</c> in <seealso marker="erts:erl">erl(1)</seealso>.</p> + + <p>The Erlang VM supports file names in Unicode to a limited + extent. Depending on how the VM is started (with the parameter + <c>+fnu</c> or <c>+fnl</c>), file names given can contain + characters > 255 and the VM system will convert file names + back and forth to the native file name encoding.</p> + + <p>The default behavior for Unicode character translation depends + on to what extent the underlying OS/filesystem enforces consistent + naming. On OSes where all file names are ensured to be in one or + another encoding, Unicode is the default (currently this holds for + Windows and MacOSX). On OSes with completely transparent file + naming (i.e. all Unixes except MacOSX), ISO-latin-1 file naming is + the default. The reason for the ISO-latin-1 default is that + file names are not guaranteed to be possible to interpret according to + the Unicode encoding expected (i.e. UTF-8), and file names that + cannot be decoded will only be accessible by using "raw + file names", in other word file names given as binaries.</p> + + <p>As file names are traditionally not binaries in Erlang, + applications that need to handle raw file names need to be + converted, why the Unicode mode for file names is not default on + systems having completely transparent file naming.</p> + + <note>As of R14B01, the most basic file handling modules + (<c>file</c>, <c>prim_file</c>, <c>filelib</c> and + <c>filename</c>) accept raw file names, but the rest of OTP is not + guaranteed to handle them, why Unicode file naming on systems + where it is not default is still considered experimental.</note> + + <p>Raw file names is a new feature in OTP R14B01, which allows the + user to supply completely uninterpreted file names to the + underlying OS/filesystem. They are supplied as binaries, where it + is up to the user to supply a correct encoding for the + environment. The function <c>file:native_name_encoding()</c> can + be used to check what encoding the VM is working in. If the + function returns <c>latin1</c> file names are not in any way + converted to Unicode, if it is <c>utf8</c>, raw file names should + be encoded as UTF-8 if they are to follow the convention of the VM + (and usually the convention of the OS as well). Using raw + file names is useful if you have a filesystem with inconsistent + file naming, where some files are named in UTF-8 encoding while + others are not. A file:list_dir on such mixed file name systems + when the VM is in Unicode file name mode might return file names as + raw binaries as they cannot be interpreted as Unicode + file names. Raw file names can also be used to give UTF-8 encoded + file names even though the VM is not started in Unicode file name + translation mode.</p> + + <p>Note that on Windows, <c>file:native_name_encoding()</c> + returns <c>utf8</c> per default, which is the format for raw + file names even on Windows, although the underlying OS specific + code works in a limited version of little endian UTF16. As far as + the Erlang programmer is concerned, Windows native Unicode format + is UTF-8...</p> </description> <section> @@ -47,8 +102,14 @@ iodata() = iolist() | binary() io_device() as returned by file:open/2, a process handling IO protocols -name() = string() | atom() | DeepList +name() = string() | atom() | DeepList | RawFilename DeepList = [char() | atom() | DeepList] + RawFilename = binary() + If VM is in unicode filename mode, string() and char() are allowed to be > 255. + RawFilename is a filename not subject to Unicode translation, meaning that it + can contain characters not conforming to the Unicode encoding expected from the + filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode + filename mode). posix() an atom which is named from the POSIX error codes used in @@ -598,13 +659,24 @@ f.txt: {person, "kalle", 25}. </desc> </func> <func> + <name>native_name_encoding() -> latin1 | utf8</name> + <fsummary>Retunr the VMs configure filename encoding.</fsummary> + <desc> + <p>This function returns the configured default file name encoding to use for raw file names. Generally an application supplying file names raw (as binaries), should obey the character encoding returned by this function.</p> + <p>By default, the VM uses ISO-latin-1 file name encoding on filesystems and/or OSes that use completely transparent file naming. This includes all Unix versions except for MacOSX, where the vfs layer enforces UTF-8 file naming. By giving the experimental option <c>+fnu</c> when starting Erlang, UTF-8 translation of file names can be turned on even for those systems. If Unicode file name translation is in effect, the system behaves as usual as long as file names conform to the encoding, but will return file names that are not properly encoded in UTF-8 as raw file names (i.e. binaries).</p> + <p>On Windows, this function also returns <c>utf8</c> by default. The OS uses a pure Unicode naming scheme and file names are always possible to interpret as valid Unicode. The fact that the underlying Windows OS actually encodes file names using little endian UTF-16 can be ignored by the Erlang programmer. Windows and MacOSX are the only operating systems where the VM operates in Unicode file name mode by default.</p> + </desc> + </func> + <func> <name>open(Filename, Modes) -> {ok, IoDevice} | {error, Reason}</name> <fsummary>Open a file</fsummary> <type> <v>Filename = name()</v> <v>Modes = [Mode]</v> - <v> Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed</v> + <v> Mode = read | write | append | exclusive | raw | binary | {delayed_write, Size, Delay} | delayed_write | {read_ahead, Size} | read_ahead | compressed | {encoding, Encoding}</v> <v> Size = Delay = int()</v> + <v> Encoding = latin1 | unicode | utf8 | utf16 | {utf16, Endian} | utf32 | {utf32, Endian}</v> + <v> Endian = big | little</v> <v>IoDevice = io_device()</v> <v>Reason = ext_posix() | system_limit</v> </type> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index 2ae230152c..a22c0a8346 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -220,6 +220,69 @@ fe80::204:acff:fe17:bf38 <p>Returns the local hostname. Will never fail.</p> </desc> </func> + + <func> + <name>getifaddrs() -> {ok,Iflist} | {error,posix}</name> + <fsummary>Return a list of interfaces and their addresses</fsummary> + <type> + <v>Iflist = {Ifname,[Ifopt]}</v> + <v>Ifname = string()</v> + <v>Ifopt = {flag,[Flag]} | {addr,Addr} | {netmask,Netmask} + | {broadaddr,Broadaddr} | {dstaddr,Dstaddr} + | {hwaddr,Hwaddr}</v> + <v>Flag = up | broadcast | loopback | pointtopoint + | running | multicast</v> + <v>Addr = Netmask = Broadadddr = Dstaddr = ip_address()</v> + <v>Hwaddr = [byte()]</v> + </type> + </func> + <desc> + <p> + Returns a list of 2-tuples containing interface names and the + interface's addresses. <c>Ifname</c> is a Unicode string. + <c>Hwaddr</c> is hardware dependent, e.g on Ethernet interfaces + it is the 6-byte Ethernet address (MAC address (EUI-48 address)). + </p> + <p> + The <c>{addr,Addr}</c>, <c>{netmask,_}</c> and <c>{broadaddr,_}</c> + tuples are repeated in the result list iff the interface has multiple + addresses. If you come across an interface that has + multiple <c>{flag,_}</c> or <c>{hwaddr,_}</c> tuples you have + a really strange interface or possibly a bug in this function. + The <c>{flag,_}</c> tuple is mandatory, all other optional. + </p> + <p> + Do not rely too much on the order of <c>Flag</c> atoms or + <c>Ifopt</c> tuples. There are some rules, though: + <list> + <item> + Immediately after <c>{addr,_}</c> follows <c>{netmask,_}</c> + </item> + <item> + Immediately thereafter follows <c>{broadaddr,_}</c> if + the <c>broadcast</c> flag is <em>not</em> set and the + <c>pointtopoint</c>flag <em>is</em> set. + </item> + <item> + Any <c>{netmask,_}</c>, <c>{broadaddr,_}</c> or + <c>{dstaddr,_}</c> tuples that follow an <c>{addr,_}</c> + tuple concerns that address. + </item> + </list> + </p> + <p> + The <c>{hwaddr,_}</c> tuple is not returned on Solaris since the + hardware address historically belongs to the link layer and only + the superuser can read such addresses. + </p> + <p> + On Windows, the data is fetched from quite different OS API + functions, so the <c>Netmask</c> and <c>Broadaddr</c> + values may be calculated, just as some <c>Flag</c> values. + You have been warned. Report flagrant bugs. + </p> + </desc> + <func> <name>getopts(Socket, Options) -> {ok, OptionValues} | {error, posix()}</name> <fsummary>Get one or more options for a socket</fsummary> diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 9859183390..edd6ea52b0 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,29 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 2.14.1.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>In embedded mode, on_load handlers that called + <c>code:priv_dir/1</c> or other functions in <c>code</c> + would hang the system. Since the <c>crypto</c> + application now contains an on_loader handler that calls + <c>code:priv_dir/1</c>, including the <c>crypto</c> + application in the boot file would prevent the system + from starting.</p> + <p>Also extended the <c>-init_debug</c> option to print + information about on_load handlers being run to + facilitate debugging.</p> + <p> + Own Id: OTP-8902 Aux Id: seq11703 </p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 2.14.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl index ec256d5806..feb5131aad 100644 --- a/lib/kernel/src/code.erl +++ b/lib/kernel/src/code.erl @@ -213,19 +213,20 @@ unstick_mod(Mod) when is_atom(Mod) -> call({unstick_mod,Mod}). -spec is_sticky(Module :: atom()) -> boolean(). is_sticky(Mod) when is_atom(Mod) -> call({is_sticky,Mod}). --spec set_path(Directories :: [file:filename()]) -> 'true' | {'error', term()}. +-spec set_path(Directories :: [file:filename()]) -> + 'true' | {'error', 'bad_directory' | 'bad_path'}. set_path(PathList) when is_list(PathList) -> call({set_path,PathList}). -spec get_path() -> [file:filename()]. get_path() -> call(get_path). --spec add_path(Directory :: file:filename()) -> 'true' | {'error', term()}. +-spec add_path(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}. add_path(Dir) when is_list(Dir) -> call({add_path,last,Dir}). --spec add_pathz(Directory :: file:filename()) -> 'true' | {'error', term()}. +-spec add_pathz(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}. add_pathz(Dir) when is_list(Dir) -> call({add_path,last,Dir}). --spec add_patha(Directory :: file:filename()) -> 'true' | {'error', term()}. +-spec add_patha(Directory :: file:filename()) -> 'true' | {'error', 'bad_directory'}. add_patha(Dir) when is_list(Dir) -> call({add_path,first,Dir}). -spec add_paths(Directories :: [file:filename()]) -> 'ok'. @@ -237,7 +238,6 @@ add_pathsz(Dirs) when is_list(Dirs) -> call({add_paths,last,Dirs}). -spec add_pathsa(Directories :: [file:filename()]) -> 'ok'. add_pathsa(Dirs) when is_list(Dirs) -> call({add_paths,first,Dirs}). -%% XXX Contract's input argument differs from add_path/1 -- why? -spec del_path(Name :: file:filename() | atom()) -> boolean() | {'error', 'bad_name'}. del_path(Name) when is_list(Name) ; is_atom(Name) -> call({del_path,Name}). @@ -286,6 +286,8 @@ do_start(Flags) -> ets:module_info(module), os:module_info(module), + binary:module_info(module), + unicode:module_info(module), filename:module_info(module), lists:module_info(module), diff --git a/lib/kernel/src/error_handler.erl b/lib/kernel/src/error_handler.erl index 17dd02acd4..885eeb2b0f 100644 --- a/lib/kernel/src/error_handler.erl +++ b/lib/kernel/src/error_handler.erl @@ -17,6 +17,11 @@ %% %CopyrightEnd% %% -module(error_handler). +%% FIXME: remove no_native directive after HiPE has been changed to make +%% remote calls link to the target's Export* like BEAM does. +%% For a detailed explanation see the commit titled +%% "error_handler: add no_native compiler directive" +-compile(no_native). %% A simple error handler. diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index cffe4e3db5..bc95359986 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -75,25 +75,34 @@ -define(RAM_FILE, ram_file). % Module %% data types --type filename() :: string(). +-type filename() :: string() | binary(). -type file_info() :: #file_info{}. -type fd() :: #file_descriptor{}. -type io_device() :: pid() | fd(). -type location() :: integer() | {'bof', integer()} | {'cur', integer()} | {'eof', integer()} | 'bof' | 'cur' | 'eof'. --type mode() :: 'read' | 'write' | 'append' | 'raw' | 'binary' | - {'delayed_write', non_neg_integer(), non_neg_integer()} | - 'delayed_write' | {'read_ahead', pos_integer()} | - 'read_ahead' | 'compressed' | 'exclusive'. --type name() :: string() | atom() | [name()]. --type posix() :: atom(). +-type mode() :: 'read' | 'write' | 'append' + | 'exclusive' | 'raw' | 'binary' + | {'delayed_write', non_neg_integer(), non_neg_integer()} + | 'delayed_write' | {'read_ahead', pos_integer()} + | 'read_ahead' | 'compressed' + | {'encoding', unicode:encoding()}. +-type name() :: string() | atom() | [name()] | binary(). +-type posix() :: 'eacces' | 'eagain' | 'ebadf' | 'ebusy' | 'edquot' + | 'eexist' | 'efault' | 'efbig' | 'eintr' | 'einval' + | 'eio' | 'eisdir' | 'eloop' | 'emfile' | 'emlink' + | 'enametoolong' + | 'enfile' | 'enodev' | 'enoent' | 'enomem' | 'enospc' + | 'enotblk' | 'enotdir' | 'enotsup' | 'enxio' | 'eperm' + | 'epipe' | 'erofs' | 'espipe' | 'esrch' | 'estale' + | 'exdev'. -type bindings() :: any(). -type date() :: {pos_integer(), pos_integer(), pos_integer()}. -type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. -type date_time() :: {date(), time()}. --type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' | - 'will_need' | 'dont_need'. +-type posix_file_advise() :: 'normal' | 'sequential' | 'random' + | 'no_reuse' | 'will_need' | 'dont_need'. %%%----------------------------------------------------------------- %%% General functions @@ -174,7 +183,7 @@ make_dir(Name) -> del_dir(Name) -> check_and_call(del_dir, [file_name(Name)]). --spec read_file_info(Name :: name()) -> {'ok', #file_info{}} | {'error', posix()}. +-spec read_file_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}. read_file_info(Name) -> check_and_call(read_file_info, [file_name(Name)]). @@ -184,7 +193,7 @@ read_file_info(Name) -> altname(Name) -> check_and_call(altname, [file_name(Name)]). --spec read_link_info(Name :: name()) -> {'ok', #file_info{}} | {'error', posix()}. +-spec read_link_info(Name :: name()) -> {'ok', file_info()} | {'error', posix()}. read_link_info(Name) -> check_and_call(read_link_info, [file_name(Name)]). @@ -194,7 +203,7 @@ read_link_info(Name) -> read_link(Name) -> check_and_call(read_link, [file_name(Name)]). --spec write_file_info(Name :: name(), Info :: #file_info{}) -> +-spec write_file_info(Name :: name(), Info :: file_info()) -> 'ok' | {'error', posix()}. write_file_info(Name, Info = #file_info{}) -> @@ -205,7 +214,8 @@ write_file_info(Name, Info = #file_info{}) -> list_dir(Name) -> check_and_call(list_dir, [file_name(Name)]). --spec read_file(Name :: name()) -> {'ok', binary()} | {'error', posix()}. +-spec read_file(Name :: name()) -> + {'ok', binary()} | {'error', posix() | 'terminated' | 'system_limit'}. read_file(Name) -> check_and_call(read_file, [file_name(Name)]). @@ -220,15 +230,15 @@ make_link(Old, New) -> make_symlink(Old, New) -> check_and_call(make_symlink, [file_name(Old), file_name(New)]). --spec write_file(Name :: name(), Bin :: binary()) -> 'ok' | {'error', posix()}. +-spec write_file(Name :: name(), Bin :: iodata()) -> + 'ok' | {'error', posix() | 'terminated' | 'system_limit'}. write_file(Name, Bin) -> check_and_call(write_file, [file_name(Name), make_binary(Bin)]). %% This whole operation should be moved to the file_server and prim_file %% when it is time to change file server protocol again. -%% Meanwhile, it is implemented here, slihtly less efficient. -%% +%% Meanwhile, it is implemented here, slightly less efficient. -spec write_file(Name :: name(), Bin :: binary(), Modes :: [mode()]) -> 'ok' | {'error', posix()}. @@ -286,7 +296,7 @@ raw_write_file_info(Name, #file_info{} = Info) -> %% Contemporary mode specification - list of options -spec open(Name :: name(), Modes :: [mode()]) -> - {'ok', io_device()} | {'error', posix()}. + {'ok', io_device()} | {'error', posix() | 'system_limit'}. open(Item, ModeList) when is_list(ModeList) -> case lists:member(raw, ModeList) of @@ -339,7 +349,7 @@ open(Item, Mode) -> %%% The File argument must be either a Pid or a handle %%% returned from ?PRIM_FILE:open. --spec close(File :: io_device()) -> 'ok' | {'error', posix()}. +-spec close(File :: io_device()) -> 'ok' | {'error', posix() | 'terminated'}. close(File) when is_pid(File) -> R = file_request(File, close), @@ -358,7 +368,7 @@ close(_) -> {error, badarg}. -spec advise(File :: io_device(), Offset :: integer(), - Length :: integer(), Advise :: posix_file_advise()) -> + Length :: integer(), Advise :: posix_file_advise()) -> 'ok' | {'error', posix()}. advise(File, Offset, Length, Advise) when is_pid(File) -> @@ -440,7 +450,7 @@ pread(_, _, _) -> {error, badarg}. -spec write(File :: io_device() | atom(), Byte :: iodata()) -> - 'ok' | {'error', posix()}. + 'ok' | {'error', posix() | 'terminated'}. write(File, Bytes) when (is_pid(File) orelse is_atom(File)) -> case make_binary(Bytes) of @@ -1024,22 +1034,26 @@ path_open_first([], _Name, _Mode, LastError) -> %% Generates a flat file name from a deep list of atoms and %% characters (integers). +file_name(N) when is_binary(N) -> + N; file_name(N) -> try - file_name_1(N) + file_name_1(N,file:native_name_encoding()) catch Reason -> {error, Reason} end. -file_name_1([C|T]) when is_integer(C), C > 0, C =< 255 -> - [C|file_name_1(T)]; -file_name_1([H|T]) -> - file_name_1(H) ++ file_name_1(T); -file_name_1([]) -> +file_name_1([C|T],latin1) when is_integer(C), C < 256-> + [C|file_name_1(T,latin1)]; +file_name_1([C|T],utf8) when is_integer(C) -> + [C|file_name_1(T,utf8)]; +file_name_1([H|T],E) -> + file_name_1(H,E) ++ file_name_1(T,E); +file_name_1([],_) -> []; -file_name_1(N) when is_atom(N) -> +file_name_1(N,_) when is_atom(N) -> atom_to_list(N); -file_name_1(_) -> +file_name_1(_,_) -> throw(badarg). make_binary(Bin) when is_binary(Bin) -> diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl index 39dc32bb79..14da9c1a55 100644 --- a/lib/kernel/src/file_io_server.erl +++ b/lib/kernel/src/file_io_server.erl @@ -44,11 +44,11 @@ format_error(ErrorId) -> erl_posix_msg:message(ErrorId). start(Owner, FileName, ModeList) - when is_pid(Owner), is_list(FileName), is_list(ModeList) -> + when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) -> do_start(spawn, Owner, FileName, ModeList). start_link(Owner, FileName, ModeList) - when is_pid(Owner), is_list(FileName), is_list(ModeList) -> + when is_pid(Owner), (is_list(FileName) orelse is_binary(FileName)), is_list(ModeList) -> do_start(spawn_link, Owner, FileName, ModeList). %%%----------------------------------------------------------------- diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index 93d75321ba..327e0f93f1 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -25,6 +25,7 @@ %% socket -export([peername/1, sockname/1, port/1, send/2, setopts/2, getopts/2, + getifaddrs/0, getifaddrs/1, getif/1, getif/0, getiflist/0, getiflist/1, ifget/3, ifget/2, ifset/3, ifset/2, getstat/1, getstat/2, @@ -265,6 +266,17 @@ setopts(Socket, Opts) -> getopts(Socket, Opts) -> prim_inet:getopts(Socket, Opts). +-spec getifaddrs(Socket :: socket()) -> + {'ok', [string()]} | {'error', posix()}. + +getifaddrs(Socket) -> + prim_inet:getifaddrs(Socket). + +-spec getifaddrs() -> {'ok', [string()]} | {'error', posix()}. + +getifaddrs() -> + withsocket(fun(S) -> prim_inet:getifaddrs(S) end). + -spec getiflist(Socket :: socket()) -> {'ok', [string()]} | {'error', posix()}. diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index cf357b7fba..6f1688c6a2 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -82,6 +82,7 @@ -define(INET_REQ_IFGET, 22). -define(INET_REQ_IFSET, 23). -define(INET_REQ_SUBSCRIBE, 24). +-define(INET_REQ_GETIFADDRS, 25). %% TCP requests -define(TCP_REQ_ACCEPT, 40). -define(TCP_REQ_LISTEN, 41). diff --git a/lib/kernel/src/kernel.erl b/lib/kernel/src/kernel.erl index 92ee7b441a..1e07620a3e 100644 --- a/lib/kernel/src/kernel.erl +++ b/lib/kernel/src/kernel.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -143,6 +143,13 @@ init(safe) -> Boot = start_boot_server(), DiskLog = start_disk_log(), Pg2 = start_pg2(), + + %% Run the on_load handlers for all modules that have been + %% loaded so far. Running them at this point means that + %% on_load handlers can safely call kernel processes + %% (and in particular call code:priv_dir/1 or code:lib_dir/1). + init:run_on_load_handlers(), + {ok, {SupFlags, Boot ++ DiskLog ++ Pg2}}. get_code_args() -> diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 293c368e2a..f84b343de8 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -51,6 +51,7 @@ MODULES= \ error_logger_SUITE \ error_logger_warn_SUITE \ file_SUITE \ + file_name_SUITE \ prim_file_SUITE \ ram_file_SUITE \ gen_tcp_api_SUITE \ diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index c9437df258..e52f8a0e37 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -19,7 +19,7 @@ -module(code_SUITE). -include("test_server.hrl"). - +%-compile(export_all). -export([all/1]). -export([set_path/1, get_path/1, add_path/1, add_paths/1, del_path/1, replace_path/1, load_file/1, load_abs/1, ensure_loaded/1, @@ -31,6 +31,7 @@ where_is_file_cached/1, where_is_file_no_cache/1, purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1, code_archive/1, code_archive2/1, on_load/1, + big_boot_embedded/1, on_load_embedded/1, on_load_errors/1, native_early_modules/1]). -export([init_per_testcase/2, fin_per_testcase/2, @@ -53,6 +54,7 @@ all(suite) -> where_is_file_no_cache, where_is_file_cached, purge_stacktrace, mult_lib_roots, bad_erl_libs, code_archive, code_archive2, on_load, on_load_embedded, + big_boot_embedded, on_load_errors, native_early_modules]. init_per_suite(Config) -> @@ -584,13 +586,21 @@ clash(Config) when is_list(Config) -> TmpEzFile = Priv++"foobar-0.tmp.ez", ?line {ok, _} = file:copy(DDir++"foobar-0.1.ez", TmpEzFile), ?line true = code:add_path(TmpEzFile++"/foobar-0.1/ebin"), - ?line ok = file:delete(TmpEzFile), + case os:type() of + {win32,_} -> + %% The file wont be deleted on windows until it's closed, why we + %% need to rename instead. + ?line ok = file:rename(TmpEzFile,TmpEzFile++".moved"); + _ -> + ?line ok = file:delete(TmpEzFile) + end, test_server:capture_start(), ?line ok = code:clash(), test_server:capture_stop(), ?line [BadPathMsg|_] = test_server:capture_get(), ?line true = lists:prefix("** Bad path can't read", BadPathMsg), ?line true = code:set_path(P), + file:delete(TmpEzFile++".moved"), %% Only effect on windows ok. ext_mod_dep(suite) -> @@ -635,7 +645,7 @@ analyse([], [This={M,F,A}|Path], Visited, ErrCnt0) -> %% These modules should be loaded by code.erl before %% the code_server is started. OK = [erlang, os, prim_file, erl_prim_loader, init, ets, - code_server, lists, lists_sort, filename, packages, + code_server, lists, lists_sort, unicode, binary, filename, packages, gb_sets, gb_trees, hipe_unified_loader, hipe_bifs, prim_zip, zlib], ErrCnt1 = @@ -664,6 +674,22 @@ analyse2(MFA={_,_,_}, Path, Visited0) -> %%%% We need to check these manually... % fun's are ok as long as they are defined locally. check_funs({'$M_EXPR','$F_EXPR',_}, + [{unicode,characters_to_binary_int,3}, + {unicode,characters_to_binary,3}, + {filename,filename_string_to_binary,1}|_]) -> 0; +check_funs({'$M_EXPR','$F_EXPR',_}, + [{unicode,ml_map,3}, + {unicode,characters_to_binary_int,3}, + {unicode,characters_to_binary,3}, + {filename,filename_string_to_binary,1}|_]) -> 0; +check_funs({'$M_EXPR','$F_EXPR',_}, + [{unicode,do_o_binary2,2}, + {unicode,do_o_binary,2}, + {unicode,o_trans,1}, + {unicode,characters_to_binary_int,3}, + {unicode,characters_to_binary,3}, + {filename,filename_string_to_binary,1}|_]) -> 0; +check_funs({'$M_EXPR','$F_EXPR',_}, [{code_server,load_native_code,4}, {code_server,load_native_code_1,2}, {code_server,load_native_code,2}, @@ -1145,6 +1171,22 @@ compile_files([File | Files], SrcDir, OutDir) -> compile_files([], _, _) -> ok. +big_boot_embedded(suite) -> + []; +big_boot_embedded(doc) -> + ["Test that a boot file with (almost) all of OTP can be used to start an" + " embeddedd system."]; +big_boot_embedded(Config) when is_list(Config) -> + ?line {BootArg,AppsInBoot} = create_big_boot(Config), + ?line {ok, Node} = + ?t:start_node(big_boot_embedded, slave, + [{args,"-boot "++BootArg++" -mode embedded"}]), + ?line RemoteNodeApps = + [ {X,Y} || {X,_,Y} <- + rpc:call(Node,application,loaded_applications,[]) ], + ?line true = lists:sort(AppsInBoot) =:= lists:sort(RemoteNodeApps), + ok. + on_load(Config) when is_list(Config) -> Master = on_load_test_case_process, @@ -1226,7 +1268,8 @@ on_load_embedded_1(Config) -> ?line LibRoot = code:lib_dir(), ?line LinkName = filename:join(LibRoot, "on_load_app-1.0"), ?line OnLoadApp = filename:join(DataDir, "on_load_app-1.0"), - ?line file:delete(LinkName), + ?line del_link(LinkName), + io:format("LinkName :~p, OnLoadApp: ~p~n",[LinkName,OnLoadApp]), case file:make_symlink(OnLoadApp, LinkName) of {error,enotsup} -> throw({skip,"Support for symlinks required"}); @@ -1255,7 +1298,15 @@ on_load_embedded_1(Config) -> %% Clean up. ?line stop_node(Node), - ?line ok = file:delete(LinkName). + ?line ok = del_link(LinkName). + +del_link(LinkName) -> + case file:delete(LinkName) of + {error,eperm} -> + file:del_dir(LinkName); + Other -> + Other + end. create_boot(Config, Options) -> ?line {ok, OldDir} = file:get_cwd(), @@ -1281,6 +1332,73 @@ create_script(Config) -> ?line file:close(Fd), {filename:dirname(Name),filename:basename(Name)}. +create_big_boot(Config) -> + ?line {ok, OldDir} = file:get_cwd(), + ?line {Options,Local} = case is_source_dir() of + true -> {[no_module_tests,local],true}; + _ -> {[no_module_tests],false} + end, + ?line {LatestDir,LatestName,Apps} = create_big_script(Config,Local), + ?line ok = file:set_cwd(LatestDir), + ?line ok = systools:make_script(LatestName, Options), + ?line ok = file:set_cwd(OldDir), + {filename:join(LatestDir, LatestName),Apps}. + +% The following apps cannot be loaded +% hipe .app references (or can reference) files that have no +% corresponding beam file (if hipe is not enabled) +filter_app("hipe",_) -> + false; +% Dialyzer and typer depends on hipe +filter_app("dialyzer",_) -> + false; +filter_app("typer",_) -> + false; +% Orber requires explicit configuration +filter_app("orber",_) -> + false; +% cos* depends on orber +filter_app("cos"++_,_) -> + false; +% ic has a mod instruction in the app file but no corresponding start function +filter_app("ic",_) -> + false; +% Netconf has some dependency that I really do not understand (maybe like orber) +filter_app("netconf",_) -> + false; +% Safe has the same kind of error in the .app file as ic +filter_app("safe",_) -> + false; +% OS_mon does not find it's port program when running cerl +filter_app("os_mon",true) -> + false; +% Other apps should be OK. +filter_app(_,_) -> + true. +create_big_script(Config,Local) -> + ?line PrivDir = ?config(priv_dir, Config), + ?line Name = filename:join(PrivDir,"full_script_test"), + ?line InitialApplications=application:loaded_applications(), + %% Applications left loaded by the application suite, unload them! + ?line UnloadFix=[app0,app1,app2,group_leader,app_start_error], + ?line [application:unload(Leftover) || + Leftover <- UnloadFix, + lists:keymember(Leftover,1,InitialApplications) ], + %% Now we should have only "real" applications... + ?line [application:load(list_to_atom(Y)) || {match,[Y]} <- [ re:run(X,code:lib_dir()++"/"++"([^/-]*).*/ebin",[{capture,[1],list}]) || X <- code:get_path()],filter_app(Y,Local)], + ?line Apps = [ {N,V} || {N,_,V} <- application:loaded_applications()], + ?line {ok,Fd} = file:open(Name ++ ".rel", write), + ?line io:format(Fd, + "{release, {\"Test release 3\", \"P2A\"}, \n" + " {erts, \"9.42\"}, \n" + " ~p}.\n", + [Apps]), + ?line file:close(Fd), + ?line NewlyLoaded = + application:loaded_applications() -- InitialApplications, + ?line [ application:unload(N) || {N,_,_} <- NewlyLoaded], + {filename:dirname(Name),filename:basename(Name),Apps}. + is_source_dir() -> filename:basename(code:lib_dir(kernel)) =:= "kernel" andalso filename:basename(code:lib_dir(stdlib)) =:= "stdlib". diff --git a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl index a39332f81d..646921026d 100644 --- a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl +++ b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl @@ -3,6 +3,15 @@ -on_load(run_me/0). run_me() -> + %% An onload handler typically calls code:priv_dir/1 + %% or code:lib_dir/1, so make sure that it works. + LibDir = code:lib_dir(on_load_app), + PrivDir = code:priv_dir(on_load_app), + LibDir = filename:dirname(PrivDir), + ModPath = filename:join(filename:split(code:which(?MODULE))), + LibDir = filename:dirname(filename:dirname(ModPath)), + + %% Start a process to remember that the on_load was called. spawn(fun() -> register(everything_is_fine, self()), receive Any -> diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl index 17c47f871d..47592ddb14 100644 --- a/lib/kernel/test/file_SUITE.erl +++ b/lib/kernel/test/file_SUITE.erl @@ -3268,7 +3268,7 @@ large_file(Config) when is_list(Config) -> {{unix,sunos},{A,B,C}} when A == 5, B == 5, C >= 1; A == 5, B >= 6; A >= 6 -> do_large_file(Config); - {{unix,Unix},_} when Unix =:= linux; Unix =:= darwin -> + {{unix,Unix},_} when Unix =/= sunos -> N = unix_free(Config), io:format("Free: ~w KByte~n", [N]), if N < 5 * (1 bsl 20) -> @@ -3278,7 +3278,7 @@ large_file(Config) when is_list(Config) -> do_large_file(Config) end; _ -> - {skipped,"Only supported on Win32, Linux, or SunOS >= 5.5.1"} + {skipped,"Only supported on Win32, Unix or SunOS >= 5.5.1"} end. unix_free(Config) -> @@ -3290,7 +3290,7 @@ unix_free(Config) -> N. do_large_file(Config) -> - ?line Watchdog = ?t:timetrap(?t:minutes(4)), + ?line Watchdog = ?t:timetrap(?t:minutes(5)), %% ?line Name = filename:join(?config(priv_dir, Config), ?MODULE_STRING ++ "_large_file"), @@ -3329,6 +3329,17 @@ do_large_file(Config) -> ?line {ok,P} = ?FILE_MODULE:position(F, {eof,-L}), ?line {ok,Rs} = ?FILE_MODULE:read(F, L+1), ?line ok = ?FILE_MODULE:close(F), + %% Reopen the file with 'append'; used to fail on Windows causing + %% writes to go to the beginning of the file for files > 4GB. + ?line PL = P + L, + ?line PLL = PL + L, + ?line {ok,F1} = ?FILE_MODULE:open(Name, [raw,read,write,append]), + ?line ok = ?FILE_MODULE:write(F1, R), + ?line {ok,PLL} = ?FILE_MODULE:position(F1, {cur,0}), + ?line {ok,Rs} = ?FILE_MODULE:pread(F1, P, L), + ?line {ok,PL} = ?FILE_MODULE:position(F1, {eof,-L}), + ?line {ok,R} = ?FILE_MODULE:read(F1, L+1), + ?line ok = ?FILE_MODULE:close(F1), %% ?line Mref = erlang:monitor(process, Deleter), ?line Deleter ! {Tester,done}, diff --git a/lib/kernel/test/file_name_SUITE.erl b/lib/kernel/test/file_name_SUITE.erl new file mode 100644 index 0000000000..fea4df8539 --- /dev/null +++ b/lib/kernel/test/file_name_SUITE.erl @@ -0,0 +1,1729 @@ +-module(file_name_SUITE). +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1996-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("test_server.hrl"). +-include_lib("kernel/include/file.hrl"). + +%% +%% File operations that take filenames as parameters (* not prim_file operation) (** a drive): +%% altname +%% copy (*) +%% del_dir +%% delete +%% get_cwd (**) +%% list_dir +%% make_dir +%% make_link +%% make_symlink +%% open +%% read_file +%% read_file_info +%% read_link +%% read_link_info +%% rename +%% set_cwd +%% write_file +%% write_file_info +%% +%% File operations that opens/uses separate driver port (not connected to file) +%% altname +%% del_dir +%% delete +%% get_cwd +%% list_dir +%% make_dir +%% make_link +%% make_symlink +%% read_file_info +%% read_link +%% read_link_info +%% rename +%% set_cwd +%% write_file_info +%% +%% Operations that use ?FD_DRV in prim_file +%% open +%% read_file +%% write_file +%% +%% +%% Operations that return a filename/path +%% altname +%% get_cwd +%% list_dir +%% read_link + +-export([all/1,init_per_testcase/2, fin_per_testcase/2]). +-export([normal/1,icky/1,very_icky/1,normalize/1]). + + +init_per_testcase(_Func, Config) -> + Dog = test_server:timetrap(test_server:seconds(60)), + [{watchdog,Dog}|Config]. + +fin_per_testcase(_Func, Config) -> + Dog = ?config(watchdog, Config), + test_server:timetrap_cancel(Dog). + + +all(suite) -> + [normal,icky,very_icky,normalize]. + +normalize(suite) -> + []; +normalize(doc) -> + ["Check that filename normalization works"]; +normalize(Config) when is_list(Config) -> + random:seed({1290,431421,830412}), + try + ?line UniMode = file:native_name_encoding() =/= latin1, + if + not UniMode -> + throw(need_unicode_mode); + true -> + ok + end, + ?line Pairs = [rand_comp_decomp(200) || _ <- lists:seq(1,1000)], + case os:type() of + {unix,darwin} -> + ?line [ true = (A =:= prim_file:internal_native2name(B)) || + {A,B} <- Pairs ]; + _ -> + ok + end, + ?line [ true = (A =:= prim_file:internal_normalize_utf8(B)) || + {A,B} <- Pairs ] + + catch + throw:need_unicode_mode -> + io:format("Sorry, can only run in unicode mode.~n"), + {skipped,"VM needs to be started in Unicode filename mode"} + end. + +normal(suite) -> + []; +normal(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +normal(Config) when is_list(Config) -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + ok = check_normal(prim_file), + put(file_module,file), + ok = check_normal(file) + after + file:set_cwd(Dir) + end. + + +icky(suite) -> + []; +icky(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +icky(Config) when is_list(Config) -> + case hopeless_darwin() of + true -> + {skipped,"This version of darwin does not support icky names at all."}; + false -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + ok = check_icky(prim_file), + put(file_module,file), + ok = check_icky(file) + after + file:set_cwd(Dir) + end + end. +very_icky(suite) -> + []; +very_icky(doc) -> + "Check file operations on normal file names regardless of unicode mode"; +very_icky(Config) when is_list(Config) -> + case hopeless_darwin() of + true -> + {skipped,"This version of darwin does not support icky names at all."}; + false -> + {ok,Dir} = file:get_cwd(), + try + Priv = ?config(priv_dir, Config), + file:set_cwd(Priv), + put(file_module,prim_file), + case check_very_icky(prim_file) of + need_unicode_mode -> + {skipped,"VM needs to be started in Unicode filename mode"}; + ok -> + put(file_module,file), + ok = check_very_icky(file) + end + after + file:set_cwd(Dir) + end + end. + + +check_normal(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line make_normal_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + %erlang:display(L1), + ?line L1 = lists:sort(list(normal_dir())), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), + ?line case Mod:altname("fil1") of + {error,enotsup} -> + ok; + {ok,LLL} when is_list(LLL) -> + ok + end, + ?line [ true = is_list(El) || El <- L1], + ?line Syms = [ {S,Targ,list_to_binary(get_data(Targ,normal_dir()))} + || {T,S,Targ} <- normal_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,"temp_dir",normal_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("tmp_dir"), + ?line ok = Mod:set_cwd("temp_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r(Mod,"temp_dir"), + ?line true = is_list(Dir), + ?line [ true = is_list(FN) || FN <- L0 ], + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse"), + ?line {ok, <<"fil1">>} = Mod:read_file("nisse"), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse"), + ?line ok = Mod:delete("nisse"), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse"), + ?line {error,enoent} = Mod:read_link_info("nisse"); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- normal_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary(Content), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- normal_dir() ], + ?line Mod:rename("fil1","tmp_fil1"), + ?line {ok, <<"fil1">>} = Mod:read_file("tmp_fil1"), + ?line {error,enoent} = Mod:read_file("fil1"), + ?line Mod:rename("tmp_fil1","fil1"), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("tmp_fil1"), + ?line {ok,FI} = Mod:read_file_info("fil1"), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("fil1"), + ?line ok = Mod:write_file_info("fil1",FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("fil1"), + ok + after + case Mod:read_file_info("fil1") of + {ok,FII} -> + NewModeI = FII#file_info.mode bor 8#777, + Mod:write_file_info("fil1",FII#file_info{mode = NewModeI}); + _ -> + ok + end, + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +check_icky(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line true=(length("���") =:= 3), + ?line UniMode = file:native_name_encoding() =/= latin1, + ?line make_icky_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + io:format("~p ~p~n",[L1,list(icky_dir())]), + ?line L1 = lists:sort(convlist(list(icky_dir()))), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), +%% Altname only on windows, and there are no non native filenames there +%% ?line case Mod:altname("fil1") of +%% {error,enotsup} -> +%% ok; +%% {ok,LLL} when is_list(LLL) -> +%% ok +%% end, + ?line [ true = ((is_list(El) or (UniMode and is_binary(El)))) || El <- L1], + ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,icky_dir()))} + || {T,S,Targ} <- icky_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,"���_dir",icky_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("��_dir"), + ?line ok = Mod:set_cwd("���_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = is_list(NowAt), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,"���_dir"), + {OS,TYPE} = os:type(), + % Check that treat_icky really converts to the same as the OS + case UniMode of + true -> + ?line chk_cre_dir(Mod,[{directory,"���_dir",[]}]), + ?line ok = Mod:set_cwd("���_dir"), + ?line ok = Mod:write_file(<<"���">>,<<"hello">>), + ?line Treated = treat_icky(<<"���">>), + ?line {ok,[Treated]} = Mod:list_dir("."), + ?line ok = Mod:delete(<<"���">>), + ?line {ok,[]} = Mod:list_dir("."), + ?line ok = Mod:set_cwd(".."), + ?line rm_r2(Mod,"���_dir"); + false -> + ok + end, + + ?line chk_cre_dir(Mod,[{directory,treat_icky(<<"���_dir">>),icky_dir()}]), + if + UniMode and (OS =/= win32) -> + ?line {error,enoent} = Mod:set_cwd("���_dir"); + true -> + ok + end, + ?line ok = Mod:set_cwd(treat_icky(<<"���_dir">>)), + ?line {ok, NowAt2} = Mod:get_cwd(), + io:format("~p~n",[NowAt2]), + % Cannot create raw unicode-breaking filenames on windows or macos + ?line true = ((((not UniMode) or (OS =:= win32) or (TYPE=:=darwin)) and is_list(NowAt2)) orelse ((UniMode) and is_binary(NowAt2))), + ?line true = BeginAt =/= NowAt2, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,conv(treat_icky(<<"���_dir">>))), + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse�"), + ?line {ok, <<"fil1">>} = Mod:read_file("nisse�"), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info("nisse�"), + ?line ok = Mod:delete("nisse�"), + ?line ok = Mod:make_link("fil1",treat_icky(<<"nisse�">>)), + ?line {ok, <<"fil1">>} = Mod:read_file(treat_icky(<<"nisse�">>)), + ?line {ok, #file_info{type = regular}} = Mod:read_link_info(treat_icky(<<"nisse�">>)), + ?line ok = Mod:delete(treat_icky(<<"nisse�">>)), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse�"), + ?line {error,enoent} = Mod:read_link_info("nisse�"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"nisse�">>)), + ?line {error,enoent} = Mod:read_link_info(treat_icky(<<"nisse�">>)); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- icky_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary([Content]), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- icky_dir() ], + ?line Mod:rename("���2","���_fil1"), + ?line {ok, <<"���2">>} = Mod:read_file("���_fil1"), + ?line {error,enoent} = Mod:read_file("���2"), + ?line Mod:rename("���_fil1","���2"), + ?line {ok, <<"���2">>} = Mod:read_file("���2"), + ?line {error,enoent} = Mod:read_file("���_fil1"), + + ?line Mod:rename("���2",treat_icky(<<"���_fil1">>)), + ?line {ok, <<"���2">>} = Mod:read_file(treat_icky(<<"���_fil1">>)), + if + UniMode and (OS =/= win32) -> + {error,enoent} = Mod:read_file("���_fil1"); + true -> + ok + end, + ?line {error,enoent} = Mod:read_file("���2"), + ?line Mod:rename(treat_icky(<<"���_fil1">>),"���2"), + ?line {ok, <<"���2">>} = Mod:read_file("���2"), + ?line {error,enoent} = Mod:read_file("���_fil1"), + ?line {error,enoent} = Mod:read_file(treat_icky(<<"���_fil1">>)), + + ?line {ok,FI} = Mod:read_file_info("���2"), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info("���2"), + ?line ok = Mod:write_file_info("���2",FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info("���2"), + + ?line {ok,FII} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info(treat_icky(<<"���5">>),FII#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = Mod:read_file_info(treat_icky(<<"���5">>)), + ?line ok = Mod:write_file_info(<<"���5">>,FII#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = Mod:read_file_info(treat_icky(<<"���5">>)), + ok + after + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +check_very_icky(Mod) -> + {ok,Dir} = Mod:get_cwd(), + try + ?line true=(length("���") =:= 3), + ?line UniMode = file:native_name_encoding() =/= latin1, + if + not UniMode -> + throw(need_unicode_mode); + true -> + ok + end, + ?line make_very_icky_dir(Mod), + ?line {ok, L0} = Mod:list_dir("."), + ?line L1 = lists:sort(L0), + ?line L1 = lists:sort(convlist(list(very_icky_dir()))), + ?line {ok,D2} = Mod:get_cwd(), + ?line true = is_list(D2), + ?line [ true = ((is_list(El) or is_binary(El))) || El <- L1], + ?line Syms = [ {S,conv(Targ),list_to_binary(get_data(Targ,very_icky_dir()))} + || {T,S,Targ} <- very_icky_dir(), T =:= symlink ], + ?line [ {ok, Cont} = Mod:read_file(SymL) || {SymL,_,Cont} <- Syms ], + ?line [ {ok, Targ} = fixlink(Mod:read_link(SymL)) || {SymL,Targ,_} <- Syms ], + ?line chk_cre_dir(Mod,[{directory,[1088,1079,1091]++"_dir",very_icky_dir()}]), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line true = is_list(BeginAt), + ?line {error,enoent} = Mod:set_cwd("��_dir"), + ?line ok = Mod:set_cwd([1088,1079,1091]++"_dir"), + ?line {ok, NowAt} = Mod:get_cwd(), + ?line true = is_list(NowAt), + ?line true = BeginAt =/= NowAt, + ?line ok = Mod:set_cwd(".."), + ?line {ok,BeginAt} = Mod:get_cwd(), + ?line rm_r2(Mod,[1088,1079,1091]++"_dir"), + + case has_links() of + true -> + ?line ok = Mod:make_link("fil1","nisse"++[1088,1079,1091]), + ?line {ok, <<"fil1">>} = + Mod:read_file("nisse"++[1088,1079,1091]), + ?line {ok, #file_info{type = regular}} = + Mod:read_link_info("nisse"++[1088,1079,1091]), + ?line ok = Mod:delete("nisse"++[1088,1079,1091]), + ?line ok = Mod:make_link("fil1",<<"nisse�">>), + ?line {ok, <<"fil1">>} = Mod:read_file(<<"nisse�">>), + ?line {ok, #file_info{type = regular}} = + Mod:read_link_info(<<"nisse�">>), + ?line ok = Mod:delete(<<"nisse�">>), + ?line {ok, <<"fil1">>} = Mod:read_file("fil1"), + ?line {error,enoent} = Mod:read_file("nisse"++[1088,1079,1091]), + ?line {error,enoent} = Mod:read_link_info("nisse"++[1088,1079,1091]), + ?line {error,enoent} = Mod:read_file(<<"nisse�">>), + ?line {error,enoent} = Mod:read_link_info(<<"nisse�">>); + false -> + ok + end, + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read]), + ?line {ok, Content} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- very_icky_dir() ], + ?line [ begin + ?line {ok, FD} = Mod:open(Name,[read,binary]), + ?line BC = list_to_binary([Content]), + ?line {ok, BC} = Mod:read(FD,1024), + ?line ok = file:close(FD) + end || {regular,Name,Content} <- very_icky_dir() ], + ?line Mod:rename([956,965,963,954,959,49], + [956,965,963,954,959]++"_fil1"), + ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959]++"_fil1"), + ?line {error,enoent} = Mod:read_file([956,965,963,954,959,49]), + ?line Mod:rename([956,965,963,954,959]++"_fil1",[956,965,963,954,959,49]), + ?line {ok, <<"���2">>} = Mod:read_file([956,965,963,954,959,49]), + ?line {error,enoent} = Mod:read_file([956,965,963,954,959]++"_fil1"), + + ?line {ok,FI} = Mod:read_file_info([956,965,963,954,959,49]), + ?line NewMode = FI#file_info.mode band (bnot 8#333), + ?line NewMode2 = NewMode bor 8#222, + ?line true = NewMode2 =/= NewMode, + ?line ok = Mod:write_file_info([956,965,963,954,959,49], + FI#file_info{mode = NewMode}), + ?line {ok,#file_info{mode = NewMode}} = + Mod:read_file_info([956,965,963,954,959,49]), + ?line ok = Mod:write_file_info([956,965,963,954,959,49], + FI#file_info{mode = NewMode2}), + ?line {ok,#file_info{mode = NewMode2}} = + Mod:read_file_info([956,965,963,954,959,49]), + ?line NumOK0 = case has_links() of + true -> 5; + false -> 3 + end, + ?line NumNOK0 = case has_links() of + true -> 4; + false -> 3 + end, + ?line {NumOK,NumNOK} = case is_binary(treat_icky(<<"foo">>)) of + false -> + {NumOK0+NumNOK0,0}; + true -> + {NumOK0,NumNOK0} + end, + ?line {NumOK,NumNOK} = filelib:fold_files(".",".*",true,fun(_F,{N,M}) when is_list(_F) -> io:format("~ts~n",[_F]),{N+1,M}; (_F,{N,M}) -> io:format("~p~n",[_F]),{N,M+1} end,{0,0}), + ?line ok = filelib:fold_files(".",[1076,1089,1072,124,46,42],true,fun(_F,_) -> ok end,false), + ?line SF3 = unicode:characters_to_binary("���subfil3",file:native_name_encoding()), + ?line Sorted = lists:sort([SF3,<<"���subfil2">>]), + ?line Sorted = lists:sort(filelib:wildcard("*",<<"���subdir2">>)), + ok + catch + throw:need_unicode_mode -> + io:format("Sorry, can only run in unicode mode.~n"), + need_unicode_mode + after + Mod:set_cwd(Dir), + io:format("Wd now: ~s~n",[Dir]) + end. + +%% +%% Utilities +%% + + +rm_rf(Mod,Dir) -> + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok, Content} = Mod:list_dir(Dir), + [ rm_rf(Mod,filename:join(Dir,C)) || C <- Content ], + Mod:del_dir(Dir), + ok; + {ok, #file_info{}} -> + Mod:delete(Dir); + _ -> + ok + end. + +rm_r(Mod,Dir) -> + %erlang:display({rm_r,Dir}), + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), + {ok, Content} = Mod:list_dir(Dir), + [ true = is_list(Part) || Part <- Content ], + [ true = is_list(filename:join(Dir,Part)) || Part <- Content ], + [ rm_r(Mod,filename:join(Dir,C)) || C <- Content ], + ok = Mod:del_dir(Dir), + ok; + {ok, #file_info{type = regular}} -> + {ok,#file_info{type = regular}} = Mod:read_file_info(Dir), + ok = Mod:delete(Dir); + {ok, #file_info{type = symlink}} -> + ok = Mod:delete(Dir) + end. +%% For icky test, allow binaries sometimes +rm_r2(Mod,Dir) -> + %erlang:display({rm_r2,Dir}), + case Mod:read_link_info(Dir) of + {ok, #file_info{type = directory}} -> + {ok,#file_info{type = directory}} = Mod:read_file_info(Dir), + {ok, Content} = Mod:list_dir(Dir), + UniMode = file:native_name_encoding() =/= latin1, + [ true = (is_list(Part) orelse UniMode) || Part <- Content ], + [ true = (is_list(filename:join(Dir,Part)) orelse UniMode) || Part <- Content ], + [ rm_r2(Mod,filename:join(Dir,C)) || C <- Content ], + ok = Mod:del_dir(Dir), + ok; + {ok, #file_info{type = regular}} -> + {ok,#file_info{type = regular}} = Mod:read_file_info(Dir), + ok = Mod:delete(Dir); + {ok, #file_info{type = symlink}} -> + ok = Mod:delete(Dir) + end. +chk_cre_dir(_,[]) -> + ok; +chk_cre_dir(Mod,[{regular,Name,Content}|T]) -> + %io:format("~p~n",[Name]), + ok = Mod:write_file(Name,Content), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{link,Name,Target}|T]) -> + ok = Mod:make_link(Target,Name), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{symlink,Name,Target}|T]) -> + ok = Mod:make_symlink(Target,Name), + chk_cre_dir(Mod,T); +chk_cre_dir(Mod,[{directory,Name,Content}|T]) -> + ok = Mod:make_dir(Name), + %io:format("Content = ~p~n",[Content]), + Content2 = [{Ty,filename:join(Name,N),case Ty of link -> filename:join(Name,C); _ -> C end} || {Ty,N,C} <- Content ], + %io:format("Content2 = ~p~n",[Content2]), + chk_cre_dir(Mod,Content2), + chk_cre_dir(Mod,T). + +has_links() -> + case os:type() of + {win32,_} -> + case os:version() of + {N,NN,_} when (N > 5) andalso (NN >= 1) -> + true; + _ -> + false + end; + _ -> + true + end. + +make_normal_dir(Mod) -> + rm_rf(Mod,"normal_dir"), + Mod:make_dir("normal_dir"), + Mod:set_cwd("normal_dir"), + Mod:write_file("fil1","fil1"), + Mod:write_file("fil2","fil2"), + case has_links() of + true -> + Mod:make_link("fil2","fil3"), + Mod:make_symlink("fil2","fil4"); + _ -> + ok + end, + Mod:make_dir("subdir"), + Mod:write_file(filename:join("subdir","subfil1"),"subfil1"), + ok. + +normal_dir() -> + [{regular,"fil1","fil1"}, + {regular,"fil2","fil2"}] ++ + case has_links() of + true -> + [{regular,"fil3","fil2"}, + {symlink,"fil4","fil2"}]; + false -> + [] + end ++ + [{directory,"subdir", + [{regular,"subfil1","subfil1"}]}]. + +make_icky_dir(Mod) -> + rm_rf(Mod,"icky_dir"), + Icky=icky_dir(), + chk_cre_dir(Mod,[{directory,"icky_dir",linkify([],Icky)}]), + Mod:set_cwd("icky_dir"), + ok. + +linkify(_Passed,[]) -> + []; +linkify(Passed,[{regular,Name,Content}|T]) -> + Regulars = [ {N,C} || {regular,N,C} <- Passed, N =/= Name ], + case lists:keysearch(Content,2,Regulars) of + {value, {Linkto, Content}} -> + [{link,Name,Linkto} | linkify(Passed,T)]; + _ -> + [{regular,Name,Content} | linkify([{regular,Name,Content}|Passed],T)] + end; +linkify(Passed,[{directory, Name, Content}|T]) -> + [{directory,Name, linkify(Content,Content)}|linkify(Passed,T)]; +linkify(Passed,[H|T]) -> + [H|linkify([H|Passed],T)]. + +hopeless_darwin() -> + case {os:type(),os:version()} of + {{unix,darwin},{Major,_,_}} when Major < 9 -> + true; + _ -> + false + end. + +icky_dir() -> + [{regular,"fil1","fil1"}, + {regular,"���2","���2"}] ++ + case has_links() of + true -> + [{regular,"���3","���2"}, + {symlink,"���4","���2"}]; + false -> + [] + end ++ + [{regular,treat_icky(<<"���5">>),"���5"}] ++ + case has_links() of + true -> + [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + false -> + [] + end ++ + [{directory,treat_icky(<<"���subdir2">>), + [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, + {regular,"���subfil3","���subfil13"}]}, + {directory,"���subdir", + [{regular,"���subfil1","���subfil1"}]}]. + +make_very_icky_dir(Mod) -> + rm_rf(Mod,"very_icky_dir"), + Icky=very_icky_dir(), + chk_cre_dir(Mod,[{directory,"very_icky_dir",linkify([],Icky)}]), + Mod:set_cwd("very_icky_dir"), + ok. + +very_icky_dir() -> + [{regular,"fil1","fil1"}, + {regular,[956,965,963,954,959,49],"���2"}] ++ + case has_links() of + true -> + [{regular,[956,965,963,954,959,50],"���2"}, + {symlink,[956,965,963,954,959,51],[956,965,963,954,959,49]}]; + false -> + [] + end ++ + [{regular,treat_icky(<<"���5">>),"���5"}] ++ + case has_links() of + true -> + [{symlink,treat_icky(<<"���6">>),treat_icky(<<"���5">>)}]; + false -> + [] + end ++ + [{directory,treat_icky(<<"���subdir2">>), + [{regular,treat_icky(<<"���subfil2">>),"���subfil12"}, + {regular,"���subfil3","���subfil13"}]}, + {directory,[956,965,963,954,959]++"subdir1", + [{regular,[956,965,963,954,959]++"subfil1","���subfil1"}]}]. + +%% Some OS'es simply do not allow non UTF8 filenames +treat_icky(Bin) -> + case os:type() of + {unix,darwin} -> + binary_to_list(procentify(Bin)); + {win32,_} -> + binary_to_list(Bin); + _ -> + Bin + end. + +% Handle windows having absolute soft link targets. +fixlink({ok,Link}) -> + case os:type() of + {win32,_} -> + {ok,filename:basename(Link)}; + _ -> + {ok,Link} + end; +fixlink(X) -> + X. + +procentify(<<>>) -> + <<>>; +procentify(<<X:8,Rst/binary>>) when X > 127 -> + T=procentify(Rst), + Y = list_to_binary([$% + | io_lib:format("~2.16B",[X])]), + <<Y/binary,T/binary>>; +procentify(<<X:8,Rst/binary>>) -> + T=procentify(Rst), + <<X:8,T/binary>>. + + +list([]) -> + []; +list([{_,Name,_} | T]) -> + [Name | list(T)]. + + +get_data(FN,List) -> + case lists:keysearch(FN,2,List) of + {value,{regular,FN,C}} -> + C; + {value,{symlink,FN,NewFN}} -> + get_data(NewFN,List); + _-> + [] + end. + + +convlist(L) -> + convlist(file:native_name_encoding(),L). +convlist(latin1,[Bin|T]) when is_binary(Bin) -> + %erlang:display('Convert...'), + [binary_to_list(Bin)| convlist(latin1,T)]; +convlist(Any,[H|T]) -> + [H|convlist(Any,T)]; +convlist(_,[]) -> + []. + +conv(L) -> + NoUniMode = file:native_name_encoding() =:= latin1, + if + NoUniMode, is_binary(L) -> + binary_to_list(L); + true -> + L + end. + + +rand_comp_decomp(Max) -> + N = random:uniform(Max), + L = [ rand_decomp() || _ <- lists:seq(1,N) ], + LC = [ A || {A,_} <- L], + LD = lists:flatten([B || {_,B} <- L]), + LB = unicode:characters_to_binary(LD,unicode,utf8), + {LC,LB}. + +rand_decomp() -> + BT = bigtup(), + SZ = tuple_size(BT), + element(random:uniform(SZ),BT). +bigtup() -> + {{192,[65,768]}, + {200,[69,768]}, + {204,[73,768]}, + {210,[79,768]}, + {217,[85,768]}, + {7808,[87,768]}, + {7922,[89,768]}, + {224,[97,768]}, + {232,[101,768]}, + {236,[105,768]}, + {242,[111,768]}, + {249,[117,768]}, + {7809,[119,768]}, + {7923,[121,768]}, + {8173,[168,768]}, + {7846,[65,770,768]}, + {7872,[69,770,768]}, + {7890,[79,770,768]}, + {7847,[97,770,768]}, + {7873,[101,770,768]}, + {7891,[111,770,768]}, + {7700,[69,772,768]}, + {7760,[79,772,768]}, + {7701,[101,772,768]}, + {7761,[111,772,768]}, + {7856,[65,774,768]}, + {7857,[97,774,768]}, + {475,[85,776,768]}, + {476,[117,776,768]}, + {8146,[953,776,768]}, + {8162,[965,776,768]}, + {8074,[913,837,787,768]}, + {8090,[919,837,787,768]}, + {8106,[937,837,787,768]}, + {8066,[945,837,787,768]}, + {8082,[951,837,787,768]}, + {8098,[969,837,787,768]}, + {7946,[913,787,768]}, + {7962,[917,787,768]}, + {7978,[919,787,768]}, + {7994,[921,787,768]}, + {8010,[927,787,768]}, + {8042,[937,787,768]}, + {7938,[945,787,768]}, + {7954,[949,787,768]}, + {7970,[951,787,768]}, + {7986,[953,787,768]}, + {8002,[959,787,768]}, + {8018,[965,787,768]}, + {8034,[969,787,768]}, + {8075,[913,837,788,768]}, + {8091,[919,837,788,768]}, + {8107,[937,837,788,768]}, + {8067,[945,837,788,768]}, + {8083,[951,837,788,768]}, + {8099,[969,837,788,768]}, + {7947,[913,788,768]}, + {7963,[917,788,768]}, + {7979,[919,788,768]}, + {7995,[921,788,768]}, + {8011,[927,788,768]}, + {8027,[933,788,768]}, + {8043,[937,788,768]}, + {7939,[945,788,768]}, + {7955,[949,788,768]}, + {7971,[951,788,768]}, + {7987,[953,788,768]}, + {8003,[959,788,768]}, + {8019,[965,788,768]}, + {8035,[969,788,768]}, + {7900,[79,795,768]}, + {7914,[85,795,768]}, + {7901,[111,795,768]}, + {7915,[117,795,768]}, + {8114,[945,837,768]}, + {8130,[951,837,768]}, + {8178,[969,837,768]}, + {8122,[913,768]}, + {8136,[917,768]}, + {8138,[919,768]}, + {8154,[921,768]}, + {8184,[927,768]}, + {8170,[933,768]}, + {8186,[937,768]}, + {8048,[945,768]}, + {8050,[949,768]}, + {8052,[951,768]}, + {8054,[953,768]}, + {8056,[959,768]}, + {8058,[965,768]}, + {8060,[969,768]}, + {8141,[8127,768]}, + {8157,[8190,768]}, + {193,[65,769]}, + {262,[67,769]}, + {201,[69,769]}, + {500,[71,769]}, + {205,[73,769]}, + {7728,[75,769]}, + {313,[76,769]}, + {7742,[77,769]}, + {323,[78,769]}, + {211,[79,769]}, + {7764,[80,769]}, + {340,[82,769]}, + {346,[83,769]}, + {218,[85,769]}, + {7810,[87,769]}, + {221,[89,769]}, + {377,[90,769]}, + {225,[97,769]}, + {263,[99,769]}, + {233,[101,769]}, + {501,[103,769]}, + {237,[105,769]}, + {7729,[107,769]}, + {314,[108,769]}, + {7743,[109,769]}, + {324,[110,769]}, + {243,[111,769]}, + {7765,[112,769]}, + {341,[114,769]}, + {347,[115,769]}, + {250,[117,769]}, + {7811,[119,769]}, + {253,[121,769]}, + {378,[122,769]}, + {8174,[168,769]}, + {508,[198,769]}, + {510,[216,769]}, + {509,[230,769]}, + {511,[248,769]}, + {7844,[65,770,769]}, + {7870,[69,770,769]}, + {7888,[79,770,769]}, + {7845,[97,770,769]}, + {7871,[101,770,769]}, + {7889,[111,770,769]}, + {7756,[79,771,769]}, + {7800,[85,771,769]}, + {7757,[111,771,769]}, + {7801,[117,771,769]}, + {7702,[69,772,769]}, + {7762,[79,772,769]}, + {7703,[101,772,769]}, + {7763,[111,772,769]}, + {7854,[65,774,769]}, + {7855,[97,774,769]}, + {7726,[73,776,769]}, + {471,[85,776,769]}, + {7727,[105,776,769]}, + {472,[117,776,769]}, + {8147,[953,776,769]}, + {8163,[965,776,769]}, + {506,[65,778,769]}, + {507,[97,778,769]}, + {8076,[913,837,787,769]}, + {8092,[919,837,787,769]}, + {8108,[937,837,787,769]}, + {8068,[945,837,787,769]}, + {8084,[951,837,787,769]}, + {8100,[969,837,787,769]}, + {7948,[913,787,769]}, + {7964,[917,787,769]}, + {7980,[919,787,769]}, + {7996,[921,787,769]}, + {8012,[927,787,769]}, + {8044,[937,787,769]}, + {7940,[945,787,769]}, + {7956,[949,787,769]}, + {7972,[951,787,769]}, + {7988,[953,787,769]}, + {8004,[959,787,769]}, + {8020,[965,787,769]}, + {8036,[969,787,769]}, + {8077,[913,837,788,769]}, + {8093,[919,837,788,769]}, + {8109,[937,837,788,769]}, + {8069,[945,837,788,769]}, + {8085,[951,837,788,769]}, + {8101,[969,837,788,769]}, + {7949,[913,788,769]}, + {7965,[917,788,769]}, + {7981,[919,788,769]}, + {7997,[921,788,769]}, + {8013,[927,788,769]}, + {8029,[933,788,769]}, + {8045,[937,788,769]}, + {7941,[945,788,769]}, + {7957,[949,788,769]}, + {7973,[951,788,769]}, + {7989,[953,788,769]}, + {8005,[959,788,769]}, + {8021,[965,788,769]}, + {8037,[969,788,769]}, + {7898,[79,795,769]}, + {7912,[85,795,769]}, + {7899,[111,795,769]}, + {7913,[117,795,769]}, + {7688,[67,807,769]}, + {7689,[99,807,769]}, + {8116,[945,837,769]}, + {8132,[951,837,769]}, + {8180,[959,837,769]}, + {8123,[913,769]}, + {8137,[917,769]}, + {8139,[919,769]}, + {8155,[921,769]}, + {8185,[927,769]}, + {8171,[933,769]}, + {8187,[937,769]}, + {8049,[945,769]}, + {8051,[949,769]}, + {8053,[951,769]}, + {8055,[953,769]}, + {8057,[959,769]}, + {8059,[965,769]}, + {8061,[969,769]}, + {1027,[1043,769]}, + {1036,[1050,769]}, + {1107,[1075,769]}, + {1116,[1082,769]}, + {8142,[8127,769]}, + {8158,[8190,769]}, + {194,[65,770]}, + {264,[67,770]}, + {202,[69,770]}, + {284,[71,770]}, + {292,[72,770]}, + {206,[73,770]}, + {308,[74,770]}, + {212,[79,770]}, + {348,[83,770]}, + {219,[85,770]}, + {372,[87,770]}, + {374,[89,770]}, + {7824,[90,770]}, + {226,[97,770]}, + {265,[99,770]}, + {234,[101,770]}, + {285,[103,770]}, + {293,[104,770]}, + {238,[105,770]}, + {309,[106,770]}, + {244,[111,770]}, + {349,[115,770]}, + {251,[117,770]}, + {373,[119,770]}, + {375,[121,770]}, + {7825,[122,770]}, + {7852,[65,803,770]}, + {7878,[69,803,770]}, + {7896,[79,803,770]}, + {7853,[97,803,770]}, + {7879,[101,803,770]}, + {7897,[111,803,770]}, + {195,[65,771]}, + {7868,[69,771]}, + {296,[73,771]}, + {209,[78,771]}, + {213,[79,771]}, + {360,[85,771]}, + {7804,[86,771]}, + {7928,[89,771]}, + {227,[97,771]}, + {7869,[101,771]}, + {297,[105,771]}, + {241,[110,771]}, + {245,[111,771]}, + {361,[117,771]}, + {7805,[118,771]}, + {7929,[121,771]}, + {7850,[65,770,771]}, + {7876,[69,770,771]}, + {7894,[79,770,771]}, + {7851,[97,770,771]}, + {7877,[101,770,771]}, + {7895,[111,770,771]}, + {7860,[65,774,771]}, + {7861,[97,774,771]}, + {7904,[79,795,771]}, + {7918,[85,795,771]}, + {7905,[111,795,771]}, + {7919,[117,795,771]}, + {256,[65,772]}, + {274,[69,772]}, + {7712,[71,772]}, + {298,[73,772]}, + {332,[79,772]}, + {362,[85,772]}, + {257,[97,772]}, + {275,[101,772]}, + {7713,[103,772]}, + {299,[105,772]}, + {333,[111,772]}, + {363,[117,772]}, + {482,[198,772]}, + {483,[230,772]}, + {480,[65,775,772]}, + {481,[97,775,772]}, + {478,[65,776,772]}, + {469,[85,776,772]}, + {479,[97,776,772]}, + {470,[117,776,772]}, + {7736,[76,803,772]}, + {7772,[82,803,772]}, + {7737,[108,803,772]}, + {7773,[114,803,772]}, + {492,[79,808,772]}, + {493,[111,808,772]}, + {8121,[913,772]}, + {8153,[921,772]}, + {8169,[933,772]}, + {8113,[945,772]}, + {8145,[953,772]}, + {8161,[965,772]}, + {1250,[1048,772]}, + {1262,[1059,772]}, + {1251,[1080,772]}, + {1263,[1091,772]}, + {258,[65,774]}, + {276,[69,774]}, + {286,[71,774]}, + {300,[73,774]}, + {334,[79,774]}, + {364,[85,774]}, + {259,[97,774]}, + {277,[101,774]}, + {287,[103,774]}, + {301,[105,774]}, + {335,[111,774]}, + {365,[117,774]}, + {7862,[65,803,774]}, + {7863,[97,803,774]}, + {7708,[69,807,774]}, + {7709,[101,807,774]}, + {8120,[913,774]}, + {8152,[921,774]}, + {8168,[933,774]}, + {8112,[945,774]}, + {8144,[953,774]}, + {8160,[965,774]}, + {1232,[1040,774]}, + {1238,[1045,774]}, + {1217,[1046,774]}, + {1049,[1048,774]}, + {1038,[1059,774]}, + {1233,[1072,774]}, + {1239,[1077,774]}, + {1218,[1078,774]}, + {1081,[1080,774]}, + {1118,[1091,774]}, + {7682,[66,775]}, + {266,[67,775]}, + {7690,[68,775]}, + {278,[69,775]}, + {7710,[70,775]}, + {288,[71,775]}, + {7714,[72,775]}, + {304,[73,775]}, + {7744,[77,775]}, + {7748,[78,775]}, + {7766,[80,775]}, + {7768,[82,775]}, + {7776,[83,775]}, + {7786,[84,775]}, + {7814,[87,775]}, + {7818,[88,775]}, + {7822,[89,775]}, + {379,[90,775]}, + {7683,[98,775]}, + {267,[99,775]}, + {7691,[100,775]}, + {279,[101,775]}, + {7711,[102,775]}, + {289,[103,775]}, + {7715,[104,775]}, + {7745,[109,775]}, + {7749,[110,775]}, + {7767,[112,775]}, + {7769,[114,775]}, + {7777,[115,775]}, + {7787,[116,775]}, + {7815,[119,775]}, + {7819,[120,775]}, + {7823,[121,775]}, + {380,[122,775]}, + {7835,[383,775]}, + {7780,[83,769,775]}, + {7781,[115,769,775]}, + {784,[774,775]}, + {7782,[83,780,775]}, + {7783,[115,780,775]}, + {7784,[83,803,775]}, + {7785,[115,803,775]}, + {196,[65,776]}, + {203,[69,776]}, + {7718,[72,776]}, + {207,[73,776]}, + {214,[79,776]}, + {220,[85,776]}, + {7812,[87,776]}, + {7820,[88,776]}, + {376,[89,776]}, + {228,[97,776]}, + {235,[101,776]}, + {7719,[104,776]}, + {239,[105,776]}, + {246,[111,776]}, + {7831,[116,776]}, + {252,[117,776]}, + {7813,[119,776]}, + {7821,[120,776]}, + {255,[121,776]}, + {1242,[399,776]}, + {1258,[415,776]}, + {1243,[601,776]}, + {1259,[629,776]}, + {7758,[79,771,776]}, + {7759,[111,771,776]}, + {7802,[85,772,776]}, + {7803,[117,772,776]}, + {938,[921,776]}, + {939,[933,776]}, + {970,[953,776]}, + {971,[965,776]}, + {980,[978,776]}, + {1031,[1030,776]}, + {1234,[1040,776]}, + {1025,[1045,776]}, + {1244,[1046,776]}, + {1246,[1047,776]}, + {1252,[1048,776]}, + {1254,[1054,776]}, + {1264,[1059,776]}, + {1268,[1063,776]}, + {1272,[1067,776]}, + {1235,[1072,776]}, + {1105,[1077,776]}, + {1245,[1078,776]}, + {1247,[1079,776]}, + {1253,[1080,776]}, + {1255,[1086,776]}, + {1265,[1091,776]}, + {1269,[1095,776]}, + {1273,[1099,776]}, + {1111,[1110,776]}, + {7842,[65,777]}, + {7866,[69,777]}, + {7880,[73,777]}, + {7886,[79,777]}, + {7910,[85,777]}, + {7926,[89,777]}, + {7843,[97,777]}, + {7867,[101,777]}, + {7881,[105,777]}, + {7887,[111,777]}, + {7911,[117,777]}, + {7927,[121,777]}, + {7848,[65,770,777]}, + {7874,[69,770,777]}, + {7892,[79,770,777]}, + {7849,[97,770,777]}, + {7875,[101,770,777]}, + {7893,[111,770,777]}, + {7858,[65,774,777]}, + {7859,[97,774,777]}, + {7902,[79,795,777]}, + {7916,[85,795,777]}, + {7903,[111,795,777]}, + {7917,[117,795,777]}, + {197,[65,778]}, + {366,[85,778]}, + {229,[97,778]}, + {367,[117,778]}, + {7832,[119,778]}, + {7833,[121,778]}, + {336,[79,779]}, + {368,[85,779]}, + {337,[111,779]}, + {369,[117,779]}, + {1266,[1059,779]}, + {1267,[1091,779]}, + {461,[65,780]}, + {268,[67,780]}, + {270,[68,780]}, + {282,[69,780]}, + {486,[71,780]}, + {463,[73,780]}, + {488,[75,780]}, + {317,[76,780]}, + {327,[78,780]}, + {465,[79,780]}, + {344,[82,780]}, + {352,[83,780]}, + {356,[84,780]}, + {467,[85,780]}, + {381,[90,780]}, + {462,[97,780]}, + {269,[99,780]}, + {271,[100,780]}, + {283,[101,780]}, + {487,[103,780]}, + {464,[105,780]}, + {496,[106,780]}, + {489,[107,780]}, + {318,[108,780]}, + {328,[110,780]}, + {466,[111,780]}, + {345,[114,780]}, + {353,[115,780]}, + {357,[116,780]}, + {468,[117,780]}, + {382,[122,780]}, + {494,[439,780]}, + {495,[658,780]}, + {473,[85,776,780]}, + {474,[117,776,780]}, + {901,[168,781]}, + {912,[953,776,781]}, + {944,[965,776,781]}, + {902,[913,781]}, + {904,[917,781]}, + {905,[919,781]}, + {906,[921,781]}, + {908,[927,781]}, + {910,[933,781]}, + {911,[937,781]}, + {940,[945,781]}, + {941,[949,781]}, + {942,[951,781]}, + {943,[953,781]}, + {972,[959,781]}, + {973,[965,781]}, + {974,[969,781]}, + {979,[978,781]}, + {512,[65,783]}, + {516,[69,783]}, + {520,[73,783]}, + {524,[79,783]}, + {528,[82,783]}, + {532,[85,783]}, + {513,[97,783]}, + {517,[101,783]}, + {521,[105,783]}, + {525,[111,783]}, + {529,[114,783]}, + {533,[117,783]}, + {1142,[1140,783]}, + {1143,[1141,783]}, + {514,[65,785]}, + {518,[69,785]}, + {522,[73,785]}, + {526,[79,785]}, + {530,[82,785]}, + {534,[85,785]}, + {515,[97,785]}, + {519,[101,785]}, + {523,[105,785]}, + {527,[111,785]}, + {531,[114,785]}, + {535,[117,785]}, + {8072,[913,837,787]}, + {8088,[919,837,787]}, + {8104,[937,837,787]}, + {8064,[945,837,787]}, + {8080,[951,837,787]}, + {8096,[969,837,787]}, + {7944,[913,787]}, + {7960,[917,787]}, + {7976,[919,787]}, + {7992,[921,787]}, + {8008,[927,787]}, + {8040,[937,787]}, + {7936,[945,787]}, + {7952,[949,787]}, + {7968,[951,787]}, + {7984,[953,787]}, + {8000,[959,787]}, + {8164,[961,787]}, + {8016,[965,787]}, + {8032,[969,787]}, + {8073,[913,837,788]}, + {8089,[919,837,788]}, + {8105,[937,837,788]}, + {8065,[945,837,788]}, + {8081,[951,837,788]}, + {8097,[969,837,788]}, + {7945,[913,788]}, + {7961,[917,788]}, + {7977,[919,788]}, + {7993,[921,788]}, + {8009,[927,788]}, + {8172,[929,788]}, + {8025,[933,788]}, + {8041,[937,788]}, + {7937,[945,788]}, + {7953,[949,788]}, + {7969,[951,788]}, + {7985,[953,788]}, + {8001,[959,788]}, + {8165,[961,788]}, + {8017,[965,788]}, + {8033,[969,788]}, + {416,[79,795]}, + {431,[85,795]}, + {417,[111,795]}, + {432,[117,795]}, + {7840,[65,803]}, + {7684,[66,803]}, + {7692,[68,803]}, + {7864,[69,803]}, + {7716,[72,803]}, + {7882,[73,803]}, + {7730,[75,803]}, + {7734,[76,803]}, + {7746,[77,803]}, + {7750,[78,803]}, + {7884,[79,803]}, + {7770,[82,803]}, + {7778,[83,803]}, + {7788,[84,803]}, + {7908,[85,803]}, + {7806,[86,803]}, + {7816,[87,803]}, + {7924,[89,803]}, + {7826,[90,803]}, + {7841,[97,803]}, + {7685,[98,803]}, + {7693,[100,803]}, + {7865,[101,803]}, + {7717,[104,803]}, + {7883,[105,803]}, + {7731,[107,803]}, + {7735,[108,803]}, + {7747,[109,803]}, + {7751,[110,803]}, + {7885,[111,803]}, + {7771,[114,803]}, + {7779,[115,803]}, + {7789,[116,803]}, + {7909,[117,803]}, + {7807,[118,803]}, + {7817,[119,803]}, + {7925,[121,803]}, + {7827,[122,803]}, + {7906,[79,795,803]}, + {7920,[85,795,803]}, + {7907,[111,795,803]}, + {7921,[117,795,803]}, + {7794,[85,804]}, + {7795,[117,804]}, + {7680,[65,805]}, + {7681,[97,805]}, + {199,[67,807]}, + {7696,[68,807]}, + {290,[71,807]}, + {7720,[72,807]}, + {310,[75,807]}, + {315,[76,807]}, + {325,[78,807]}, + {342,[82,807]}, + {350,[83,807]}, + {354,[84,807]}, + {231,[99,807]}, + {7697,[100,807]}, + {291,[103,807]}, + {7721,[104,807]}, + {311,[107,807]}, + {316,[108,807]}, + {326,[110,807]}, + {343,[114,807]}, + {351,[115,807]}, + {355,[116,807]}, + {260,[65,808]}, + {280,[69,808]}, + {302,[73,808]}, + {490,[79,808]}, + {370,[85,808]}, + {261,[97,808]}, + {281,[101,808]}, + {303,[105,808]}, + {491,[111,808]}, + {371,[117,808]}, + {7698,[68,813]}, + {7704,[69,813]}, + {7740,[76,813]}, + {7754,[78,813]}, + {7792,[84,813]}, + {7798,[85,813]}, + {7699,[100,813]}, + {7705,[101,813]}, + {7741,[108,813]}, + {7755,[110,813]}, + {7793,[116,813]}, + {7799,[117,813]}, + {7722,[72,814]}, + {7723,[104,814]}, + {7706,[69,816]}, + {7724,[73,816]}, + {7796,[85,816]}, + {7707,[101,816]}, + {7725,[105,816]}, + {7797,[117,816]}, + {7686,[66,817]}, + {7694,[68,817]}, + {7732,[75,817]}, + {7738,[76,817]}, + {7752,[78,817]}, + {7774,[82,817]}, + {7790,[84,817]}, + {7828,[90,817]}, + {7687,[98,817]}, + {7695,[100,817]}, + {7830,[104,817]}, + {7733,[107,817]}, + {7739,[108,817]}, + {7753,[110,817]}, + {7775,[114,817]}, + {7791,[116,817]}, + {7829,[122,817]}, + {8129,[168,834]}, + {8151,[953,776,834]}, + {8167,[965,776,834]}, + {8078,[913,837,787,834]}, + {8094,[919,837,787,834]}, + {8110,[937,837,787,834]}, + {8070,[945,837,787,834]}, + {8086,[951,837,787,834]}, + {8102,[969,837,787,834]}, + {7950,[913,787,834]}, + {7982,[919,787,834]}, + {7998,[921,787,834]}, + {8046,[937,787,834]}, + {7942,[945,787,834]}, + {7974,[951,787,834]}, + {7990,[953,787,834]}, + {8022,[965,787,834]}, + {8038,[969,787,834]}, + {8079,[913,837,788,834]}, + {8095,[919,837,788,834]}, + {8111,[937,837,788,834]}, + {8071,[945,837,788,834]}, + {8087,[951,837,788,834]}, + {8103,[969,837,788,834]}, + {7951,[913,788,834]}, + {7983,[919,788,834]}, + {7999,[921,788,834]}, + {8031,[933,788,834]}, + {8047,[937,788,834]}, + {7943,[945,788,834]}, + {7975,[951,788,834]}, + {7991,[953,788,834]}, + {8023,[965,788,834]}, + {8039,[969,788,834]}, + {8119,[945,837,834]}, + {8135,[951,837,834]}, + {8183,[969,837,834]}, + {8118,[945,834]}, + {8134,[951,834]}, + {8150,[953,834]}, + {8166,[965,834]}, + {8182,[969,834]}, + {8143,[8127,834]}, + {8159,[8190,834]}, + {8124,[913,837]}, + {8140,[919,837]}, + {8188,[937,837]}, + {8115,[945,837]}, + {8131,[951,837]}, + {8179,[969,837]}, + {64302,[1488,1463]}, + {64287,[1522,1463]}, + {64303,[1488,1464]}, + {64331,[1493,1465]}, + {64304,[1488,1468]}, + {64305,[1489,1468]}, + {64306,[1490,1468]}, + {64307,[1491,1468]}, + {64308,[1492,1468]}, + {64309,[1493,1468]}, + {64310,[1494,1468]}, + {64312,[1496,1468]}, + {64313,[1497,1468]}, + {64314,[1498,1468]}, + {64315,[1499,1468]}, + {64316,[1500,1468]}, + {64318,[1502,1468]}, + {64320,[1504,1468]}, + {64321,[1505,1468]}, + {64323,[1507,1468]}, + {64324,[1508,1468]}, + {64326,[1510,1468]}, + {64327,[1511,1468]}, + {64328,[1512,1468]}, + {64329,[1513,1468]}, + {64330,[1514,1468]}, + {64332,[1489,1471]}, + {64333,[1499,1471]}, + {64334,[1508,1471]}, + {64300,[1513,1468,1473]}, + {64298,[1513,1473]}, + {64301,[1513,1468,1474]}, + {64299,[1513,1474]}, + {2392,[2325,2364]}, + {2393,[2326,2364]}, + {2394,[2327,2364]}, + {2395,[2332,2364]}, + {2396,[2337,2364]}, + {2397,[2338,2364]}, + {2345,[2344,2364]}, + {2398,[2347,2364]}, + {2399,[2351,2364]}, + {2353,[2352,2364]}, + {2356,[2355,2364]}, + {2524,[2465,2492]}, + {2525,[2466,2492]}, + {2480,[2476,2492]}, + {2527,[2479,2492]}, + {2507,[2503,2494]}, + {2508,[2503,2519]}, + {2649,[2582,2620]}, + {2650,[2583,2620]}, + {2651,[2588,2620]}, + {2652,[2593,2620]}, + {2654,[2603,2620]}, + {2908,[2849,2876]}, + {2909,[2850,2876]}, + {2911,[2863,2876]}, + {2891,[2887,2878]}, + {2888,[2887,2902]}, + {2892,[2887,2903]}, + {3018,[3014,3006]}, + {3019,[3015,3006]}, + {2964,[2962,3031]}, + {3020,[3014,3031]}, + {3144,[3142,3158]}, + {3274,[3270,3266]}, + {3264,[3263,3285]}, + {3275,[3270,3266,3285]}, + {3271,[3270,3285]}, + {3272,[3270,3286]}, + {3402,[3398,3390]}, + {3403,[3399,3390]}, + {3404,[3398,3415]}, + {3635,[3661,3634]}, + {3763,[3789,3762]}, + {3955,[3954,3953]}, + {3957,[3956,3953]}, + {3959,[4018,3968,3953]}, + {3961,[4019,3968,3953]}, + {3958,[4018,3968]}, + {3960,[4019,3968]}, + {3945,[3904,4021]}, + {4025,[3984,4021]}, + {3907,[3906,4023]}, + {3917,[3916,4023]}, + {3922,[3921,4023]}, + {3927,[3926,4023]}, + {3932,[3931,4023]}, + {3987,[3986,4023]}, + {3997,[3996,4023]}, + {4002,[4001,4023]}, + {4007,[4006,4023]}, + {4012,[4011,4023]}, + {12436,[12358,12441]}, + {12364,[12363,12441]}, + {12366,[12365,12441]}, + {12368,[12367,12441]}, + {12370,[12369,12441]}, + {12372,[12371,12441]}, + {12374,[12373,12441]}, + {12376,[12375,12441]}, + {12378,[12377,12441]}, + {12380,[12379,12441]}, + {12382,[12381,12441]}, + {12384,[12383,12441]}, + {12386,[12385,12441]}, + {12389,[12388,12441]}, + {12391,[12390,12441]}, + {12393,[12392,12441]}, + {12400,[12399,12441]}, + {12403,[12402,12441]}, + {12406,[12405,12441]}, + {12409,[12408,12441]}, + {12412,[12411,12441]}, + {12446,[12445,12441]}, + {12532,[12454,12441]}, + {12460,[12459,12441]}, + {12462,[12461,12441]}, + {12464,[12463,12441]}, + {12466,[12465,12441]}, + {12468,[12467,12441]}, + {12470,[12469,12441]}, + {12472,[12471,12441]}, + {12474,[12473,12441]}, + {12476,[12475,12441]}, + {12478,[12477,12441]}, + {12480,[12479,12441]}, + {12482,[12481,12441]}, + {12485,[12484,12441]}, + {12487,[12486,12441]}, + {12489,[12488,12441]}, + {12496,[12495,12441]}, + {12499,[12498,12441]}, + {12502,[12501,12441]}, + {12505,[12504,12441]}, + {12508,[12507,12441]}, + {12535,[12527,12441]}, + {12536,[12528,12441]}, + {12537,[12529,12441]}, + {12538,[12530,12441]}, + {12542,[12541,12441]}, + {12401,[12399,12442]}, + {12404,[12402,12442]}, + {12407,[12405,12442]}, + {12410,[12408,12442]}, + {12413,[12411,12442]}, + {12497,[12495,12442]}, + {12500,[12498,12442]}, + {12503,[12501,12442]}, + {12506,[12504,12442]}, + {12509,[12507,12442]}}. diff --git a/lib/kernel/test/gen_udp_SUITE.erl b/lib/kernel/test/gen_udp_SUITE.erl index bbdfbd3cb0..2ff1d7210a 100644 --- a/lib/kernel/test/gen_udp_SUITE.erl +++ b/lib/kernel/test/gen_udp_SUITE.erl @@ -423,7 +423,11 @@ connect(Config) when is_list(Config) -> ?line ok = gen_udp:close(S1), ?line ok = gen_udp:connect(S2, Addr, P1), ?line ok = gen_udp:send(S2, <<16#deadbeef:32>>), - ?line {error,econnrefused} = gen_udp:recv(S2, 0, 5), + ?line ok = case gen_udp:recv(S2, 0, 5) of + {error,econnrefused} -> ok; + {error,econnreset} -> ok; + Other -> Other + end, ok. implicit_inet6(Config) when is_list(Config) -> diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index f4f27933a5..ec05bf99b9 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -27,7 +27,7 @@ ipv4_to_ipv6/1, host_and_addr/1, parse/1, t_gethostnative/1, gethostnative_parallell/1, cname_loop/1, gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1, - getif_ifr_name_overflow/1,getservbyname_overflow/1]). + getif_ifr_name_overflow/1,getservbyname_overflow/1,getifaddrs/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0]). @@ -40,7 +40,7 @@ all(suite) -> ipv4_to_ipv6, host_and_addr, parse,t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level,gethostnative_soft_restart, - getif,getif_ifr_name_overflow,getservbyname_overflow]. + getif,getif_ifr_name_overflow,getservbyname_overflow,getifaddrs]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -873,6 +873,14 @@ getif(suite) -> getif(doc) -> ["Tests basic functionality of getiflist, getif, and ifget"]; getif(Config) when is_list(Config) -> + ?line case os:type() of + {unix,Osname} -> + ?line do_getif(Osname); + {_,_} -> + {skip,"inet:getif/0 probably not supported"} + end. + +do_getif(Osname) -> ?line {ok,Hostname} = inet:gethostname(), ?line {ok,Address} = inet:getaddr(Hostname, inet), ?line {ok,Loopback} = inet:getaddr("localhost", inet), @@ -887,7 +895,8 @@ getif(Config) when is_list(Config) -> end end, [], Interfaces)), ?line io:format("HWAs = ~p~n", [HWAs]), - ?line length(HWAs) > 0 orelse ?t:fail(no_HWAs), + ?line (Osname =/= sunos) + andalso ((length(HWAs) > 0) orelse (?t:fail(no_HWAs))), ?line Addresses = lists:sort( lists:foldl( @@ -906,6 +915,14 @@ getif(Config) when is_list(Config) -> getif_ifr_name_overflow(doc) -> "Test long interface names do not overrun buffer"; getif_ifr_name_overflow(Config) when is_list(Config) -> + ?line case os:type() of + {unix,Osname} -> + ?line do_getif_ifr_name_overflow(Osname); + {_,_} -> + {skip,"inet:ifget/2 probably not supported"} + end. + +do_getif_ifr_name_overflow(_) -> %% emulator should not crash ?line {ok,[]} = inet:ifget(lists:duplicate(128, "x"), [addr]), ok. @@ -917,6 +934,112 @@ getservbyname_overflow(Config) when is_list(Config) -> ?line {error,einval} = inet:getservbyname(list_to_atom(lists:flatten(lists:duplicate(128, "x"))), tcp), ok. +getifaddrs(doc) -> + "Test inet:gifaddrs/0"; +getifaddrs(Config) when is_list (Config) -> + ?line {ok,IfAddrs} = inet:getifaddrs(), + ?line ?t:format("IfAddrs = ~p.~n", [IfAddrs]), + ?line + case + {os:type(), + [If || + {If,Opts} <- IfAddrs, + lists:keymember(hwaddr, 1, Opts)]} of + {{unix,sunos},[]} -> ok; + {OT,[]} -> + ?t:fail({should_have_hwaddr,OT}); + _ -> ok + end, + ?line Addrs = + [element(1, A) || A <- ifaddrs(IfAddrs)], + ?line ?t:format("Addrs = ~p.~n", [Addrs]), + ?line [check_addr(Addr) || Addr <- Addrs], + ok. + +check_addr(Addr) + when tuple_size(Addr) =:= 8, + element(1, Addr) band 16#FFC0 =:= 16#FE80 -> + ?line ?t:format("Addr: ~p link local; SKIPPED!~n", [Addr]), + ok; +check_addr(Addr) -> + ?line ?t:format("Addr: ~p.~n", [Addr]), + ?line Ping = "ping", + ?line Pong = "pong", + ?line {ok,L} = gen_tcp:listen(0, [{ip,Addr},{active,false}]), + ?line {ok,P} = inet:port(L), + ?line {ok,S1} = gen_tcp:connect(Addr, P, [{active,false}]), + ?line {ok,S2} = gen_tcp:accept(L), + ?line ok = gen_tcp:send(S2, Ping), + ?line {ok,Ping} = gen_tcp:recv(S1, length(Ping)), + ?line ok = gen_tcp:send(S1, Pong), + ?line ok = gen_tcp:close(S1), + ?line {ok,Pong} = gen_tcp:recv(S2, length(Pong)), + ?line ok = gen_tcp:close(S2), + ?line ok = gen_tcp:close(L), + ok. + +-record(ifopts, {name,flags,addrs=[],hwaddr}). + +ifaddrs([]) -> []; +ifaddrs([{If,Opts}|IOs]) -> + ?line #ifopts{flags=Flags} = Ifopts = + check_ifopts(Opts, #ifopts{name=If}), + ?line case Flags =/= undefined andalso lists:member(up, Flags) of + true -> + Ifopts#ifopts.addrs; + false -> + [] + end++ifaddrs(IOs). + +check_ifopts([], #ifopts{name=If,flags=Flags,addrs=Raddrs}=Ifopts) -> + Addrs = lists:reverse(Raddrs), + R = Ifopts#ifopts{addrs=Addrs}, + ?t:format("~p.~n", [R]), + %% See how we did... + if is_list(Flags) -> ok; + true -> + ?t:fail({flags_undefined,If}) + end, + case lists:member(broadcast, Flags) of + true -> + [case A of + {_,_,_} -> A; + {T,_} when tuple_size(T) =:= 8 -> A; + _ -> + ?t:fail({broaddr_missing,If,A}) + end || A <- Addrs]; + false -> + [case A of {_,_} -> A; + _ -> + ?t:fail({should_have_netmask,If,A}) + end || A <- Addrs] + end, + R; +check_ifopts([{flags,Flags}|Opts], #ifopts{flags=undefined}=Ifopts) -> + check_ifopts(Opts, Ifopts#ifopts{flags=Flags}); +check_ifopts([{flags,Fs}|Opts], #ifopts{flags=Flags}=Ifopts) -> + case Fs of + Flags -> + check_ifopts(Opts, Ifopts#ifopts{}); + _ -> + ?t:fail({multiple_flags,Fs,Ifopts}) + end; +check_ifopts( + [{addr,Addr},{netmask,Netmask},{broadaddr,Broadaddr}|Opts], + #ifopts{addrs=Addrs}=Ifopts) -> + check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr,Netmask,Broadaddr}|Addrs]}); +check_ifopts( + [{addr,Addr},{netmask,Netmask}|Opts], + #ifopts{addrs=Addrs}=Ifopts) -> + check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr,Netmask}|Addrs]}); +check_ifopts([{addr,Addr}|Opts], #ifopts{addrs=Addrs}=Ifopts) -> + check_ifopts(Opts, Ifopts#ifopts{addrs=[{Addr}|Addrs]}); +check_ifopts([{hwaddr,Hwaddr}|Opts], #ifopts{hwaddr=undefined}=Ifopts) + when is_list(Hwaddr) -> + check_ifopts(Opts, Ifopts#ifopts{hwaddr=Hwaddr}); +check_ifopts([{hwaddr,HwAddr}|_], #ifopts{}=Ifopts) -> + ?t:fail({multiple_hwaddrs,HwAddr,Ifopts}). + %% Works just like lists:member/2, except that any {127,_,_,_} tuple %% matches any other {127,_,_,_}. We do this to handle Linux systems %% that use (for instance) 127.0.1.1 as the IP address for the hostname. diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl index ace9501d18..eacf3c7584 100644 --- a/lib/kernel/test/os_SUITE.erl +++ b/lib/kernel/test/os_SUITE.erl @@ -204,8 +204,9 @@ evil(Config) when is_list(Config) -> evil_loop(Parent, ?EVIL_LOOPS,N) end) end, lists:seq(1, ?EVIL_PROCS)), - Devil = spawn(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end), + Devil = spawn_link(fun () -> devil(hd(Ps), hd(lists:reverse(Ps))) end), lists:foreach(fun (P) -> receive {P, done} -> ok end end, Ps), + unlink(Devil), exit(Devil, kill), test_server:timetrap_cancel(Dog), ok. diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 651d082379..03fe63e385 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 2.14.1 +KERNEL_VSN = 2.14.2 diff --git a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc index 0714c7b645..2e2cc386b7 100644 --- a/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc +++ b/lib/mnesia/doc/src/Mnesia_chap2.xmlsrc @@ -235,9 +235,7 @@ <seealso marker="Mnesia_chap3#start_mnesia">Starting Mnesia</seealso>. </item> </list> - <p>Continuing the dialogue with the Erlang shell will produce the following - the following: - </p> + <p>Continuing the dialogue with the Erlang shell will produce the following:</p> <pre><![CDATA[ 3> company:init(). {atomic,ok} @@ -418,7 +416,7 @@ In_proj</tcaption> interchangeably throughout this book. </p> <p>A Mnesia table is populated by Mnesia records. For example, - the tuple <c>{boss, klacke, bjarne}</c> is an record. The + the tuple <c>{boss, klacke, bjarne}</c> is a record. The second element in this tuple is the key. In order to uniquely identify a table row both the key and the table name is needed. The term <em>object identifier</em>, @@ -553,7 +551,7 @@ In_proj</tcaption> stored in the database: </p> <pre> -\011 mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]). +mnesia:select(employee, [{#employee{sex = female, name = '$1', _ = '_'},[], ['$1']}]). </pre> <p>Select must always run within an activity such as a transaction. To be able to call from the shell we might @@ -587,8 +585,8 @@ In_proj</tcaption> </p> <pre> Q = qlc:q([E#employee.name || E <![CDATA[<-]]> mnesia:table(employee), -\011 E#employee.sex == female]), -\011 qlc:e(Q), + E#employee.sex == female]), + qlc:e(Q), </pre> <p>Accessing mnesia tables from a QLC list comprehension must always be done within a transaction. Consider the following diff --git a/lib/mnesia/doc/src/Mnesia_chap3.xml b/lib/mnesia/doc/src/Mnesia_chap3.xml index 9a382bcb5a..2db9af9cf7 100644 --- a/lib/mnesia/doc/src/Mnesia_chap3.xml +++ b/lib/mnesia/doc/src/Mnesia_chap3.xml @@ -132,7 +132,7 @@ function changes the format on all records in table <c>Tab</c>. It applies the argument <c>Fun</c> to all records in the table. <c>Fun</c> shall be a function which - takes an record of the old type, and returns the record of the new + takes a record of the old type, and returns the record of the new type. The table key may not be changed.</p> <code type="none"> -record(old, {key, val}). @@ -418,8 +418,8 @@ skeppet %<input>erl -sname b -mnesia dir '"/ldisc/scratch/Mnesia.company"'</inpu type <c>set</c> and <c>bag</c>: </p> <pre> f() -> F = fun() -> -\011 mnesia:write({foo, 1, 2}), mnesia:write({foo, 1, 3}), -\011 mnesia:read({foo, 1}) end, mnesia:transaction(F). </pre> + mnesia:write({foo, 1, 2}), mnesia:write({foo, 1, 3}), + mnesia:read({foo, 1}) end, mnesia:transaction(F). </pre> <p>This transaction will return the list <c>[{foo,1,3}]</c> if the <c>foo</c> table is of type <c>set</c>. However, list <c>[{foo,1,2}, {foo,1,3}]</c> will return if the table is diff --git a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc index 7d89c1b0dd..6e8055326b 100644 --- a/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc +++ b/lib/mnesia/doc/src/Mnesia_chap4.xmlsrc @@ -514,13 +514,13 @@ The behavior is undefined if any process perform a write of the table itself. This is an implementation detail, but remember the dirty functions are low level functions. </item> - <item><c>mnesia:dirty_last(Tab)</c> This function works exactly as + <item><c>mnesia:dirty_last(Tab)</c> This function works exactly like <c>mnesia:dirty_first/1</c> but returns the last object in Erlang term order for the <c>ordered_set</c> table type. For all other table types, <c>mnesia:dirty_first/1</c> and <c>mnesia:dirty_last/1</c> are synonyms. </item> - <item><c>mnesia:dirty_prev(Tab, Key)</c> This function works exactly as + <item><c>mnesia:dirty_prev(Tab, Key)</c> This function works exactly like <c>mnesia:dirty_next/2</c> but returns the previous object in Erlang term order for the ordered_set table type. For all other table types, <c>mnesia:dirty_next/2</c> and diff --git a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc index 1c7e3662e1..30a8991465 100644 --- a/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc +++ b/lib/mnesia/doc/src/Mnesia_chap5.xmlsrc @@ -335,7 +335,7 @@ ok explicitly be set at table creation. The default is <c>0</c>, but if <c>n_disc_copies</c> and <c>n_disc_only_copies</c> also are <c>0</c>, - <c>n_ram_copies</c>\011will default be set to <c>1</c>. + <c>n_ram_copies</c> will default be set to <c>1</c>. </p> </item> <tag><c>{n_disc_copies, Int}</c></tag> @@ -408,7 +408,7 @@ ok (a@sam)4> SecProps = [{foreign_key, {prim_dict, sec_val}}]. [{foreign_key,{prim_dict,sec_val}}] (a@sam)5> mnesia:create_table(sec_dict, -\011 [{frag_properties, SecProps}, + [{frag_properties, SecProps}, (a@sam)5> {attributes, [sec_key, sec_val]}]). {atomic,ok} (a@sam)6> Write = fun(Rec) -> mnesia:write(Rec) end. @@ -418,23 +418,23 @@ ok (a@sam)8> SecKey = 42. 42 (a@sam)9> mnesia:activity(sync_dirty, Write, -\011\011 [{prim_dict, PrimKey, -11}], mnesia_frag). + [{prim_dict, PrimKey, -11}], mnesia_frag). ok (a@sam)10> mnesia:activity(sync_dirty, Write, -\011\011 [{sec_dict, SecKey, PrimKey}], mnesia_frag). + [{sec_dict, SecKey, PrimKey}], mnesia_frag). ok (a@sam)11> mnesia:change_table_frag(prim_dict, {add_frag, [node()]}). {atomic,ok} (a@sam)12> SecRead = fun(PrimKey, SecKey) -> -\011\011 mnesia:read({sec_dict, PrimKey}, SecKey, read) end. + mnesia:read({sec_dict, PrimKey}, SecKey, read) end. #Fun<erl_eval> (a@sam)13> mnesia:activity(transaction, SecRead, -\011\011 [PrimKey, SecKey], mnesia_frag). + [PrimKey, SecKey], mnesia_frag). [{sec_dict,42,11}] (a@sam)14> Info = fun(Tab, Item) -> mnesia:table_info(Tab, Item) end. #Fun<erl_eval> (a@sam)15> mnesia:activity(sync_dirty, Info, -\011\011 [prim_dict, frag_size], mnesia_frag). + [prim_dict, frag_size], mnesia_frag). [{prim_dict,0}, {prim_dict_frag2,0}, {prim_dict_frag3,0}, @@ -444,7 +444,7 @@ ok {prim_dict_frag7,0}, {prim_dict_frag8,0}] (a@sam)16> mnesia:activity(sync_dirty, Info, -\011\011 [sec_dict, frag_size], mnesia_frag). + [sec_dict, frag_size], mnesia_frag). [{sec_dict,0}, {sec_dict_frag2,0}, {sec_dict_frag3,0}, @@ -1051,7 +1051,7 @@ ok ActivityID will be received. Note that this event may still be received even if no table events with a corresponding ActivityID were received, depending on the tables to which the receiving process is subscribed.</p> - <p>Dirty operations always only contain one update and thus no activity event is sent.</p> + <p>Dirty operations always only contain one update and thus no activity event is sent.</p> </item> </taglist> </section> diff --git a/lib/mnesia/doc/src/mnesia.xml b/lib/mnesia/doc/src/mnesia.xml index 5d3bcf830e..16e78ea0af 100644 --- a/lib/mnesia/doc/src/mnesia.xml +++ b/lib/mnesia/doc/src/mnesia.xml @@ -799,7 +799,7 @@ mnesia:change_table_copy_type(person, node(), disc_copies) </item> <item> <p><c>{local_content, Bool}</c>, where <c>Bool</c> must be - either <c>true</c> or <c>false</c>. The default value is <c>false</c>.\011 </p> + either <c>true</c> or <c>false</c>. The default value is <c>false</c>.</p> </item> </list> <p>For example, the following call creates the <c>person</c> table @@ -1022,7 +1022,7 @@ mnesia:create_table(person, <name>dirty_last(Tab) -> Key | exit({aborted, Reason}) </name> <fsummary>Return the key for the last record in a table.</fsummary> <desc> - <p>This function works exactly + <p>This function works exactly like <c>mnesia:dirty_first/1</c> but returns the last object in Erlang term order for the <c>ordered_set</c> table type. For all other table types, <c>mnesia:dirty_first/1</c> and @@ -1063,11 +1063,11 @@ mnesia:create_table(person, <name>dirty_prev(Tab, Key) -> Key | exit({aborted, Reason}) </name> <fsummary>Return the previous key in a table. </fsummary> <desc> - <p>This function works exactly + <p>This function works exactly like <c>mnesia:dirty_next/2</c> but returns the previous object in Erlang term order for the ordered_set table type. For all other table types, <c>mnesia:dirty_next/2</c> and - <c>mnesia:dirty_prev/2</c> are synonyms.\011 </p> + <c>mnesia:dirty_prev/2</c> are synonyms.</p> </desc> </func> <func> @@ -1334,7 +1334,7 @@ mnesia:create_table(person, <name>foldr(Function, Acc, Table) -> NewAcc | transaction abort </name> <fsummary>Call Function for each record in Table </fsummary> <desc> - <p>This function works exactly as + <p>This function works exactly like <c>foldl/3</c> but iterates the table in the opposite order for the <c>ordered_set</c> table type. For all other table types, <c>foldr/3</c> and @@ -1512,14 +1512,14 @@ mnesia:create_table(person, <fsummary>Check if code is running in a transaction.</fsummary> <desc> <p>When this function is executed inside a transaction context - it returns <c>true</c>, otherwise <c>false</c>.</p> + it returns <c>true</c>, otherwise <c>false</c>.</p> </desc> </func> <func> <name>last(Tab) -> Key | transaction abort </name> <fsummary>Return the key for the last record in a table.</fsummary> <desc> - <p>This function works exactly + <p>This function works exactly like <c>mnesia:first/1</c> but returns the last object in Erlang term order for the <c>ordered_set</c> table type. For all other table types, <c>mnesia:first/1</c> and @@ -1698,11 +1698,11 @@ mnesia:create_table(person, <name>prev(Tab, Key) -> Key | transaction abort </name> <fsummary>Return the previous key in a table. </fsummary> <desc> - <p>This function works exactly + <p>This function works exactly like <c>mnesia:next/2</c> but returns the previous object in Erlang term order for the ordered_set table type. For all other table types, <c>mnesia:next/2</c> and - <c>mnesia:prev/2</c> are synonyms.\011 </p> + <c>mnesia:prev/2</c> are synonyms.</p> </desc> </func> <func> @@ -1891,10 +1891,10 @@ mnesia:create_table(person, <p>For example to find the names of all male persons with an age over 30 in table Tab do:</p> <code type="none"> -\011 MatchHead = #person{name='$1', sex=male, age='$2', _='_'}, -\011 Guard = {'>', '$2', 30}, -\011 Result = '$1', -\011 mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]), +MatchHead = #person{name='$1', sex=male, age='$2', _='_'}, +Guard = {'>', '$2', 30}, +Result = '$1', +mnesia:select(Tab,[{MatchHead, [Guard], [Result]}]), </code> </desc> </func> @@ -2835,7 +2835,7 @@ raise(Name, Amount) -> </func> <func> <name>write(Tab, Record, LockKind) -> transaction abort | ok </name> - <fsummary>Write an record into the database.</fsummary> + <fsummary>Write a record into the database.</fsummary> <desc> <p>Writes the record <c>Record</c> to the table <c>Tab</c>. </p> diff --git a/lib/mnesia/src/mnesia.appup.src b/lib/mnesia/src/mnesia.appup.src index 47c9bf9979..22ef5178a7 100644 --- a/lib/mnesia/src/mnesia.appup.src +++ b/lib/mnesia/src/mnesia.appup.src @@ -1,7 +1,13 @@ %% -*- erlang -*- {"%VSN%", [ + {"4.4.15",[ + {update, mnesia_dumper, soft, soft_purge, soft_purge, []} + ]} ], [ + {"4.4.15",[ + {update, mnesia_dumper, soft, soft_purge, soft_purge, []} + ]} ] }. diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl index 0298b382a6..021be8af2a 100644 --- a/lib/mnesia/src/mnesia_controller.erl +++ b/lib/mnesia/src/mnesia_controller.erl @@ -98,6 +98,8 @@ connect_nodes2/3 ]). +-compile({no_auto_import,[error/2]}). + -import(mnesia_lib, [set/2, add/2]). -import(mnesia_lib, [fatal/2, error/2, verbose/2, dbg_out/2]). diff --git a/lib/mnesia/src/mnesia_dumper.erl b/lib/mnesia/src/mnesia_dumper.erl index f669d009c6..644133cf5d 100644 --- a/lib/mnesia/src/mnesia_dumper.erl +++ b/lib/mnesia/src/mnesia_dumper.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -643,7 +643,7 @@ insert_op(Tid, _, {op, create_table, TabDef}, InPlace, InitBy) -> true -> ignore; false -> mnesia_log:open_log(temp, - mnesia_log:dcl_log_header(), + mnesia_log:dcd_log_header(), Dcd, false, false, diff --git a/lib/mnesia/src/mnesia_locker.erl b/lib/mnesia/src/mnesia_locker.erl index cfa3f171b2..6b5770d91e 100644 --- a/lib/mnesia/src/mnesia_locker.erl +++ b/lib/mnesia/src/mnesia_locker.erl @@ -49,6 +49,8 @@ system_code_change/4 ]). +-compile({no_auto_import,[error/2]}). + -include("mnesia.hrl"). -import(mnesia_lib, [dbg_out/2, error/2, verbose/2]). diff --git a/lib/mnesia/src/mnesia_log.erl b/lib/mnesia/src/mnesia_log.erl index 00ec4740ee..11b792026e 100644 --- a/lib/mnesia/src/mnesia_log.erl +++ b/lib/mnesia/src/mnesia_log.erl @@ -182,6 +182,8 @@ ]). +-compile({no_auto_import,[error/2]}). + -include("mnesia.hrl"). -import(mnesia_lib, [val/1, dir/1]). -import(mnesia_lib, [exists/1, fatal/2, error/2, dbg_out/2]). diff --git a/lib/mnesia/src/mnesia_monitor.erl b/lib/mnesia/src/mnesia_monitor.erl index 5bd93d6b9b..b6eda9ad3a 100644 --- a/lib/mnesia/src/mnesia_monitor.erl +++ b/lib/mnesia/src/mnesia_monitor.erl @@ -70,6 +70,8 @@ negotiate_protocol_impl/2 ]). +-compile({no_auto_import,[error/2]}). + -import(mnesia_lib, [dbg_out/2, verbose/2, error/2, fatal/2, set/2]). -include("mnesia.hrl"). diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl index 0ca7bf3f7f..7435b6896a 100644 --- a/lib/mnesia/src/mnesia_recover.erl +++ b/lib/mnesia/src/mnesia_recover.erl @@ -62,6 +62,7 @@ code_change/3 ]). +-compile({no_auto_import,[error/2]}). -include("mnesia.hrl"). -import(mnesia_lib, [set/2, verbose/2, error/2, fatal/2]). diff --git a/lib/mnesia/src/mnesia_subscr.erl b/lib/mnesia/src/mnesia_subscr.erl index 93d4a86f7f..415c69d508 100644 --- a/lib/mnesia/src/mnesia_subscr.erl +++ b/lib/mnesia/src/mnesia_subscr.erl @@ -43,6 +43,8 @@ code_change/3 ]). +-compile({no_auto_import,[error/2]}). + -include("mnesia.hrl"). -import(mnesia_lib, [error/2]). diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index bce0f7b739..5b52bc6075 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.4.15 +MNESIA_VSN = 4.4.16 diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile index dde1ea17be..b4eb518dd7 100644 --- a/lib/observer/src/Makefile +++ b/lib/observer/src/Makefile @@ -111,7 +111,8 @@ release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/src $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/examples + $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples $(INSTALL_DIR) $(RELSYSDIR)/include $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include $(INSTALL_DIR) $(RELSYSDIR)/ebin diff --git a/lib/odbc/c_src/odbcserver.c b/lib/odbc/c_src/odbcserver.c index c9627e9d05..077d78bfe5 100644 --- a/lib/odbc/c_src/odbcserver.c +++ b/lib/odbc/c_src/odbcserver.c @@ -108,8 +108,8 @@ #if defined WIN32 #include <winsock2.h> -/* #include <ws2tcpip.h > When we can support a newer c-compiler*/ #include <windows.h> +#include <ws2tcpip.h > #include <fcntl.h> #include <sql.h> #include <sqlext.h> @@ -1599,7 +1599,7 @@ static Boolean decode_params(db_state *state, byte *buffer, int *index, param_ar break; case SQL_C_TYPE_TIMESTAMP: ts = (TIMESTAMP_STRUCT*) param->values.string; - ei_decode_tuple_header(buffer, index, &val); + ei_decode_tuple_header(buffer, index, &size); ei_decode_long(buffer, index, &val); ts[j].year = (SQLUSMALLINT)val; ei_decode_long(buffer, index, &val); @@ -1727,74 +1727,48 @@ static byte * receive_erlang_port_msg(void) } /* ------------- Socket communication functions --------------------------*/ -#define USE_IPV4 -#ifdef UNIX -#define SOCKET int -#endif -#if defined WIN32 || defined USE_IPV4 -/* Currently only an old windows compiler is supported so we do not have ipv6 - capabilities */ +#if defined(WIN32) static SOCKET connect_to_erlang(const char *port) -{ - SOCKET sock; - struct sockaddr_in sin; - - sock = socket(AF_INET, SOCK_STREAM, 0); - - memset(&sin, 0, sizeof(sin)); - sin.sin_port = htons ((unsigned short)atoi(port)); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = inet_addr("127.0.0.1"); - - if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) { - close_socket(sock); - DO_EXIT(EXIT_SOCKET_CONNECT); - } - return sock; -} #elif defined(UNIX) static int connect_to_erlang(const char *port) +#endif { - int sock; - - struct addrinfo hints; - struct addrinfo *erlang_ai, *first; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - if (getaddrinfo("localhost", port, &hints, &first) != 0) { - DO_EXIT(EXIT_FAILURE); - } +#if defined(WIN32) + SOCKET sock; +#elif defined(UNIX) + int sock; +#endif + struct sockaddr_in sin; + +#if defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_ADDR) && defined(AF_INET6) + struct sockaddr_in6 sin6; + + sock = socket(AF_INET6, SOCK_STREAM, 0); + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_port = htons ((unsigned short)atoi(port)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = in6addr_loopback; - for (erlang_ai = first; erlang_ai; erlang_ai = erlang_ai->ai_next) { + if (connect(sock, (struct sockaddr*)&sin6, sizeof(sin6)) == 0) { + return sock; + } + close_socket(sock); +#endif + sock = socket(AF_INET, SOCK_STREAM, 0); + + memset(&sin, 0, sizeof(sin)); + sin.sin_port = htons ((unsigned short)atoi(port)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - sock = socket(erlang_ai->ai_family, erlang_ai->ai_socktype, - erlang_ai->ai_protocol); - if (sock < 0) - continue; - if (connect(sock, (struct sockaddr*)erlang_ai->ai_addr, - erlang_ai->ai_addrlen) < 0) { - close(sock); - sock = -1; - continue; - } else { - break; + if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) { + close_socket(sock); + DO_EXIT(EXIT_SOCKET_CONNECT); } - } - freeaddrinfo(first); - - if (sock < 0){ - close_socket(sock); - DO_EXIT(EXIT_SOCKET_CONNECT); - } - - return sock; + return sock; } -#endif #ifdef WIN32 static void close_socket(SOCKET socket) @@ -2177,9 +2151,9 @@ static void init_param_column(param_array *params, byte *buffer, int *index, params->type.sql = SQL_TYPE_TIMESTAMP; params->type.len = sizeof(TIMESTAMP_STRUCT); params->type.c = SQL_C_TYPE_TIMESTAMP; - params->type.col_size = (SQLUINTEGER)19;//;sizeof(TIMESTAMP_STRUCT); + params->type.col_size = (SQLUINTEGER)COL_SQL_TIMESTAMP; params->values.string = - (TIMESTAMP_STRUCT *)safe_malloc(num_param_values * params->type.len); + (byte *)safe_malloc(num_param_values * params->type.len); break; case USER_FLOAT: params->type.sql = SQL_FLOAT; diff --git a/lib/odbc/c_src/odbcserver.h b/lib/odbc/c_src/odbcserver.h index e6d8df1f58..3e2b22ab7d 100644 --- a/lib/odbc/c_src/odbcserver.h +++ b/lib/odbc/c_src/odbcserver.h @@ -98,6 +98,7 @@ #define COL_SQL_REAL 7 #define COL_SQL_DOUBLE 15 #define COL_SQL_TINYINT 4 +#define COL_SQL_TIMESTAMP 19 /* Types of parameters given to param_query*/ #define USER_SMALL_INT 1 diff --git a/lib/odbc/configure.in b/lib/odbc/configure.in index 94e8a214d4..2369e16813 100644 --- a/lib/odbc/configure.in +++ b/lib/odbc/configure.in @@ -118,11 +118,18 @@ AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, main, [LIBS="$LIBS -lnsl"])) dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h]) +AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h winsock2.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T +AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_addr], [], [], + [#if HAVE_WINSOCK2_H + #include <winsock2.h> + #include <ws2tcpip.h> + #else + #include <netinet/in.h> + #endif]) dnl Checks for library functions. AC_CHECK_FUNCS([memset socket]) diff --git a/lib/odbc/src/odbc.appup.src b/lib/odbc/src/odbc.appup.src index e95e542ff5..f1a370d925 100644 --- a/lib/odbc/src/odbc.appup.src +++ b/lib/odbc/src/odbc.appup.src @@ -1 +1,8 @@ -{"%VSN%", [],[]} +%% -*- erlang -*- +{"%VSN%", + [ + {"2.10.8", [{restart_application, ssl}]} + ], + [ + {"2.10.8", [{restart_application, ssl}]} + ]}. diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl index eb27a471ec..83d9f33102 100644 --- a/lib/odbc/src/odbc.erl +++ b/lib/odbc/src/odbc.erl @@ -441,10 +441,12 @@ init(Args) -> {ok, ListenSocketSup} = gen_tcp:listen(0, [Inet, binary, {packet, ?LENGTH_INDICATOR_SIZE}, - {active, false}, {nodelay, true}]), + {active, false}, {nodelay, true}, + {ip, loopback}]), {ok, ListenSocketOdbc} = gen_tcp:listen(0, [Inet, binary, {packet, ?LENGTH_INDICATOR_SIZE}, - {active, false}, {nodelay, true}]), + {active, false}, {nodelay, true}, + {ip, loopback}]), %% Start the port program (a c program) that utilizes the odbc driver case os:find_executable(?SERVERPROG, ?SERVERDIR) of diff --git a/lib/odbc/vsn.mk b/lib/odbc/vsn.mk index fac3f06d4b..aacf3924db 100644 --- a/lib/odbc/vsn.mk +++ b/lib/odbc/vsn.mk @@ -1 +1 @@ -ODBC_VSN = 2.10.8 +ODBC_VSN = 2.10.9 diff --git a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl index 7792839e22..768653c898 100644 --- a/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl +++ b/lib/orber/COSS/CosNaming/orber_cosnaming_utils.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -536,8 +536,15 @@ lookup(_, _Ctx) -> receive_msg(Socket, Acc, Timeout) -> receive {tcp_closed, Socket} -> - [_Header, Body] = re:split(Acc,"\r\n\r\n",[{return,list}]), - Body; + case re:split(Acc,"\r\n\r\n",[{return,list}]) of + [_Header, Body] -> + Body; + What -> + orber:dbg("[~p] orber_cosnaming_utils:receive_msg();~n" + "HTTP server closed the connection before sending a complete reply: ~p.", + [?LINE, What], ?DEBUG_LEVEL), + corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_NO}) + end; {tcp, Socket, Response} -> receive_msg(Socket, Acc ++ Response, Timeout); {tcp_error, Socket, Reason} -> diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml index 17f7ac8270..6eda16a517 100644 --- a/lib/orber/doc/src/notes.xml +++ b/lib/orber/doc/src/notes.xml @@ -32,23 +32,41 @@ <file>notes.xml</file> </header> - <section><title>Orber 3.6.17</title> + <section> + <title>Orber 3.6.18</title> + <section> + <title>Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>A corbaloc http string could return an EXIT message, instead + of a system exception, if the HTTP server closed the socket + without returning a complete message. I.e. header and a body + containing a stringified IOR.</p> + <p>Own Id: OTP-8900 Aux Id: seq11704</p> + </item> + </list> + </section> + </section> - <section><title>Improvements and New Features</title> - <list> + <section> + <title>Orber 3.6.17</title> + + <section> + <title>Improvements and New Features</title> + <list type="bulleted"> <item> <p> - Eliminated warnings for auto-imported BIF clashes.</p> + Eliminated warnings for auto-imported BIF clashes.</p> <p> - Own Id: OTP-8840</p> + Own Id: OTP-8840</p> </item> </list> </section> + </section> -</section> - -<section> + <section> <title>Orber 3.6.16</title> + <section> <title>Improvements and New Features</title> <list type="bulleted"> @@ -56,16 +74,17 @@ <p> Test suites published.</p> <p> - Own Id: OTP-8543 Aux Id:</p> + Own Id: OTP-8543O Aux Id:</p> </item> </list> </section> + <section> <title>Fixed Bugs and Malfunctions</title> <list type="bulleted"> <item> <p>Added missing trailing bracket to define in hrl-file.</p> - <p>Own id: OTP-8489 Aux Id:</p> + <p>Own Id: OTP-8489 Aux Id:</p> </item> </list> </section> @@ -104,11 +123,11 @@ <list type="bulleted"> <item> <p>Removed superfluous VT in the documentation.</p> - <p>Own id: OTP-8353 Aux Id:</p> + <p>Own Id: OTP-8353 Aux Id:</p> </item> <item> <p>Removed superfluous backslash in the documentation.</p> - <p>Own id: OTP-8354 Aux Id:</p> + <p>Own Id: OTP-8354 Aux Id:</p> </item> </list> </section> @@ -140,7 +159,7 @@ <item> <p>Obsolete guards, e.g. record vs is_record, has been changed to avoid compiler warnings.</p> - <p>Own id: OTP-7987</p> + <p>Own Id: OTP-7987</p> </item> </list> </section> @@ -158,7 +177,7 @@ Naming Service (INS) instead. INS is a part of the OMG standard specification.</p> <p>*** POTENTIAL INCOMPATIBILITY ***</p> - <p>Own id: OTP-7906 Aux Id: seq11243</p> + <p>Own Id: OTP-7906 Aux Id: seq11243</p> </item> </list> </section> @@ -172,7 +191,7 @@ <list type="bulleted"> <item> <p>Updated file headers.</p> - <p>Own id: OTP-7837</p> + <p>Own Id: OTP-7837</p> </item> </list> </section> @@ -186,7 +205,7 @@ <list type="bulleted"> <item> <p>Documentation source included in open source releases.</p> - <p>Own id: OTP-7595</p> + <p>Own Id: OTP-7595</p> </item> </list> </section> @@ -200,11 +219,11 @@ <list type="bulleted"> <item> <p>Updated file headers.</p> - <p>Own id: OTP-7011</p> + <p>Own Id: OTP-7011</p> </item> <item> <p>Now compliant with the new behavior of stdlib.</p> - <p>Own id: OTP-7030 Aux Id: seq10827</p> + <p>Own Id: OTP-7030 Aux Id: seq10827</p> </item> </list> </section> diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index 681b82b51b..584a52ab84 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1 +1 @@ -ORBER_VSN = 3.6.17 +ORBER_VSN = 3.6.18 diff --git a/lib/parsetools/include/yeccpre.hrl b/lib/parsetools/include/yeccpre.hrl index 39dea0552d..80a3afbdb6 100644 --- a/lib/parsetools/include/yeccpre.hrl +++ b/lib/parsetools/include/yeccpre.hrl @@ -167,7 +167,7 @@ yecctoken2string({char,_,C}) -> io_lib:write_char(C); yecctoken2string({var,_,V}) -> io_lib:format("~s", [V]); yecctoken2string({string,_,S}) -> io_lib:write_unicode_string(S); yecctoken2string({reserved_symbol, _, A}) -> io_lib:write(A); -yecctoken2string({_Cat, _, Val}) -> io_lib:write(Val); +yecctoken2string({_Cat, _, Val}) -> io_lib:format("~p",[Val]); yecctoken2string({dot, _}) -> "'.'"; yecctoken2string({'$end', _}) -> []; diff --git a/lib/parsetools/test/yecc_SUITE.erl b/lib/parsetools/test/yecc_SUITE.erl index 93949a074a..8153be7e61 100644 --- a/lib/parsetools/test/yecc_SUITE.erl +++ b/lib/parsetools/test/yecc_SUITE.erl @@ -46,7 +46,7 @@ bugs/1, otp_5369/1, otp_6362/1, otp_7945/1, otp_8483/1, otp_8486/1, improvements/1, - otp_7292/1, otp_7969/1]). + otp_7292/1, otp_7969/1, otp_8919/1]). % Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). @@ -1541,7 +1541,7 @@ otp_8486(Config) when is_list(Config) -> ok. improvements(suite) -> - [otp_7292, otp_7969]. + [otp_7292, otp_7969, otp_8919]. otp_7292(doc) -> "OTP-7292. Header declarations for edoc."; @@ -1773,6 +1773,14 @@ otp_7969(Config) when is_list(Config) -> ?line {error,{{1,11},erl_parse,_}} = erl_parse:parse_and_scan({F6, []}), ok. +otp_8919(doc) -> + "OTP-8919. Improve formating of Yecc error messages."; +otp_8919(suite) -> []; +otp_8919(Config) when is_list(Config) -> + {error,{1,Mod,Mess}} = erl_parse:parse([{cat,1,"hello"}]), + "syntax error before: \"hello\"" = lists:flatten(Mod:format_error(Mess)), + ok. + yeccpre_size() -> yeccpre_size(default_yeccpre()). diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1 index c0cf440496..ad704191a9 100644 --- a/lib/public_key/asn1/OTP-PKIX.asn1 +++ b/lib/public_key/asn1/OTP-PKIX.asn1 @@ -302,18 +302,25 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= { -- DSA Keys and Signatures + + DSAParams ::= CHOICE + { + params Dss-Parms, + null NULL + } + -- SubjectPublicKeyInfo: dsa PUBLIC-KEY-ALGORITHM-CLASS ::= { ID id-dsa - TYPE Dss-Parms -- XXX Must be OPTIONAL + TYPE DSAParams -- XXX Must be OPTIONAL PUBLIC-KEY-TYPE DSAPublicKey } -- Certificate.signatureAlgorithm dsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= { - ID id-dsa-with-sha1 - TYPE Dss-Parms } + ID id-dsa-with-sha1 + TYPE DSAParams } -- -- RSA Keys and Signatures diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index baa0e6c464..6e7381eb18 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -1,11 +1,11 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> <year>2008</year> - <year>2008</year> + <year>2010</year> <holder>Ericsson AB, All Rights Reserved</holder> </copyright> <legalnotice> @@ -34,6 +34,55 @@ <file>notes.xml</file> </header> +<section><title>Public_Key 0.9</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Updated ssl to ignore CA certs that violate the asn1-spec + for a certificate, and updated public key asn1 spec to + handle inherited DSS-params.</p> + <p> + Own Id: OTP-7884</p> + </item> + <item> + <p> + Changed ssl implementation to retain backwards + compatibility for old option {verify, 0} that shall be + equivalent to {verify, verify_none}, also separate the + cases unknown ca and selfsigned peer cert, and restored + return value of deprecated function + public_key:pem_to_der/1.</p> + <p> + Own Id: OTP-8858</p> + </item> + <item> + <p> + Better handling of v1 and v2 certificates. V1 and v2 + certificates does not have any extensions so then + validate_extensions should just accept that there are + none and not end up in missing_basic_constraints clause.</p> + <p> + Own Id: OTP-8867</p> + </item> + <item> + <p> + Changed the verify fun so that it differentiate between + the peer certificate and CA certificates by using + valid_peer or valid as the second argument to the verify + fun. It may not always be trivial or even possible to + know when the peer certificate is reached otherwise.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8873</p> + </item> + </list> + </section> + +</section> + <section><title>Public_Key 0.8</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl index a16eb10fe6..4950597fb5 100644 --- a/lib/public_key/include/public_key.hrl +++ b/lib/public_key/include/public_key.hrl @@ -34,6 +34,8 @@ (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> {valid, UserState} end, []}). diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl index e704c168f1..fadb993ed9 100644 --- a/lib/public_key/src/pubkey_cert.erl +++ b/lib/public_key/src/pubkey_cert.erl @@ -164,7 +164,7 @@ validate_signature(OtpCert, DerCert, Key, KeyParams, verify_fun(OtpCert, {bad_cert, invalid_signature}, UserState, VerifyFun) end. %%-------------------------------------------------------------------- --spec validate_names(#'OTPCertificate'{}, list(), list(), +-spec validate_names(#'OTPCertificate'{}, no_constraints | list(), list(), term(), term(), fun())-> term(). %% %% Description: Validate Subject Alternative Name. @@ -223,10 +223,15 @@ validate_revoked_status(_OtpCert, UserState, _VerifyFun) -> %%-------------------------------------------------------------------- validate_extensions(OtpCert, ValidationState, UserState, VerifyFun) -> TBSCert = OtpCert#'OTPCertificate'.tbsCertificate, - Extensions = TBSCert#'OTPTBSCertificate'.extensions, - validate_extensions(OtpCert, Extensions, ValidationState, no_basic_constraint, - is_self_signed(OtpCert), UserState, VerifyFun). - + case TBSCert#'OTPTBSCertificate'.version of + N when N >= 3 -> + Extensions = TBSCert#'OTPTBSCertificate'.extensions, + validate_extensions(OtpCert, Extensions, + ValidationState, no_basic_constraint, + is_self_signed(OtpCert), UserState, VerifyFun); + _ -> %% Extensions not present in versions 1 & 2 + {ValidationState, UserState} + end. %%-------------------------------------------------------------------- -spec normalize_general_name({rdnSequence, term()}) -> {rdnSequence, term()}. %% @@ -290,8 +295,8 @@ is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate = %%-------------------------------------------------------------------- --spec verify_fun(#'OTPTBSCertificate'{}, {bad_cert, atom()} | {extension, #'Extension'{}}| - valid, term(), fun()) -> term(). +-spec verify_fun(#'OTPCertificate'{}, {bad_cert, atom()} | {extension, #'Extension'{}}| + valid | valid_peer, term(), fun()) -> term(). %% %% Description: Gives the user application the opportunity handle path %% validation errors and unknown extensions and optional do other @@ -313,7 +318,7 @@ verify_fun(Otpcert, Result, UserState0, VerifyFun) -> {extension, #'Extension'{critical = true}} -> throw({bad_cert, unknown_critical_extension}); _ -> - UserState + UserState end end. @@ -389,10 +394,12 @@ public_key_info(PublicKeyInfo, NewPublicKeyParams = case PublicKeyParams of - 'NULL' when WorkingAlgorithm == Algorithm -> + {null, 'NULL'} when WorkingAlgorithm == Algorithm -> WorkingParams; - _ -> - PublicKeyParams + {params, Params} -> + Params; + Params -> + Params end, {Algorithm, PublicKey, NewPublicKeyParams}. diff --git a/lib/public_key/src/public_key.appup.src b/lib/public_key/src/public_key.appup.src index c9d15b8747..6b6b76d0a5 100644 --- a/lib/public_key/src/public_key.appup.src +++ b/lib/public_key/src/public_key.appup.src @@ -1,29 +1,16 @@ %% -*- erlang -*- {"%VSN%", [ - {"0.7", + {"0.9", [ - {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, - {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} - {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] - }, - {"0.6", - [ - {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} {update, pubkey_cert, soft, soft_purge, soft_purge, []} ] }, - {"0.5", + {"0.8", [ {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, {update, pubkey_pem, soft, soft_purge, soft_purge, []}, {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}, {update, pubkey_cert, soft, soft_purge, soft_purge, []} @@ -31,32 +18,19 @@ } ], [ - {"0.7", - [ - {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, - {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} - {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] - }, - {"0.6", - [ - {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, - {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_pem, soft, soft_purge, soft_purge, []}, - {update, pubkey_cert_records, soft, soft_purge, soft_purge, []} - {update, pubkey_cert, soft, soft_purge, soft_purge, []} - ] - }, - {"0.5", + {"0.9", + [ + {update, public_key, soft, soft_purge, soft_purge, []}, + {update, pubkey_cert, soft, soft_purge, soft_purge, []} + ] + }, + {"0.8", [ {update, 'OTP-PUB-KEY', soft, soft_purge, soft_purge, []}, {update, public_key, soft, soft_purge, soft_purge, []}, - {update, pubkey_crypto, soft, soft_purge, soft_purge, []}, {update, pubkey_pem, soft, soft_purge, soft_purge, []}, {update, pubkey_cert_records, soft, soft_purge, soft_purge, []}, {update, pubkey_cert, soft, soft_purge, soft_purge, []} ] - } + } ]}. diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 9c7817fa8e..30398df9cc 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -213,10 +213,13 @@ decrypt_private(CipherText, crypto:mpint(D)], Padding). %%-------------------------------------------------------------------- --spec decrypt_public(CipherText :: binary(), rsa_public_key()) -> +-spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> PlainText :: binary(). --spec decrypt_public(CipherText :: binary(), rsa_public_key(), +-spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key(), public_crypt_options()) -> PlainText :: binary(). +%% NOTE: The rsa_private_key() is not part of the documented API it is +%% here for testing purposes, in a real situation this is not a relevant +%% thing to do. %% %% Description: Public key decryption using the public key. %%-------------------------------------------------------------------- @@ -232,10 +235,14 @@ decrypt_public(CipherText,#'RSAPrivateKey'{modulus = N, publicExponent = E}, decrypt_public(CipherText, N,E, Options). %%-------------------------------------------------------------------- --spec encrypt_public(PlainText :: binary(), rsa_public_key()) -> +-spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key()) -> CipherText :: binary(). --spec encrypt_public(PlainText :: binary(), rsa_public_key(), +-spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key(), public_crypt_options()) -> CipherText :: binary(). + +%% NOTE: The rsa_private_key() is not part of the documented API it is +%% here for testing purposes, in a real situation this is not a relevant +%% thing to do. %% %% Description: Public key encryption using the public key. %%-------------------------------------------------------------------- @@ -280,8 +287,8 @@ encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, sign(PlainText, DigestType, #'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D}) when is_binary(PlainText), - DigestType == md5; - DigestType == sha -> + (DigestType == md5 orelse + DigestType == sha) -> crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E), crypto:mpint(N), @@ -437,7 +444,7 @@ pkix_normalize_name(Issuer) -> pubkey_cert:normalize_general_name(Issuer). %%-------------------------------------------------------------------- --spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | unknown_ca, +-spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | atom(), CertChain :: [der_encoded()] , Options :: list()) -> {ok, {PublicKeyInfo :: term(), @@ -445,11 +452,11 @@ pkix_normalize_name(Issuer) -> {error, {bad_cert, Reason :: term()}}. %% Description: Performs a basic path validation according to RFC 5280. %%-------------------------------------------------------------------- -pkix_path_validation(unknown_ca, [Cert | Chain], Options0) -> +pkix_path_validation(PathErr, [Cert | Chain], Options0) when is_atom(PathErr)-> {VerifyFun, Userstat0} = proplists:get_value(verify_fun, Options0, ?DEFAULT_VERIFYFUN), Otpcert = pkix_decode_cert(Cert, otp), - Reason = {bad_cert, unknown_ca}, + Reason = {bad_cert, PathErr}, try VerifyFun(Otpcert, Reason, Userstat0) of {valid, Userstate} -> Options = proplists:delete(verify_fun, Options0), @@ -528,7 +535,6 @@ path_validation([DerCert | _] = Path, {error, Reason} end. - validate(DerCert, #path_validation_state{working_issuer_name = Issuer, working_public_key = Key, working_public_key_parameters = @@ -557,26 +563,31 @@ validate(DerCert, #path_validation_state{working_issuer_name = Issuer, %% We want the key_usage extension to be checked before we validate %% the signature. - UserState0 = pubkey_cert:validate_signature(OtpCert, DerCert, + UserState6 = pubkey_cert:validate_signature(OtpCert, DerCert, Key, KeyParams, UserState5, VerifyFun), - UserState = pubkey_cert:verify_fun(OtpCert, valid, UserState0, VerifyFun), + UserState = case Last of + false -> + pubkey_cert:verify_fun(OtpCert, valid, UserState6, VerifyFun); + true -> + pubkey_cert:verify_fun(OtpCert, valid_peer, + UserState6, VerifyFun) + end, + ValidationState = ValidationState1#path_validation_state{user_state = UserState}, pubkey_cert:prepare_for_next_cert(OtpCert, ValidationState). -sized_binary(Binary) when is_binary(Binary) -> +sized_binary(Binary) -> Size = size(Binary), - <<?UINT32(Size), Binary/binary>>; -sized_binary(List) -> - sized_binary(list_to_binary(List)). + <<?UINT32(Size), Binary/binary>>. %%-------------------------------------------------------------------- %%% Deprecated functions %%-------------------------------------------------------------------- pem_to_der(CertSource) -> {ok, Bin} = file:read_file(CertSource), - pubkey_pem:decode(Bin). + {ok, pubkey_pem:decode(Bin)}. decode_private_key(KeyInfo) -> decode_private_key(KeyInfo, no_passwd). diff --git a/lib/public_key/test/erl_make_certs.erl b/lib/public_key/test/erl_make_certs.erl index e31e5552d3..8b01ca3ad4 100644 --- a/lib/public_key/test/erl_make_certs.erl +++ b/lib/public_key/test/erl_make_certs.erl @@ -66,7 +66,7 @@ make_cert(Opts) -> %% @end %%-------------------------------------------------------------------- write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) -> - ok = der_to_pem(filename:join(Dir, FileName ++ ".pem"), + ok = der_to_pem(filename:join(Dir, FileName ++ ".pem"), [{'Certificate', Cert, not_encrypted}]), ok = der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]). @@ -268,7 +268,7 @@ publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> subjectPublicKey = Public}; publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', - parameters=#'Dss-Parms'{p=P, q=Q, g=G}}, + parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}}, #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. validity(Opts) -> @@ -290,7 +290,7 @@ sign_algorithm(#'RSAPrivateKey'{}, Opts) -> end, {Type, 'NULL'}; sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> - {?'id-dsa-with-sha1', #'Dss-Parms'{p=P, q=Q, g=G}}. + {?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}}. make_key(rsa, _Opts) -> %% (OBS: for testing only) diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index ea6a925139..88cfbcf2b6 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -249,10 +249,8 @@ sign_verify(Config) when is_list(Config) -> true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}), %% RSA sign - Msg0 = lists:duplicate(5, "Foo bar 100"), - Msg = list_to_binary(Msg0), + Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), - RSASign = public_key:sign(Msg0, sha, PrivateRSA), RSASign = public_key:sign(Msg, sha, PrivateRSA), true = public_key:verify(Msg, sha, RSASign, PublicRSA), false = public_key:verify(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA), @@ -379,6 +377,8 @@ pkix_path_validation(Config) when is_list(Config) -> (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> {valid, UserState} end, []}, {ok, _} = @@ -411,11 +411,11 @@ deprecated(suite) -> []; deprecated(Config) when is_list(Config) -> Datadir = ?config(data_dir, Config), - [DsaKey = {'DSAPrivateKey', _DsaKey, _}] = + {ok, [DsaKey = {'DSAPrivateKey', _DsaKey, _}]} = public_key:pem_to_der(filename:join(Datadir, "dsa.pem")), - [RsaKey = {'RSAPrivateKey', _RsaKey,_}] = + {ok, [RsaKey = {'RSAPrivateKey', _RsaKey,_}]} = public_key:pem_to_der(filename:join(Datadir, "client_key.pem")), - [ProtectedRsaKey = {'RSAPrivateKey', _ProtectedRsaKey,_}] = + {ok, [ProtectedRsaKey = {'RSAPrivateKey', _ProtectedRsaKey,_}]} = public_key:pem_to_der(filename:join(Datadir, "rsa.pem")), {ok, #'DSAPrivateKey'{}} = public_key:decode_private_key(DsaKey), diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk index f70209d891..334b9d792e 100644 --- a/lib/public_key/vsn.mk +++ b/lib/public_key/vsn.mk @@ -1 +1 @@ -PUBLIC_KEY_VSN = 0.8 +PUBLIC_KEY_VSN = 0.10 diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index 950c249e72..9bedd446f4 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -29,8 +29,52 @@ <file>notes.xml</file> </header> - <section><title>Ssh 2.0.1</title> +<section><title>Ssh 2.0.3</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The fix regarding OTP-8849 was not included in the + previous version as stated.</p> + <p> + Own Id: OTP-8918</p> + </item> + </list> + </section> +</section> +<section><title>Ssh 2.0.2</title> + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + The ssh_system_sup did not catch noproc and shutdown + messages.</p> + <p> + Own Id: OTP-8863</p> + </item> + <item> + <p> + In some cases a crash report was generated when a + connection was closing down. This was caused by a race + condition between two processes.</p> + <p> + Own Id: OTP-8881 Aux Id: seq11656, seq11648 </p> + </item> + </list> + </section> + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + SSH no longer use deprecated public_key functions.</p> + <p> + Own Id: OTP-8849</p> + </item> + </list> + </section> + </section> + <section><title>Ssh 2.0.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> <item> diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src index 21f7508555..9c806bcd03 100644 --- a/lib/ssh/src/ssh.appup.src +++ b/lib/ssh/src/ssh.appup.src @@ -19,9 +19,13 @@ {"%VSN%", [ + {"2.0.2", [{load_module, ssh_file, soft_purge, soft_purge, []}]}, + {"2.0.1", [{restart_application, ssh}]} ], [ - ] + {"2.0.2", [{load_module, ssh_file, soft_purge, soft_purge, []}]}, + {"2.0.1", [{restart_application, ssh}]} + ] }. diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl index d46002c494..0ba11b0a26 100644 --- a/lib/ssh/src/ssh_connection_handler.erl +++ b/lib/ssh/src/ssh_connection_handler.erl @@ -705,11 +705,19 @@ generate_event(<<?BYTE(Byte), _/binary>> = Msg, StateName, Byte == ?SSH_MSG_CHANNEL_REQUEST; Byte == ?SSH_MSG_CHANNEL_SUCCESS; Byte == ?SSH_MSG_CHANNEL_FAILURE -> - ssh_connection_manager:event(Pid, Msg), - State = generate_event_new_state(State0, EncData), - next_packet(State), - {next_state, StateName, State}; + try + ssh_connection_manager:event(Pid, Msg), + State = generate_event_new_state(State0, EncData), + next_packet(State), + {next_state, StateName, State} + catch + exit:{noproc, _Reason} -> + Report = io_lib:format("~p Connection Handler terminated: ~p~n", + [self(), Pid]), + error_logger:info_report(Report), + {stop, normal, State0} + end; generate_event(Msg, StateName, State0, EncData) -> Event = ssh_bits:decode(Msg), State = generate_event_new_state(State0, EncData), diff --git a/lib/ssh/src/ssh_file.erl b/lib/ssh/src/ssh_file.erl index 5572349fe7..13722656db 100755 --- a/lib/ssh/src/ssh_file.erl +++ b/lib/ssh/src/ssh_file.erl @@ -198,12 +198,17 @@ read_public_key_v1(File) -> %% pem_type("ssh-rsa") -> "RSA". read_private_key_v2(File, Type) -> - case catch (public_key:pem_to_der(File)) of - {ok, [{_, Bin, not_encrypted}]} -> - decode_private_key_v2(Bin, Type); - Error -> %% Note we do not handle password encrypted keys at the moment - {error, Error} - end. + case file:read_file(File) of + {ok, PemBin} -> + case catch (public_key:pem_decode(PemBin)) of + [{_, Bin, not_encrypted}] -> + decode_private_key_v2(Bin, Type); + Error -> %% Note we do not handle password encrypted keys at the moment + {error, Error} + end; + {error, Reason} -> + {error, Reason} + end. %% case file:read_file(File) of %% {ok,Bin} -> %% case read_pem(binary_to_list(Bin), pem_type(Type)) of diff --git a/lib/ssh/src/ssh_system_sup.erl b/lib/ssh/src/ssh_system_sup.erl index f4570b8a48..920baaadef 100644 --- a/lib/ssh/src/ssh_system_sup.erl +++ b/lib/ssh/src/ssh_system_sup.erl @@ -85,7 +85,7 @@ start_subsystem(SystemSup, Options) -> supervisor:start_child(SystemSup, Spec). stop_subsystem(SystemSup, SubSys) -> - case lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of + case catch lists:keyfind(SubSys, 2, supervisor:which_children(SystemSup)) of false -> {error, not_found}; {Id, _, _, _} -> diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk index 79fd36cd83..db03168ad9 100644 --- a/lib/ssh/vsn.mk +++ b/lib/ssh/vsn.mk @@ -1,4 +1,5 @@ #-*-makefile-*- ; force emacs to enter makefile-mode -SSH_VSN = 2.0.1 +SSH_VSN = 2.0.3 APP_VSN = "ssh-$(SSH_VSN)" + diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 5f9e436348..756c0d1b1f 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -31,7 +31,47 @@ <p>This document describes the changes made to the SSL application. </p> - <section><title>SSL 4.0.1</title> + <section><title>SSL 4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Updated ssl to ignore CA certs that violate the asn1-spec + for a certificate, and updated public key asn1 spec to + handle inherited DSS-params.</p> + <p> + Own Id: OTP-7884</p> + </item> + <item> + <p> + Changed ssl implementation to retain backwards + compatibility for old option {verify, 0} that shall be + equivalent to {verify, verify_none}, also separate the + cases unknown ca and selfsigned peer cert, and restored + return value of deprecated function + public_key:pem_to_der/1.</p> + <p> + Own Id: OTP-8858</p> + </item> + <item> + <p> + Changed the verify fun so that it differentiate between + the peer certificate and CA certificates by using + valid_peer or valid as the second argument to the verify + fun. It may not always be trivial or even possible to + know when the peer certificate is reached otherwise.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-8873</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 4.0.1</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index d5b7253ef3..ec272379bb 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -114,7 +114,7 @@ <p><c>ciphersuite() = {key_exchange(), cipher(), hash()}</c></p> - <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa + <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa | dh_anon </c></p> <p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc' @@ -170,8 +170,13 @@ <tag>{ciphers, ciphers()}</tag> <item>The cipher suites that should be supported. The function - <c>ciphers_suites/0</c> can be used to find all available - ciphers. + <c>cipher_suites/0</c> can be used to find all available + ciphers. Additionally some anonymous cipher suites ({dh_anon, + rc4_128, md5}, {dh_anon, des_cbc, sha}, {dh_anon, + '3des_ede_cbc', sha}, {dh_anon, aes_128_cbc, sha}, {dh_anon, + aes_256_cbc, sha}) are supported for testing purposes and will + only work if explicitly enabled by this option and they are supported/enabled + by the peer also. </item> <tag>{ssl_imp, ssl_imp()}</tag> @@ -202,10 +207,10 @@ <p>The verification fun should be defined as:</p> <code> -fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} | +fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom()} | {extension, #'Extension'{}}, InitialUserState :: term()) -> - {valid, UserState :: term()} | {fail, Reason :: term()} | - {unknown, UserState :: term()}. + {valid, UserState :: term()} | {valid_peer, UserState :: term()} | + {fail, Reason :: term()} | {unknown, UserState :: term()}. </code> <p>The verify fun will be called during the X509-path @@ -213,10 +218,12 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} | application is encountered. Additionally it will be called when a certificate is considered valid by the path validation to allow access to each certificate in the path to the user - application. - See - <seealso marker="public_key:application">public_key(3)</seealso> - for definition of #'OtpCertificate'{} and #'Extension'{}.</p> + application. Note that the it will differentiate between the + peer certificate and CA certificates by using valid_peer or + valid as the second argument to the verify fun. See <seealso + marker="public_key:cert_records">the public_key User's + Guide</seealso> for definition of #'OTPCertificate'{} and + #'Extension'{}.</p> <p>If the verify callback fun returns {fail, Reason}, the verification process is immediately stopped and an alert is @@ -237,21 +244,23 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} | (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> - {valid, UserState} + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} end, []} </code> <p>The default verify_fun option in verify_none mode:</p> <code> -{fun(_,{bad_cert, unknown_ca}, UserState) -> +{fun(_,{bad_cert, _}, UserState) -> {valid, UserState}; - (_,{bad_cert, _} = Reason, _) -> - {fail, Reason}; (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> - {valid, UserState} + {valid, UserState}; + (_, valid_peer, UserState) -> + {valid, UserState} end, []} </code> @@ -267,13 +276,14 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} | <section> <title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title> - <p>Option described here are client specific or has a slightly different + <p>Options described here are client specific or has a slightly different meaning in the client than in the server.</p> <taglist> <tag>{verify, verify_type()}</tag> - <item> In verify_none mode the x509-path validation error {bad_cert, unknown_ca} - will automatically be accepted. See also the verify_fun option. + <item> In verify_none mode the default behavior will be to + allow all x509-path validation errors. See also the verify_fun + option. </item> <tag>{reuse_sessions, boolean()}</tag> <item>Specifies if client should try to reuse sessions @@ -286,7 +296,7 @@ fun(OtpCert :: #'OtpCertificate'{}, Event :: {bad_cert, Reason :: atom()} | <section> <title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title> - <p>Option described here are server specific or has a slightly different + <p>Options described here are server specific or has a slightly different meaning in the server than in the client.</p> <taglist> diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src index 88cd73be74..51c5289bd2 100644 --- a/lib/ssl/src/ssl.appup.src +++ b/lib/ssl/src/ssl.appup.src @@ -1,32 +1,11 @@ %% -*- erlang -*- {"%VSN%", [ - {"4.0", [{restart_application, ssl}]}, - {"3.11.1", [{restart_application, ssl}]}, - {"3.11", [{restart_application, ssl}]}, - {"3.10", [{restart_application, ssl}]}, - {"3.10.1", [{restart_application, ssl}]}, - {"3.10.2", [{restart_application, ssl}]}, - {"3.10.3", [{restart_application, ssl}]}, - {"3.10.4", [{restart_application, ssl}]}, - {"3.10.5", [{restart_application, ssl}]}, - {"3.10.6", [{restart_application, ssl}]}, - {"3.10.7", [{restart_application, ssl}]}, - {"3.10.8", [{restart_application, ssl}]}, - {"3.10.9", [{restart_application, ssl}]} + {"4.1", [{restart_application, ssl}]}, + {"4.0.1", [{restart_application, ssl}]} ], [ - {"4.0", [{restart_application, ssl}]}, - {"3.11.1", [{restart_application, ssl}]}, - {"3.11", [{restart_application, ssl}]}, - {"3.10", [{restart_application, ssl}]}, - {"3.10.1", [{restart_application, ssl}]}, - {"3.10.2", [{restart_application, ssl}]}, - {"3.10.3", [{restart_application, ssl}]}, - {"3.10.4", [{restart_application, ssl}]}, - {"3.10.5", [{restart_application, ssl}]}, - {"3.10.6", [{restart_application, ssl}]}, - {"3.10.8", [{restart_application, ssl}]}, - {"3.10.9", [{restart_application, ssl}]} + {"4.1", [{restart_application, ssl}]}, + {"4.0.1", [{restart_application, ssl}]} ]}. diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 12dffb413c..7e5929d708 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -190,7 +190,8 @@ transport_accept(#sslsocket{} = ListenSocket, Timeout) -> %%-------------------------------------------------------------------- -spec ssl_accept(#sslsocket{}) -> {ok, #sslsocket{}} | {error, reason()}. --spec ssl_accept(#sslsocket{}, timeout()) -> {ok, #sslsocket{}} | {error, reason()}. +-spec ssl_accept(#sslsocket{}, list() | timeout()) -> {ok, #sslsocket{}} | {error, reason()}. +-spec ssl_accept(port(), list(), timeout()) -> {ok, #sslsocket{}} | {error, reason()}. %% %% Description: Performs accept on a ssl listen socket. e.i. performs %% ssl handshake. @@ -463,11 +464,102 @@ versions() -> %%--------------------------------------------------------------- -spec renegotiate(#sslsocket{}) -> ok | {error, reason()}. %% -%% Description: +%% Description: Initiates a renegotiation. %%-------------------------------------------------------------------- renegotiate(#sslsocket{pid = Pid, fd = new_ssl}) -> ssl_connection:renegotiation(Pid). +%%--------------------------------------------------------------- +-spec format_error({error, term()}) -> list(). +%% +%% Description: Creates error string. +%%-------------------------------------------------------------------- +format_error({error, Reason}) -> + format_error(Reason); +format_error(Reason) when is_list(Reason) -> + Reason; +format_error(closed) -> + "The connection is closed"; +format_error(ecacertfile) -> + "Own CA certificate file is invalid."; +format_error(ecertfile) -> + "Own certificate file is invalid."; +format_error(ekeyfile) -> + "Own private key file is invalid."; +format_error(esslaccept) -> + "Server SSL handshake procedure between client and server failed."; +format_error(esslconnect) -> + "Client SSL handshake procedure between client and server failed."; +format_error({eoptions, Options}) -> + lists:flatten(io_lib:format("Error in options list: ~p~n", [Options])); + +%%%%%%%%%%%% START OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +format_error(ebadsocket) -> + "Connection not found (internal error)."; +format_error(ebadstate) -> + "Connection not in connect state (internal error)."; +format_error(ebrokertype) -> + "Wrong broker type (internal error)."; +format_error(echaintoolong) -> + "The chain of certificates provided by peer is too long."; +format_error(ecipher) -> + "Own list of specified ciphers is invalid."; +format_error(ekeymismatch) -> + "Own private key does not match own certificate."; +format_error(enoissuercert) -> + "Cannot find certificate of issuer of certificate provided by peer."; +format_error(enoservercert) -> + "Attempt to do accept without having set own certificate."; +format_error(enotlistener) -> + "Attempt to accept on a non-listening socket."; +format_error(enoproxysocket) -> + "No proxy socket found (internal error or max number of file " + "descriptors exceeded)."; +format_error(enooptions) -> + "List of options is empty."; +format_error(enotstarted) -> + "The SSL application has not been started."; +format_error(eoptions) -> + "Invalid list of options."; +format_error(epeercert) -> + "Certificate provided by peer is in error."; +format_error(epeercertexpired) -> + "Certificate provided by peer has expired."; +format_error(epeercertinvalid) -> + "Certificate provided by peer is invalid."; +format_error(eselfsignedcert) -> + "Certificate provided by peer is self signed."; +format_error(esslerrssl) -> + "SSL protocol failure. Typically because of a fatal alert from peer."; +format_error(ewantconnect) -> + "Protocol wants to connect, which is not supported in this " + "version of the SSL application."; +format_error(ex509lookup) -> + "Protocol wants X.509 lookup, which is not supported in this " + "version of the SSL application."; +format_error({badcall, _Call}) -> + "Call not recognized for current mode (active or passive) and state " + "of socket."; +format_error({badcast, _Cast}) -> + "Call not recognized for current mode (active or passive) and state " + "of socket."; + +format_error({badinfo, _Info}) -> + "Call not recognized for current mode (active or passive) and state " + "of socket."; + +%%%%%%%%%%%%%%%%%% END OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +format_error(Error) -> + case (catch inet:format_error(Error)) of + "unkknown POSIX" ++ _ -> + no_format(Error); + {'EXIT', _} -> + no_format(Error); + Other -> + Other + end. + %%%-------------------------------------------------------------- %%% Internal functions %%%-------------------------------------------------------------------- @@ -529,17 +621,19 @@ handle_options(Opts0, _Role) -> ReuseSessionFun = fun(_, _, _, _) -> true end, - VerifyNoneFun = - {fun(_,{bad_cert, unknown_ca}, UserState) -> + DefaultVerifyNoneFun = + {fun(_,{bad_cert, _}, UserState) -> {valid, UserState}; - (_,{bad_cert, _} = Reason, _) -> - {fail, Reason}; (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> {valid, UserState} end, []}, + VerifyNoneFun = handle_option(verify_fun, Opts, DefaultVerifyNoneFun), + UserFailIfNoPeerCert = handle_option(fail_if_no_peer_cert, Opts, false), UserVerifyFun = handle_option(verify_fun, Opts, undefined), CaCerts = handle_option(cacerts, Opts, undefined), @@ -635,6 +729,8 @@ validate_option(verify_fun, Fun) when is_function(Fun) -> (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> {valid, UserState} end, Fun}; validate_option(verify_fun, {Fun, _} = Value) when is_function(Fun) -> @@ -651,7 +747,7 @@ validate_option(depth, Value) when is_integer(Value), validate_option(cert, Value) when Value == undefined; is_binary(Value) -> Value; -validate_option(certfile, Value) when is_list(Value) -> +validate_option(certfile, Value) when Value == undefined; is_list(Value) -> Value; validate_option(key, undefined) -> @@ -794,7 +890,7 @@ cipher_suites(Version, [{_,_,_}| _] = Ciphers0) -> Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0], cipher_suites(Version, Ciphers); cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) -> - Supported = ssl_cipher:suites(Version), + Supported = ssl_cipher:suites(Version) ++ ssl_cipher:anonymous_suites(), case [Cipher || Cipher <- Ciphers0, lists:member(Cipher, Supported)] of [] -> Supported; @@ -810,92 +906,6 @@ cipher_suites(Version, Ciphers0) -> Ciphers = [ssl_cipher:openssl_suite(C) || C <- string:tokens(Ciphers0, ":")], cipher_suites(Version, Ciphers). -format_error({error, Reason}) -> - format_error(Reason); -format_error(Reason) when is_list(Reason) -> - Reason; -format_error(closed) -> - "The connection is closed"; -format_error(ecacertfile) -> - "Own CA certificate file is invalid."; -format_error(ecertfile) -> - "Own certificate file is invalid."; -format_error(ekeyfile) -> - "Own private key file is invalid."; -format_error(esslaccept) -> - "Server SSL handshake procedure between client and server failed."; -format_error(esslconnect) -> - "Client SSL handshake procedure between client and server failed."; -format_error({eoptions, Options}) -> - lists:flatten(io_lib:format("Error in options list: ~p~n", [Options])); - -%%%%%%%%%%%% START OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -format_error(ebadsocket) -> - "Connection not found (internal error)."; -format_error(ebadstate) -> - "Connection not in connect state (internal error)."; -format_error(ebrokertype) -> - "Wrong broker type (internal error)."; -format_error(echaintoolong) -> - "The chain of certificates provided by peer is too long."; -format_error(ecipher) -> - "Own list of specified ciphers is invalid."; -format_error(ekeymismatch) -> - "Own private key does not match own certificate."; -format_error(enoissuercert) -> - "Cannot find certificate of issuer of certificate provided by peer."; -format_error(enoservercert) -> - "Attempt to do accept without having set own certificate."; -format_error(enotlistener) -> - "Attempt to accept on a non-listening socket."; -format_error(enoproxysocket) -> - "No proxy socket found (internal error or max number of file " - "descriptors exceeded)."; -format_error(enooptions) -> - "List of options is empty."; -format_error(enotstarted) -> - "The SSL application has not been started."; -format_error(eoptions) -> - "Invalid list of options."; -format_error(epeercert) -> - "Certificate provided by peer is in error."; -format_error(epeercertexpired) -> - "Certificate provided by peer has expired."; -format_error(epeercertinvalid) -> - "Certificate provided by peer is invalid."; -format_error(eselfsignedcert) -> - "Certificate provided by peer is self signed."; -format_error(esslerrssl) -> - "SSL protocol failure. Typically because of a fatal alert from peer."; -format_error(ewantconnect) -> - "Protocol wants to connect, which is not supported in this " - "version of the SSL application."; -format_error(ex509lookup) -> - "Protocol wants X.509 lookup, which is not supported in this " - "version of the SSL application."; -format_error({badcall, _Call}) -> - "Call not recognized for current mode (active or passive) and state " - "of socket."; -format_error({badcast, _Cast}) -> - "Call not recognized for current mode (active or passive) and state " - "of socket."; - -format_error({badinfo, _Info}) -> - "Call not recognized for current mode (active or passive) and state " - "of socket."; - -%%%%%%%%%%%%%%%%%% END OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -format_error(Error) -> - case (catch inet:format_error(Error)) of - "unkknown POSIX" ++ _ -> - no_format(Error); - {'EXIT', _} -> - no_format(Error); - Other -> - Other - end. - no_format(Error) -> lists:flatten(io_lib:format("No format string for error: \"~p\" available.", [Error])). diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 206024315e..8c0c2bfa5d 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -28,7 +28,6 @@ -include("ssl_handshake.hrl"). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). --include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([trusted_cert_and_path/2, @@ -57,30 +56,32 @@ trusted_cert_and_path(CertChain, CertDbRef) -> Path = [Cert | _] = lists:reverse(CertChain), OtpCert = public_key:pkix_decode_cert(Cert, otp), - IssuerID = + SignedAndIssuerID = case public_key:pkix_is_self_signed(OtpCert) of true -> {ok, IssuerId} = public_key:pkix_issuer_id(OtpCert, self), - IssuerId; + {self, IssuerId}; false -> case public_key:pkix_issuer_id(OtpCert, other) of {ok, IssuerId} -> - IssuerId; + {other, IssuerId}; {error, issuer_not_found} -> case find_issuer(OtpCert, no_candidate) of {ok, IssuerId} -> - IssuerId; + {other, IssuerId}; Other -> Other end end end, - case IssuerID of + case SignedAndIssuerID of {error, issuer_not_found} -> %% The root CA was not sent and can not be found. {unknown_ca, Path}; - {SerialNr, Issuer} -> + {self, _} when length(Path) == 1 -> + {selfsigned_peer, Path}; + {_ ,{SerialNr, Issuer}} -> case ssl_manager:lookup_trusted_cert(CertDbRef, SerialNr, Issuer) of {ok, {BinCert,_}} -> {BinCert, Path}; @@ -110,9 +111,10 @@ file_to_certificats(File) -> {ok, List} = ssl_manager:cache_pem_file(File), [Bin || {'Certificate', Bin, not_encrypted} <- List]. %%-------------------------------------------------------------------- --spec validate_extension(term(), #'Extension'{}, term()) -> {valid, term()} | - {fail, tuple()} | - {unknown, term()}. +-spec validate_extension(term(), #'Extension'{} | {bad_cert, atom()} | valid, + term()) -> {valid, term()} | + {fail, tuple()} | + {unknown, term()}. %% %% Description: Validates ssl/tls specific extensions %%-------------------------------------------------------------------- @@ -129,6 +131,8 @@ validate_extension(_, {bad_cert, _} = Reason, _) -> validate_extension(_, {extension, _}, Role) -> {unknown, Role}; validate_extension(_, valid, Role) -> + {valid, Role}; +validate_extension(_, valid_peer, Role) -> {valid, Role}. %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl index 86477f369d..2a5a7f3394 100644 --- a/lib/ssl/src/ssl_certificate_db.erl +++ b/lib/ssl/src/ssl_certificate_db.erl @@ -216,9 +216,15 @@ add_certs_from_file(File, Ref, CertsDb) -> [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries]. add_certs(Cert, Ref, CertsDb) -> - ErlCert = public_key:pkix_decode_cert(Cert, otp), - TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate, - SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber, - Issuer = public_key:pkix_normalize_name( - TBSCertificate#'OTPTBSCertificate'.issuer), - insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb). + try ErlCert = public_key:pkix_decode_cert(Cert, otp), + TBSCertificate = ErlCert#'OTPCertificate'.tbsCertificate, + SerialNumber = TBSCertificate#'OTPTBSCertificate'.serialNumber, + Issuer = public_key:pkix_normalize_name( + TBSCertificate#'OTPTBSCertificate'.issuer), + insert({Ref, SerialNumber, Issuer}, {Cert,ErlCert}, CertsDb) + catch + error:_ -> + Report = io_lib:format("SSL WARNING: Ignoring a CA cert as " + "it could not be correctly decoded.~n", []), + error_logger:info_report(Report) + end. diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl index 8230149304..72f02a4362 100644 --- a/lib/ssl/src/ssl_cipher.erl +++ b/lib/ssl/src/ssl_cipher.erl @@ -29,12 +29,11 @@ -include("ssl_record.hrl"). -include("ssl_cipher.hrl"). -include("ssl_alert.hrl"). --include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([security_parameters/2, suite_definition/1, decipher/5, cipher/4, - suite/1, suites/1, + suite/1, suites/1, anonymous_suites/0, openssl_suite/1, openssl_suite_name/1, filter/2]). -compile(inline). @@ -75,20 +74,12 @@ cipher(?RC4, CipherState, Mac, Fragment) -> S -> S end, GenStreamCipherList = [Fragment, Mac], - - ?DBG_HEX(GenStreamCipherList), - ?DBG_HEX(State0), {State1, T} = crypto:rc4_encrypt_with_state(State0, GenStreamCipherList), - ?DBG_HEX(T), {T, CipherState#cipher_state{state = State1}}; cipher(?DES, CipherState, Mac, Fragment) -> block_cipher(fun(Key, IV, T) -> crypto:des_cbc_encrypt(Key, IV, T) end, block_size(des_cbc), CipherState, Mac, Fragment); -%% cipher(?DES40, CipherState, Mac, Fragment) -> -%% block_cipher(fun(Key, IV, T) -> -%% crypto:des_cbc_encrypt(Key, IV, T) -%% end, block_size(des_cbc), CipherState, Mac, Fragment); cipher(?'3DES', CipherState, Mac, Fragment) -> block_cipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) -> crypto:des3_cbc_encrypt(K1, K2, K3, IV, T) @@ -109,11 +100,7 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, TotSz = byte_size(Mac) + erlang:iolist_size(Fragment) + 1, {PaddingLength, Padding} = get_padding(TotSz, BlockSz), L = [Fragment, Mac, PaddingLength, Padding], - ?DBG_HEX(Key), - ?DBG_HEX(IV), - ?DBG_HEX(L), T = Fun(Key, IV, L), - ?DBG_HEX(T), NextIV = next_iv(T, IV), {T, CS0#cipher_state{iv=NextIV}}. @@ -127,26 +114,29 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0, decipher(?NULL, _HashSz, CipherState, Fragment, _) -> {Fragment, <<>>, CipherState}; decipher(?RC4, HashSz, CipherState, Fragment, _) -> - ?DBG_TERM(CipherState#cipher_state.key), State0 = case CipherState#cipher_state.state of undefined -> crypto:rc4_set_key(CipherState#cipher_state.key); S -> S end, - ?DBG_HEX(State0), - ?DBG_HEX(Fragment), - {State1, T} = crypto:rc4_encrypt_with_state(State0, Fragment), - ?DBG_HEX(T), - GSC = generic_stream_cipher_from_bin(T, HashSz), - #generic_stream_cipher{content=Content, mac=Mac} = GSC, - {Content, Mac, CipherState#cipher_state{state=State1}}; + try crypto:rc4_encrypt_with_state(State0, Fragment) of + {State, Text} -> + GSC = generic_stream_cipher_from_bin(Text, HashSz), + #generic_stream_cipher{content = Content, mac = Mac} = GSC, + {Content, Mac, CipherState#cipher_state{state = State}} + catch + _:_ -> + %% This is a DECRYPTION_FAILED but + %% "differentiating between bad_record_mac and decryption_failed + %% alerts may permit certain attacks against CBC mode as used in + %% TLS [CBCATT]. It is preferable to uniformly use the + %% bad_record_mac alert to hide the specific type of the error." + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) + end; + decipher(?DES, HashSz, CipherState, Fragment, Version) -> block_decipher(fun(Key, IV, T) -> crypto:des_cbc_decrypt(Key, IV, T) end, CipherState, HashSz, Fragment, Version); -%% decipher(?DES40, HashSz, CipherState, Fragment, Version) -> -%% block_decipher(fun(Key, IV, T) -> -%% crypto:des_cbc_decrypt(Key, IV, T) -%% end, CipherState, HashSz, Fragment, Version); decipher(?'3DES', HashSz, CipherState, Fragment, Version) -> block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) -> crypto:des3_cbc_decrypt(K1, K2, K3, IV, T) @@ -164,22 +154,27 @@ decipher(?AES, HashSz, CipherState, Fragment, Version) -> block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0, HashSz, Fragment, Version) -> - ?DBG_HEX(Key), - ?DBG_HEX(IV), - ?DBG_HEX(Fragment), - T = Fun(Key, IV, Fragment), - ?DBG_HEX(T), - GBC = generic_block_cipher_from_bin(T, HashSz), - case is_correct_padding(GBC, Version) of - true -> - Content = GBC#generic_block_cipher.content, - Mac = GBC#generic_block_cipher.mac, - CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)}, - {Content, Mac, CipherState1}; - false -> + try Fun(Key, IV, Fragment) of + Text -> + GBC = generic_block_cipher_from_bin(Text, HashSz), + case is_correct_padding(GBC, Version) of + true -> + Content = GBC#generic_block_cipher.content, + Mac = GBC#generic_block_cipher.mac, + CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)}, + {Content, Mac, CipherState1}; + false -> + ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) + end + catch + _:_ -> + %% This is a DECRYPTION_FAILED but + %% "differentiating between bad_record_mac and decryption_failed + %% alerts may permit certain attacks against CBC mode as used in + %% TLS [CBCATT]. It is preferable to uniformly use the + %% bad_record_mac alert to hide the specific type of the error." ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC) end. - %%-------------------------------------------------------------------- -spec suites(tls_version()) -> [cipher_suite()]. %% @@ -191,6 +186,19 @@ suites({3, N}) when N == 1; N == 2 -> ssl_tls1:suites(). %%-------------------------------------------------------------------- +-spec anonymous_suites() -> [cipher_suite()]. +%% +%% Description: Returns a list of the anonymous cipher suites, only supported +%% if explicitly set by user. Intended only for testing. +%%-------------------------------------------------------------------- +anonymous_suites() -> + [?TLS_DH_anon_WITH_RC4_128_MD5, + ?TLS_DH_anon_WITH_DES_CBC_SHA, + ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, + ?TLS_DH_anon_WITH_AES_128_CBC_SHA, + ?TLS_DH_anon_WITH_AES_256_CBC_SHA]. + +%%-------------------------------------------------------------------- -spec suite_definition(cipher_suite()) -> erl_cipher_suite(). %% %% Description: Return erlang cipher suite definition. @@ -235,7 +243,20 @@ suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) -> suite_definition(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) -> {dhe_dss, aes_256_cbc, sha}; suite_definition(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) -> - {dhe_rsa, aes_256_cbc, sha}. + {dhe_rsa, aes_256_cbc, sha}; + +%%% DH-ANON deprecated by TLS spec and not available +%%% by default, but good for testing purposes. +suite_definition(?TLS_DH_anon_WITH_RC4_128_MD5) -> + {dh_anon, rc4_128, md5}; +suite_definition(?TLS_DH_anon_WITH_DES_CBC_SHA) -> + {dh_anon, des_cbc, sha}; +suite_definition(?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) -> + {dh_anon, '3des_ede_cbc', sha}; +suite_definition(?TLS_DH_anon_WITH_AES_128_CBC_SHA) -> + {dh_anon, aes_128_cbc, sha}; +suite_definition(?TLS_DH_anon_WITH_AES_256_CBC_SHA) -> + {dh_anon, aes_256_cbc, sha}. %%-------------------------------------------------------------------- -spec suite(erl_cipher_suite()) -> cipher_suite(). @@ -266,12 +287,12 @@ suite({dhe_rsa, des_cbc, sha}) -> ?TLS_DHE_RSA_WITH_DES_CBC_SHA; suite({dhe_rsa, '3des_ede_cbc', sha}) -> ?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA; -%% suite({dh_anon, rc4_128, md5}) -> -%% ?TLS_DH_anon_WITH_RC4_128_MD5; -%% suite({dh_anon, des40_cbc, sha}) -> -%% ?TLS_DH_anon_WITH_DES_CBC_SHA; -%% suite({dh_anon, '3des_ede_cbc', sha}) -> -%% ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; +suite({dh_anon, rc4_128, md5}) -> + ?TLS_DH_anon_WITH_RC4_128_MD5; +suite({dh_anon, des_cbc, sha}) -> + ?TLS_DH_anon_WITH_DES_CBC_SHA; +suite({dh_anon, '3des_ede_cbc', sha}) -> + ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; %%% TSL V1.1 AES suites suite({rsa, aes_128_cbc, sha}) -> @@ -280,16 +301,16 @@ suite({dhe_dss, aes_128_cbc, sha}) -> ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA; suite({dhe_rsa, aes_128_cbc, sha}) -> ?TLS_DHE_RSA_WITH_AES_128_CBC_SHA; -%% suite({dh_anon, aes_128_cbc, sha}) -> -%% ?TLS_DH_anon_WITH_AES_128_CBC_SHA; +suite({dh_anon, aes_128_cbc, sha}) -> + ?TLS_DH_anon_WITH_AES_128_CBC_SHA; suite({rsa, aes_256_cbc, sha}) -> ?TLS_RSA_WITH_AES_256_CBC_SHA; suite({dhe_dss, aes_256_cbc, sha}) -> ?TLS_DHE_DSS_WITH_AES_256_CBC_SHA; suite({dhe_rsa, aes_256_cbc, sha}) -> - ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA. -%% suite({dh_anon, aes_256_cbc, sha}) -> -%% ?TLS_DH_anon_WITH_AES_256_CBC_SHA. + ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA; +suite({dh_anon, aes_256_cbc, sha}) -> + ?TLS_DH_anon_WITH_AES_256_CBC_SHA. %%-------------------------------------------------------------------- -spec openssl_suite(openssl_cipher_suite()) -> cipher_suite(). @@ -390,8 +411,6 @@ bulk_cipher_algorithm(null) -> %% ?IDEA; bulk_cipher_algorithm(rc4_128) -> ?RC4; -%% bulk_cipher_algorithm(des40_cbc) -> -%% ?DES40; bulk_cipher_algorithm(des_cbc) -> ?DES; bulk_cipher_algorithm('3des_ede_cbc') -> @@ -405,7 +424,6 @@ type(Cipher) when Cipher == null; ?STREAM; type(Cipher) when Cipher == idea_cbc; - Cipher == des40_cbc; Cipher == des_cbc; Cipher == '3des_ede_cbc'; Cipher == aes_128_cbc; @@ -417,8 +435,6 @@ key_material(null) -> key_material(Cipher) when Cipher == idea_cbc; Cipher == rc4_128 -> 16; -%%key_material(des40_cbc) -> -%% 5; key_material(des_cbc) -> 8; key_material('3des_ede_cbc') -> @@ -433,8 +449,7 @@ expanded_key_material(null) -> expanded_key_material(Cipher) when Cipher == idea_cbc; Cipher == rc4_128 -> 16; -expanded_key_material(Cipher) when Cipher == des_cbc; - Cipher == des40_cbc -> +expanded_key_material(Cipher) when Cipher == des_cbc -> 8; expanded_key_material('3des_ede_cbc') -> 24; @@ -445,8 +460,6 @@ expanded_key_material(Cipher) when Cipher == aes_128_cbc; effective_key_bits(null) -> 0; -%%effective_key_bits(des40_cbc) -> -%% 40; effective_key_bits(des_cbc) -> 56; effective_key_bits(Cipher) when Cipher == idea_cbc; @@ -465,7 +478,6 @@ iv_size(Cipher) -> block_size(Cipher). block_size(Cipher) when Cipher == idea_cbc; - Cipher == des40_cbc; Cipher == des_cbc; Cipher == '3des_ede_cbc' -> 8; @@ -580,5 +592,3 @@ filter_rsa_suites(Use, KeyUse, CipherSuits, RsaSuites) -> false -> CipherSuits -- RsaSuites end. - - diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index c94199c336..6c9ac65b64 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -29,7 +29,6 @@ -behaviour(gen_fsm). --include("ssl_debug.hrl"). -include("ssl_handshake.hrl"). -include("ssl_alert.hrl"). -include("ssl_record.hrl"). @@ -75,7 +74,7 @@ session, % #session{} from ssl_handshake.hrl session_cache, % session_cache_cb, % - negotiated_version, % #protocol_version{} + negotiated_version, % tls_version() supported_protocol_versions, % [atom()] client_certificate_requested = false, key_algorithm, % atom as defined by cipher_suite @@ -374,7 +373,7 @@ hello(#server_hello{cipher_suite = CipherSuite, case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of {Version, NewId, ConnectionStates} -> - {KeyAlgorithm, _, _} = + {KeyAlgorithm, _, _} = ssl_cipher:suite_definition(CipherSuite), PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm), @@ -512,7 +511,7 @@ certify(#certificate{} = Cert, certify(#server_key_exchange{} = KeyExchangeMsg, #state{role = client, negotiated_version = Version, key_algorithm = Alg} = State0) - when Alg == dhe_dss; Alg == dhe_rsa -> + when Alg == dhe_dss; Alg == dhe_rsa; Alg == dh_anon -> case handle_server_key(KeyExchangeMsg, State0) of #state{} = State1 -> {Record, State} = next_record(State1), @@ -613,25 +612,10 @@ certify_client_key_exchange(#client_diffie_hellman_public{dh_public = ClientPubl #state{negotiated_version = Version, diffie_hellman_params = #'DHParameter'{prime = P, base = G}, - diffie_hellman_keys = {_, ServerDhPrivateKey}, - role = Role, - session = Session, - connection_states = ConnectionStates0} = State0) -> - - PMpint = crypto:mpint(P), - GMpint = crypto:mpint(G), - PremasterSecret = crypto:dh_compute_key(mpint_binary(ClientPublicDhKey), - ServerDhPrivateKey, - [PMpint, GMpint]), - - case ssl_handshake:master_secret(Version, PremasterSecret, - ConnectionStates0, Role) of - {MasterSecret, ConnectionStates} -> - State1 = State0#state{session = - Session#session{master_secret - = MasterSecret}, - connection_states = ConnectionStates}, + diffie_hellman_keys = {_, ServerDhPrivateKey}} = State0) -> + case dh_master_secret(crypto:mpint(P), crypto:mpint(G), ClientPublicDhKey, ServerDhPrivateKey, State0) of + #state{} = State1 -> {Record, State} = next_record(State1), next_state(cipher, Record, State); #alert{} = Alert -> @@ -653,12 +637,10 @@ cipher(#certificate_verify{signature = Signature}, public_key_info = PublicKeyInfo, negotiated_version = Version, session = #session{master_secret = MasterSecret}, - key_algorithm = Algorithm, tls_handshake_hashes = Hashes } = State0) -> case ssl_handshake:certificate_verify(Signature, PublicKeyInfo, - Version, MasterSecret, - Algorithm, Hashes) of + Version, MasterSecret, Hashes) of valid -> {Record, State} = next_record(State0), next_state(cipher, Record, State); @@ -984,15 +966,14 @@ handle_info(Msg, StateName, State) -> %% necessary cleaning up. When it returns, the gen_fsm terminates with %% Reason. The return value is ignored. %%-------------------------------------------------------------------- -terminate(_Reason, connection, #state{negotiated_version = Version, +terminate(Reason, connection, #state{negotiated_version = Version, connection_states = ConnectionStates, transport_cb = Transport, socket = Socket, send_queue = SendQueue, renegotiation = Renegotiate}) -> notify_senders(SendQueue), notify_renegotiater(Renegotiate), - {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY), - Version, ConnectionStates), + BinAlert = terminate_alert(Reason, Version, ConnectionStates), Transport:send(Socket, BinAlert), workaround_transport_delivery_problems(Socket, Transport), Transport:close(Socket); @@ -1058,6 +1039,8 @@ init_certificates(#ssl_options{cacerts = CaCerts, end, init_certificates(Cert, CertDbRef, CacheRef, CertFile, Role). +init_certificates(undefined, CertDbRef, CacheRef, "", _) -> + {ok, CertDbRef, CacheRef, undefined}; init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) -> try @@ -1068,18 +1051,18 @@ init_certificates(undefined, CertDbRef, CacheRef, CertFile, client) -> end; init_certificates(undefined, CertDbRef, CacheRef, CertFile, server) -> - try + try [OwnCert] = ssl_certificate:file_to_certificats(CertFile), {ok, CertDbRef, CacheRef, OwnCert} - catch - Error:Reason -> - handle_file_error(?LINE, Error, Reason, CertFile, ecertfile, - erlang:get_stacktrace()) - end; + catch + Error:Reason -> + handle_file_error(?LINE, Error, Reason, CertFile, ecertfile, + erlang:get_stacktrace()) + end; init_certificates(Cert, CertDbRef, CacheRef, _, _) -> {ok, CertDbRef, CacheRef, Cert}. -init_private_key(undefined, "", _Password, client) -> +init_private_key(undefined, "", _Password, _Client) -> undefined; init_private_key(undefined, KeyFile, Password, _) -> try @@ -1182,16 +1165,15 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, negotiated_version = Version, own_cert = OwnCert, socket = Socket, - key_algorithm = KeyAlg, private_key = PrivateKey, session = #session{master_secret = MasterSecret}, tls_handshake_hashes = Hashes0} = State) -> + case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, - Version, KeyAlg, - PrivateKey, Hashes0) of + Version, PrivateKey, Hashes0) of #certificate_verify{} = Verified -> {BinVerified, ConnectionStates1, Hashes1} = - encode_handshake(Verified, KeyAlg, Version, + encode_handshake(Verified, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinVerified), State#state{connection_states = ConnectionStates1, @@ -1340,15 +1322,17 @@ server_hello_done(#state{transport_cb = Transport, Transport:send(Socket, BinHelloDone), State#state{connection_states = NewConnectionStates, tls_handshake_hashes = NewHashes}. - -certify_server(#state{transport_cb = Transport, - socket = Socket, - negotiated_version = Version, - connection_states = ConnectionStates, - tls_handshake_hashes = Hashes, - cert_db_ref = CertDbRef, - own_cert = OwnCert} = State) -> +certify_server(#state{key_algorithm = dh_anon} = State) -> + State; + +certify_server(#state{transport_cb = Transport, + socket = Socket, + negotiated_version = Version, + connection_states = ConnectionStates, + tls_handshake_hashes = Hashes, + cert_db_ref = CertDbRef, + own_cert = OwnCert} = State) -> case ssl_handshake:certificate(OwnCert, CertDbRef, server) of CertMsg = #certificate{} -> {BinCertMsg, NewConnectionStates, NewHashes} = @@ -1373,7 +1357,8 @@ key_exchange(#state{role = server, key_algorithm = Algo, transport_cb = Transport } = State) when Algo == dhe_dss; - Algo == dhe_rsa -> + Algo == dhe_rsa; + Algo == dh_anon -> Keys = crypto:dh_generate_key([crypto:mpint(P), crypto:mpint(G)]), ConnectionState = @@ -1392,11 +1377,6 @@ key_exchange(#state{role = server, key_algorithm = Algo, diffie_hellman_keys = Keys, tls_handshake_hashes = Hashes1}; - -%% key_algorithm = dh_anon is not supported. Should be by default disabled -%% if support is implemented and then we need a key_exchange clause for it -%% here. - key_exchange(#state{role = client, connection_states = ConnectionStates0, key_algorithm = rsa, @@ -1419,7 +1399,8 @@ key_exchange(#state{role = client, socket = Socket, transport_cb = Transport, tls_handshake_hashes = Hashes0} = State) when Algorithm == dhe_dss; - Algorithm == dhe_rsa -> + Algorithm == dhe_rsa; + Algorithm == dh_anon -> Msg = ssl_handshake:key_exchange(client, {dh, DhPubKey}), {BinMsg, ConnectionStates1, Hashes1} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), @@ -1497,23 +1478,30 @@ save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbrev save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) -> ssl_record:set_server_verify_data(current_write, Data, ConnectionStates). +handle_server_key(#server_key_exchange{params = + #server_dh_params{dh_p = P, + dh_g = G, + dh_y = ServerPublicDhKey}, + signed_params = <<>>}, + #state{key_algorithm = dh_anon} = State) -> + dh_master_secret(P, G, ServerPublicDhKey, undefined, State); + handle_server_key( #server_key_exchange{params = #server_dh_params{dh_p = P, dh_g = G, dh_y = ServerPublicDhKey}, signed_params = Signed}, - #state{session = Session, negotiated_version = Version, role = Role, - public_key_info = PubKeyInfo, + #state{public_key_info = PubKeyInfo, key_algorithm = KeyAlgo, - connection_states = ConnectionStates0} = State) -> + connection_states = ConnectionStates} = State) -> PLen = size(P), GLen = size(G), YLen = size(ServerPublicDhKey), ConnectionState = - ssl_record:pending_connection_state(ConnectionStates0, read), + ssl_record:pending_connection_state(ConnectionStates, read), SecParams = ConnectionState#connection_state.security_parameters, #security_parameters{client_random = ClientRandom, server_random = ServerRandom} = SecParams, @@ -1527,29 +1515,11 @@ handle_server_key( case verify_dh_params(Signed, Hash, PubKeyInfo) of true -> - PMpint = mpint_binary(P), - GMpint = mpint_binary(G), - Keys = {_, ClientDhPrivateKey} = - crypto:dh_generate_key([PMpint,GMpint]), - PremasterSecret = - crypto:dh_compute_key(mpint_binary(ServerPublicDhKey), - ClientDhPrivateKey, [PMpint, GMpint]), - case ssl_handshake:master_secret(Version, PremasterSecret, - ConnectionStates0, Role) of - {MasterSecret, ConnectionStates} -> - State#state{diffie_hellman_keys = Keys, - session = - Session#session{master_secret - = MasterSecret}, - connection_states = ConnectionStates}; - #alert{} = Alert -> - Alert - end; + dh_master_secret(P, G, ServerPublicDhKey, undefined, State); false -> - ?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE) + ?ALERT_REC(?FATAL, ?DECRYPT_ERROR) end. - verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) -> case public_key:decrypt_public(Signed, PubKey, [{rsa_pad, rsa_pkcs1_padding}]) of @@ -1561,6 +1531,30 @@ verify_dh_params(Signed, Hashes, {?rsaEncryption, PubKey, _PubKeyParams}) -> verify_dh_params(Signed, Hash, {?'id-dsa', PublicKey, PublicKeyParams}) -> public_key:verify(Hash, none, Signed, {PublicKey, PublicKeyParams}). +dh_master_secret(Prime, Base, PublicDhKey, undefined, State) -> + PMpint = mpint_binary(Prime), + GMpint = mpint_binary(Base), + Keys = {_, PrivateDhKey} = + crypto:dh_generate_key([PMpint,GMpint]), + dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, State#state{diffie_hellman_keys = Keys}); + +dh_master_secret(PMpint, GMpint, PublicDhKey, PrivateDhKey, + #state{session = Session, + negotiated_version = Version, role = Role, + connection_states = ConnectionStates0} = State) -> + PremasterSecret = + crypto:dh_compute_key(mpint_binary(PublicDhKey), PrivateDhKey, + [PMpint, GMpint]), + case ssl_handshake:master_secret(Version, PremasterSecret, + ConnectionStates0, Role) of + {MasterSecret, ConnectionStates} -> + State#state{ + session = + Session#session{master_secret = MasterSecret}, + connection_states = ConnectionStates}; + #alert{} = Alert -> + Alert + end. cipher_role(client, Data, Session, #state{connection_states = ConnectionStates0} = State) -> ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0), @@ -1578,20 +1572,13 @@ cipher_role(server, Data, Session, #state{connection_states = ConnectionStates0 tls_handshake_hashes = Hashes})). encode_alert(#alert{} = Alert, Version, ConnectionStates) -> - ?DBG_TERM(Alert), ssl_record:encode_alert_record(Alert, Version, ConnectionStates). encode_change_cipher(#change_cipher_spec{}, Version, ConnectionStates) -> - ?DBG_TERM(#change_cipher_spec{}), ssl_record:encode_change_cipher_spec(Version, ConnectionStates). -encode_handshake(HandshakeRec, Version, ConnectionStates, Hashes) -> - encode_handshake(HandshakeRec, null, Version, - ConnectionStates, Hashes). - -encode_handshake(HandshakeRec, SigAlg, Version, ConnectionStates0, Hashes0) -> - ?DBG_TERM(HandshakeRec), - Frag = ssl_handshake:encode_handshake(HandshakeRec, Version, SigAlg), +encode_handshake(HandshakeRec, Version, ConnectionStates0, Hashes0) -> + Frag = ssl_handshake:encode_handshake(HandshakeRec, Version), Hashes1 = ssl_handshake:update_hashes(Hashes0, Frag), {E, ConnectionStates1} = ssl_record:encode_handshake(Frag, Version, ConnectionStates0), @@ -1848,7 +1835,6 @@ next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} = _ChangeCipher, #state{connection_states = ConnectionStates0} = State0) -> - ?DBG_TERM(_ChangeCipher), ConnectionStates1 = ssl_record:activate_pending_connection_state(ConnectionStates0, read), {Record, State} = next_record(State0#state{connection_states = ConnectionStates1}), @@ -2179,7 +2165,7 @@ renegotiate(#state{role = server, negotiated_version = Version, connection_states = ConnectionStates0} = State0) -> HelloRequest = ssl_handshake:hello_request(), - Frag = ssl_handshake:encode_handshake(HelloRequest, Version, null), + Frag = ssl_handshake:encode_handshake(HelloRequest, Version), Hs0 = ssl_handshake:init_hashes(), {BinMsg, ConnectionStates} = ssl_record:encode_handshake(Frag, Version, ConnectionStates0), @@ -2199,6 +2185,15 @@ notify_renegotiater({true, From}) when not is_atom(From) -> notify_renegotiater(_) -> ok. +terminate_alert(Reason, Version, ConnectionStates) when Reason == normal; Reason == shutdown -> + {BinAlert, _} = encode_alert(?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), + Version, ConnectionStates), + BinAlert; +terminate_alert(_, Version, ConnectionStates) -> + {BinAlert, _} = encode_alert(?ALERT_REC(?FATAL, ?INTERNAL_ERROR), + Version, ConnectionStates), + BinAlert. + workaround_transport_delivery_problems(Socket, Transport) -> %% Standard trick to try to make sure all %% data sent to to tcp port is really sent diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 99bc47f04b..c7a1c4965d 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -28,16 +28,15 @@ -include("ssl_cipher.hrl"). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). --include("ssl_debug.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([master_secret/4, client_hello/5, server_hello/4, hello/4, hello_request/0, certify/6, certificate/3, - client_certificate_verify/6, certificate_verify/6, + client_certificate_verify/5, certificate_verify/5, certificate_request/2, key_exchange/2, server_key_exchange_hash/2, finished/4, verify_connection/5, get_tls_handshake/2, - decode_client_key/3, server_hello_done/0, sig_alg/1, - encode_handshake/3, init_hashes/0, update_hashes/2, + decode_client_key/3, server_hello_done/0, + encode_handshake/2, init_hashes/0, update_hashes/2, decrypt_premaster_secret/2]). -type tls_handshake() :: #client_hello{} | #server_hello{} | @@ -237,7 +236,7 @@ certificate(OwnCert, CertDbRef, client) -> {error, _} -> %% If no suitable certificate is available, the client %% SHOULD send a certificate message containing no - %% certificates. (chapter 7.4.6. rfc 4346) + %% certificates. (chapter 7.4.6. RFC 4346) [] end, #certificate{asn1_certificates = Chain}; @@ -252,17 +251,17 @@ certificate(OwnCert, CertDbRef, server) -> %%-------------------------------------------------------------------- -spec client_certificate_verify(undefined | der_cert(), binary(), - tls_version(), key_algo(), private_key(), + tls_version(), private_key(), {{binary(), binary()},{binary(), binary()}}) -> #certificate_verify{} | ignore | #alert{}. %% %% Description: Creates a certificate_verify message, called by the client. %%-------------------------------------------------------------------- -client_certificate_verify(undefined, _, _, _, _, _) -> +client_certificate_verify(undefined, _, _, _, _) -> ignore; -client_certificate_verify(_, _, _, _, undefined, _) -> +client_certificate_verify(_, _, _, undefined, _) -> ignore; -client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm, +client_certificate_verify(OwnCert, MasterSecret, Version, PrivateKey, {Hashes0, _}) -> case public_key:pkix_is_fixed_dh_cert(OwnCert) of true -> @@ -270,33 +269,30 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm, false -> Hashes = calc_certificate_verify(Version, MasterSecret, - Algorithm, Hashes0), + alg_oid(PrivateKey), Hashes0), Signed = digitally_signed(Hashes, PrivateKey), #certificate_verify{signature = Signed} end. %%-------------------------------------------------------------------- -%% -spec certificate_verify(binary(), public_key_info(), tls_version(), -%% binary(), key_algo(), -%% {_, {binary(), binary()}}) -> valid | #alert{}. +-spec certificate_verify(binary(), public_key_info(), tls_version(), + binary(), {_, {binary(), binary()}}) -> valid | #alert{}. %% %% Description: Checks that the certificate_verify message is valid. %%-------------------------------------------------------------------- -certificate_verify(Signature, {_, PublicKey, _}, Version, - MasterSecret, Algorithm, {_, Hashes0}) - when Algorithm == rsa; - Algorithm == dhe_rsa -> +certificate_verify(Signature, {?'rsaEncryption'= Algorithm, PublicKey, _}, Version, + MasterSecret, {_, Hashes0}) -> Hashes = calc_certificate_verify(Version, MasterSecret, Algorithm, Hashes0), - case public_key:decrypt_public(Signature, PublicKey, + case public_key:decrypt_public(Signature, PublicKey, [{rsa_pad, rsa_pkcs1_padding}]) of Hashes -> valid; _ -> ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE) end; -certificate_verify(Signature, {_, PublicKey, PublicKeyParams}, Version, - MasterSecret, dhe_dss = Algorithm, {_, Hashes0}) -> +certificate_verify(Signature, {?'id-dsa' = Algorithm, PublicKey, PublicKeyParams}, Version, + MasterSecret, {_, Hashes0}) -> Hashes = calc_certificate_verify(Version, MasterSecret, Algorithm, Hashes0), case public_key:verify(Hashes, none, Signature, {PublicKey, PublicKeyParams}) of @@ -355,15 +351,22 @@ key_exchange(server, {dh, {<<?UINT32(Len), PublicKey:Len/binary>>, _}, YLen = byte_size(PublicKey), ServerDHParams = #server_dh_params{dh_p = PBin, dh_g = GBin, dh_y = PublicKey}, - Hash = - server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary, - ServerRandom/binary, - ?UINT16(PLen), PBin/binary, - ?UINT16(GLen), GBin/binary, - ?UINT16(YLen), PublicKey/binary>>), - Signed = digitally_signed(Hash, PrivateKey), - #server_key_exchange{params = ServerDHParams, - signed_params = Signed}. + + case KeyAlgo of + dh_anon -> + #server_key_exchange{params = ServerDHParams, + signed_params = <<>>}; + _ -> + Hash = + server_key_exchange_hash(KeyAlgo, <<ClientRandom/binary, + ServerRandom/binary, + ?UINT16(PLen), PBin/binary, + ?UINT16(GLen), GBin/binary, + ?UINT16(YLen), PublicKey/binary>>), + Signed = digitally_signed(Hash, PrivateKey), + #server_key_exchange{params = ServerDHParams, + signed_params = Signed} + end. %%-------------------------------------------------------------------- -spec master_secret(tls_version(), #session{} | binary(), #connection_states{}, @@ -424,13 +427,11 @@ finished(Version, Role, MasterSecret, {Hashes, _}) -> % use the current hashes verify_connection(Version, #finished{verify_data = Data}, Role, MasterSecret, {_, {MD5, SHA}}) -> %% use the previous hashes - ?DBG_HEX(crypto:md5_final(MD5)), - ?DBG_HEX(crypto:sha_final(SHA)), case calc_finished(Version, Role, MasterSecret, {MD5, SHA}) of Data -> verified; - _E -> - ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE) + _ -> + ?ALERT_REC(?FATAL, ?DECRYPT_ERROR) end. %%-------------------------------------------------------------------- -spec server_hello_done() -> #server_hello_done{}. @@ -441,13 +442,12 @@ server_hello_done() -> #server_hello_done{}. %%-------------------------------------------------------------------- --spec encode_handshake(tls_handshake(), tls_version(), key_algo()) -> iolist(). +-spec encode_handshake(tls_handshake(), tls_version()) -> iolist(). %% %% Description: Encode a handshake packet to binary %%-------------------------------------------------------------------- -encode_handshake(Package, Version, KeyAlg) -> - SigAlg = sig_alg(KeyAlg), - {MsgType, Bin} = enc_hs(Package, Version, SigAlg), +encode_handshake(Package, Version) -> + {MsgType, Bin} = enc_hs(Package, Version), Len = byte_size(Bin), [MsgType, ?uint24(Len), Bin]. @@ -474,6 +474,70 @@ decode_client_key(ClientKey, Type, Version) -> dec_client_key(ClientKey, key_exchange_alg(Type), Version). %%-------------------------------------------------------------------- +-spec init_hashes() ->{{binary(), binary()}, {binary(), binary()}}. + +%% +%% Description: Calls crypto hash (md5 and sha) init functions to +%% initalize the hash context. +%%-------------------------------------------------------------------- +init_hashes() -> + T = {crypto:md5_init(), crypto:sha_init()}, + {T, T}. + +%%-------------------------------------------------------------------- +-spec update_hashes({{binary(), binary()}, {binary(), binary()}}, Data ::term()) -> + {{binary(), binary()}, {binary(), binary()}}. +%% +%% Description: Calls crypto hash (md5 and sha) update functions to +%% update the hash context with Data. +%%-------------------------------------------------------------------- +update_hashes(Hashes, % special-case SSL2 client hello + <<?CLIENT_HELLO, ?UINT24(_), ?BYTE(Major), ?BYTE(Minor), + ?UINT16(CSLength), ?UINT16(0), + ?UINT16(CDLength), + CipherSuites:CSLength/binary, + ChallengeData:CDLength/binary>>) -> + update_hashes(Hashes, + <<?CLIENT_HELLO, ?BYTE(Major), ?BYTE(Minor), + ?UINT16(CSLength), ?UINT16(0), + ?UINT16(CDLength), + CipherSuites:CSLength/binary, + ChallengeData:CDLength/binary>>); +update_hashes({{MD50, SHA0}, _Prev}, Data) -> + {MD51, SHA1} = {crypto:md5_update(MD50, Data), + crypto:sha_update(SHA0, Data)}, + {{MD51, SHA1}, {MD50, SHA0}}. + +%%-------------------------------------------------------------------- +-spec decrypt_premaster_secret(binary(), #'RSAPrivateKey'{}) -> binary(). + +%% +%% Description: Public key decryption using the private key. +%%-------------------------------------------------------------------- +decrypt_premaster_secret(Secret, RSAPrivateKey) -> + try public_key:decrypt_private(Secret, RSAPrivateKey, + [{rsa_pad, rsa_pkcs1_padding}]) + catch + _:_ -> + throw(?ALERT_REC(?FATAL, ?DECRYPT_ERROR)) + end. + +%%-------------------------------------------------------------------- +-spec server_key_exchange_hash(rsa | dhe_rsa| dhe_dss | dh_anon, binary()) -> binary(). + +%% +%% Description: Calculate server key exchange hash +%%-------------------------------------------------------------------- +server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa; + Algorithm == dhe_rsa -> + MD5 = crypto:md5(Value), + SHA = crypto:sha(Value), + <<MD5/binary, SHA/binary>>; + +server_key_exchange_hash(dhe_dss, Value) -> + crypto:sha(Value). + +%%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- get_tls_handshake_aux(<<?BYTE(Type), ?UINT24(Length), @@ -496,6 +560,8 @@ path_validation_alert({bad_cert, unknown_critical_extension}) -> ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE); path_validation_alert({bad_cert, cert_revoked}) -> ?ALERT_REC(?FATAL, ?CERTIFICATE_REVOKED); +path_validation_alert({bad_cert, selfsigned_peer}) -> + ?ALERT_REC(?FATAL, ?BAD_CERTIFICATE); path_validation_alert({bad_cert, unknown_ca}) -> ?ALERT_REC(?FATAL, ?UNKNOWN_CA); path_validation_alert(_) -> @@ -710,8 +776,7 @@ master_secret(Version, MasterSecret, #security_parameters{ ServerWriteKey, ClientIV, ServerIV} = setup_keys(Version, MasterSecret, ServerRandom, ClientRandom, HashSize, KML, EKML, IVS), - ?DBG_HEX(ClientWriteKey), - ?DBG_HEX(ClientIV), + ConnStates1 = ssl_record:set_master_secret(MasterSecret, ConnectionStates), ConnStates2 = ssl_record:set_mac_secret(ClientWriteMacSecret, ServerWriteMacSecret, @@ -735,8 +800,6 @@ dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), ?UINT16(CDLength), CipherSuites:CSLength/binary, ChallengeData:CDLength/binary>>) -> - ?DBG_HEX(CipherSuites), - ?DBG_HEX(CipherSuites), #client_hello{client_version = {Major, Minor}, random = ssl_ssl2:client_random(ChallengeData, CDLength), session_id = 0, @@ -792,6 +855,13 @@ dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>) -> dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary, ?UINT16(GLen), G:GLen/binary, ?UINT16(YLen), Y:YLen/binary, + ?UINT16(0)>>) -> %% May happen if key_algorithm is dh_anon + #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G, + dh_y = Y}, + signed_params = <<>>}; +dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary, + ?UINT16(GLen), G:GLen/binary, + ?UINT16(YLen), Y:YLen/binary, ?UINT16(Len), Sig:Len/binary>>) -> #server_key_exchange{params = #server_dh_params{dh_p = P,dh_g = G, dh_y = Y}, @@ -859,14 +929,6 @@ encrypted_premaster_secret(Secret, RSAPublicKey) -> throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)) end. -decrypt_premaster_secret(Secret, RSAPrivateKey) -> - try public_key:decrypt_private(Secret, RSAPrivateKey, - [{rsa_pad, rsa_pkcs1_padding}]) - catch - _:_ -> - throw(?ALERT_REC(?FATAL, ?DECRYPTION_FAILED)) - end. - %% encode/decode stream of certificate data to/from list of certificate data certs_to_list(ASN1Certs) -> certs_to_list(ASN1Certs, []). @@ -882,14 +944,14 @@ certs_from_list(ACList) -> <<?UINT24(CertLen), Cert/binary>> end || Cert <- ACList]). -enc_hs(#hello_request{}, _Version, _) -> +enc_hs(#hello_request{}, _Version) -> {?HELLO_REQUEST, <<>>}; enc_hs(#client_hello{client_version = {Major, Minor}, random = Random, session_id = SessionID, cipher_suites = CipherSuites, compression_methods = CompMethods, - renegotiation_info = RenegotiationInfo}, _Version, _) -> + renegotiation_info = RenegotiationInfo}, _Version) -> SIDLength = byte_size(SessionID), BinCompMethods = list_to_binary(CompMethods), CmLength = byte_size(BinCompMethods), @@ -907,20 +969,20 @@ enc_hs(#server_hello{server_version = {Major, Minor}, session_id = Session_ID, cipher_suite = Cipher_suite, compression_method = Comp_method, - renegotiation_info = RenegotiationInfo}, _Version, _) -> + renegotiation_info = RenegotiationInfo}, _Version) -> SID_length = byte_size(Session_ID), Extensions = hello_extensions(RenegotiationInfo), ExtensionsBin = enc_hello_extensions(Extensions), {?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary, ?BYTE(SID_length), Session_ID/binary, Cipher_suite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>}; -enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) -> +enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version) -> ASN1Certs = certs_from_list(ASN1CertList), ACLen = erlang:iolist_size(ASN1Certs), {?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>}; enc_hs(#server_key_exchange{params = #server_dh_params{ dh_p = P, dh_g = G, dh_y = Y}, - signed_params = SignedParams}, _Version, _) -> + signed_params = SignedParams}, _Version) -> PLen = byte_size(P), GLen = byte_size(G), YLen = byte_size(Y), @@ -932,21 +994,21 @@ enc_hs(#server_key_exchange{params = #server_dh_params{ }; enc_hs(#certificate_request{certificate_types = CertTypes, certificate_authorities = CertAuths}, - _Version, _) -> + _Version) -> CertTypesLen = byte_size(CertTypes), CertAuthsLen = byte_size(CertAuths), {?CERTIFICATE_REQUEST, <<?BYTE(CertTypesLen), CertTypes/binary, ?UINT16(CertAuthsLen), CertAuths/binary>> }; -enc_hs(#server_hello_done{}, _Version, _) -> +enc_hs(#server_hello_done{}, _Version) -> {?SERVER_HELLO_DONE, <<>>}; -enc_hs(#client_key_exchange{exchange_keys = ExchangeKeys}, Version, _) -> +enc_hs(#client_key_exchange{exchange_keys = ExchangeKeys}, Version) -> {?CLIENT_KEY_EXCHANGE, enc_cke(ExchangeKeys, Version)}; -enc_hs(#certificate_verify{signature = BinSig}, _, _) -> +enc_hs(#certificate_verify{signature = BinSig}, _) -> EncSig = enc_bin_sig(BinSig), {?CERTIFICATE_VERIFY, EncSig}; -enc_hs(#finished{verify_data = VerifyData}, _Version, _) -> +enc_hs(#finished{verify_data = VerifyData}, _Version) -> {?FINISHED, VerifyData}. enc_cke(#encrypted_premaster_secret{premaster_secret = PKEPMS},{3, 0}) -> @@ -985,29 +1047,6 @@ enc_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest Len = InfoLen +1, enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), ?BYTE(InfoLen), Info/binary, Acc/binary>>). -init_hashes() -> - T = {crypto:md5_init(), crypto:sha_init()}, - {T, T}. - -update_hashes(Hashes, % special-case SSL2 client hello - <<?CLIENT_HELLO, ?UINT24(_), ?BYTE(Major), ?BYTE(Minor), - ?UINT16(CSLength), ?UINT16(0), - ?UINT16(CDLength), - CipherSuites:CSLength/binary, - ChallengeData:CDLength/binary>>) -> - update_hashes(Hashes, - <<?CLIENT_HELLO, ?BYTE(Major), ?BYTE(Minor), - ?UINT16(CSLength), ?UINT16(0), - ?UINT16(CDLength), - CipherSuites:CSLength/binary, - ChallengeData:CDLength/binary>>); -update_hashes({{MD50, SHA0}, _Prev}, Data) -> - ?DBG_HEX(Data), - {MD51, SHA1} = {crypto:md5_update(MD50, Data), - crypto:sha_update(SHA0, Data)}, - ?DBG_HEX(crypto:md5_final(MD51)), - ?DBG_HEX(crypto:sha_final(SHA1)), - {{MD51, SHA1}, {MD50, SHA0}}. from_3bytes(Bin3) -> from_3bytes(Bin3, []). @@ -1096,28 +1135,10 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes) when N == 1; N == 2 -> ssl_tls1:certificate_verify(Algorithm, Hashes). -server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa; - Algorithm == dhe_rsa -> - MD5 = crypto:md5(Value), - SHA = crypto:sha(Value), - <<MD5/binary, SHA/binary>>; - -server_key_exchange_hash(dhe_dss, Value) -> - crypto:sha(Value). - -sig_alg(dh_anon) -> - ?SIGNATURE_ANONYMOUS; -sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa -> - ?SIGNATURE_RSA; -sig_alg(dhe_dss) -> - ?SIGNATURE_DSA; -sig_alg(_) -> - ?NULL. - key_exchange_alg(rsa) -> ?KEY_EXCHANGE_RSA; key_exchange_alg(Alg) when Alg == dhe_rsa; Alg == dhe_dss; - Alg == dh_dss; Alg == dh_rsa -> + Alg == dh_dss; Alg == dh_rsa; Alg == dh_anon -> ?KEY_EXCHANGE_DIFFIE_HELLMAN; key_exchange_alg(_) -> ?NULL. @@ -1131,3 +1152,8 @@ apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState) -> {unknown, UserState} -> {unknown, {SslState, UserState}} end. + +alg_oid(#'RSAPrivateKey'{}) -> + ?'rsaEncryption'; +alg_oid(#'DSAPrivateKey'{}) -> + ?'id-dsa'. diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index 74fba3786c..68a7802ef2 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -26,6 +26,13 @@ -ifndef(ssl_handshake). -define(ssl_handshake, true). +-include_lib("public_key/include/public_key.hrl"). + +-type algo_oid() :: ?'rsaEncryption' | ?'id-dsa'. +-type public_key() :: #'RSAPublicKey'{} | integer(). +-type public_key_params() :: #'Dss-Parms'{} | term(). +-type public_key_info() :: {algo_oid(), public_key(), public_key_params()}. + -record(session, { session_id, peer_certificate, diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index ddb05e70f6..43a85c2d9d 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -25,6 +25,24 @@ -include_lib("public_key/include/public_key.hrl"). +-type reason() :: term(). +-type reply() :: term(). +-type msg() :: term(). +-type from() :: term(). +-type host() :: string() | tuple(). +-type port_num() :: integer(). +-type session_id() :: 0 | binary(). +-type tls_version() :: {integer(), integer()}. +-type tls_atom_version() :: sslv3 | tlsv1. +-type cache_ref() :: term(). +-type certdb_ref() :: term(). +-type key_algo() :: null | rsa | dhe_rsa | dhe_dss | dh_anon. +-type der_cert() :: binary(). +-type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}. +-type issuer() :: tuple(). +-type serialnumber() :: integer(). +-type cert_key() :: {reference(), integer(), issuer()}. + %% basic binary constructors -define(BOOLEAN(X), X:8/unsigned-big-integer). -define(BYTE(X), X:8/unsigned-big-integer). @@ -93,28 +111,6 @@ active = true }). --type reason() :: term(). --type reply() :: term(). --type msg() :: term(). --type from() :: term(). --type host() :: string() | tuple(). --type port_num() :: integer(). --type session_id() :: 0 | binary(). --type tls_version() :: {integer(), integer()}. --type tls_atom_version() :: sslv3 | tlsv1. --type cache_ref() :: term(). --type certdb_ref() :: term(). --type key_algo() :: null | rsa | dhe_rsa | dhe_dss. --type enum_algo() :: integer(). --type public_key() :: #'RSAPublicKey'{} | integer(). --type public_key_params() :: #'Dss-Parms'{} | term(). --type public_key_info() :: {enum_algo(), public_key(), public_key_params()}. --type der_cert() :: binary(). --type private_key() :: #'RSAPrivateKey'{} | #'DSAPrivateKey'{}. --type issuer() :: tuple(). --type serialnumber() :: integer(). --type cert_key() :: {reference(), integer(), issuer()}. - -endif. % -ifdef(ssl_internal). diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index 0116466677..3b02d96562 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -122,6 +122,7 @@ server_session_id(Port, SuggestedSessionId, SslOpts) -> call({server_session_id, Port, SuggestedSessionId, SslOpts}). %%-------------------------------------------------------------------- +-spec register_session(port_num(), #session{}) -> ok. -spec register_session(host(), port_num(), #session{}) -> ok. %% %% Description: Make the session available for reuse. @@ -132,6 +133,7 @@ register_session(Host, Port, Session) -> register_session(Port, Session) -> cast({register_session, Port, Session}). %%-------------------------------------------------------------------- +-spec invalidate_session(port_num(), #session{}) -> ok. -spec invalidate_session(host(), port_num(), #session{}) -> ok. %% %% Description: Make the session unavilable for reuse. diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl index acd0d49c19..f1c0073965 100644 --- a/lib/ssl/src/ssl_record.erl +++ b/lib/ssl/src/ssl_record.erl @@ -30,7 +30,6 @@ -include("ssl_alert.hrl"). -include("ssl_handshake.hrl"). -include("ssl_cipher.hrl"). --include("ssl_debug.hrl"). %% Connection state handling -export([init_connection_states/1, @@ -497,6 +496,66 @@ decode_cipher_text(CipherText, ConnnectionStates0) -> #alert{} = Alert -> Alert end. +%%-------------------------------------------------------------------- +-spec encode_data(iolist(), tls_version(), #connection_states{}, integer()) -> + {iolist(), iolist(), #connection_states{}}. +%% +%% Description: Encodes data to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_data(Frag, Version, ConnectionStates, RenegotiateAt) + when byte_size(Frag) < (?MAX_PLAIN_TEXT_LENGTH - 2048) -> + case encode_plain_text(?APPLICATION_DATA,Version,Frag,ConnectionStates, RenegotiateAt) of + {renegotiate, Data} -> + {[], Data, ConnectionStates}; + {Msg, CS} -> + {Msg, [], CS} + end; + +encode_data(Frag, Version, ConnectionStates, RenegotiateAt) when is_binary(Frag) -> + Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH - 2048), + encode_data(Data, Version, ConnectionStates, RenegotiateAt); + +encode_data(Data, Version, ConnectionStates0, RenegotiateAt) when is_list(Data) -> + {ConnectionStates, EncodedMsg, NotEncdedData} = + lists:foldl(fun(B, {CS0, Encoded, Rest}) -> + case encode_plain_text(?APPLICATION_DATA, + Version, B, CS0, RenegotiateAt) of + {renegotiate, NotEnc} -> + {CS0, Encoded, [NotEnc | Rest]}; + {Enc, CS1} -> + {CS1, [Enc | Encoded], Rest} + end + end, {ConnectionStates0, [], []}, Data), + {lists:reverse(EncodedMsg), lists:reverse(NotEncdedData), ConnectionStates}. + +%%-------------------------------------------------------------------- +-spec encode_handshake(iolist(), tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes a handshake message to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_handshake(Frag, Version, ConnectionStates) -> + encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates). + +%%-------------------------------------------------------------------- +-spec encode_alert_record(#alert{}, tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes an alert message to send on the ssl-socket. +%%-------------------------------------------------------------------- +encode_alert_record(#alert{level = Level, description = Description}, + Version, ConnectionStates) -> + encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>, + ConnectionStates). + +%%-------------------------------------------------------------------- +-spec encode_change_cipher_spec(tls_version(), #connection_states{}) -> + {iolist(), #connection_states{}}. +%% +%% Description: Encodes a change_cipher_spec-message to send on the ssl socket. +%%-------------------------------------------------------------------- +encode_change_cipher_spec(Version, ConnectionStates) -> + encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates). %%-------------------------------------------------------------------- %%% Internal functions @@ -550,43 +609,6 @@ split_bin(Bin, ChunkSize, Acc) -> lists:reverse(Acc, [Bin]) end. -encode_data(Frag, Version, ConnectionStates, RenegotiateAt) - when byte_size(Frag) < (?MAX_PLAIN_TEXT_LENGTH - 2048) -> - case encode_plain_text(?APPLICATION_DATA,Version,Frag,ConnectionStates, RenegotiateAt) of - {renegotiate, Data} -> - {[], Data, ConnectionStates}; - {Msg, CS} -> - {Msg, [], CS} - end; - -encode_data(Frag, Version, ConnectionStates, RenegotiateAt) when is_binary(Frag) -> - Data = split_bin(Frag, ?MAX_PLAIN_TEXT_LENGTH - 2048), - encode_data(Data, Version, ConnectionStates, RenegotiateAt); - -encode_data(Data, Version, ConnectionStates0, RenegotiateAt) when is_list(Data) -> - {ConnectionStates, EncodedMsg, NotEncdedData} = - lists:foldl(fun(B, {CS0, Encoded, Rest}) -> - case encode_plain_text(?APPLICATION_DATA, - Version, B, CS0, RenegotiateAt) of - {renegotiate, NotEnc} -> - {CS0, Encoded, [NotEnc | Rest]}; - {Enc, CS1} -> - {CS1, [Enc | Encoded], Rest} - end - end, {ConnectionStates0, [], []}, Data), - {lists:reverse(EncodedMsg), lists:reverse(NotEncdedData), ConnectionStates}. - -encode_handshake(Frag, Version, ConnectionStates) -> - encode_plain_text(?HANDSHAKE, Version, Frag, ConnectionStates). - -encode_alert_record(#alert{level = Level, description = Description}, - Version, ConnectionStates) -> - encode_plain_text(?ALERT, Version, <<?BYTE(Level), ?BYTE(Description)>>, - ConnectionStates). - -encode_change_cipher_spec(Version, ConnectionStates) -> - encode_plain_text(?CHANGE_CIPHER_SPEC, Version, <<1:8>>, ConnectionStates). - encode_plain_text(Type, Version, Data, ConnectionStates, RenegotiateAt) -> #connection_states{current_write = #connection_state{sequence_number = Num}} = ConnectionStates, @@ -626,9 +648,7 @@ cipher(Type, Version, Fragment, CS0) -> BCA} }} = hash_and_bump_seqno(CS0, Type, Version, Length, Fragment), - ?DBG_HEX(Fragment), {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment), - ?DBG_HEX(Ciphered), CS2 = CS1#connection_state{cipher_state=CipherS1}, {Ciphered, CS2}. diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl index 1add203fb0..c49f9f1e6d 100644 --- a/lib/ssl/src/ssl_ssl3.erl +++ b/lib/ssl/src/ssl_ssl3.erl @@ -25,7 +25,6 @@ -module(ssl_ssl3). -include("ssl_cipher.hrl"). --include("ssl_debug.hrl"). -include("ssl_internal.hrl"). -include("ssl_record.hrl"). % MD5 and SHA @@ -41,9 +40,6 @@ -spec master_secret(binary(), binary(), binary()) -> binary(). master_secret(PremasterSecret, ClientRandom, ServerRandom) -> - ?DBG_HEX(PremasterSecret), - ?DBG_HEX(ClientRandom), - ?DBG_HEX(ServerRandom), %% draft-ietf-tls-ssl-version3-00 - 6.2.2 %% key_block = %% MD5(master_secret + SHA(`A' + master_secret + @@ -55,9 +51,8 @@ master_secret(PremasterSecret, ClientRandom, ServerRandom) -> %% MD5(master_secret + SHA(`CCC' + master_secret + %% ServerHello.random + %% ClientHello.random)) + [...]; - B = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48), - ?DBG_HEX(B), - B. + Block = generate_keyblock(PremasterSecret, ClientRandom, ServerRandom, 48), + Block. -spec finished(client | server, binary(), {binary(), binary()}) -> binary(). @@ -79,10 +74,9 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> SHA = handshake_hash(?SHA, MasterSecret, Sender, SHAHash), <<MD5/binary, SHA/binary>>. --spec certificate_verify(key_algo(), binary(), {binary(), binary()}) -> binary(). +-spec certificate_verify(OID::tuple(), binary(), {binary(), binary()}) -> binary(). -certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash}) - when Algorithm == rsa; Algorithm == dhe_rsa -> +certificate_verify(?'rsaEncryption', MasterSecret, {MD5Hash, SHAHash}) -> %% md5_hash %% MD5(master_secret + pad_2 + %% MD5(handshake_messages + master_secret + pad_1)); @@ -94,7 +88,7 @@ certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash}) SHA = handshake_hash(?SHA, MasterSecret, undefined, SHAHash), <<MD5/binary, SHA/binary>>; -certificate_verify(dhe_dss, MasterSecret, {_, SHAHash}) -> +certificate_verify(?'id-dsa', MasterSecret, {_, SHAHash}) -> %% sha_hash %% SHA(master_secret + pad_2 + %% SHA(handshake_messages + master_secret + pad_1)); @@ -111,14 +105,11 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) -> case Method of ?NULL -> ok; _ -> - ?DBG_HEX(Mac_write_secret), - ?DBG_HEX(hash(Method, Fragment)), ok end, Mac = mac_hash(Method, Mac_write_secret, [<<?UINT64(Seq_num), ?BYTE(Type), ?UINT16(Length)>>, Fragment]), - ?DBG_HEX(Mac), Mac. -spec setup_keys(binary(), binary(), binary(), @@ -140,12 +131,6 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) -> <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary, ClientWriteKey:KML/binary, ServerWriteKey:KML/binary, ClientIV:IVS/binary, ServerIV:IVS/binary>> = KeyBlock, - ?DBG_HEX(ClientWriteMacSecret), - ?DBG_HEX(ServerWriteMacSecret), - ?DBG_HEX(ClientWriteKey), - ?DBG_HEX(ServerWriteKey), - ?DBG_HEX(ClientIV), - ?DBG_HEX(ServerIV), {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey, ServerWriteKey, ClientIV, ServerIV}. diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl index d1bc0730ba..3784483e9c 100644 --- a/lib/ssl/src/ssl_tls1.erl +++ b/lib/ssl/src/ssl_tls1.erl @@ -27,7 +27,6 @@ -include("ssl_cipher.hrl"). -include("ssl_internal.hrl"). -include("ssl_record.hrl"). --include("ssl_debug.hrl"). -export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7, setup_keys/6, suites/0]). @@ -60,15 +59,14 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) -> SHA = hash_final(?SHA, SHAHash), prf(MasterSecret, finished_label(Role), [MD5, SHA], 12). --spec certificate_verify(key_algo(), {binary(), binary()}) -> binary(). +-spec certificate_verify(OID::tuple(), {binary(), binary()}) -> binary(). -certificate_verify(Algorithm, {MD5Hash, SHAHash}) when Algorithm == rsa; - Algorithm == dhe_rsa -> +certificate_verify(?'rsaEncryption', {MD5Hash, SHAHash}) -> MD5 = hash_final(?MD5, MD5Hash), SHA = hash_final(?SHA, SHAHash), <<MD5/binary, SHA/binary>>; -certificate_verify(dhe_dss, {_, SHAHash}) -> +certificate_verify(?'id-dsa', {_, SHAHash}) -> hash_final(?SHA, SHAHash). -spec setup_keys(binary(), binary(), binary(), integer(), @@ -133,15 +131,12 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor}, case Method of ?NULL -> ok; _ -> - ?DBG_HEX(Mac_write_secret), - ?DBG_HEX(hash(Method, Fragment)), ok end, Mac = hmac_hash(Method, Mac_write_secret, [<<?UINT64(Seq_num), ?BYTE(Type), ?BYTE(Major), ?BYTE(Minor), ?UINT16(Length)>>, Fragment]), - ?DBG_HEX(Mac), Mac. -spec suites() -> [cipher_suite()]. diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 9e4aecac45..c0a7f8d257 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -40,6 +40,7 @@ MODULES = \ ssl_packet_SUITE \ ssl_payload_SUITE \ ssl_to_openssl_SUITE \ + ssl_session_cache_SUITE \ ssl_test_MACHINE \ old_ssl_active_SUITE \ old_ssl_active_once_SUITE \ diff --git a/lib/ssl/test/erl_make_certs.erl b/lib/ssl/test/erl_make_certs.erl index f8aef55754..8b01ca3ad4 100644 --- a/lib/ssl/test/erl_make_certs.erl +++ b/lib/ssl/test/erl_make_certs.erl @@ -268,7 +268,7 @@ publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) -> subjectPublicKey = Public}; publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) -> Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa', - parameters=#'Dss-Parms'{p=P, q=Q, g=G}}, + parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}}, #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}. validity(Opts) -> @@ -290,7 +290,7 @@ sign_algorithm(#'RSAPrivateKey'{}, Opts) -> end, {Type, 'NULL'}; sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) -> - {?'id-dsa-with-sha1', #'Dss-Parms'{p=P, q=Q, g=G}}. + {?'id-dsa-with-sha1', {params,#'Dss-Parms'{p=P, q=Q, g=G}}}. make_key(rsa, _Opts) -> %% (OBS: for testing only) diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 3cb9337775..8f9554f3ce 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -31,15 +31,10 @@ -define('24H_in_sec', 86400). -define(TIMEOUT, 60000). +-define(LONG_TIMEOUT, 600000). -define(EXPIRE, 10). -define(SLEEP, 500). --behaviour(ssl_session_cache_api). - -%% For the session cache tests --export([init/1, terminate/1, lookup/2, update/3, - delete/2, foldl/3, select_session/2]). - %% Test server callback functions %%-------------------------------------------------------------------- %% Function: init_per_suite(Config) -> Config @@ -51,7 +46,7 @@ %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config0) -> - Dog = ssl_test_lib:timetrap(?TIMEOUT *2), + Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2), crypto:start(), application:start(public_key), ssl:start(), @@ -89,13 +84,6 @@ end_per_suite(_Config) -> %% variable, but should NOT alter/remove any existing entries. %% Description: Initialization before each test case %%-------------------------------------------------------------------- -init_per_testcase(session_cache_process_list, Config) -> - init_customized_session_cache(list, Config); - -init_per_testcase(session_cache_process_mnesia, Config) -> - mnesia:start(), - init_customized_session_cache(mnesia, Config); - init_per_testcase(reuse_session_expired, Config0) -> Config = lists:keydelete(watchdog, 1, Config0), Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5), @@ -142,16 +130,6 @@ init_per_testcase(_TestCase, Config0) -> Dog = test_server:timetrap(?TIMEOUT), [{watchdog, Dog} | Config]. -init_customized_session_cache(Type, Config0) -> - Config = lists:keydelete(watchdog, 1, Config0), - Dog = test_server:timetrap(?TIMEOUT), - ssl:stop(), - application:load(ssl), - application:set_env(ssl, session_cb, ?MODULE), - application:set_env(ssl, session_cb_init_args, [Type]), - ssl:start(), - [{watchdog, Dog} | Config]. - %%-------------------------------------------------------------------- %% Function: end_per_testcase(TestCase, Config) -> _ %% Case - atom() @@ -160,16 +138,6 @@ init_customized_session_cache(Type, Config0) -> %% A list of key/value pairs, holding the test case configuration. %% Description: Cleanup after each test case %%-------------------------------------------------------------------- -end_per_testcase(session_cache_process_list, Config) -> - application:unset_env(ssl, session_cb), - end_per_testcase(default_action, Config); -end_per_testcase(session_cache_process_mnesia, Config) -> - application:unset_env(ssl, session_cb), - application:unset_env(ssl, session_cb_init_args), - mnesia:stop(), - ssl:stop(), - ssl:start(), - end_per_testcase(default_action, Config); end_per_testcase(reuse_session_expired, Config) -> application:unset_env(ssl, session_lifetime), end_per_testcase(default_action, Config); @@ -216,6 +184,8 @@ all(suite) -> ciphers_dsa_signed_certs_ssl3, ciphers_dsa_signed_certs_openssl_names, ciphers_dsa_signed_certs_openssl_names_ssl3, + anonymous_cipher_suites, + default_reject_anonymous, send_close, close_transport_accept, dh_params, server_verify_peer_passive, server_verify_peer_active, server_verify_peer_active_once, @@ -226,7 +196,6 @@ all(suite) -> server_verify_client_once_active, server_verify_client_once_active_once, client_verify_none_passive, client_verify_none_active, client_verify_none_active_once, - session_cache_process_list, session_cache_process_mnesia, reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session, client_renegotiate, server_renegotiate, client_renegotiate_reused_session, @@ -1165,13 +1134,13 @@ ecertfile(Config) when is_list(Config) -> Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, {from, self()}, - {options, ServerBadOpts}]), + {options, ServerBadOpts}]), Port = ssl_test_lib:inet_port(Server), Client = ssl_test_lib:start_client_error([{node, ClientNode}, - {port, Port}, {host, Hostname}, + {port, Port}, {host, Hostname}, {from, self()}, {options, ClientOpts}]), @@ -1522,6 +1491,14 @@ ciphers_dsa_signed_certs_openssl_names_ssl3(Config) when is_list(Config) -> Ciphers = ssl_test_lib:openssl_dsa_suites(), run_suites(Ciphers, Version, Config, dsa). +anonymous_cipher_suites(doc)-> + ["Test the anonymous ciphersuites"]; +anonymous_cipher_suites(suite) -> + []; +anonymous_cipher_suites(Config) when is_list(Config) -> + Version = ssl_record:protocol_version(ssl_record:highest_protocol_version([])), + Ciphers = ssl_test_lib:anonymous_suites(), + run_suites(Ciphers, Version, Config, anonymous). run_suites(Ciphers, Version, Config, Type) -> {ClientOpts, ServerOpts} = @@ -1531,8 +1508,12 @@ run_suites(Ciphers, Version, Config, Type) -> ?config(server_opts, Config)}; dsa -> {?config(client_opts, Config), - ?config(server_dsa_opts, Config)} - end, + ?config(server_dsa_opts, Config)}; + anonymous -> + %% No certs in opts! + {?config(client_opts, Config), + ?config(server_anon, Config)} + end, Result = lists:map(fun(Cipher) -> cipher(Cipher, Version, Config, ClientOpts, ServerOpts) end, @@ -1593,6 +1574,32 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> end. %%-------------------------------------------------------------------- +default_reject_anonymous(doc)-> + ["Test that by default anonymous cipher suites are rejected "]; +default_reject_anonymous(suite) -> + []; +default_reject_anonymous(Config) when is_list(Config) -> + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + [Cipher | _] = ssl_test_lib:anonymous_suites(), + + Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0}, + {from, self()}, + {options, ServerOpts}]), + Port = ssl_test_lib:inet_port(Server), + Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {options, + [{ciphers,[Cipher]} | + ClientOpts]}]), + + ssl_test_lib:check_result(Server, {error, "insufficient security"}, + Client, {error, "insufficient security"}). + +%%-------------------------------------------------------------------- reuse_session(doc) -> ["Test reuse of sessions (short handshake)"]; @@ -2857,11 +2864,13 @@ unknown_server_ca_fail(Config) when is_list(Config) -> {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), - FunAndState = {fun(_,{bad_cert, _} = Reason, _) -> + FunAndState = {fun(_,{bad_cert, unknown_ca} = Reason, _) -> {fail, Reason}; (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, [test_to_update_user_state | UserState]}; + (_, valid_peer, UserState) -> {valid, UserState} end, []}, @@ -2930,6 +2939,8 @@ unknown_server_ca_accept_verify_peer(Config) when is_list(Config) -> (_,{extension, _}, UserState) -> {unknown, UserState}; (_, valid, UserState) -> + {valid, UserState}; + (_, valid_peer, UserState) -> {valid, UserState} end, []}, @@ -2948,7 +2959,7 @@ unknown_server_ca_accept_verify_peer(Config) when is_list(Config) -> %%-------------------------------------------------------------------- unknown_server_ca_accept_backwardscompatibilty(doc) -> - ["Test that the client succeds if the ca is unknown in verify_none mode"]; + ["Test that old style verify_funs will work"]; unknown_server_ca_accept_backwardscompatibilty(suite) -> []; unknown_server_ca_accept_backwardscompatibilty(Config) when is_list(Config) -> @@ -3043,6 +3054,17 @@ der_input_opts(Opts) -> %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +erlang_ssl_receive(Socket, Data) -> + receive + {ssl, Socket, Data} -> + io:format("Received ~p~n",[Data]), + ok; + Other -> + test_server:fail({unexpected_message, Other}) + after ?SLEEP * 3 -> + test_server:fail({did_not_get, Data}) + end. + send_recv_result(Socket) -> ssl:send(Socket, "Hello world"), {ok,"Hello world"} = ssl:recv(Socket, 11), @@ -3082,162 +3104,3 @@ renegotiate_reuse_session(Socket, Data) -> %% Make sure session is registerd test_server:sleep(?SLEEP), renegotiate(Socket, Data). - -session_cache_process_list(doc) -> - ["Test reuse of sessions (short handshake)"]; - -session_cache_process_list(suite) -> - []; -session_cache_process_list(Config) when is_list(Config) -> - session_cache_process(list,Config). - -session_cache_process_mnesia(doc) -> - ["Test reuse of sessions (short handshake)"]; - -session_cache_process_mnesia(suite) -> - []; -session_cache_process_mnesia(Config) when is_list(Config) -> - session_cache_process(mnesia,Config). - -session_cache_process(_Type,Config) when is_list(Config) -> - reuse_session(Config). - -init([Type]) -> - ets:new(ssl_test, [named_table, public, set]), - ets:insert(ssl_test, {type, Type}), - case Type of - list -> - spawn(fun() -> session_loop([]) end); - mnesia -> - mnesia:start(), - {atomic,ok} = mnesia:create_table(sess_cache, []), - sess_cache - end. - -session_cb() -> - [{type, Type}] = ets:lookup(ssl_test, type), - Type. - -terminate(Cache) -> - case session_cb() of - list -> - Cache ! terminate; - mnesia -> - catch {atomic,ok} = - mnesia:delete_table(sess_cache) - end. - -lookup(Cache, Key) -> - case session_cb() of - list -> - Cache ! {self(), lookup, Key}, - receive {Cache, Res} -> Res end; - mnesia -> - case mnesia:transaction(fun() -> - mnesia:read(sess_cache, - Key, read) - end) of - {atomic, [{sess_cache, Key, Value}]} -> - Value; - _ -> - undefined - end - end. - -update(Cache, Key, Value) -> - case session_cb() of - list -> - Cache ! {update, Key, Value}; - mnesia -> - {atomic, ok} = - mnesia:transaction(fun() -> - mnesia:write(sess_cache, - {sess_cache, Key, Value}, write) - end) - end. - -delete(Cache, Key) -> - case session_cb() of - list -> - Cache ! {delete, Key}; - mnesia -> - {atomic, ok} = - mnesia:transaction(fun() -> - mnesia:delete(sess_cache, Key) - end) - end. - -foldl(Fun, Acc, Cache) -> - case session_cb() of - list -> - Cache ! {self(),foldl,Fun,Acc}, - receive {Cache, Res} -> Res end; - mnesia -> - Foldl = fun() -> - mnesia:foldl(Fun, Acc, sess_cache) - end, - {atomic, Res} = mnesia:transaction(Foldl), - Res - end. - -select_session(Cache, PartialKey) -> - case session_cb() of - list -> - Cache ! {self(),select_session, PartialKey}, - receive - {Cache, Res} -> - Res - end; - mnesia -> - Sel = fun() -> - mnesia:select(Cache, - [{{sess_cache,{PartialKey,'$1'}, '$2'}, - [],['$$']}]) - end, - {atomic, Res} = mnesia:transaction(Sel), - Res - end. - -session_loop(Sess) -> - receive - terminate -> - ok; - {Pid, lookup, Key} -> - case lists:keysearch(Key,1,Sess) of - {value, {Key,Value}} -> - Pid ! {self(), Value}; - _ -> - Pid ! {self(), undefined} - end, - session_loop(Sess); - {update, Key, Value} -> - NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)], - session_loop(NewSess); - {delete, Key} -> - session_loop(lists:keydelete(Key,1,Sess)); - {Pid,foldl,Fun,Acc} -> - Res = lists:foldl(Fun, Acc,Sess), - Pid ! {self(), Res}, - session_loop(Sess); - {Pid,select_session,PKey} -> - Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 -> - [[Id, Session]|Acc]; - (_,Acc) -> - Acc - end, - Sessions = lists:foldl(Sel, [], Sess), - Pid ! {self(), Sessions}, - session_loop(Sess) - end. - - -erlang_ssl_receive(Socket, Data) -> - receive - {ssl, Socket, Data} -> - io:format("Received ~p~n",[Data]), - ok; - Other -> - test_server:fail({unexpected_message, Other}) - after ?SLEEP * 3 -> - test_server:fail({did_not_get, Data}) - end. diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl new file mode 100644 index 0000000000..0f39759d97 --- /dev/null +++ b/lib/ssl/test/ssl_session_cache_SUITE.erl @@ -0,0 +1,306 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2010-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/.2 +%% +%% 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(ssl_session_cache_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include("test_server.hrl"). + +-define(SLEEP, 500). +-define(TIMEOUT, 60000). +-define(LONG_TIMEOUT, 600000). +-behaviour(ssl_session_cache_api). + +%% For the session cache tests +-export([init/1, terminate/1, lookup/2, update/3, + delete/2, foldl/3, select_session/2]). + +%% Test server callback functions +%%-------------------------------------------------------------------- +%% Function: init_per_suite(Config) -> Config +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Initialization before the whole suite +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%%-------------------------------------------------------------------- +init_per_suite(Config0) -> + Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2), + crypto:start(), + application:start(public_key), + ssl:start(), + + %% make rsa certs using oppenssl + Result = + (catch make_certs:all(?config(data_dir, Config0), + ?config(priv_dir, Config0))), + test_server:format("Make certs ~p~n", [Result]), + + Config1 = ssl_test_lib:make_dsa_cert(Config0), + Config = ssl_test_lib:cert_options(Config1), + [{watchdog, Dog} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_suite(Config) -> _ +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after the whole suite +%%-------------------------------------------------------------------- +end_per_suite(_Config) -> + ssl:stop(), + crypto:stop(). + +%%-------------------------------------------------------------------- +%% Function: init_per_testcase(TestCase, Config) -> Config +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% +%% Description: Initialization before each test case +%% +%% Note: This function is free to add any key/value pairs to the Config +%% variable, but should NOT alter/remove any existing entries. +%% Description: Initialization before each test case +%%-------------------------------------------------------------------- +init_per_testcase(session_cache_process_list, Config) -> + init_customized_session_cache(list, Config); + +init_per_testcase(session_cache_process_mnesia, Config) -> + mnesia:start(), + init_customized_session_cache(mnesia, Config); + +init_per_testcase(_TestCase, Config0) -> + Config = lists:keydelete(watchdog, 1, Config0), + Dog = test_server:timetrap(?TIMEOUT), + [{watchdog, Dog} | Config]. + +init_customized_session_cache(Type, Config0) -> + Config = lists:keydelete(watchdog, 1, Config0), + Dog = test_server:timetrap(?TIMEOUT), + ssl:stop(), + application:load(ssl), + application:set_env(ssl, session_cb, ?MODULE), + application:set_env(ssl, session_cb_init_args, [Type]), + ssl:start(), + [{watchdog, Dog} | Config]. + +%%-------------------------------------------------------------------- +%% Function: end_per_testcase(TestCase, Config) -> _ +%% Case - atom() +%% Name of the test case that is about to be run. +%% Config - [tuple()] +%% A list of key/value pairs, holding the test case configuration. +%% Description: Cleanup after each test case +%%-------------------------------------------------------------------- +end_per_testcase(session_cache_process_list, Config) -> + application:unset_env(ssl, session_cb), + end_per_testcase(default_action, Config); +end_per_testcase(session_cache_process_mnesia, Config) -> + application:unset_env(ssl, session_cb), + application:unset_env(ssl, session_cb_init_args), + mnesia:kill(), + ssl:stop(), + ssl:start(), + end_per_testcase(default_action, Config); +end_per_testcase(_TestCase, Config) -> + Dog = ?config(watchdog, Config), + case Dog of + undefined -> + ok; + _ -> + test_server:timetrap_cancel(Dog) + end. + +%%-------------------------------------------------------------------- +%% Function: all(Clause) -> TestCases +%% Clause - atom() - suite | doc +%% TestCases - [Case] +%% Case - atom() +%% Name of a test case. +%% Description: Returns a list of all test cases in this test suite +%%-------------------------------------------------------------------- +all(doc) -> + ["Test session cach API"]; + +all(suite) -> + [ + session_cache_process_list, session_cache_process_mnesia + ]. + +session_cache_process_list(doc) -> + ["Test reuse of sessions (short handshake)"]; + +session_cache_process_list(suite) -> + []; +session_cache_process_list(Config) when is_list(Config) -> + session_cache_process(list,Config). +%%-------------------------------------------------------------------- +session_cache_process_mnesia(doc) -> + ["Test reuse of sessions (short handshake)"]; + +session_cache_process_mnesia(suite) -> + []; +session_cache_process_mnesia(Config) when is_list(Config) -> + session_cache_process(mnesia,Config). + + +%%-------------------------------------------------------------------- +%%% Session cache API callbacks +%%-------------------------------------------------------------------- + +init([Type]) -> + ets:new(ssl_test, [named_table, public, set]), + ets:insert(ssl_test, {type, Type}), + case Type of + list -> + spawn(fun() -> session_loop([]) end); + mnesia -> + mnesia:start(), + {atomic,ok} = mnesia:create_table(sess_cache, []), + sess_cache + end. + +session_cb() -> + [{type, Type}] = ets:lookup(ssl_test, type), + Type. + +terminate(Cache) -> + case session_cb() of + list -> + Cache ! terminate; + mnesia -> + catch {atomic,ok} = + mnesia:delete_table(sess_cache) + end. + +lookup(Cache, Key) -> + case session_cb() of + list -> + Cache ! {self(), lookup, Key}, + receive {Cache, Res} -> Res end; + mnesia -> + case mnesia:transaction(fun() -> + mnesia:read(sess_cache, + Key, read) + end) of + {atomic, [{sess_cache, Key, Value}]} -> + Value; + _ -> + undefined + end + end. + +update(Cache, Key, Value) -> + case session_cb() of + list -> + Cache ! {update, Key, Value}; + mnesia -> + {atomic, ok} = + mnesia:transaction(fun() -> + mnesia:write(sess_cache, + {sess_cache, Key, Value}, write) + end) + end. + +delete(Cache, Key) -> + case session_cb() of + list -> + Cache ! {delete, Key}; + mnesia -> + {atomic, ok} = + mnesia:transaction(fun() -> + mnesia:delete(sess_cache, Key) + end) + end. + +foldl(Fun, Acc, Cache) -> + case session_cb() of + list -> + Cache ! {self(),foldl,Fun,Acc}, + receive {Cache, Res} -> Res end; + mnesia -> + Foldl = fun() -> + mnesia:foldl(Fun, Acc, sess_cache) + end, + {atomic, Res} = mnesia:transaction(Foldl), + Res + end. + +select_session(Cache, PartialKey) -> + case session_cb() of + list -> + Cache ! {self(),select_session, PartialKey}, + receive + {Cache, Res} -> + Res + end; + mnesia -> + Sel = fun() -> + mnesia:select(Cache, + [{{sess_cache,{PartialKey,'$1'}, '$2'}, + [],['$$']}]) + end, + {atomic, Res} = mnesia:transaction(Sel), + Res + end. + +session_loop(Sess) -> + receive + terminate -> + ok; + {Pid, lookup, Key} -> + case lists:keysearch(Key,1,Sess) of + {value, {Key,Value}} -> + Pid ! {self(), Value}; + _ -> + Pid ! {self(), undefined} + end, + session_loop(Sess); + {update, Key, Value} -> + NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)], + session_loop(NewSess); + {delete, Key} -> + session_loop(lists:keydelete(Key,1,Sess)); + {Pid,foldl,Fun,Acc} -> + Res = lists:foldl(Fun, Acc,Sess), + Pid ! {self(), Res}, + session_loop(Sess); + {Pid,select_session,PKey} -> + Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 -> + [[Id, Session]|Acc]; + (_,Acc) -> + Acc + end, + Sessions = lists:foldl(Sel, [], Sess), + Pid ! {self(), Sessions}, + session_loop(Sess) + end. + +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- + +session_cache_process(_Type,Config) when is_list(Config) -> + ssl_basic_SUITE:reuse_session(Config). diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index ce164f7e4c..e1e8214ed6 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -300,6 +300,7 @@ cert_options(Config) -> {ssl_imp, new}]}, {server_opts, [{ssl_imp, new},{reuseaddr, true}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, + {server_anon, [{ssl_imp, new},{reuseaddr, true}, {ciphers, anonymous_suites()}]}, {server_verification_opts, [{ssl_imp, new},{reuseaddr, true}, {cacertfile, ServerCaCertFile}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, @@ -616,6 +617,13 @@ openssl_dsa_suites() -> end end, Ciphers). +anonymous_suites() -> + [{dh_anon, rc4_128, md5}, + {dh_anon, des_cbc, sha}, + {dh_anon, '3des_ede_cbc', sha}, + {dh_anon, aes_128_cbc, sha}, + {dh_anon, aes_256_cbc, sha}]. + pem_to_der(File) -> {ok, PemBin} = file:read_file(File), public_key:pem_decode(PemBin). @@ -633,7 +641,7 @@ cipher_result(Socket, Result) -> receive {ssl, Socket, "Hello\n"} -> ssl:send(Socket, " world\n"), - receive + receive {ssl, Socket, " world\n"} -> ok end; diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 7f512f2ab9..afedeaf099 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -27,6 +27,7 @@ -include("test_server.hrl"). -define(TIMEOUT, 120000). +-define(LONG_TIMEOUT, 600000). -define(SLEEP, 1000). -define(OPENSSL_RENEGOTIATE, "r\n"). -define(OPENSSL_QUIT, "Q\n"). @@ -44,7 +45,7 @@ %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config0) -> - Dog = ssl_test_lib:timetrap(?TIMEOUT *2), + Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2), case os:find_executable("openssl") of false -> {skip, "Openssl not found"}; @@ -1116,8 +1117,6 @@ run_suites(Ciphers, Version, Config, Type) -> test_server:fail(cipher_suite_failed_see_test_case_log) end. - - cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> process_flag(trap_exit, true), test_server:format("Testing CipherSuite ~p~n", [CipherSuite]), @@ -1128,8 +1127,8 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> KeyFile = proplists:get_value(keyfile, ServerOpts), Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++ - " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", - + " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ "", + test_server:format("openssl cmd: ~p~n", [Cmd]), OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]), @@ -1140,11 +1139,11 @@ cipher(CipherSuite, Version, Config, ClientOpts, ServerOpts) -> Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port}, {host, Hostname}, - {from, self()}, - {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}}, - {options, - [{ciphers,[CipherSuite]} | - ClientOpts]}]), + {from, self()}, + {mfa, {ssl_test_lib, cipher_result, [ConnectionInfo]}}, + {options, + [{ciphers,[CipherSuite]} | + ClientOpts]}]), port_command(OpenSslPort, "Hello\n"), diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index 709a089892..ee692adb3b 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1,2 @@ -SSL_VSN = 4.0.1 + +SSL_VSN = 4.1.1 diff --git a/lib/stdlib/doc/src/dets.xml b/lib/stdlib/doc/src/dets.xml index ad100d2cf5..b002af6616 100644 --- a/lib/stdlib/doc/src/dets.xml +++ b/lib/stdlib/doc/src/dets.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -816,7 +816,7 @@ ok </item> <item> <p><c>{max_no_slots, no_slots()}</c>, the maximum number - of slots that will be used. The default value is 2 M, and + of slots that will be used. The default value as well as the maximal value is 32 M. Note that a higher value may increase the fragmentation of the table, and conversely, that a smaller value may decrease the fragmentation, at diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index dd4a289c61..746f94d3f4 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -56,8 +56,8 @@ Even if there are no references to a table from any process, it will not automatically be destroyed unless the owner process terminates. It can be destroyed explicitly by using - <c>delete/1</c>.</p> - <p>Since R13B01, table ownership can be transferred at process termination + <c>delete/1</c>. The default owner is the process that created the + table. Table ownership can be transferred at process termination by using the <seealso marker="#heir">heir</seealso> option or explicitly by calling <seealso marker="#give_away/3">give_away/3</seealso>.</p> <p>Some implementation details:</p> @@ -82,11 +82,15 @@ <c>float()</c> that extends to the same value, hence the key <c>1</c> and the key <c>1.0</c> are regarded as equal in an <c>ordered_set</c> table.</p> - <p>In general, the functions below will exit with reason - <c>badarg</c> if any argument is of the wrong format, or if the - table identifier is invalid.</p> </description> - + <section> + <title>Failure</title> + <p>In general, the functions below will exit with reason + <c>badarg</c> if any argument is of the wrong format, if the + table identifier is invalid or if the operation is denied due to + table access rights (<seealso marker="#protected">protected</seealso> + or <seealso marker="#private">private</seealso>).</p> + </section> <section><marker id="concurrency"></marker> <title>Concurrency</title> <p>This module provides some limited support for concurrent access. @@ -481,6 +485,9 @@ Error: fun containing local Erlang function calls <item><c>Item=protection, Value=public|protected|private</c> <br></br> The table access rights.</item> + <item><c>Item=compressed, Value=true|false</c> <br></br> + + Indicates if the table is compressed or not.</item> </list> </desc> </func> @@ -947,9 +954,10 @@ ets:select(Table,MatchSpec),</code> <type> <v>Name = atom()</v> <v>Options = [Option]</v> - <v> Option = Type | Access | named_table | {keypos,Pos} | {heir,pid(),HeirData} | {heir,none} | {write_concurrency,bool()}</v> + <v> Option = Type | Access | named_table | {keypos,Pos} | {heir,pid(),HeirData} | {heir,none} | Tweaks</v> <v> Type = set | ordered_set | bag | duplicate_bag</v> <v> Access = public | protected | private</v> + <v> Tweaks = {write_concurrency,bool()} | {read_concurrency,bool()} | compressed</v> <v> Pos = int()</v> <v> HeirData = term()</v> </type> @@ -963,7 +971,7 @@ ets:select(Table,MatchSpec),</code> table is named or not. If one or more options are left out, the default values are used. This means that not specifying any options (<c>[]</c>) is the same as specifying - <c>[set,protected,{keypos,1},{heir,none},{write_concurrency,false}]</c>.</p> + <c>[set,protected,{keypos,1},{heir,none},{write_concurrency,false},{read_concurrency,false}]</c>.</p> <list type="bulleted"> <item> <p><c>set</c> @@ -1002,12 +1010,14 @@ ets:select(Table,MatchSpec),</code> Any process may read or write to the table.</p> </item> <item> + <marker id="protected"></marker> <p><c>protected</c> The owner process can read and write to the table. Other processes can only read the table. This is the default setting for the access rights.</p> </item> <item> + <marker id="private"></marker> <p><c>private</c> Only the owner process can read or write to the table.</p> </item> @@ -1041,13 +1051,13 @@ ets:select(Table,MatchSpec),</code> <item> <marker id="new_2_write_concurrency"></marker> <p><c>{write_concurrency,bool()}</c> - Performance tuning. Default is <c>false</c>. An operation that + Performance tuning. Default is <c>false</c>, in which case an operation that mutates (writes to) the table will obtain exclusive access, blocking any concurrent access of the same table until finished. If set to <c>true</c>, the table is optimized towards concurrent write access. Different objects of the same table can be mutated (and read) by concurrent processes. This is achieved to some degree - at the expense of single access and concurrent reader performance. + at the expense of sequential access and concurrent reader performance. The <c>write_concurrency</c> option can be combined with the <seealso marker="#new_2_read_concurrency">read_concurrency</seealso> option. You typically want to combine these when large concurrent @@ -1085,6 +1095,15 @@ ets:select(Table,MatchSpec),</code> option. You typically want to combine these when large concurrent read bursts and large concurrent write bursts are common.</p> </item> + <item> + <marker id="new_2_compressed"></marker> + <p><c>compressed</c> + If this option is present, the table data will be stored in a more compact format to + consume less memory. The downside is that it will make table operations slower. + Especially operations that need to inspect entire objects, + such as <c>match</c> and <c>select</c>, will get much slower. The key element + is not compressed in current implementation.</p> + </item> </list> </desc> </func> diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml index c1c4ca9350..969aff4fcb 100644 --- a/lib/stdlib/doc/src/filelib.xml +++ b/lib/stdlib/doc/src/filelib.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -36,14 +36,23 @@ <description> <p>This module contains utilities on a higher level than the <c>file</c> module.</p> + <p>The module supports Unicode file names, so that it will match against regular expressions given in Unicode and that it will find and process raw file names (i.e. files named in a way that does not confirm to the expected encoding).</p> + <p>If the VM operates in Unicode file naming mode on a machine with transparent file naming, the <c>fun()</c> provided to <c>fold_files/5</c> needs to be prepared to handle binary file names.</p> + <p>For more information about raw file names, see the <seealso marker="kernel:file">file</seealso> module.</p> </description> <section> <title>DATA TYPES</title> <code type="none"> -filename() = string() | atom() | DeepList -dirname() = filename() -DeepList = [char() | atom() | DeepList]</code> +filename() = = string() | atom() | DeepList | RawFilename + DeepList = [char() | atom() | DeepList] + RawFilename = binary() + If VM is in unicode filename mode, string() and char() are allowed to be > 255. + RawFilename is a filename not subject to Unicode translation, meaning that it + can contain characters not conforming to the Unicode encoding expected from the + filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode + filename mode). +dirname() = filename()</code> </section> <funcs> @@ -90,6 +99,18 @@ DeepList = [char() | atom() | DeepList]</code> If <c>Recursive</c> is true all sub-directories to <c>Dir</c> are processed. The regular expression matching is done on just the filename without the directory part.</p> + + <p>If Unicode file name translation is in effect and the file + system is completely transparent, file names that cannot be + interpreted as Unicode may be encountered, in which case the + <c>fun()</c> must be prepared to handle raw file names + (i.e. binaries). If the regular expression contains + codepoints beyond 255, it will not match file names that does + not conform to the expected character encoding (i.e. are not + encoded in valid UTF-8).</p> + + <p>For more information about raw file names, see the + <seealso marker="kernel:file">file</seealso> module.</p> </desc> </func> <func> @@ -160,6 +181,12 @@ DeepList = [char() | atom() | DeepList]</code> <p>Matches any number of characters up to the end of the filename, the next dot, or the next slash.</p> </item> + <tag>[Character1,Character2,...]</tag> + <item> + <p>Matches any of the characters listed. Two characters + separated by a hyphen will match a range of characters. + Example: <c>[A-Z]</c> will match any uppercase letter.</p> + </item> <tag>{Item,...}</tag> <item> <p>Alternation. Matches one of the alternatives.</p> diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index fe6c6f898e..cdee6e4a81 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -43,13 +43,22 @@ only, even if the arguments contain back slashes. Use <c>join/1</c> to normalize a file name by removing redundant directory separators.</p> + <p>The module supports raw file names in the way that if a binary is present, or the file name cannot be interpreted according to the return value of + <seealso marker="kernel:file#native_name_encoding/0">file:native_name_encoding/0</seealso>, a raw file name will also be returned. For example filename:join/1 provided with a path component being a binary (and also not being possible to interpret under the current native file name encoding) will result in a raw file name being returned (the join operation will have been performed of course). For more information about raw file names, see the <seealso marker="kernel:file">file</seealso> module.</p> </description> <section> <title>DATA TYPES</title> <code type="none"> -name() = string() | atom() | DeepList -DeepList = [char() | atom() | DeepList]</code> +name() = string() | atom() | DeepList | RawFilename + DeepList = [char() | atom() | DeepList] + RawFilename = binary() + If VM is in unicode filename mode, string() and char() are allowed to be > 255. + RawFilename is a filename not subject to Unicode translation, meaning that it + can contain characters not conforming to the Unicode encoding expected from the + filesystem (i.e. non-UTF-8 characters although the VM is started in Unicode + filename mode). + </code> </section> <funcs> <func> diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml index 80adc3e347..056e7bc9b9 100644 --- a/lib/stdlib/doc/src/re.xml +++ b/lib/stdlib/doc/src/re.xml @@ -37,29 +37,24 @@ <modulesummary>Perl like regular expressions for Erlang</modulesummary> <description> - <p>This module contains functions for regular expression - matching for strings and binaries.</p> + <p>This module contains regular expression matching functions for + strings and binaries.</p> <p>The regular expression syntax and semantics resemble that of - Perl. This library in many ways replaces the old regexp library - written purely in Erlang, as it has a richer syntax as well as - many more options. The library is also faster than the - older regexp implementation.</p> - - <p>Although the library's matching algorithms are currently based - on the PCRE library, it is not to be viewed as an Erlang to PCRE - mapping. Only parts of the PCRE library is interfaced and the re - library in some ways extend PCRE. The PCRE documentation contains - many parts of no interest to the Erlang programmer, why only the - relevant part of the documentation is included here. There should - bee no need to go directly to the PCRE library documentation.</p> + Perl. This library replaces the deprecated pure-Erlang regexp + library; it has a richer syntax, more options and is faster.</p> + + <p>The library's matching algorithms are currently based on the + PCRE library, but not all of the PCRE library is interfaced and + some parts of the library go beyond what PCRE offers. The sections of + the PCRE documentation which are relevant to this module are included + here.</p> <note> - <p>The Erlang literal syntax for strings give special - meaning to the "\" (backslash) character. To literally write - a regular expression or a replacement string containing a - backslash in your code or in the shell, two backslashes have to be written: - "\\".</p> + <p>The Erlang literal syntax for strings uses the "\" + (backslash) character as an escape code. You need to escape + backslashes in literal strings, both in your code and in the shell, + with an additional backslash, i.e.: "\\".</p> </note> @@ -72,7 +67,7 @@ - a binary is allowed as the tail of the list</code> <code type="none"> unicode_binary() = binary() with characters encoded in UTF-8 coding standard - unicode_char() = integer() representing valid unicode codepoint + unicode_char() = integer() representing a valid unicode codepoint chardata() = charlist() | unicode_binary() @@ -82,9 +77,9 @@ <code type="none"> mp() = Opaque datatype containing a compiled regular expression. - The mp() is guaranteed to be a tuple() having the atom - 're_pattern' as it's first element, to allow for matching in + 're_pattern' as its first element, to allow for matching in guards. The arity of the tuple() or the content of the other fields - is however not to be trusted.</code> + may change in future releases.</code> </section> <funcs> <func> @@ -132,7 +127,7 @@ <tag><c>dollar_endonly</c></tag> <item>A dollar metacharacter in the pattern matches only at the end of the subject string. Without this option, a dollar also matches immediately before a newline at the end of the string (but not before any other newlines). The <c>dollar_endonly</c> option is ignored if <c>multiline</c> is given. There is no equivalent option in Perl, and no way to set it within a pattern.</item> <tag><c>dotall</c></tag> - <item>A dot maturate in the pattern matches all characters, including those that indicate newline. Without it, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of the setting of this option.</item> + <item>A dot in the pattern matches all characters, including those that indicate newline. Without it, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of this option's setting.</item> <tag><c>extended</c></tag> <item>Whitespace data characters in the pattern are ignored except when escaped or inside a character class. Whitespace does not include the VT character (ASCII 11). In addition, characters between an unescaped # outside a character class and the next newline, inclusive, are also ignored. This is equivalent to Perl's /x option, and it can be changed within a pattern by a (?x) option setting. @@ -214,9 +209,10 @@ This option makes it possible to include comments inside complicated patterns. N or as a pre compiled <c>mp()</c> in which case it is executed against the subject directly.</p> - <p>When compilation is involved, the exception <c>badarg</c> is thrown if - a compilation error occurs. To locate the error in the regular - expression, use the function <c>re:compile/2</c> to get more information.</p> + <p>When compilation is involved, the exception <c>badarg</c> is + thrown if a compilation error occurs. Call <c>re:compile/2</c> + to get information about the location of the error in the + regular expression.</p> <p>If the regular expression is previously compiled, the option list can only contain the options <c>anchored</c>, @@ -246,7 +242,7 @@ This option makes it possible to include comments inside complicated patterns. N how captured substrings are to be returned (as index tuples, lists or binaries). The <c>capture</c> option makes the function quite flexible and powerful. The different options are described - in detail below</p> + in detail below.</p> <p>If the capture options describe that no substring capturing at all is to be done (<c>{capture, none}</c>), the function will @@ -256,7 +252,7 @@ This option makes it possible to include comments inside complicated patterns. N be done either by specifying <c>none</c> or an empty list as <c>ValueSpec</c>.</p> - <p>A description of all the options relevant for execution follows:</p> + <p>The options relevant for execution are:</p> <taglist> <tag><c>anchored</c></tag> @@ -270,27 +266,25 @@ This option makes it possible to include comments inside complicated patterns. N <tag><c>global</c></tag> <item> - <p>Implements global (repetitive) search as the <c>g</c> flag in - i.e. Perl. Each match found is returned as a separate + <p>Implements global (repetitive) search (the <c>g</c> flag in + Perl). Each match is returned as a separate <c>list()</c> containing the specific match as well as any matching subexpressions (or as specified by the <c>capture option</c>). The <c>Captured</c> part of the return value will - hence be a <c>list()</c> of <c>list()</c>'s when this + hence be a <c>list()</c> of <c>list()</c>s when this option is given.</p> - <p>When the regular expression matches an empty string, the - behaviour might seem non-intuitive, why the behaviour requites - some clarifying. With the global option, <c>re:run/3</c> - handles empty matches in the same way as Perl, meaning that a - match at any point giving an empty string (with length 0) will - be retried with the options - <c>[anchored, notempty]</c> as well. If that - search gives a result of length > 0, the result is included. - An example:</p> + <p>The interaction of the global option with a regular + expression which matches an empty string surprises some users. + When the global option is given, <c>re:run/3</c> handles empty + matches in the same way as Perl: a zero-length match at any + point will be retried with the options <c>[anchored, + notempty]</c> as well. If that search gives a result of length + > 0, the result is included. For example:</p> <code> re:run("cat","(|at)",[global]).</code> - <p>The matching will be performed as following:</p> + <p>The following matching will be performed:</p> <taglist> <tag>At offset <c>0</c></tag> <item>The regexp <c>(|at)</c> will first match at the initial @@ -302,11 +296,11 @@ This option makes it possible to include comments inside complicated patterns. N <item> The search is retried with the options <c>[anchored, notempty]</c> at the same position, which does not give any interesting result of longer - length, why the search position is now advanced to the next + length, so the search position is now advanced to the next character (<c>a</c>).</item> <tag>At offset <c>1</c></tag> - <item>Now the search results in - <c>[{1,0},{1,0}]</c> meaning this search will also be repeated + <item>This time, the search results in + <c>[{1,0},{1,0}]</c>, so this search will also be repeated with the extra options.</item> <tag>At offset <c>1</c> with <c>[anchored, notempty]</c></tag> <item>Now the <c>ab</c> alternative @@ -333,16 +327,17 @@ This option makes it possible to include comments inside complicated patterns. N entire match fails. For example, if the pattern</p> <code> a?b?</code> <p>is applied to a string not beginning with "a" or "b", it - matches the empty string at the start of the subject. With - <c>notempty</c> given, this match is not valid, so re:run/3 searches - further into the string for occurrences of "a" or "b".</p> + would normally match the empty string at the start of the + subject. With the <c>notempty</c> option, this match is not + valid, so re:run/3 searches further into the string for + occurrences of "a" or "b".</p> <p>Perl has no direct equivalent of <c>notempty</c>, but it does make a special case of a pattern match of the empty string within its split() function, and when using the /g modifier. It is possible to emulate Perl's behavior after matching a null string by first trying the match again at the same offset with - <c>notempty</c> and <c>anchored</c>, and then if that fails by + <c>notempty</c> and <c>anchored</c>, and then, if that fails, by advancing the starting offset (see below) and trying an ordinary match again.</p> </item> @@ -352,7 +347,7 @@ This option makes it possible to include comments inside complicated patterns. N string is not the beginning of a line, so the circumflex metacharacter should not match before it. Setting this without <c>multiline</c> (at compile time) causes circumflex never to - match. This option affects only the behavior of the circumflex + match. This option only affects the behavior of the circumflex metacharacter. It does not affect \A.</item> <tag><c>noteol</c></tag> @@ -388,7 +383,7 @@ This option makes it possible to include comments inside complicated patterns. N </taglist> </item> <tag><c>bsr_anycrlf</c></tag> - <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters.(overrides compilation option)</item> + <item>Specifies specifically that \R is to match only the cr, lf or crlf sequences, not the Unicode specific newline characters. (overrides compilation option)</item> <tag><c>bsr_unicode</c></tag> <item>Specifies specifically that \R is to match all the Unicode newline characters (including crlf etc, the default).(overrides compilation option)</item> @@ -444,7 +439,7 @@ This option makes it possible to include comments inside complicated patterns. N <tag><c>none</c></tag> <item>Do not return matching subpatterns at all, yielding the single atom <c>match</c> as the return value of the function when matching successfully instead of the <c>{match, list()}</c> return. Specifying an empty list gives the same behavior.</item> </taglist> - <p>The value list is a list of indexes for the subpatterns to return, where index 0 is for all of the pattern, and 1 is for the first explicit capturing subpattern in the regular expression, and so forth. When using named captured subpatterns (see below) in the regular expression, one can use <c>atom()</c>'s or <c>string()</c>'s to specify the subpatterns to be returned. This deserves an example, consider the following regular expression:</p> + <p>The value list is a list of indexes for the subpatterns to return, where index 0 is for all of the pattern, and 1 is for the first explicit capturing subpattern in the regular expression, and so forth. When using named captured subpatterns (see below) in the regular expression, one can use <c>atom()</c>s or <c>string()</c>s to specify the subpatterns to be returned. For example, consider the regular expression:</p> <code> ".*(abcd).*"</code> <p>matched against the string ""ABCabcdABC", capturing only the "abcd" part (the first explicit subpattern):</p> <code> re:run("ABCabcdABC",".*(abcd).*",[{capture,[1]}]).</code> @@ -455,7 +450,7 @@ This option makes it possible to include comments inside complicated patterns. N <code> ".*(?<FOO>abcd).*"</code> <p>With this expression, we could still give the index of the subpattern with the following call:</p> <code> re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,[1]}]).</code> - <p>giving the same result as before. But as the subpattern is named, we can also give its name in the value list:</p> + <p>giving the same result as before. But, since the subpattern is named, we can also specify its name in the value list:</p> <code> re:run("ABCabcdABC",".*(?<FOO>abcd).*",[{capture,['FOO']}]).</code> <p>which would yield the same result as the earlier examples, namely:</p> <code> {match,[{3,4}]}</code> @@ -473,15 +468,15 @@ This option makes it possible to include comments inside complicated patterns. N <item><p>Optionally specifies how captured substrings are to be returned. If omitted, the default of <c>index</c> is used. The <c>Type</c> can be one of the following:</p> <taglist> <tag><c>index</c></tag> - <item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly imagined) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem contra-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item> + <item>Return captured substrings as pairs of byte indexes into the subject string and length of the matching string in the subject (as if the subject string was flattened with <c>iolist_to_binary/1</c> or <c>unicode:characters_to_binary/2</c> prior to matching). Note that the <c>unicode</c> option results in <em>byte-oriented</em> indexes in a (possibly virtual) <em>UTF-8 encoded</em> binary. A byte index tuple <c>{0,2}</c> might therefore represent one or two characters when <c>unicode</c> is in effect. This might seem counter-intuitive, but has been deemed the most effective and useful way to way to do it. To return lists instead might result in simpler code if that is desired. This return type is the default.</item> <tag><c>list</c></tag> - <item>Return matching substrings as lists of characters (Erlang <c>string()</c>'s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that has is not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item> + <item>Return matching substrings as lists of characters (Erlang <c>string()</c>s). It the <c>unicode</c> option is used in combination with the \C sequence in the regular expression, a captured subpattern can contain bytes that are not valid UTF-8 (\C matches bytes regardless of character encoding). In that case the <c>list</c> capturing may result in the same types of tuples that <c>unicode:characters_to_list/2</c> can return, namely three-tuples with the tag <c>incomplete</c> or <c>error</c>, the successfully converted characters and the invalid UTF-8 tail of the conversion as a binary. The best strategy is to avoid using the \C sequence when capturing lists.</item> <tag><c>binary</c></tag> - <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries is in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item> + <item>Return matching substrings as binaries. If the <c>unicode</c> option is used, these binaries are in UTF-8. If the \C sequence is used together with <c>unicode</c> the binaries may be invalid UTF-8.</item> </taglist> </item> </taglist> - <p>In general, subpatterns that got assigned no value in the match are returned as the tuple <c>{-1,0}</c> when <c>type</c> is <c>index</c>. Unassigned subpatterns are returned as the empty binary or list respectively for other return types. Consider the regular expression:</p> + <p>In general, subpatterns that were not assigned a value in the match are returned as the tuple <c>{-1,0}</c> when <c>type</c> is <c>index</c>. Unassigned subpatterns are returned as the empty binary or list, respectively, for other return types. Consider the regular expression:</p> <code> ".*((?<FOO>abdd)|a(..d)).*"</code> <p>There are three explicitly capturing subpatterns, where the opening parenthesis position determines the order in the result, hence <c>((?<FOO>abdd)|a(..d))</c> is subpattern index 1, <c>(?<FOO>abdd)</c> is subpattern index 2 and <c>(..d)</c> is subpattern index 3. When matched against the following string:</p> <code> "ABCabcdABC"</code> @@ -533,8 +528,8 @@ This option makes it possible to include comments inside complicated patterns. N <v>NLSpec = cr | crlf | lf | anycrlf | any </v> </type> <desc> - <p>Replaces the matched part of the <c>Subject</c> string with the content of <c>Replacement</c>.</p> - <p>Options are given as to the <c>re:run/3</c> function except that the <c>capture</c> option of <c>re:run/3</c> is not allowed. + <p>Replaces the matched part of the <c>Subject</c> string with the contents of <c>Replacement</c>.</p> + <p>The permissible options are the same as for <c>re:run/3</c>, except that the <c>capture</c> option is not allowed. Instead a <c>{return, ReturnType}</c> is present. The default return type is <c>iodata</c>, constructed in a way to minimize copying. The <c>iodata</c> result can be used directly in many i/o-operations. If a flat <c>list()</c> is desired, specify <c>{return, list}</c> and if a binary is preferred, specify <c>{return, binary}</c>.</p> @@ -544,7 +539,7 @@ This option makes it possible to include comments inside complicated patterns. N a Unicode <c>charlist()</c>. If compilation is done implicitly and the <c>unicode</c> compilation option is given to this function, both the regular expression and the <c>Subject</c> - should be given as valid Unicode <c>charlist()</c>'s.</p> + should be given as valid Unicode <c>charlist()</c>s.</p> <p>The replacement string can contain the special character <c>&</c>, which inserts the whole matching expression in the @@ -554,7 +549,7 @@ This option makes it possible to include comments inside complicated patterns. N generated by the regular expression, nothing is inserted.</p> <p>To insert an <c>&</c> or <c>\</c> in the result, precede it with a <c>\</c>. Note that Erlang already gives a special - meaning to <c>\</c> in literal strings, why a single <c>\</c> + meaning to <c>\</c> in literal strings, so a single <c>\</c> has to be written as <c>"\\"</c> and therefore a double <c>\</c> as <c>"\\\\"</c>. Example:</p> <code> re:replace("abcd","c","[&]",[{return,list}]).</code> @@ -611,7 +606,7 @@ This option makes it possible to include comments inside complicated patterns. N a Unicode <c>charlist()</c>. If compilation is done implicitly and the <c>unicode</c> compilation option is given to this function, both the regular expression and the <c>Subject</c> - should be given as valid Unicode <c>charlist()</c>'s.</p> + should be given as valid Unicode <c>charlist()</c>s.</p> <p>The result is given as a list of "strings", the preferred datatype given in the <c>return</c> option (default iodata).</p> @@ -656,25 +651,25 @@ This option makes it possible to include comments inside complicated patterns. N <p>Here the regular expression matched first the "l", causing "Er" to be the first part in the result. When the regular expression matched, the (only) subexpression was - bound to the "l", why the "l" is inserted + bound to the "l", so the "l" is inserted in the group together with "Er". The next match is of the "n", making "a" the next part to be - returned. As the subexpression is bound to the substring + returned. Since the subexpression is bound to the substring "n" in this case, the "n" is inserted into this group. The last group consists of the rest of the string, as no more matches are found.</p> <p>By default, all parts of the string, including the empty - strings are returned from the function. As an example:</p> + strings, are returned from the function. For example:</p> <code> re:split("Erlang","[lg]",[{return,list}]).</code> - <p>The result will be:</p> + <p>will return:</p> <code> ["Er","an",[]]</code> - <p>as the matching of the "g" in the end of the string + <p>since the matching of the "g" in the end of the string leaves an empty rest which is also returned. This behaviour differs from the default behaviour of the split function in Perl, where empty strings at the end are by default removed. To @@ -701,10 +696,10 @@ This option makes it possible to include comments inside complicated patterns. N <p>Note that the last part is "ang", not "an", as we only specified splitting into two parts, - and the splitting stops when enough parts are given, why the - result differs from that of <c>trim</c>.</p> + and the splitting stops when enough parts are given, which is + why the result differs from that of <c>trim</c>.</p> - <p>More than three parts are not possible with this indata, why</p> + <p>More than three parts are not possible with this indata, so</p> <code> re:split("Erlang","[lg]",[{return,list},{parts,4}]).</code> @@ -745,7 +740,7 @@ This option makes it possible to include comments inside complicated patterns. N the parts of the string matching the subexpressions of the regexp.</p> <p>The return value from the function will in this case be a - <c>list()</c> of <c>list()</c>'s. Each sublist begins with the + <c>list()</c> of <c>list()</c>s. Each sublist begins with the string picked out of the subject string, followed by the parts matching each of the subexpressions in order of occurrence in the regular expression.</p> @@ -782,10 +777,8 @@ This option makes it possible to include comments inside complicated patterns. N <title>PERL LIKE REGULAR EXPRESSIONS SYNTAX</title> <p>The following sections contain reference material for the regular expressions used by this module. The regular expression - reference is taken from the PCRE documentation, but converted as - needed.</p> - <p>The documentation is altered where appropriate and where the re - module behaves differently than the PCRE library.</p> + reference is based on the PCRE documentation, with changes in + cases where the re module behaves differently to the PCRE library.</p> </section> <section><title>PCRE regular expression details</title> diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml index c696434d49..45fa0847a8 100644 --- a/lib/stdlib/doc/src/supervisor.xml +++ b/lib/stdlib/doc/src/supervisor.xml @@ -156,7 +156,7 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules} the child process to terminate by calling <c>exit(Child,shutdown)</c> and then wait for an exit signal with reason <c>shutdown</c> back from the child process. If - no exit signal is received within the specified time, + no exit signal is received within the specified number of milliseconds, the child process is unconditionally terminated using <c>exit(Child,kill)</c>.</p> <p>If the child process is another supervisor, <c>Shutdown</c> diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml index f1b0659ea2..c02ea3cbcb 100644 --- a/lib/stdlib/doc/src/unicode_usage.xml +++ b/lib/stdlib/doc/src/unicode_usage.xml @@ -5,7 +5,7 @@ <header> <copyright> <year>1999</year> - <year>2009</year> + <year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -168,6 +168,48 @@ Eshell V5.7 (abort with ^G) <image file="ushell2.gif"><icaption>Unicode characters in allowed and disallowed context</icaption></image> </section> <section> +<title>Unicode file names</title> +<p>Most modern operating systems support Unicode file names in some way or another. There are several different ways to do this and Erlang by default treats the different approaches differently:</p> +<taglist> +<tag>Mandatory Unicode file naming</tag> +<item> +<p>Windows and, for most common uses, MacOSX enforces Unicode support for file names. All files created in the filesystem has names that can consistently be interpreted. In MacOSX, all file names are retrieved in UTF-8 encoding, while Windows have selected an approach where each system call handling file names has a special Unicode aware variant, giving much the same effect. There are no file names on these systems that are not Unicode file names, why the default behavior of the Erlang VM is to work in "Unicode file name translation mode", meaning that a file name can be given as a Unicode list and that will be automatically translated to the proper name encoding for the underlying operating and file system.</p> +<p>Doing i.e. a <c>file:list_dir/1</c> on one of these systems may return Unicode lists with codepoints beyond 255, depending on the content of the actual filesystem.</p> +<p>As the feature is fairly new, you may still stumble upon non core applications that cannot handle being provided with file names containing characters with codepoints larger than 255, but the core Erlang system should have no problems with Unicode file names.</p> +</item> +<tag>Transparent file naming</tag> +<item> +<p>Most Unix operating systems have adopted a simpler approach, namely that Unicode file naming is not enforced, but by convention. Those systems usually use UTF-8 encoding for Unicode file names, but do not enforce it. On such a system, a file name containing characters having codepoints between 128 and 255 may be named either as plain ISO-latin-1 or using UTF-8 encoding. As no consistency is enforced, the Erlang VM can do no consistent translation of all file names. If the VM would automatically select encoding based on heuristics, one could get unexpected behavior on these systems, therefore file names not being encoded in UTF-8 are returned as "raw file names" if Unicode file naming support is turned on.</p> +<p>A raw file name is not a list, but a binary. Many non core applications still does not handle file names given as binaries, why such raw names are avoided by default. This means that systems having implemented Unicode file naming through transparent file systems and an UTF-8 convention, does not by default have Unicode file naming turned on. Explicitly turning Unicode file name handling on for these types of systems is considered experimental.</p> +</item> +</taglist> +<p>The Unicode file naming support was introduced with OTP release R14B01. A VM operating in Unicode file mode can work with files having names in any language or character set (as long as it's supported by the underlying OS and file system). The Unicode character list is used to denote file or directory names and if the file system content is listed, you will also be able to get Unicode lists as return value. The support lies in the kernel and stdlib modules, why most applications (that does not explicitly require the file names to be in the ISO-latin-1 range) will benefit from the Unicode support without change.</p> + +<p>On Operating systems with mandatory Unicode file names, this means that you more easily conform to the file names of other (non Erlang) applications, and you can also process file names that, at least on Windows, where completely inaccessible (due to having names that could not be represented in ISO-latin-1). Also you will avoid creating incomprehensible file names on MacOSX as the vfs layer of the OS will accept all your file names as UTF-8 and will not rewrite them.</p> + +<p>For most systems, turning on Unicode file name translation is no problem even if it uses transparent file naming. Very few systems have mixed file name encodings. A consistent UTF-8 named system will work perfectly in Unicode file name mode. It is still however considered experimental in R14B01. Unicode file name translation is turned on with the <c>+fnu</c> switch to the <c>erl</c> program. If the VM is started in Unicode file name translation mode, <c>file:native_name_encoding/0</c> will return the atom <c>utf8</c>.</p> + +<p>In Unicode file name mode, file names given to the BIF <c>open_port/2</c> with the option <c>{spawn_executable,...}</c> are also interpreted as Unicode. So is the parameter list given in the <c>args</c> option available when using <c>spawn_executable</c>. The UTF-8 translation of arguments can be avoided using binaries, see the discussion about raw file names below.</p> + +<p>It is worth noting that the file <c>encoding</c> options given when opening a file has nothing to do with the file <em>name</em> encoding convention. You can very well open files containing UTF-8 but having file names in ISO-latin-1 or vice versa.</p> + +<note>Erlang drivers and NIF shared objects still can not be named with names containing codepoints beyond 127. This is a known limitation to be removed in a future release. Erlang modules however can, but it is definitely not a good idea and is still considered experimental.</note> + +<section> +<title>Notes about raw file names and automatic file name conversion</title> +<p>Raw file names is introduced together with Unicode file name support in erts-5.8.2 (OTP R14B01). The reason the "raw file names" is introduced in the system is to be able to consistently represent file names given in different encodings on the same system. Having the VM automatically translate a file name that is not in UTF-8 when to a list of Unicode characters might seem practical, but this would open up for both duplicate file names and other inconsistent behavior. Consider a directory containing a file named "bj�rn" in ISO-latin-1, while the Erlang VM is operating in Unicode file name mode (and therefore expecting UTF-8 file naming). The ISO-latin-1 name is not valid UTF-8 and one could be tempted to think that automatic conversion in for example <c>file:list_dir/1</c> is a good idea. But what would happen if we later tried to open the file and has the name as a Unicode list (magically converted from the ISO-latin-1 file name)? The VM will convert the file name given to UTF-8, as this is the encoding expected. Effectively this means trying to open the file named <<"bj�rn"/utf8>>. This file does not exist, and even if it existed it would not be the same file as the one that was listed. We could even create two files named "bj�rn", one named in the UTF-8 encoding and one not. If <c>file:list_dir/1</c> would automatically convert the ISO-latin-1 file name to a list, we would get two identical file names as the result. To avoid this, we need to differentiate between file names being properly encoded according to the Unicode file naming convention (i.e. UTF-8) and file names being invalid under the encoding. This is done by representing invalid encoding as "raw" file names, i.e. as binaries.</p> +<p>The core system of Erlang (kernel and stdlib) accept raw file names except for loadable drivers and executables invoked using <c>open_port({spawn, ...} ...)</c>. <c>open_port({spawn_executable, ...} ...)</c> however does accept them. As mentioned earlier, the arguments given in the option list to <c>open_port({spawn_executable, ...} ...)</c> undergo the same conversion as the file names, meaning that the executable will be provided with arguments in UTF-8 as well. This translation is avoided consistently with how the file names are treated, by giving the argument as a binary.</p> +<p>To force Unicode file name translation mode on systems where this is not the default is considered experimental in OTP R14B01 due to the raw file names possibly being a new experience to the programmer and that the non core applications of OTP are not tested for compliance with raw file names yet. Unicode file name translation is expected to be default in future releases.</p> +<p>If working with raw file names, one can still conform to the encoding convention of the Erlang VM by using the <c>file:native_name_encoding/0</c> function, which returns either the atom <c>latin1</c> or the atom <c>utf8</c> depending on the file name translation mode. On Linux, an VM started without explicitly stating the file name translation mode will default to <c>latin1</c> as the native file name encoding, why file names on the disk encoded as UTF-8 will be returned as a list of the names interpreted as ISO-latin-1. The "UTF-8 list" is not a practical type for displaying or operating on in Erlang, but it is backward compatible and usable in all functions requiring a file name. On Windows and MacOSX, the default behavior is that of file name translation, why the <c>file:native_name_encoding/0</c> by default returns <c>utf8</c> on those systems (the fact that Windows actually does not use UTF-8 on the file system level can safely be ignored by the Erlang programmer). The default behavior can be changed using the <c>+fnu</c> or <c>+fnl</c> options to the VM, see the <c>erl</c> command manual page.</p> +<p>Even if you are operating without Unicode file naming translation automatically done by the VM, you can access and create files with names in UTF-8 encoding by using raw file names encoded as UTF-8. Enforcing the UTF-8 encoding regardless of the mode the Erlang VM is started in might, in some circumstances be a good idea, as the convention of using UTF-8 file names is spreading.</p> +</section> +<section> +<title>Notes about MacOSX</title> +<p>MacOSXs vfs layer enforces UTF-8 file names in a quite aggressive way. Older versions did this by simply refusing to create non UTF-8 conforming file names, while newer versions replace offending bytes with the sequence "%HH", where HH is the original character in hexadecimal notation. As Unicode translation is enabled by default on MacOSX, the only way to come up against this is to either start the VM with the <c>+fnl</c> flag or to use a raw file name in <c>latin1</c> encoding. In that case, the file can not be opened with the same name as the one used to create this. The problem is by design in newer versions of MacOSX.</p> +<p>MacOSX also reorganizes the names of files so that the representation of accents etc is denormalized, i.e. the character <c>�</c> is represented as the codepoints [111,776], where 111 is the character <c>o</c> and 776 is a special accent character. This type of denormalized Unicode is otherwise very seldom used and Erlang normalizes those file names on retrieval, so that denormalized file names is not passed up to the Erlang application. In Erlang the file name "bj�rn" is retrieved as [98,106,246,114,110], not as [98,106,117,776,114,110], even though the file system might think differently.</p> +</section> +</section> +<section> <title>Unicode-aware modules</title> <p>Most of the modules in Erlang/OTP are of course Unicode-unaware in the sense that they have no notion of Unicode and really shouldn't have. Typically they handle non-textual or byte-oriented data (like <c>gen_tcp</c> etc).</p> <p>Modules that actually handle textual data (like <c>io_lib</c>, <c>string</c> etc) are sometimes subject to conversion or extension to be able to handle Unicode characters.</p> diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl index 6d50a575eb..d04d8f191f 100644 --- a/lib/stdlib/src/c.erl +++ b/lib/stdlib/src/c.erl @@ -659,7 +659,7 @@ portformat(Name, Id, Cmd) -> pwd() -> case file:get_cwd() of {ok, Str} -> - ok = io:format("~s\n", [Str]); + ok = io:format("~ts\n", [fixup_one_bin(Str)]); {error, _} -> ok = io:format("Cannot determine current directory\n") end. @@ -684,11 +684,27 @@ ls() -> ls(Dir) -> case file:list_dir(Dir) of {ok, Entries} -> - ls_print(sort(Entries)); + ls_print(sort(fixup_bin(Entries))); {error,_E} -> format("Invalid directory\n") end. +fixup_one_bin(X) when is_binary(X) -> + L = binary_to_list(X), + [ if + El > 127 -> + $?; + true -> + El + end || El <- L]; +fixup_one_bin(X) -> + X. +fixup_bin([H|T]) -> + [fixup_one_bin(H) | fixup_bin(T)]; +fixup_bin([]) -> + []. + + ls_print([]) -> ok; ls_print(L) -> Width = min([max(lengths(L, [])), 40]) + 5, @@ -698,7 +714,7 @@ ls_print(X, Width, Len) when Width + Len >= 80 -> io:nl(), ls_print(X, Width, 0); ls_print([H|T], Width, Len) -> - io:format("~-*s",[Width,H]), + io:format("~-*ts",[Width,H]), ls_print(T, Width, Len+Width); ls_print([], _, _) -> io:nl(). diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl index 4584b8184f..6c91f1efb7 100644 --- a/lib/stdlib/src/dets.erl +++ b/lib/stdlib/src/dets.erl @@ -147,6 +147,7 @@ bin, % small chunk not consumed, or 'eof' at end-of-file alloc, % the part of the file not yet scanned, mostly a binary tab, + proc, % the pid of the Dets process match_program % true | compiled_match_spec() | undefined }). @@ -208,8 +209,6 @@ all() -> bchunk(Tab, start) -> badarg(treq(Tab, {bchunk_init, Tab}), [Tab, start]); -bchunk(Tab, #dets_cont{bin = eof, tab = Tab}) -> - '$end_of_table'; bchunk(Tab, #dets_cont{what = bchunk, tab = Tab} = State) -> badarg(treq(Tab, {bchunk, State}), [Tab, State]); bchunk(Tab, Term) -> @@ -722,11 +721,14 @@ init_chunk_match(Tab, Pat, What, N) when is_integer(N), N >= 0; N =:= default -> case compile_match_spec(What, Pat) of {Spec, MP} -> - case req(dets_server:get_pid(Tab), {match, MP, Spec, N}) of + Proc = dets_server:get_pid(Tab), + case req(Proc, {match, MP, Spec, N}) of {done, L} -> - {L, #dets_cont{tab = Tab, what = What, bin = eof}}; + {L, #dets_cont{tab = Tab, proc = Proc, what = What, + bin = eof}}; {cont, State} -> - chunk_match(State#dets_cont{what = What, tab = Tab}); + chunk_match(State#dets_cont{what = What, tab = Tab, + proc = Proc}); Error -> Error end; @@ -736,34 +738,28 @@ init_chunk_match(Tab, Pat, What, N) when is_integer(N), N >= 0; init_chunk_match(_Tab, _Pat, _What, _) -> badarg. -chunk_match(State) -> - case catch dets_server:get_pid(State#dets_cont.tab) of - {'EXIT', _Reason} -> - badarg; - _Proc when State#dets_cont.bin =:= eof -> - '$end_of_table'; - Proc -> - case req(Proc, {match_init, State}) of - {cont, {Bins, NewState}} -> - MP = NewState#dets_cont.match_program, - case catch do_foldl_bins(Bins, MP) of - {'EXIT', _} -> - case ets:is_compiled_ms(MP) of - true -> - Bad = dets_utils:bad_object(chunk_match, - Bins), - req(Proc, {corrupt, Bad}); - false -> - badarg - end; - [] -> - chunk_match(NewState); - Terms -> - {Terms, NewState} - end; - Error -> - Error - end +chunk_match(#dets_cont{proc = Proc}=State) -> + case req(Proc, {match_init, State}) of + '$end_of_table'=Reply -> + Reply; + {cont, {Bins, NewState}} -> + MP = NewState#dets_cont.match_program, + case catch do_foldl_bins(Bins, MP) of + {'EXIT', _} -> + case ets:is_compiled_ms(MP) of + true -> + Bad = dets_utils:bad_object(chunk_match, Bins), + req(Proc, {corrupt, Bad}); + false -> + badarg + end; + [] -> + chunk_match(NewState); + Terms -> + {Terms, NewState} + end; + Error -> + Error end. do_foldl_bins(Bins, true) -> @@ -1094,7 +1090,9 @@ do_apply_op(Op, From, Head, N) -> {N2, H2} when is_record(H2, head), is_integer(N2) -> open_file_loop(H2, N2); H2 when is_record(H2, head) -> - open_file_loop(H2, N) + open_file_loop(H2, N); + {{more,From1,Op1,N1}, NewHead} -> + do_apply_op(Op1, From1, NewHead, N1) catch exit:normal -> exit(normal); @@ -1363,37 +1361,35 @@ start_auto_save_timer(Head) -> %% lookup requests in parallel. Evalute delete_object, delete and %% insert as well. stream_op(Op, Pid, Pids, Head, N) -> - stream_op(Head, Pids, [], N, Pid, Op, Head#head.fixed). + #head{fixed = Fxd, update_mode = M} = Head, + stream_op(Head, Pids, [], N, Pid, Op, Fxd, M). -stream_loop(Head, Pids, C, N, false = Fxd) -> +stream_loop(Head, Pids, C, N, false = Fxd, M) -> receive ?DETS_CALL(From, Message) -> - stream_op(Head, Pids, C, N, From, Message, Fxd) + stream_op(Head, Pids, C, N, From, Message, Fxd, M) after 0 -> stream_end(Head, Pids, C, N, no_more) end; -stream_loop(Head, Pids, C, N, _Fxd) -> +stream_loop(Head, Pids, C, N, _Fxd, _M) -> stream_end(Head, Pids, C, N, no_more). -stream_op(Head, Pids, C, N, Pid, {lookup_keys,Keys}, Fxd) -> +stream_op(Head, Pids, C, N, Pid, {lookup_keys,Keys}, Fxd, M) -> NC = [{{lookup,Pid},Keys} | C], - stream_loop(Head, Pids, NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, {insert, _Objects} = Op, Fxd) -> - NC = [Op | C], - stream_loop(Head, [Pid | Pids], NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, {insert_new, _Objects} = Op, Fxd) -> + stream_loop(Head, Pids, NC, N, Fxd, M); +stream_op(Head, Pids, C, N, Pid, {insert, _Objects} = Op, Fxd, dirty = M) -> NC = [Op | C], - stream_loop(Head, [Pid | Pids], NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, {delete_key, _Keys} = Op, Fxd) -> + stream_loop(Head, [Pid | Pids], NC, N, Fxd, M); +stream_op(Head, Pids, C, N, Pid, {delete_key, _Keys} = Op, Fxd, dirty = M) -> NC = [Op | C], - stream_loop(Head, [Pid | Pids], NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, {delete_object, _Objects} = Op, Fxd) -> + stream_loop(Head, [Pid | Pids], NC, N, Fxd, M); +stream_op(Head, Pids, C, N, Pid, {delete_object, _Os} = Op, Fxd, dirty = M) -> NC = [Op | C], - stream_loop(Head, [Pid | Pids], NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, {member, Key}, Fxd) -> + stream_loop(Head, [Pid | Pids], NC, N, Fxd, M); +stream_op(Head, Pids, C, N, Pid, {member, Key}, Fxd, M) -> NC = [{{lookup,[Pid]},[Key]} | C], - stream_loop(Head, Pids, NC, N, Fxd); -stream_op(Head, Pids, C, N, Pid, Op, _Fxd) -> + stream_loop(Head, Pids, NC, N, Fxd, M); +stream_op(Head, Pids, C, N, Pid, Op, _Fxd, _M) -> stream_end(Head, Pids, C, N, {Pid,Op}). stream_end(Head, Pids0, C, N, Next) -> @@ -1438,7 +1434,7 @@ stream_end2([], Ps, no_more, N, C, Head, _Reply) -> penalty(Head, Ps, C), {N, Head}; stream_end2([], _Ps, {From, Op}, N, _C, Head, _Reply) -> - apply_op(Op, From, Head, N). + {{more,From,Op,N},Head}. penalty(H, _Ps, _C) when H#head.fixed =:= false -> ok; @@ -1578,13 +1574,18 @@ do_bchunk_init(Head, Tab) -> L = dets_utils:all_allocated(H2), C0 = #dets_cont{no_objs = default, bin = <<>>, alloc = L}, BinParms = term_to_binary(Parms), - {H2, {C0#dets_cont{tab = Tab, what = bchunk}, [BinParms]}} + {H2, {C0#dets_cont{tab = Tab, proc = self(),what = bchunk}, + [BinParms]}} end; {NewHead, _} = HeadError when is_record(NewHead, head) -> HeadError end. %% -> {NewHead, {cont(), [binary()]}} | {NewHead, Error} +do_bchunk(Head, #dets_cont{proc = Proc}) when Proc =/= self() -> + {Head, badarg}; +do_bchunk(Head, #dets_cont{bin = eof}) -> + {Head, '$end_of_table'}; do_bchunk(Head, State) -> case dets_v9:read_bchunks(Head, State#dets_cont.alloc) of {error, Reason} -> @@ -1954,6 +1955,8 @@ flookup_keys(Head, Keys) -> end. %% -> {NewHead, Result} +fmatch_init(Head, #dets_cont{bin = eof}) -> + {Head, '$end_of_table'}; fmatch_init(Head, C) -> case scan(Head, C) of {scan_error, Reason} -> diff --git a/lib/stdlib/src/dets.hrl b/lib/stdlib/src/dets.hrl index 6e59770753..fbffc9d008 100644 --- a/lib/stdlib/src/dets.hrl +++ b/lib/stdlib/src/dets.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -18,7 +18,7 @@ %% -define(DEFAULT_MIN_NO_SLOTS, 256). --define(DEFAULT_MAX_NO_SLOTS, 2*1024*1024). +-define(DEFAULT_MAX_NO_SLOTS, 32*1024*1024). -define(DEFAULT_AUTOSAVE, 3). % minutes -define(DEFAULT_CACHE, {3000, 14000}). % {delay,size} in {milliseconds,bytes} diff --git a/lib/stdlib/src/dets_v8.erl b/lib/stdlib/src/dets_v8.erl index 1f9f84cd27..af36958c1c 100644 --- a/lib/stdlib/src/dets_v8.erl +++ b/lib/stdlib/src/dets_v8.erl @@ -1074,6 +1074,8 @@ wl([], _Type, Del, Lookup, I, Objs) -> [{Del, Lookup, Objs} | I]. %% -> {NewHead, ok} | {NewHead, Error} +may_grow(Head, 0, once) -> + {Head, ok}; may_grow(Head, _N, _How) when Head#head.fixed =/= false -> {Head, ok}; may_grow(#head{access = read}=Head, _N, _How) -> diff --git a/lib/stdlib/src/dets_v9.erl b/lib/stdlib/src/dets_v9.erl index 53238e962f..132af01f79 100644 --- a/lib/stdlib/src/dets_v9.erl +++ b/lib/stdlib/src/dets_v9.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. +%% 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 @@ -1908,6 +1908,9 @@ write_cache(Head) -> end. %% -> {NewHead, ok} | {NewHead, Error} +may_grow(Head, 0, once) -> + %% Do not re-hash if there is a chance that the file is not dirty. + {Head, ok}; may_grow(Head, _N, _How) when Head#head.fixed =/= false -> {Head, ok}; may_grow(#head{access = read}=Head, _N, _How) -> diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl index b5f52da921..5edc868a94 100644 --- a/lib/stdlib/src/digraph.erl +++ b/lib/stdlib/src/digraph.erl @@ -36,7 +36,7 @@ -export([get_short_path/3, get_short_cycle/2]). --export_type([d_type/0, vertex/0]). +-export_type([digraph/0, d_type/0, vertex/0]). -record(digraph, {vtab = notable :: ets:tab(), etab = notable :: ets:tab(), diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl index 81b2431f40..e5ccaddbb4 100644 --- a/lib/stdlib/src/epp.erl +++ b/lib/stdlib/src/epp.erl @@ -33,7 +33,9 @@ %% Epp state record. -record(epp, {file, %Current file location, %Current location + delta, %Offset from Location (-file) name="", %Current file name + name2="", %-"-, modified by -file istk=[], %Ifdef stack sstk=[], %State stack path=[], %Include-path @@ -234,8 +236,8 @@ init_server(Pid, Name, File, AtLocation, Path, Pdm, Pre) -> case user_predef(Pdm, Ms0) of {ok,Ms1} -> epp_reply(Pid, {ok,self()}), - St = #epp{file=File, location=AtLocation, name=Name, - path=Path, macs=Ms1, pre_opened = Pre}, + St = #epp{file=File, location=AtLocation, delta=0, name=Name, + name2=Name, path=Path, macs=Ms1, pre_opened = Pre}, From = wait_request(St), enter_file_reply(From, Name, AtLocation, AtLocation), wait_req_scan(St); @@ -358,8 +360,8 @@ enter_file2(NewF, Pname, From, St, AtLocation, ExtraPath) -> enter_file_reply(From, Pname, Loc, AtLocation), Ms = dict:store({atom,'FILE'}, {none,[{string,Loc,Pname}]}, St#epp.macs), Path = St#epp.path ++ ExtraPath, - #epp{location=Loc,file=NewF, - name=Pname,sstk=[St|St#epp.sstk],path=Path,macs=Ms}. + #epp{file=NewF,location=Loc,name=Pname,delta=0, + sstk=[St|St#epp.sstk],path=Path,macs=Ms}. enter_file_reply(From, Name, Location, AtLocation) -> Attr = loc_attr(AtLocation), @@ -391,14 +393,23 @@ leave_file(From, St) -> case St#epp.sstk of [OldSt|Sts] -> close_file(St), - enter_file_reply(From, OldSt#epp.name, - OldSt#epp.location, OldSt#epp.location), + #epp{location=OldLoc, delta=Delta, name=OldName, + name2=OldName2} = OldSt, + CurrLoc = add_line(OldLoc, Delta), Ms = dict:store({atom,'FILE'}, - {none, - [{string,OldSt#epp.location, - OldSt#epp.name}]}, + {none,[{string,CurrLoc,OldName2}]}, St#epp.macs), - wait_req_scan(OldSt#epp{sstk=Sts,macs=Ms}); + NextSt = OldSt#epp{sstk=Sts,macs=Ms}, + enter_file_reply(From, OldName, CurrLoc, CurrLoc), + case OldName2 =:= OldName of + true -> + From; + false -> + NFrom = wait_request(NextSt), + enter_file_reply(NFrom, OldName2, OldLoc, + neg_line(CurrLoc)) + end, + wait_req_scan(NextSt); [] -> epp_reply(From, {eof,St#epp.location}), wait_req_scan(St) @@ -768,7 +779,8 @@ scan_file([{'(',_Llp},{string,_Ls,Name},{',',_Lc},{integer,_Li,Ln},{')',_Lrp}, Ms = dict:store({atom,'FILE'}, {none,[{string,1,Name}]}, St#epp.macs), Locf = loc(Tf), NewLoc = new_location(Ln, St#epp.location, Locf), - wait_req_scan(St#epp{name=Name,location=NewLoc,macs=Ms}); + Delta = abs(get_line(element(2, Tf)))-Ln + St#epp.delta, + wait_req_scan(St#epp{name2=Name,location=NewLoc,delta=Delta,macs=Ms}); scan_file(_Toks, Tf, From, St) -> epp_reply(From, {error,{loc(Tf),epp,{bad,file}}}), wait_req_scan(St). @@ -1132,6 +1144,9 @@ neg_line(L) -> abs_line(L) -> erl_scan:set_attribute(line, L, fun(Line) -> abs(Line) end). +add_line(L, Offset) -> + erl_scan:set_attribute(line, L, fun(Line) -> Line+Offset end). + start_loc(Line) when is_integer(Line) -> 1; start_loc({_Line, _Column}) -> @@ -1191,10 +1206,10 @@ interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms], %% -include or -include_lib % true = L =:= Line, case Fs of - [_, Delta1, File | Fs1] -> % end of included file - [Form | interpret_file_attr(Forms, Delta1, [File | Fs1])]; + [_, File | Fs1] -> % end of included file + [Form | interpret_file_attr(Forms, 0, [File | Fs1])]; _ -> % start of included file - [Form | interpret_file_attr(Forms, 0, [File, Delta | Fs])] + [Form | interpret_file_attr(Forms, 0, [File | Fs])] end end; interpret_file_attr([Form0 | Forms], Delta, Fs) -> diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 077621ac91..0c2d3db8ec 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -311,6 +311,8 @@ format_error({ill_defined_behaviour_callbacks,Behaviour}) -> %% --- types and specs --- format_error({singleton_typevar, Name}) -> io_lib:format("type variable ~w is only used once (is unbound)", [Name]); +format_error({bad_export_type, _ETs}) -> + io_lib:format("bad export_type declaration", []); format_error({duplicated_export_type, {T, A}}) -> io_lib:format("type ~w/~w already exported", [T, A]); format_error({undefined_type, {TypeName, Arity}}) -> @@ -1128,8 +1130,7 @@ export(Line, Es, #lint{exports = Es0, called = Called} = St0) -> export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) -> UTs0 = Usage#usage.used_types, - {ETs1,UTs1,St1} = - foldl(fun (TA, {E,U,St2}) -> + try foldl(fun ({T,A}=TA, {E,U,St2}) when is_atom(T), is_integer(A) -> St = case gb_sets:is_element(TA, E) of true -> Warn = {duplicated_export_type,TA}, @@ -1139,8 +1140,13 @@ export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) -> end, {gb_sets:add_element(TA, E), dict:store(TA, Line, U), St} end, - {ETs0,UTs0,St0}, ETs), - St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1}. + {ETs0,UTs0,St0}, ETs) of + {ETs1,UTs1,St1} -> + St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1} + catch + error:_ -> + add_error(Line, {bad_export_type, ETs}, St0) + end. -type import() :: {module(), [fa()]} | module(). -spec import(line(), import(), lint_state()) -> lint_state(). diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl index 1d033f6f7b..6e6e949e2c 100644 --- a/lib/stdlib/src/ets.erl +++ b/lib/stdlib/src/ets.erl @@ -512,7 +512,7 @@ file2tab(File) -> file2tab(File, Opts) -> try - {ok,Verify} = parse_f2t_opts(Opts,false), + {ok,Verify,TabArg} = parse_f2t_opts(Opts,false,[]), Name = make_ref(), {ok, Major, Minor, FtOptions, MD5State, FullHeader, DLContext} = case disk_log:open([{name, Name}, @@ -540,7 +540,7 @@ file2tab(File, Opts) -> true -> ok end, - {ok, Tab, HeadCount} = create_tab(FullHeader), + {ok, Tab, HeadCount} = create_tab(FullHeader, TabArg), StrippedOptions = case Verify of true -> @@ -676,15 +676,17 @@ do_read_and_verify(ReadFun,InitState,Tab,FtOptions,HeadCount,Verify) -> {ok,Tab} end. -parse_f2t_opts([],Verify) -> - {ok,Verify}; -parse_f2t_opts([{verify, true}|T],_OV) -> - parse_f2t_opts(T,true); -parse_f2t_opts([{verify,false}|T],OV) -> - parse_f2t_opts(T,OV); -parse_f2t_opts([Unexpected|_],_) -> +parse_f2t_opts([],Verify,Tab) -> + {ok,Verify,Tab}; +parse_f2t_opts([{verify, true}|T],_OV,Tab) -> + parse_f2t_opts(T,true,Tab); +parse_f2t_opts([{verify,false}|T],OV,Tab) -> + parse_f2t_opts(T,OV,Tab); +parse_f2t_opts([{table,Tab}|T],OV,[]) -> + parse_f2t_opts(T,OV,Tab); +parse_f2t_opts([Unexpected|_],_,_) -> throw({unknown_option,Unexpected}); -parse_f2t_opts(Malformed,_) -> +parse_f2t_opts(Malformed,_,_) -> throw({malformed_option,Malformed}). count_mandatory([]) -> @@ -860,19 +862,28 @@ load_table(ReadFun, State, Tab) -> load_table(ReadFun, NewState, Tab) end. -create_tab(I) -> +create_tab(I, TabArg) -> {name, Name} = lists:keyfind(name, 1, I), {type, Type} = lists:keyfind(type, 1, I), {protection, P} = lists:keyfind(protection, 1, I), {named_table, Val} = lists:keyfind(named_table, 1, I), {keypos, _Kp} = Keypos = lists:keyfind(keypos, 1, I), {size, Sz} = lists:keyfind(size, 1, I), - try - Tab = ets:new(Name, [Type, P, Keypos | named_table(Val)]), - {ok, Tab, Sz} - catch - _:_ -> - throw(cannot_create_table) + Comp = case lists:keyfind(compressed, 1, I) of + {compressed, true} -> [compressed]; + {compressed, false} -> []; + false -> [] + end, + case TabArg of + [] -> + try + Tab = ets:new(Name, [Type, P, Keypos] ++ named_table(Val) ++ Comp), + {ok, Tab, Sz} + catch _:_ -> + throw(cannot_create_table) + end; + _ -> + {ok, TabArg, Sz} end. named_table(true) -> [named_table]; diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index d5ddf9ed7e..c845b61204 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -47,14 +47,14 @@ wildcard(Pattern) when is_list(Pattern) -> ?HANDLE_ERROR(do_wildcard(Pattern, file)). -spec wildcard(file:name(), file:name() | atom()) -> [file:filename()]. -wildcard(Pattern, Cwd) when is_list(Pattern), is_list(Cwd) -> +wildcard(Pattern, Cwd) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) -> ?HANDLE_ERROR(do_wildcard(Pattern, Cwd, file)); wildcard(Pattern, Mod) when is_list(Pattern), is_atom(Mod) -> ?HANDLE_ERROR(do_wildcard(Pattern, Mod)). -spec wildcard(file:name(), file:name(), atom()) -> [file:filename()]. wildcard(Pattern, Cwd, Mod) - when is_list(Pattern), is_list(Cwd), is_atom(Mod) -> + when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)), is_atom(Mod) -> ?HANDLE_ERROR(do_wildcard(Pattern, Cwd, Mod)). -spec is_dir(file:name()) -> boolean(). @@ -118,7 +118,7 @@ do_wildcard_comp({compiled_wildcard,{exists,File}}, Mod) -> do_wildcard_comp({compiled_wildcard,[Base|Rest]}, Mod) -> do_wildcard_1([Base], Rest, Mod). -do_wildcard(Pattern, Cwd, Mod) when is_list(Pattern), is_list(Cwd) -> +do_wildcard(Pattern, Cwd, Mod) when is_list(Pattern), (is_list(Cwd) or is_binary(Cwd)) -> do_wildcard_comp(do_compile_wildcard(Pattern), Cwd, Mod). do_wildcard_comp({compiled_wildcard,{exists,File}}, Cwd, Mod) -> @@ -127,9 +127,18 @@ do_wildcard_comp({compiled_wildcard,{exists,File}}, Cwd, Mod) -> _ -> [] end; do_wildcard_comp({compiled_wildcard,[current|Rest]}, Cwd0, Mod) -> - Cwd = filename:join([Cwd0]), %Slash away redundant slashes. - PrefixLen = length(Cwd)+1, - [lists:nthtail(PrefixLen, N) || N <- do_wildcard_1([Cwd], Rest, Mod)]; + {Cwd,PrefixLen} = case filename:join([Cwd0]) of + Bin when is_binary(Bin) -> {Bin,byte_size(Bin)+1}; + Other -> {Other,length(Other)+1} + end, %Slash away redundant slashes. + [ + if + is_binary(N) -> + <<_:PrefixLen/binary,Res/binary>> = N, + Res; + true -> + lists:nthtail(PrefixLen, N) + end || N <- do_wildcard_1([Cwd], Rest, Mod)]; do_wildcard_comp({compiled_wildcard,[Base|Rest]}, _Cwd, Mod) -> do_wildcard_1([Base], Rest, Mod). @@ -166,36 +175,44 @@ do_is_regular(File, Mod) -> %% If <Recursive> is true all sub-directories to <Dir> are processed do_fold_files(Dir, RegExp, Recursive, Fun, Acc, Mod) -> - {ok, Re1} = re:compile(RegExp), - do_fold_files1(Dir, Re1, Recursive, Fun, Acc, Mod). + {ok, Re1} = re:compile(RegExp,[unicode]), + do_fold_files1(Dir, Re1, RegExp, Recursive, Fun, Acc, Mod). -do_fold_files1(Dir, RegExp, Recursive, Fun, Acc, Mod) -> +do_fold_files1(Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod) -> case eval_list_dir(Dir, Mod) of - {ok, Files} -> do_fold_files2(Files, Dir, RegExp, Recursive, Fun, Acc, Mod); + {ok, Files} -> do_fold_files2(Files, Dir, RegExp, OrigRE, + Recursive, Fun, Acc, Mod); {error, _} -> Acc end. -do_fold_files2([], _Dir, _RegExp, _Recursive, _Fun, Acc, _Mod) -> +%% OrigRE is not to be compiled as it's for non conforming filenames, +%% i.e. for filenames that does not comply to the current encoding, which should +%% be very rare. We use it only in those cases and do not want to precompile. +do_fold_files2([], _Dir, _RegExp, _OrigRE, _Recursive, _Fun, Acc, _Mod) -> Acc; -do_fold_files2([File|T], Dir, RegExp, Recursive, Fun, Acc0, Mod) -> +do_fold_files2([File|T], Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod) -> FullName = filename:join(Dir, File), case do_is_regular(FullName, Mod) of true -> - case re:run(File, RegExp, [{capture,none}]) of + case (catch re:run(File, if is_binary(File) -> OrigRE; + true -> RegExp end, + [{capture,none}])) of match -> Acc = Fun(FullName, Acc0), - do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc, Mod); + do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc, Mod); + {'EXIT',_} -> + do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod); nomatch -> - do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod) + do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod) end; false -> case Recursive andalso do_is_dir(FullName, Mod) of true -> - Acc1 = do_fold_files1(FullName, RegExp, Recursive, + Acc1 = do_fold_files1(FullName, RegExp, OrigRE, Recursive, Fun, Acc0, Mod), - do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc1, Mod); + do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc1, Mod); false -> - do_fold_files2(T, Dir, RegExp, Recursive, Fun, Acc0, Mod) + do_fold_files2(T, Dir, RegExp, OrigRE, Recursive, Fun, Acc0, Mod) end end. @@ -268,6 +285,13 @@ do_wildcard_3(Base, [Pattern|Rest], Result, Mod) -> do_wildcard_3(Base, [], Result, _Mod) -> [Base|Result]. +wildcard_4(Pattern, [File|Rest], Base, Result) when is_binary(File) -> + case wildcard_5(Pattern, binary_to_list(File)) of + true -> + wildcard_4(Pattern, Rest, Base, [join(Base, File)|Result]); + false -> + wildcard_4(Pattern, Rest, Base, Result) + end; wildcard_4(Pattern, [File|Rest], Base, Result) -> case wildcard_5(Pattern, File) of true -> diff --git a/lib/stdlib/src/filename.erl b/lib/stdlib/src/filename.erl index 01c06e4596..e38b8957f2 100644 --- a/lib/stdlib/src/filename.erl +++ b/lib/stdlib/src/filename.erl @@ -41,6 +41,9 @@ -include_lib("kernel/include/file.hrl"). +-define(IS_DRIVELETTER(Letter),(((Letter >= $A) andalso (Letter =< $Z)) orelse + ((Letter >= $a) andalso (Letter =< $z)))). + %% Converts a relative filename to an absolute filename %% or the filename itself if it already is an absolute filename %% Note that no attempt is made to create the most beatiful @@ -57,12 +60,18 @@ %% (for Unix) : absname("/") -> "/" %% (for WIN32): absname("/") -> "D:/" --spec absname(file:name()) -> string(). + +-spec absname(file:name()) -> file:filename(). absname(Name) -> {ok, Cwd} = file:get_cwd(), absname(Name, Cwd). --spec absname(file:name(), string()) -> string(). +-spec absname(file:name(), file:filename()) -> file:filename(). +absname(Name, AbsBase) when is_binary(Name), is_list(AbsBase) -> + absname(Name,filename_string_to_binary(AbsBase)); +absname(Name, AbsBase) when is_list(Name), is_binary(AbsBase) -> + absname(filename_string_to_binary(Name),AbsBase); + absname(Name, AbsBase) -> case pathtype(Name) of relative -> @@ -77,6 +86,20 @@ absname(Name, AbsBase) -> %% Handles volumerelative names (on Windows only). +absname_vr([<<"/">>|Rest1], [Volume|_], _AbsBase) -> + %% Absolute path on current drive. + join([Volume|Rest1]); +absname_vr([<<X, $:>>|Rest1], [<<X,_/binary>>|_], AbsBase) -> + %% Relative to current directory on current drive. + absname(join(Rest1), AbsBase); +absname_vr([<<X, $:>>|Name], _, _AbsBase) -> + %% Relative to current directory on another drive. + Dcwd = + case file:get_cwd([X, $:]) of + {ok, Dir} -> filename_string_to_binary(Dir); + {error, _} -> <<X, $:, $/>> + end, + absname(join(Name), Dcwd); absname_vr(["/"|Rest1], [Volume|_], _AbsBase) -> %% Absolute path on current drive. join([Volume|Rest1]); @@ -92,41 +115,13 @@ absname_vr([[X, $:]|Name], _, _AbsBase) -> end, absname(join(Name), Dcwd). -%% Joins a relative filename to an absolute base. For VxWorks the -%% resulting name is fixed to minimize the length by collapsing -%% ".." directories. -%% For other systems this is just a join/2, but assumes that +%% Joins a relative filename to an absolute base. +%% This is just a join/2, but assumes that %% AbsBase must be absolute and Name must be relative. --spec absname_join(string(), file:name()) -> string(). +-spec absname_join(file:filename(), file:name()) -> file:filename(). absname_join(AbsBase, Name) -> - case major_os_type() of - vxworks -> - absname_pretty(AbsBase, split(Name), lists:reverse(split(AbsBase))); - _Else -> - join(AbsBase, flatten(Name)) - end. - -%% Handles absolute filenames for VxWorks - these are 'pretty-printed', -%% since a C function call chdir("/erlang/lib/../bin") really sets -%% cwd to '/erlang/lib/../bin' which also works, but the long term -%% effect is potentially not so good ... -%% -%% absname_pretty("../bin", "/erlang/lib") -> "/erlang/bin" -%% absname_pretty("../../../..", "/erlang") -> "/erlang" - -absname_pretty(Abspath, Relpath, []) -> - %% AbsBase _must_ begin with a vxworks device name - {device, _Rest, Dev} = vxworks_first(Abspath), - absname_pretty(Abspath, Relpath, [lists:reverse(Dev)]); -absname_pretty(_Abspath, [], AbsBase) -> - join(lists:reverse(AbsBase)); -absname_pretty(Abspath, [[$.]|Rest], AbsBase) -> - absname_pretty(Abspath, Rest, AbsBase); -absname_pretty(Abspath, [[$.,$.]|Rest], [_|AbsRest]) -> - absname_pretty(Abspath, Rest, AbsRest); -absname_pretty(Abspath, [First|Rest], AbsBase) -> - absname_pretty(Abspath, Rest, [First|AbsBase]). + join(AbsBase, flatten(Name)). %% Returns the part of the filename after the last directory separator, %% or the filename itself if it has no separators. @@ -136,12 +131,36 @@ absname_pretty(Abspath, [First|Rest], AbsBase) -> %% basename("/usr/foo/") -> "foo" (trailing slashes ignored) %% basename("/") -> [] --spec basename(file:name()) -> string(). +-spec basename(file:name()) -> file:filename(). +basename(Name) when is_binary(Name) -> + case os:type() of + {win32,_} -> + win_basenameb(Name); + _ -> + basenameb(Name,[<<"/">>]) + end; + basename(Name0) -> Name = flatten(Name0), {DirSep2, DrvSep} = separators(), basename1(skip_prefix(Name, DrvSep), [], DirSep2). +win_basenameb(<<Letter,$:,Rest/binary>>) when ?IS_DRIVELETTER(Letter) -> + basenameb(Rest,[<<"/">>,<<"\\">>]); +win_basenameb(O) -> + basenameb(O,[<<"/">>,<<"\\">>]). +basenameb(Bin,Sep) -> + Parts = [ X || X <- binary:split(Bin,Sep,[global]), + X =/= <<>> ], + if + Parts =:= [] -> + <<>>; + true -> + lists:last(Parts) + end. + + + basename1([$/|[]], Tail, DirSep2) -> basename1([], Tail, DirSep2); basename1([$/|Rest], _Tail, DirSep2) -> @@ -155,26 +174,11 @@ basename1([Char|Rest], Tail, DirSep2) when is_integer(Char) -> basename1([], Tail, _DirSep2) -> lists:reverse(Tail). -skip_prefix(Name, false) -> % No prefix for unix, but for VxWorks. - case major_os_type() of - vxworks -> - case vxworks_first(Name) of - {device, Rest, _Device} -> - Rest; - {not_device, _Rest, _First} -> - Name - end; - _Else -> - Name - end; -skip_prefix(Name, DrvSep) -> - skip_prefix1(Name, DrvSep). - -skip_prefix1([L, DrvSep|Name], DrvSep) when is_integer(L) -> +skip_prefix(Name, false) -> Name; -skip_prefix1([L], _) when is_integer(L) -> - [L]; -skip_prefix1(Name, _) -> +skip_prefix([L, DrvSep|Name], DrvSep) when ?IS_DRIVELETTER(L) -> + Name; +skip_prefix(Name, _) -> Name. %% Returns the last component of the filename, with the given @@ -190,7 +194,29 @@ skip_prefix1(Name, _) -> %% rootname(basename("xxx.jam")) -> "xxx" %% rootname(basename("xxx.erl")) -> "xxx" --spec basename(file:name(), file:name()) -> string(). +-spec basename(file:name(), file:name()) -> file:filename(). +basename(Name, Ext) when is_binary(Name), is_list(Ext) -> + basename(Name,filename_string_to_binary(Ext)); +basename(Name, Ext) when is_list(Name), is_binary(Ext) -> + basename(filename_string_to_binary(Name),Ext); +basename(Name, Ext) when is_binary(Name), is_binary(Ext) -> + BName = basename(Name), + LAll = byte_size(Name), + LN = byte_size(BName), + LE = byte_size(Ext), + case LN - LE of + Neg when Neg < 0 -> + BName; + Pos -> + StartLen = LAll - Pos - LE, + case Name of + <<_:StartLen/binary,Part:Pos/binary,Ext/binary>> -> + Part; + _Other -> + BName + end + end; + basename(Name0, Ext0) -> Name = flatten(Name0), Ext = flatten(Ext0), @@ -204,7 +230,7 @@ basename([$/|[]], Ext, Tail, DrvSep2) -> basename([], Ext, Tail, DrvSep2); basename([$/|Rest], Ext, _Tail, DrvSep2) -> basename(Rest, Ext, [], DrvSep2); -basename([$\\|Rest], Ext, Tail, DirSep2) when is_integer(DirSep2) -> +basename([DirSep2|Rest], Ext, Tail, DirSep2) when is_integer(DirSep2) -> basename([$/|Rest], Ext, Tail, DirSep2); basename([Char|Rest], Ext, Tail, DrvSep2) when is_integer(Char) -> basename(Rest, Ext, [Char|Tail], DrvSep2); @@ -216,21 +242,43 @@ basename([], _Ext, Tail, _DrvSep2) -> %% Example: dirname("/usr/src/kalle.erl") -> "/usr/src", %% dirname("kalle.erl") -> "." --spec dirname(file:name()) -> string(). +-spec dirname(file:name()) -> file:filename(). +dirname(Name) when is_binary(Name) -> + {Dsep,Drivesep} = separators(), + SList = case Dsep of + Sep when is_integer(Sep) -> + [ <<Sep>> ]; + _ -> + [] + end, + {XPart0,Dirs} = case Drivesep of + X when is_integer(X) -> + case Name of + <<DL,X,Rest/binary>> when ?IS_DRIVELETTER(DL) -> + {<<DL,X>>,Rest}; + _ -> + {<<>>,Name} + end; + _ -> + {<<>>,Name} + end, + Parts0 = binary:split(Dirs,[<<"/">>|SList],[global]), + %% Fairly short lists of parts, OK to reverse twice... + Parts = case Parts0 of + [] -> []; + _ -> lists:reverse(fstrip(tl(lists:reverse(Parts0)))) + end, + XPart = case {Parts,XPart0} of + {[],<<>>} -> + <<".">>; + _ -> + XPart0 + end, + dirjoin(Parts,XPart,<<"/">>); + dirname(Name0) -> Name = flatten(Name0), - case os:type() of - vxworks -> - {Devicep, Restname, FirstComp} = vxworks_first(Name), - case Devicep of - device -> - dirname(Restname, FirstComp, [], separators()); - _ -> - dirname(Name, [], [], separators()) - end; - _ -> - dirname(Name, [], [], separators()) - end. + dirname(Name, [], [], separators()). dirname([[_|_]=List|Rest], Dir, File, Seps) -> dirname(List++Rest, Dir, File, Seps); @@ -258,6 +306,26 @@ dirname([], [DrvSep,Dl], File, {_,DrvSep}) -> end; dirname([], Dir, _, _) -> lists:reverse(Dir). + +%% Compatibility with lists variant, remove trailing slashes +fstrip([<<>>,X|Y]) -> + fstrip([X|Y]); +fstrip(A) -> + A. + + +dirjoin([<<>>|T],Acc,Sep) -> + dirjoin1(T,<<Acc/binary,"/">>,Sep); +dirjoin(A,B,C) -> + dirjoin1(A,B,C). + +dirjoin1([],Acc,_) -> + Acc; +dirjoin1([One],Acc,_) -> + <<Acc/binary,One/binary>>; +dirjoin1([H|T],Acc,Sep) -> + dirjoin(T,<<Acc/binary,H/binary,Sep/binary>>,Sep). + %% Given a filename string, returns the file extension, %% including the period. Returns an empty list if there @@ -268,7 +336,31 @@ dirname([], Dir, _, _) -> %% %% On Windows: fn:dirname("\\usr\\src/kalle.erl") -> "/usr/src" --spec extension(file:name()) -> string(). +-spec extension(file:name()) -> file:filename(). +extension(Name) when is_binary(Name) -> + {Dsep,_} = separators(), + SList = case Dsep of + Sep when is_integer(Sep) -> + [ <<Sep>> ]; + _ -> + [] + end, + case binary:matches(Name,[<<".">>]) of + nomatch -> % Bug in binary workaround :( + <<>>; + [] -> + <<>>; + List -> + {Pos,_} = lists:last(List), + <<_:Pos/binary,Part/binary>> = Name, + case binary:match(Part,[<<"/">>|SList]) of + nomatch -> + Part; + _ -> + <<>> + end + end; + extension(Name0) -> Name = flatten(Name0), extension(Name, [], major_os_type()). @@ -281,8 +373,6 @@ extension([$/|Rest], _Result, OsType) -> extension(Rest, [], OsType); extension([$\\|Rest], _Result, win32) -> extension(Rest, [], win32); -extension([$\\|Rest], _Result, vxworks) -> - extension(Rest, [], vxworks); extension([Char|Rest], Result, OsType) when is_integer(Char) -> extension(Rest, [Char|Result], OsType); extension([], Result, _OsType) -> @@ -290,23 +380,36 @@ extension([], Result, _OsType) -> %% Joins a list of filenames with directory separators. --spec join([string()]) -> string(). +-spec join([file:filename()]) -> file:filename(). join([Name1, Name2|Rest]) -> join([join(Name1, Name2)|Rest]); join([Name]) when is_list(Name) -> join1(Name, [], [], major_os_type()); +join([Name]) when is_binary(Name) -> + join1b(Name, <<>>, [], major_os_type()); join([Name]) when is_atom(Name) -> join([atom_to_list(Name)]). %% Joins two filenames with directory separators. --spec join(string(), string()) -> string(). +-spec join(file:filename(), file:filename()) -> file:filename(). join(Name1, Name2) when is_list(Name1), is_list(Name2) -> OsType = major_os_type(), case pathtype(Name2) of relative -> join1(Name1, Name2, [], OsType); _Other -> join1(Name2, [], [], OsType) end; +join(Name1, Name2) when is_binary(Name1), is_list(Name2) -> + join(Name1,filename_string_to_binary(Name2)); +join(Name1, Name2) when is_list(Name1), is_binary(Name2) -> + join(filename_string_to_binary(Name1),Name2); +join(Name1, Name2) when is_binary(Name1), is_binary(Name2) -> + OsType = major_os_type(), + case pathtype(Name2) of + relative -> join1b(Name1, Name2, [], OsType); + _Other -> join1b(Name2, <<>>, [], OsType) + end; + join(Name1, Name2) when is_atom(Name1) -> join(atom_to_list(Name1), Name2); join(Name1, Name2) when is_atom(Name2) -> @@ -321,8 +424,6 @@ when is_integer(UcLetter), UcLetter >= $A, UcLetter =< $Z -> join1(Rest, RelativeName, [$:, UcLetter+$a-$A], win32); join1([$\\|Rest], RelativeName, Result, win32) -> join1([$/|Rest], RelativeName, Result, win32); -join1([$\\|Rest], RelativeName, Result, vxworks) -> - join1([$/|Rest], RelativeName, Result, vxworks); join1([$/|Rest], RelativeName, [$., $/|Result], OsType) -> join1(Rest, RelativeName, [$/|Result], OsType); join1([$/|Rest], RelativeName, [$/|Result], OsType) -> @@ -344,6 +445,26 @@ join1([Char|Rest], RelativeName, Result, OsType) when is_integer(Char) -> join1([Atom|Rest], RelativeName, Result, OsType) when is_atom(Atom) -> join1(atom_to_list(Atom)++Rest, RelativeName, Result, OsType). +join1b(<<UcLetter, $:, Rest/binary>>, RelativeName, [], win32) +when is_integer(UcLetter), UcLetter >= $A, UcLetter =< $Z -> + join1b(Rest, RelativeName, [$:, UcLetter+$a-$A], win32); +join1b(<<$\\,Rest/binary>>, RelativeName, Result, win32) -> + join1b(<<$/,Rest/binary>>, RelativeName, Result, win32); +join1b(<<$/,Rest/binary>>, RelativeName, [$., $/|Result], OsType) -> + join1b(Rest, RelativeName, [$/|Result], OsType); +join1b(<<$/,Rest/binary>>, RelativeName, [$/|Result], OsType) -> + join1b(Rest, RelativeName, [$/|Result], OsType); +join1b(<<>>, <<>>, Result, OsType) -> + list_to_binary(maybe_remove_dirsep(Result, OsType)); +join1b(<<>>, RelativeName, [$:|Rest], win32) -> + join1b(RelativeName, <<>>, [$:|Rest], win32); +join1b(<<>>, RelativeName, [$/|Result], OsType) -> + join1b(RelativeName, <<>>, [$/|Result], OsType); +join1b(<<>>, RelativeName, Result, OsType) -> + join1b(RelativeName, <<>>, [$/|Result], OsType); +join1b(<<Char,Rest/binary>>, RelativeName, Result, OsType) when is_integer(Char) -> + join1b(Rest, RelativeName, [Char|Result], OsType). + maybe_remove_dirsep([$/, $:, Letter], win32) -> [Letter, $:, $/]; maybe_remove_dirsep([$/], _) -> @@ -357,7 +478,7 @@ maybe_remove_dirsep(Name, _) -> %% a given base directory, which is is assumed to be normalised %% by a previous call to join/{1,2}. --spec append(string(), file:name()) -> string(). +-spec append(file:filename(), file:name()) -> file:filename(). append(Dir, Name) -> Dir ++ [$/|Name]. @@ -376,19 +497,14 @@ append(Dir, Name) -> -spec pathtype(file:name()) -> 'absolute' | 'relative' | 'volumerelative'. pathtype(Atom) when is_atom(Atom) -> pathtype(atom_to_list(Atom)); -pathtype(Name) when is_list(Name) -> +pathtype(Name) when is_list(Name) or is_binary(Name) -> case os:type() of {unix, _} -> unix_pathtype(Name); - {win32, _} -> win32_pathtype(Name); - vxworks -> case vxworks_first(Name) of - {device, _Rest, _Dev} -> - absolute; - _ -> - relative - end; - {ose,_} -> unix_pathtype(Name) + {win32, _} -> win32_pathtype(Name) end. +unix_pathtype(<<$/,_/binary>>) -> + absolute; unix_pathtype([$/|_]) -> absolute; unix_pathtype([List|Rest]) when is_list(List) -> @@ -404,6 +520,15 @@ win32_pathtype([Atom|Rest]) when is_atom(Atom) -> win32_pathtype(atom_to_list(Atom)++Rest); win32_pathtype([Char, List|Rest]) when is_list(List) -> win32_pathtype([Char|List++Rest]); +win32_pathtype(<<$/, $/, _/binary>>) -> absolute; +win32_pathtype(<<$\\, $/, _/binary>>) -> absolute; +win32_pathtype(<<$/, $\\, _/binary>>) -> absolute; +win32_pathtype(<<$\\, $\\, _/binary>>) -> absolute; +win32_pathtype(<<$/, _/binary>>) -> volumerelative; +win32_pathtype(<<$\\, _/binary>>) -> volumerelative; +win32_pathtype(<<_Letter, $:, $/, _/binary>>) -> absolute; +win32_pathtype(<<_Letter, $:, $\\, _/binary>>) -> absolute; +win32_pathtype(<<_Letter, $:, _/binary>>) -> volumerelative; win32_pathtype([$/, $/|_]) -> absolute; win32_pathtype([$\\, $/|_]) -> absolute; win32_pathtype([$/, $\\|_]) -> absolute; @@ -422,7 +547,9 @@ win32_pathtype(_) -> relative. %% Examples: rootname("/jam.src/kalle") -> "/jam.src/kalle" %% rootname("/jam.src/foo.erl") -> "/jam.src/foo" --spec rootname(file:name()) -> string(). +-spec rootname(file:name()) -> file:filename(). +rootname(Name) when is_binary(Name) -> + list_to_binary(rootname(binary_to_list(Name))); % No need to handle unicode, . is < 128 rootname(Name0) -> Name = flatten(Name0), rootname(Name, [], [], major_os_type()). @@ -431,8 +558,6 @@ rootname([$/|Rest], Root, Ext, OsType) -> rootname(Rest, [$/]++Ext++Root, [], OsType); rootname([$\\|Rest], Root, Ext, win32) -> rootname(Rest, [$/]++Ext++Root, [], win32); -rootname([$\\|Rest], Root, Ext, vxworks) -> - rootname(Rest, [$/]++Ext++Root, [], vxworks); rootname([$.|Rest], Root, [], OsType) -> rootname(Rest, Root, ".", OsType); rootname([$.|Rest], Root, Ext, OsType) -> @@ -451,7 +576,13 @@ rootname([], Root, _Ext, _OsType) -> %% Examples: rootname("/jam.src/kalle.jam", ".erl") -> "/jam.src/kalle.jam" %% rootname("/jam.src/foo.erl", ".erl") -> "/jam.src/foo" --spec rootname(file:name(), file:name()) -> string(). +-spec rootname(file:name(), file:name()) -> file:filename(). +rootname(Name, Ext) when is_binary(Name), is_binary(Ext) -> + list_to_binary(rootname(binary_to_list(Name),binary_to_list(Ext))); +rootname(Name, Ext) when is_binary(Name) -> + rootname(Name,filename_string_to_binary(Ext)); +rootname(Name, Ext) when is_binary(Ext) -> + rootname(filename_string_to_binary(Name),Ext); rootname(Name0, Ext0) -> Name = flatten(Name0), Ext = flatten(Ext0), @@ -471,27 +602,55 @@ rootname2([Char|Rest], Ext, Result) when is_integer(Char) -> %% split("foo/bar") -> ["foo", "bar"] %% split("a:\\msdev\\include") -> ["a:/", "msdev", "include"] --spec split(file:name()) -> [string()]. +-spec split(file:name()) -> [file:filename()]. +split(Name) when is_binary(Name) -> + case os:type() of + {win32, _} -> win32_splitb(Name); + _ -> unix_splitb(Name) + end; + split(Name0) -> Name = flatten(Name0), case os:type() of - {unix, _} -> unix_split(Name); {win32, _} -> win32_split(Name); - vxworks -> vxworks_split(Name); - {ose,_} -> unix_split(Name) + _ -> unix_split(Name) end. -%% If a VxWorks filename starts with '[/\].*[^/\]' '[/\].*:' or '.*:' -%% that part of the filename is considered a device. -%% The rest of the name is interpreted exactly as for win32. -%% XXX - dirty solution to make filename:split([]) return the same thing on -%% VxWorks as on unix and win32. -vxworks_split([]) -> - []; -vxworks_split(L) -> - {_Devicep, Rest, FirstComp} = vxworks_first(L), - split(Rest, [], [lists:reverse(FirstComp)], win32). +unix_splitb(Name) -> + L = binary:split(Name,[<<"/">>],[global]), + LL = case L of + [<<>>|Rest] -> + [<<"/">>|Rest]; + _ -> + L + end, + [ X || X <- LL, X =/= <<>>]. + + +fix_driveletter(Letter0) -> + if + Letter0 >= $A, Letter0 =< $Z -> + Letter0+$a-$A; + true -> + Letter0 + end. +win32_splitb(<<Letter0,$:, Slash, Rest/binary>>) when (((Slash =:= $\\) orelse (Slash =:= $/)) andalso + ?IS_DRIVELETTER(Letter0)) -> + Letter = fix_driveletter(Letter0), + L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]), + [<<Letter,$:,$/>> | [ X || X <- L, X =/= <<>> ]]; +win32_splitb(<<Letter0,$:,Rest/binary>>) when ?IS_DRIVELETTER(Letter0) -> + Letter = fix_driveletter(Letter0), + L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]), + [<<Letter,$:>> | [ X || X <- L, X =/= <<>> ]]; +win32_splitb(<<Slash,Rest/binary>>) when ((Slash =:= $\\) orelse (Slash =:= $/)) -> + L = binary:split(Rest,[<<"/">>,<<"\\">>],[global]), + [<<$/>> | [ X || X <- L, X =/= <<>> ]]; +win32_splitb(Name) -> + L = binary:split(Name,[<<"/">>,<<"\\">>],[global]), + [ X || X <- L, X =/= <<>> ]. + unix_split(Name) -> split(Name, [], unix). @@ -502,8 +661,6 @@ win32_split([X, $\\|Rest]) when is_integer(X) -> win32_split([X, $/|Rest]); win32_split([X, Y, $\\|Rest]) when is_integer(X), is_integer(Y) -> win32_split([X, Y, $/|Rest]); -win32_split([$/, $/|Rest]) -> - split(Rest, [], [[$/, $/]]); win32_split([UcLetter, $:|Rest]) when UcLetter >= $A, UcLetter =< $Z -> win32_split([UcLetter+$a-$A, $:|Rest]); win32_split([Letter, $:, $/|Rest]) -> @@ -540,7 +697,7 @@ split([], Comp, Components, OsType) -> %% will be converted to backslashes. On all platforms, the %% name will be normalized as done by join/1. --spec nativename(string()) -> string(). +-spec nativename(file:filename()) -> file:filename(). nativename(Name0) -> Name = join([Name0]), %Normalize. case os:type() of @@ -557,13 +714,12 @@ win32_nativename([]) -> separators() -> case os:type() of - {unix, _} -> {false, false}; {win32, _} -> {$\\, $:}; - vxworks -> {$\\, false}; - {ose,_} -> {false, false} + _ -> {false, false} end. + %% find_src(Module) -- %% find_src(Module, Rules) -- %% @@ -733,45 +889,12 @@ major_os_type() -> OsT -> OsT end. -%% Need to take care of the first pathname component separately -%% due to VxWorks less than good device naming rules. -%% (i.e. this is VxWorks specific ...) -%% The following four all starts with device names -%% elrond:/foo -> elrond: -%% elrond:\\foo.bar -> elrond: -%% /DISK1:foo -> /DISK1: -%% /usr/include -> /usr -%% This one doesn't: -%% foo/bar - -vxworks_first([]) -> - {not_device, [], []}; -vxworks_first([$/|T]) -> - vxworks_first2(device, T, [$/]); -vxworks_first([$\\|T]) -> - vxworks_first2(device, T, [$/]); -vxworks_first([H|T]) when is_list(H) -> - vxworks_first(H++T); -vxworks_first([H|T]) -> - vxworks_first2(not_device, T, [H]). - -vxworks_first2(Devicep, [], FirstComp) -> - {Devicep, [], FirstComp}; -vxworks_first2(Devicep, [$/|T], FirstComp) -> - {Devicep, [$/|T], FirstComp}; -vxworks_first2(Devicep, [$\\|T], FirstComp) -> - {Devicep, [$/|T], FirstComp}; -vxworks_first2(_Devicep, [$:|T], FirstComp)-> - {device, T, [$:|FirstComp]}; -vxworks_first2(Devicep, [H|T], FirstComp) when is_list(H) -> - vxworks_first2(Devicep, H++T, FirstComp); -vxworks_first2(Devicep, [H|T], FirstComp) -> - vxworks_first2(Devicep, T, [H|FirstComp]). - %% flatten(List) %% Flatten a list, also accepting atoms. --spec flatten(file:name()) -> string(). +-spec flatten(file:name()) -> file:filename(). +flatten(Bin) when is_binary(Bin) -> + Bin; flatten(List) -> do_flatten(List, []). @@ -785,3 +908,12 @@ do_flatten([], Tail) -> Tail; do_flatten(Atom, Tail) when is_atom(Atom) -> atom_to_list(Atom) ++ flatten(Tail). + +filename_string_to_binary(List) -> + case unicode:characters_to_binary(flatten(List),unicode,file:native_name_encoding()) of + {error,_,_} -> + erlang:error(badarg); + Bin when is_binary(Bin) -> + Bin + end. + diff --git a/lib/stdlib/src/gb_sets.erl b/lib/stdlib/src/gb_sets.erl index 086dc79b46..113f29e252 100644 --- a/lib/stdlib/src/gb_sets.erl +++ b/lib/stdlib/src/gb_sets.erl @@ -657,7 +657,7 @@ intersection_2([], _, As, S) -> intersection_2(_, [], As, S) -> {S, balance_revlist(As, S)}. --spec intersection([gb_set()]) -> gb_set(). +-spec intersection([gb_set(),...]) -> gb_set(). intersection([S | Ss]) -> intersection_list(S, Ss). diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl index 08ee595f4d..c669c1f7c1 100644 --- a/lib/stdlib/src/lists.erl +++ b/lib/stdlib/src/lists.erl @@ -350,7 +350,7 @@ sort_1(X, [], R) -> %% merge(List) -> L %% merges a list of sorted lists --spec merge([T]) -> [T]. +-spec merge([[T]]) -> [T]. merge(L) -> mergel(L, []). @@ -358,7 +358,7 @@ merge(L) -> %% merge3(X, Y, Z) -> L %% merges three sorted lists X, Y and Z --spec merge3([_], [_], [_]) -> [_]. +-spec merge3([X], [Y], [Z]) -> [(X | Y | Z)]. merge3(L1, [], L3) -> merge(L1, L3); @@ -370,7 +370,7 @@ merge3(L1, [H2 | T2], [H3 | T3]) -> %% rmerge3(X, Y, Z) -> L %% merges three reversed sorted lists X, Y and Z --spec rmerge3([_], [_], [_]) -> [_]. +-spec rmerge3([X], [Y], [Z]) -> [(X | Y | Z)]. rmerge3(L1, [], L3) -> rmerge(L1, L3); @@ -382,7 +382,7 @@ rmerge3(L1, [H2 | T2], [H3 | T3]) -> %% merge(X, Y) -> L %% merges two sorted lists X and Y --spec merge([_], [_]) -> [_]. +-spec merge([X], [Y]) -> [(X | Y)]. merge(T1, []) -> T1; @@ -394,7 +394,7 @@ merge(T1, [H2 | T2]) -> %% reverse(rmerge(reverse(A),reverse(B))) is equal to merge(I,A,B). --spec rmerge([_], [_]) -> [_]. +-spec rmerge([X], [Y]) -> [(X | Y)]. rmerge(T1, []) -> T1; @@ -420,12 +420,12 @@ thing_to_list(X) when is_list(X) -> X. %Assumed to be a string %% flatten(List, Tail) %% Flatten a list, adding optional tail. --spec flatten([_]) -> [_]. +-spec flatten([term()]) -> [term()]. flatten(List) when is_list(List) -> do_flatten(List, []). --spec flatten([_], [_]) -> [_]. +-spec flatten([term()], [term()]) -> [term()]. flatten(List, Tail) when is_list(List), is_list(Tail) -> do_flatten(List, Tail). @@ -440,7 +440,7 @@ do_flatten([], Tail) -> %% flatlength(List) %% Calculate the length of a list of lists. --spec flatlength([_]) -> non_neg_integer(). +-spec flatlength([term()]) -> non_neg_integer(). flatlength(List) -> flatlength(List, 0). @@ -481,7 +481,7 @@ flatlength([], L) -> L. % keysearch3(Key, N, T); %keysearch3(Key, N, []) -> false. --spec keydelete(_, pos_integer(), [T]) -> [T]. +-spec keydelete(term(), pos_integer(), [T]) -> [T] when T :: tuple(). keydelete(K, N, L) when is_integer(N), N > 0 -> keydelete3(K, N, L). @@ -491,7 +491,7 @@ keydelete3(Key, N, [H|T]) -> [H|keydelete3(Key, N, T)]; keydelete3(_, _, []) -> []. --spec keyreplace(_, pos_integer(), [_], tuple()) -> [_]. +-spec keyreplace(term(), pos_integer(), [tuple()], tuple()) -> [tuple()]. keyreplace(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) -> keyreplace3(K, N, L, New). @@ -502,7 +502,8 @@ keyreplace3(Key, Pos, [H|T], New) -> [H|keyreplace3(Key, Pos, T, New)]; keyreplace3(_, _, [], _) -> []. --spec keytake(_, pos_integer(), [_]) -> {'value', tuple(), [_]} | 'false'. +-spec keytake(term(), pos_integer(), [tuple()]) -> + {'value', tuple(), [tuple()]} | 'false'. keytake(Key, N, L) when is_integer(N), N > 0 -> keytake(Key, N, L, []). @@ -513,7 +514,8 @@ keytake(Key, N, [H|T], L) -> keytake(Key, N, T, [H|L]); keytake(_K, _N, [], _L) -> false. --spec keystore(_, pos_integer(), [_], tuple()) -> [_]. +-spec keystore(term(), pos_integer(), [tuple()], tuple()) -> [tuple(),...]. + keystore(K, N, L, New) when is_integer(N), N > 0, is_tuple(New) -> keystore2(K, N, L, New). @@ -524,7 +526,7 @@ keystore2(Key, N, [H|T], New) -> keystore2(_Key, _N, [], New) -> [New]. --spec keysort(pos_integer(), [T]) -> [T] when is_subtype(T, tuple()). +-spec keysort(pos_integer(), [T]) -> [T] when T :: tuple(). keysort(I, L) when is_integer(I), I > 0 -> case L of @@ -582,7 +584,7 @@ keysort_1(_I, X, _EX, [], R) -> lists:reverse(R, [X]). -spec keymerge(pos_integer(), [X], [Y]) -> - [R] when is_subtype(X, tuple()), is_subtype(Y, tuple()), is_subtype(R, tuple()). + [R] when X :: tuple(), Y :: tuple(), R :: tuple(). keymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> case L2 of @@ -597,7 +599,7 @@ keymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> %% reverse(rkeymerge(I,reverse(A),reverse(B))) is equal to keymerge(I,A,B). -spec rkeymerge(pos_integer(), [X], [Y]) -> - [R] when is_subtype(X, tuple()), is_subtype(Y, tuple()), is_subtype(R, tuple()). + [R] when X :: tuple(), Y :: tuple(), R :: tuple(). rkeymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> case L2 of @@ -609,7 +611,7 @@ rkeymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> lists:reverse(M, []) end. --spec ukeysort(pos_integer(), [T]) -> [T] when is_subtype(T, tuple()). +-spec ukeysort(pos_integer(), [T]) -> [T] when T :: tuple(). ukeysort(I, L) when is_integer(I), I > 0 -> case L of @@ -675,7 +677,7 @@ ukeysort_1(_I, X, _EX, []) -> [X]. -spec ukeymerge(pos_integer(), [X], [Y]) -> - [(X | Y)] when is_subtype(X, tuple()), is_subtype(Y, tuple()). + [(X | Y)] when X :: tuple(), Y :: tuple(). ukeymerge(Index, L1, T2) when is_integer(Index), Index > 0 -> case L1 of @@ -690,7 +692,7 @@ ukeymerge(Index, L1, T2) when is_integer(Index), Index > 0 -> %% reverse(rukeymerge(I,reverse(A),reverse(B))) is equal to ukeymerge(I,A,B). -spec rukeymerge(pos_integer(), [X], [Y]) -> - [(X | Y)] when is_subtype(X, tuple()), is_subtype(Y, tuple()). + [(X | Y)] when X :: tuple(), Y :: tuple(). rukeymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> case L2 of @@ -702,7 +704,7 @@ rukeymerge(Index, T1, L2) when is_integer(Index), Index > 0 -> lists:reverse(M, []) end. --spec keymap(fun((_) -> _), pos_integer(), [tuple()]) -> [tuple()]. +-spec keymap(fun((term()) -> term()), pos_integer(), [tuple()]) -> [tuple()]. keymap(Fun, Index, [Tup|Tail]) -> [setelement(Index, Tup, Fun(element(Index, Tup)))|keymap(Fun, Index, Tail)]; @@ -725,7 +727,7 @@ sort(Fun, [X, Y | T]) -> fsplit_2(Y, X, Fun, T, [], []) end. --spec merge(fun((X, Y) -> boolean()), [X], [Y]) -> [_]. +-spec merge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)]. merge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) -> lists:reverse(fmerge2_1(T1, H2, Fun, T2, []), []); @@ -734,7 +736,7 @@ merge(Fun, T1, []) when is_function(Fun, 2) -> %% reverse(rmerge(F,reverse(A),reverse(B))) is equal to merge(F,A,B). --spec rmerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_]. +-spec rmerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)]. rmerge(Fun, T1, [H2 | T2]) when is_function(Fun, 2) -> lists:reverse(rfmerge2_1(T1, H2, Fun, T2, []), []); @@ -768,7 +770,7 @@ usort_1(Fun, X, [Y | L]) -> ufsplit_2(Y, L, Fun, [X]) end. --spec umerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_]. +-spec umerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)]. umerge(Fun, [], T2) when is_function(Fun, 2) -> T2; @@ -777,7 +779,7 @@ umerge(Fun, [H1 | T1], T2) when is_function(Fun, 2) -> %% reverse(rumerge(F,reverse(A),reverse(B))) is equal to umerge(F,A,B). --spec rumerge(fun((X, Y) -> boolean()), [X], [Y]) -> [_]. +-spec rumerge(fun((X, Y) -> boolean()), [X], [Y]) -> [(X | Y)]. rumerge(Fun, T1, []) when is_function(Fun, 2) -> T1; @@ -842,7 +844,7 @@ usort_1(X, []) -> %% umerge(List) -> L %% merges a list of sorted lists without duplicates, removes duplicates --spec umerge([T]) -> [T]. +-spec umerge([[T]]) -> [T]. umerge(L) -> umergel(L). @@ -851,7 +853,7 @@ umerge(L) -> %% merges three sorted lists X, Y and Z without duplicates, %% removes duplicates --spec umerge3([_], [_], [_]) -> [_]. +-spec umerge3([X], [Y], [Z]) -> [(X | Y | Z)]. umerge3(L1, [], L3) -> umerge(L1, L3); @@ -864,7 +866,7 @@ umerge3(L1, [H2 | T2], [H3 | T3]) -> %% merges three reversed sorted lists X, Y and Z without duplicates, %% removes duplicates --spec rumerge3([_], [_], [_]) -> [_]. +-spec rumerge3([X], [Y], [Z]) -> [(X | Y | Z)]. rumerge3(L1, [], L3) -> rumerge(L1, L3); @@ -876,7 +878,7 @@ rumerge3(L1, [H2 | T2], [H3 | T3]) -> %% umerge(X, Y) -> L %% merges two sorted lists X and Y without duplicates, removes duplicates --spec umerge([_], [_]) -> [_]. +-spec umerge([X], [Y]) -> [(X | Y)]. umerge([], T2) -> T2; @@ -889,7 +891,7 @@ umerge([H1 | T1], T2) -> %% reverse(rumerge(reverse(A),reverse(B))) is equal to umerge(I,A,B). --spec rumerge([_], [_]) -> [_]. +-spec rumerge([X], [Y]) -> [(X | Y)]. rumerge(T1, []) -> T1; @@ -952,13 +954,13 @@ flatmap(F, [Hd|Tail]) -> F(Hd) ++ flatmap(F, Tail); flatmap(F, []) when is_function(F, 1) -> []. --spec foldl(fun((T, _) -> _), _, [T]) -> _. +-spec foldl(fun((T, term()) -> term()), term(), [T]) -> term(). foldl(F, Accu, [Hd|Tail]) -> foldl(F, F(Hd, Accu), Tail); foldl(F, Accu, []) when is_function(F, 2) -> Accu. --spec foldr(fun((T, _) -> _), _, [T]) -> _. +-spec foldr(fun((T, term()) -> term()), term(), [T]) -> term(). foldr(F, Accu, [Hd|Tail]) -> F(Hd, foldr(F, Accu, Tail)); @@ -998,14 +1000,14 @@ zf(F, [Hd|Tail]) -> end; zf(F, []) when is_function(F, 1) -> []. --spec foreach(F :: fun((T) -> _), List :: [T]) -> 'ok'. +-spec foreach(F :: fun((T) -> term()), List :: [T]) -> 'ok'. foreach(F, [Hd|Tail]) -> F(Hd), foreach(F, Tail); foreach(F, []) when is_function(F, 1) -> ok. --spec mapfoldl(fun((T, _) -> {_, _}), _, [T]) -> {[_], _}. +-spec mapfoldl(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}. mapfoldl(F, Accu0, [Hd|Tail]) -> {R,Accu1} = F(Hd, Accu0), @@ -1013,7 +1015,7 @@ mapfoldl(F, Accu0, [Hd|Tail]) -> {[R|Rs],Accu2}; mapfoldl(F, Accu, []) when is_function(F, 2) -> {[],Accu}. --spec mapfoldr(fun((T, _) -> {_, _}), _, [T]) -> {[_], _}. +-spec mapfoldr(fun((A, term()) -> {B, term()}), term(), [A]) -> {[B], term()}. mapfoldr(F, Accu0, [Hd|Tail]) -> {Rs,Accu1} = mapfoldr(F, Accu0, Tail), diff --git a/lib/stdlib/src/orddict.erl b/lib/stdlib/src/orddict.erl index c7b52b933e..8a13992785 100644 --- a/lib/stdlib/src/orddict.erl +++ b/lib/stdlib/src/orddict.erl @@ -151,7 +151,7 @@ map(F, [{Key,Val}|D]) -> [{Key,F(Key, Val)}|map(F, D)]; map(F, []) when is_function(F, 2) -> []. --spec filter(fun((term(), term()) -> term()), orddict()) -> orddict(). +-spec filter(fun((term(), term()) -> boolean()), orddict()) -> orddict(). filter(F, [{Key,Val}=E|D]) -> case F(Key, Val) of diff --git a/lib/stdlib/src/ordsets.erl b/lib/stdlib/src/ordsets.erl index 05041c15f1..4c72e351d0 100644 --- a/lib/stdlib/src/ordsets.erl +++ b/lib/stdlib/src/ordsets.erl @@ -26,12 +26,14 @@ -export([subtract/2,is_subset/2]). -export([fold/3,filter/2]). +-export_type([ordset/1]). + -type ordset(T) :: [T]. %% new() -> Set. %% Return a new empty ordered set. --spec new() -> ordset(term()). +-spec new() -> []. new() -> []. @@ -84,7 +86,7 @@ is_element(_, []) -> false. %% add_element(Element, OrdSet) -> OrdSet. %% Return OrdSet with Element inserted in it. --spec add_element(term(), ordset(_)) -> ordset(_). +-spec add_element(E, ordset(T)) -> [T | E,...]. add_element(E, [H|Es]) when E > H -> [H|add_element(E, Es)]; add_element(E, [H|_]=Set) when E < H -> [E|Set]; @@ -94,7 +96,7 @@ add_element(E, []) -> [E]. %% del_element(Element, OrdSet) -> OrdSet. %% Return OrdSet but with Element removed. --spec del_element(term(), ordset(_)) -> ordset(_). +-spec del_element(term(), ordset(T)) -> ordset(T). del_element(E, [H|Es]) when E > H -> [H|del_element(E, Es)]; del_element(E, [H|_]=Set) when E < H -> Set; @@ -104,7 +106,7 @@ del_element(_, []) -> []. %% union(OrdSet1, OrdSet2) -> OrdSet %% Return the union of OrdSet1 and OrdSet2. --spec union(ordset(_), ordset(_)) -> ordset(_). +-spec union(ordset(T1), ordset(T2)) -> ordset(T1 | T2). union([E1|Es1], [E2|_]=Set2) when E1 < E2 -> [E1|union(Es1, Set2)]; @@ -118,7 +120,7 @@ union(Es1, []) -> Es1. %% union([OrdSet]) -> OrdSet %% Return the union of the list of ordered sets. --spec union([ordset(_)]) -> ordset(_). +-spec union([ordset(T)]) -> ordset(T). union([S1,S2|Ss]) -> union1(union(S1, S2), Ss); @@ -147,7 +149,7 @@ intersection(_, []) -> %% intersection([OrdSet]) -> OrdSet. %% Return the intersection of the list of ordered sets. --spec intersection([ordset(_)]) -> ordset(_). +-spec intersection([ordset(_),...]) -> ordset(_). intersection([S1,S2|Ss]) -> intersection1(intersection(S1, S2), Ss); @@ -206,7 +208,7 @@ is_subset(_, []) -> false. %% fold(Fun, Accumulator, OrdSet) -> Accumulator. %% Fold function Fun over all elements in OrdSet and return Accumulator. --spec fold(fun((_, _) -> _), _, ordset(_)) -> _. +-spec fold(fun((T, term()) -> term()), term(), ordset(T)) -> term(). fold(F, Acc, Set) -> lists:foldl(F, Acc, Set). @@ -214,7 +216,7 @@ fold(F, Acc, Set) -> %% filter(Fun, OrdSet) -> OrdSet. %% Filter OrdSet with Fun. --spec filter(fun((_) -> boolean()), ordset(_)) -> ordset(_). +-spec filter(fun((T) -> boolean()), ordset(T)) -> ordset(T). filter(F, Set) -> lists:filter(F, Set). diff --git a/lib/stdlib/src/string.erl b/lib/stdlib/src/string.erl index 6636a03f06..c987c224db 100644 --- a/lib/stdlib/src/string.erl +++ b/lib/stdlib/src/string.erl @@ -201,7 +201,7 @@ chars(C, 0, Tail) when is_integer(C) -> -spec copies(string(), non_neg_integer()) -> string(). -copies(CharList, Num) when is_list(CharList), Num >= 0 -> +copies(CharList, Num) when is_list(CharList), is_integer(Num), Num >= 0 -> copies(CharList, Num, []). copies(_CharList, 0, R) -> diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl index f5d5441184..7102fb9f6e 100644 --- a/lib/stdlib/src/supervisor.erl +++ b/lib/stdlib/src/supervisor.erl @@ -33,7 +33,9 @@ -export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]). -export([handle_cast/2]). --export_type([child_spec/0, strategy/0]). +%%-------------------------------------------------------------------------- + +-export_type([child_spec/0, del_err/0, startchild_ret/0, strategy/0]). %%-------------------------------------------------------------------------- @@ -77,6 +79,10 @@ -define(is_simple(State), State#state.strategy =:= simple_one_for_one). +%%-------------------------------------------------------------------------- + +-spec behaviour_info(atom()) -> 'undefined' | [{atom(), arity()}]. + behaviour_info(callbacks) -> [{init,1}]; behaviour_info(_Other) -> @@ -160,11 +166,13 @@ check_childspecs(X) -> {error, {badarg, X}}. %%% %%% --------------------------------------------------- +-type init_sup_name() :: sup_name() | 'self'. + -type stop_rsn() :: 'shutdown' | {'bad_return', {module(),'init', term()}} | {'bad_start_spec', term()} | {'start_spec', term()} | {'supervisor_data', term()}. --spec init({sup_name(), module(), [term()]}) -> +-spec init({init_sup_name(), module(), [term()]}) -> {'ok', state()} | 'ignore' | {'stop', stop_rsn()}. init({SupName, Mod, Args}) -> @@ -184,7 +192,7 @@ init({SupName, Mod, Args}) -> Error -> {stop, {bad_return, {Mod, init, Error}}} end. - + init_children(State, StartSpec) -> SupName = State#state.name, case check_startspec(StartSpec) of @@ -660,14 +668,15 @@ terminate_children([], _SupName, Res) -> Res. do_terminate(Child, SupName) when Child#child.pid =/= undefined -> - case shutdown(Child#child.pid, - Child#child.shutdown) of - ok -> - Child#child{pid = undefined}; - {error, OtherReason} -> - report_error(shutdown_error, OtherReason, Child, SupName), - Child#child{pid = undefined} - end; + case shutdown(Child#child.pid, Child#child.shutdown) of + ok -> + ok; + {error, normal} when Child#child.restart_type =/= permanent -> + ok; + {error, OtherReason} -> + report_error(shutdown_error, OtherReason, Child, SupName) + end, + Child#child{pid = undefined}; do_terminate(Child, _SupName) -> Child. diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl index 24e14caa69..b456c5d6c1 100644 --- a/lib/stdlib/src/timer.erl +++ b/lib/stdlib/src/timer.erl @@ -33,6 +33,9 @@ %% internal exports for test purposes only -export([get_status/0]). +%% types which can be used by other modules +-export_type([tref/0]). + %% Max -define(MAX_TIMEOUT, 16#0800000). -define(TIMER_TAB, timer_tab). diff --git a/lib/stdlib/src/unicode.erl b/lib/stdlib/src/unicode.erl index 09b1deff9c..869505ba83 100644 --- a/lib/stdlib/src/unicode.erl +++ b/lib/stdlib/src/unicode.erl @@ -25,8 +25,17 @@ %% InEncoding is not {latin1 | unicode | utf8}) %% --export([characters_to_list/1, characters_to_list_int/2, characters_to_binary/1,characters_to_binary_int/2, characters_to_binary/3,bom_to_encoding/1, encoding_to_bom/1]). +-export([characters_to_list/1, characters_to_list_int/2, + characters_to_binary/1, characters_to_binary_int/2, + characters_to_binary/3, + bom_to_encoding/1, encoding_to_bom/1]). +-export_type([encoding/0]). + +-type encoding() :: 'latin1' | 'unicode' | 'utf8' + | 'utf16' | {'utf16', endian()} + | 'utf32' | {'utf32', endian()}. +-type endian() :: 'big' | 'little'. characters_to_list(ML) -> unicode:characters_to_list(ML,unicode). diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl index 16ed9a2c26..e4cdcf6125 100644 --- a/lib/stdlib/test/binary_module_SUITE.erl +++ b/lib/stdlib/test/binary_module_SUITE.erl @@ -186,7 +186,7 @@ badargs(Config) when is_list(Config) -> binary:match(<<1,2,3>>, {ac,ets:match_spec_compile([{'_',[],['$_']}])}, [{scope,{0,1}}])), - ?line nomatch = + ?line [] = ?MASK_ERROR(binary:matches(<<1,2,3>>,<<1>>,[{scope,{0,0}}])), ?line badarg = ?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])), diff --git a/lib/stdlib/test/dets_SUITE.erl b/lib/stdlib/test/dets_SUITE.erl index 760e610e00..8b18ef5664 100644 --- a/lib/stdlib/test/dets_SUITE.erl +++ b/lib/stdlib/test/dets_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-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 @@ -50,7 +50,8 @@ otp_4208/1, otp_4989/1, many_clients/1, otp_4906/1, otp_5402/1, simultaneous_open/1, insert_new/1, repair_continuation/1, otp_5487/1, otp_6206/1, otp_6359/1, otp_4738/1, otp_7146/1, - otp_8070/1]). + otp_8070/1, otp_8856/1, otp_8898/1, otp_8899/1, otp_8903/1, + otp_8923/1]). -export([dets_dirty_loop/0]). @@ -108,7 +109,8 @@ all(suite) -> cache_duplicate_bags_v9, otp_4208, otp_4989, many_clients, otp_4906, otp_5402, simultaneous_open, insert_new, repair_continuation, otp_5487, otp_6206, otp_6359, otp_4738, - otp_7146, otp_8070]} + otp_7146, otp_8070, otp_8856, otp_8898, otp_8899, otp_8903, + otp_8923]} end. not_run(suite) -> []; @@ -2935,6 +2937,57 @@ ets_init(Tab, N) -> ets:insert(Tab, {N,N}), ets_init(Tab, N - 1). +otp_8898(doc) -> + ["OTP-8898. Truncated Dets file."]; +otp_8898(suite) -> + []; +otp_8898(Config) when is_list(Config) -> + Tab = otp_8898, + ?line FName = filename(Tab, Config), + + Server = self(), + + ?line file:delete(FName), + ?line {ok, _} = dets:open_file(Tab,[{file, FName}]), + ?line [P1,P2,P3] = new_clients(3, Tab), + + Seq = [{P1,[sync]},{P2,[{lookup,1,[]}]},{P3,[{insert,{1,b}}]}], + ?line atomic_requests(Server, Tab, [[]], Seq), + ?line true = get_replies([{P1,ok},{P2,ok},{P3,ok}]), + ?line ok = dets:close(Tab), + ?line {ok, _} = dets:open_file(Tab,[{file, FName}]), + ?line file:delete(FName), + + ok. + +otp_8899(doc) -> + ["OTP-8899. Several clients. Updated Head was ignored."]; +otp_8899(suite) -> + []; +otp_8899(Config) when is_list(Config) -> + Tab = many_clients, + ?line FName = filename(Tab, Config), + + Server = self(), + + ?line file:delete(FName), + ?line {ok, _} = dets:open_file(Tab,[{file, FName},{version,9}]), + ?line [P1,P2,P3,P4] = new_clients(4, Tab), + + MC = [Tab], + Seq6a = [{P1,[{insert,[{used_to_be_skipped_by,match}]}, + {lookup,1,[{1,a}]}]}, + {P2,[{verbose,true,MC}]}, + {P3,[{lookup,1,[{1,a}]}]}, {P4,[{verbose,true,MC}]}], + ?line atomic_requests(Server, Tab, [[{1,a},{2,b},{3,c}]], Seq6a), + ?line true = get_replies([{P1,ok}, {P2,ok}, {P3,ok}, {P4,ok}]), + ?line [{1,a},{2,b},{3,c},{used_to_be_skipped_by,match}] = + lists:sort(dets:match_object(Tab, '_')), + ?line _ = dets:close(Tab), + ?line file:delete(FName), + + ok. + many_clients(doc) -> ["Several clients accessing a table simultaneously."]; many_clients(suite) -> @@ -3071,6 +3124,11 @@ client(S, Tab) -> eval([], _Tab) -> ok; +eval([{verbose,Bool,Expected} | L], Tab) -> + ?line case dets:verbose(Bool) of + Expected -> eval(L, Tab); + Error -> {error, {verbose,Error}} + end; eval([sync | L], Tab) -> ?line case dets:sync(Tab) of ok -> eval(L, Tab); @@ -3701,6 +3759,87 @@ otp_8070(Config) when is_list(Config) -> file:delete(File), ok. +otp_8856(doc) -> + ["OTP-8856. insert_new() bug."]; +otp_8856(suite) -> + []; +otp_8856(Config) when is_list(Config) -> + Tab = otp_8856, + File = filename(Tab, Config), + file:delete(File), + Me = self(), + ?line {ok, _} = dets:open_file(Tab, [{type, bag}, {file, File}]), + spawn(fun()-> Me ! {1, dets:insert(Tab, [])} end), + spawn(fun()-> Me ! {2, dets:insert_new(Tab, [])} end), + ?line ok = dets:close(Tab), + ?line receive {1, ok} -> ok end, + ?line receive {2, true} -> ok end, + file:delete(File), + + ?line {ok, _} = dets:open_file(Tab, [{type, set}, {file, File}]), + spawn(fun() -> dets:delete(Tab, 0) end), + spawn(fun() -> Me ! {3, dets:insert_new(Tab, {0,0})} end), + ?line ok = dets:close(Tab), + ?line receive {3, true} -> ok end, + file:delete(File), + ok. + +otp_8903(doc) -> + ["OTP-8903. bchunk/match/select bug."]; +otp_8903(suite) -> + []; +otp_8903(Config) when is_list(Config) -> + Tab = otp_8903, + File = filename(Tab, Config), + ?line {ok,T} = dets:open_file(bug, [{file,File}]), + ?line ok = dets:insert(T, [{1,a},{2,b},{3,c}]), + ?line dets:safe_fixtable(T, true), + ?line {[_],C1} = dets:match_object(T, '_', 1), + ?line {BC1,_D} = dets:bchunk(T, start), + ?line ok = dets:close(T), + ?line {'EXIT', {badarg, _}} = (catch {foo,dets:match_object(C1)}), + ?line {'EXIT', {badarg, _}} = (catch {foo,dets:bchunk(T, BC1)}), + ?line {ok,T} = dets:open_file(bug, [{file,File}]), + ?line false = dets:info(T, safe_fixed), + ?line {'EXIT', {badarg, _}} = (catch {foo,dets:match_object(C1)}), + ?line {'EXIT', {badarg, _}} = (catch {foo,dets:bchunk(T, BC1)}), + ?line ok = dets:close(T), + file:delete(File), + ok. + +otp_8923(doc) -> + ["OTP-8923. rehash due to lookup after initialization."]; +otp_8923(suite) -> + []; +otp_8923(Config) when is_list(Config) -> + Tab = otp_8923, + File = filename(Tab, Config), + %% Create a file with more than 256 keys: + file:delete(File), + Bin = list_to_binary([ 0 || _ <- lists:seq(1, 400) ]), + BigBin = list_to_binary([ 0 ||_ <- lists:seq(1, 4000)]), + Ets = ets:new(temp, [{keypos,1}]), + ?line [ true = ets:insert(Ets, {C,Bin}) || C <- lists:seq(1, 700) ], + ?line true = ets:insert(Ets, {helper_data,BigBin}), + ?line true = ets:insert(Ets, {prim_btree,BigBin}), + ?line true = ets:insert(Ets, {sec_btree,BigBin}), + %% Note: too few slots; re-hash will take place + ?line {ok, Tab} = dets:open_file(Tab, [{file,File}]), + ?line Tab = ets:to_dets(Ets, Tab), + ?line ok = dets:close(Tab), + ?line true = ets:delete(Ets), + + ?line {ok,Ref} = dets:open_file(File), + ?line [{1,_}] = dets:lookup(Ref, 1), + ?line ok = dets:close(Ref), + + ?line {ok,Ref2} = dets:open_file(File), + ?line [{helper_data,_}] = dets:lookup(Ref2, helper_data), + ?line ok = dets:close(Ref2), + + file:delete(File), + ok. + %% %% Parts common to several test cases %% diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl index e31dfdd764..e9fb932632 100644 --- a/lib/stdlib/test/epp_SUITE.erl +++ b/lib/stdlib/test/epp_SUITE.erl @@ -24,7 +24,7 @@ variable/1, variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1, pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1, otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1, - otp_8562/1, otp_8665/1]). + otp_8562/1, otp_8665/1, otp_8911/1]). -export([epp_parse_erl_form/2]). @@ -64,7 +64,7 @@ all(doc) -> all(suite) -> [rec_1, upcase_mac, predef_mac, variable, otp_4870, otp_4871, otp_5362, pmod, not_circular, skip_header, otp_6277, otp_7702, otp_8130, - overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, otp_8665]. + overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, otp_8665, otp_8911]. rec_1(doc) -> ["Recursive macros hang or crash epp (OTP-1398)."]; @@ -1197,6 +1197,40 @@ otp_8562(Config) when is_list(Config) -> ?line [] = compile(Config, Cs), ok. +otp_8911(doc) -> + ["OTP-8911. -file and file inclusion bug"]; +otp_8911(suite) -> + []; +otp_8911(Config) when is_list(Config) -> + ?line {ok, CWD} = file:get_cwd(), + ?line ok = file:set_cwd(?config(priv_dir, Config)), + + File = "i.erl", + Cont = <<"-module(i). + -compile(export_all). + -file(\"fil1\", 100). + -include(\"i1.erl\"). + t() -> + a. + ">>, + ?line ok = file:write_file(File, Cont), + Incl = <<"-file(\"fil2\", 35). + t1() -> + b. + ">>, + File1 = "i1.erl", + ?line ok = file:write_file(File1, Incl), + + ?line {ok, i} = cover:compile(File), + ?line a = i:t(), + ?line {ok,[{{i,6},1}]} = cover:analyse(i, calls, line), + ?line cover:stop(), + + file:delete(File), + file:delete(File1), + ?line file:set_cwd(CWD), + ok. + otp_8665(doc) -> ["OTP-8665. Bugfix premature end."]; otp_8665(suite) -> diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 77fd190e45..162ca6006f 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -31,6 +31,7 @@ epp/1, create_and_extract/1, foldl/1, + overflow/1, verify_sections/3 ]). @@ -48,7 +49,8 @@ all(suite) -> archive_script, epp, create_and_extract, - foldl + foldl, + overflow ]. init_per_testcase(_Case, Config) -> @@ -736,6 +738,17 @@ emulate_escript_foldl(Fun, Acc, File) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +overflow(Config) when is_list(Config) -> + Data = ?config(data_dir, Config), + Dir = filename:absname(Data), %Get rid of trailing slash. + ?line run(Dir, "arg_overflow", + [<<"ExitCode:0">>]), + ?line run(Dir, "linebuf_overflow", + [<<"ExitCode:0">>]), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + run(Dir, Cmd0, Expected0) -> Expected = iolist_to_binary(expected_output(Expected0, Dir)), Cmd = case os:type() of diff --git a/lib/stdlib/test/escript_SUITE_data/arg_overflow b/lib/stdlib/test/escript_SUITE_data/arg_overflow new file mode 100755 index 0000000000..dd5accc051 --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/arg_overflow @@ -0,0 +1,5 @@ +#! /usr/bin/env escript +%% -*- erlang -*- +%%!x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x +main(_) -> + halt(0). diff --git a/lib/stdlib/test/escript_SUITE_data/linebuf_overflow b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow new file mode 100755 index 0000000000..33133c1ce9 --- /dev/null +++ b/lib/stdlib/test/escript_SUITE_data/linebuf_overflow @@ -0,0 +1,5 @@ +#! /usr/bin/env escript +%% -*- erlang -*- +%%!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +main(_) -> + halt(0). diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 7f39dbe21f..620848003c 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -31,7 +31,7 @@ -export([slot/1]). -export([match/1, match1/1, match2/1, match_object/1, match_object2/1]). -export([misc/1, dups/1, misc1/1, safe_fixtable/1, info/1, tab2list/1]). --export([files/1, tab2file/1, tab2file2/1, tab2file3/1, tabfile_ext1/1, +-export([files/1, tab2file/1, tab2file2/1, tabfile_ext1/1, tabfile_ext2/1, tabfile_ext3/1, tabfile_ext4/1]). -export([heavy/1, heavy_lookup/1, heavy_lookup_element/1, heavy_concurrent/1]). -export([lookup_element/1, lookup_element_mult/1]). @@ -70,7 +70,7 @@ exit_many_tables_owner/1, exit_many_many_tables_owner/1]). -export([write_concurrency/1, heir/1, give_away/1, setopts/1]). --export([bad_table/1]). +-export([bad_table/1, types/1]). -export([init_per_testcase/2, fin_per_testcase/2, end_per_suite/1]). %% Convenience for manual testing @@ -78,7 +78,7 @@ % internal exports -export([dont_make_worse_sub/0, make_better_sub1/0, make_better_sub2/0]). --export([t_repair_continuation_do/1, default_do/1, t_bucket_disappears_do/1, +-export([t_repair_continuation_do/1, t_bucket_disappears_do/1, select_fail_do/1, whitebox_1/1, whitebox_2/1, t_delete_all_objects_do/1, t_delete_object_do/1, t_init_table_do/1, t_insert_list_do/1, update_element_opts/1, update_element_opts/4, update_element/4, update_element_do/4, @@ -91,7 +91,8 @@ slot_do/1, match1_do/1, match2_do/1, match_object_do/1, match_object2_do/1, misc1_do/1, safe_fixtable_do/1, info_do/1, dups_do/1, heavy_lookup_do/1, heavy_lookup_element_do/1, member_do/1, otp_5340_do/1, otp_7665_do/1, meta_wb_do/1, - do_heavy_concurrent/1 + do_heavy_concurrent/1, tab2file2_do/2, exit_large_table_owner_do/2, + types_do/1, sleeper/0, rpc_externals/0, memory_do/1 ]). -export([t_select_reverse/1]). @@ -143,7 +144,7 @@ all(suite) -> exit_many_tables_owner, exit_many_many_tables_owner, write_concurrency, heir, give_away, setopts, - bad_table + bad_table, types ]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -157,7 +158,7 @@ t_bucket_disappears(Config) when is_list(Config) -> t_bucket_disappears_do(Opts) -> ?line EtsMem = etsmem(), - ?line ets:new(abcd, [named_table, public, {keypos, 2} | Opts]), + ?line ets_new(abcd, [named_table, public, {keypos, 2} | Opts]), ?line ets:insert(abcd, {abcd,1,2}), ?line ets:insert(abcd, {abcd,2,2}), ?line ets:insert(abcd, {abcd,3,2}), @@ -213,7 +214,7 @@ t_repair_continuation_do(Opts) -> ?line MS = [{'_',[],[true]}], ?line MS2 = [{{{'$1','_'},'_'},[],['$1']}], (fun() -> - ?line T = ets:new(x,[ordered_set|Opts]), + ?line T = ets_new(x,[ordered_set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{N,N}), F(N-1,F) end, ?line F(1000,F), ?line {_,C} = ets:select(T,MS,5), @@ -225,7 +226,7 @@ t_repair_continuation_do(Opts) -> ?line true = ets:delete(T) end)(), (fun() -> - ?line T = ets:new(x,[ordered_set|Opts]), + ?line T = ets_new(x,[ordered_set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{N,N}), F(N-1,F) end, ?line F(1000,F), ?line {_,C} = ets:select(T,MS,1001), @@ -237,7 +238,7 @@ t_repair_continuation_do(Opts) -> end)(), (fun() -> - ?line T = ets:new(x,[ordered_set|Opts]), + ?line T = ets_new(x,[ordered_set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{integer_to_list(N),N}), F(N-1,F) @@ -252,7 +253,7 @@ t_repair_continuation_do(Opts) -> ?line true = ets:delete(T) end)(), (fun() -> - ?line T = ets:new(x,[ordered_set|Opts]), + ?line T = ets_new(x,[ordered_set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{{integer_to_list(N),N},N}), F(N-1,F) @@ -268,7 +269,7 @@ t_repair_continuation_do(Opts) -> end)(), (fun() -> - ?line T = ets:new(x,[set|Opts]), + ?line T = ets_new(x,[set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{N,N}), F(N-1,F) @@ -283,7 +284,7 @@ t_repair_continuation_do(Opts) -> ?line true = ets:delete(T) end)(), (fun() -> - ?line T = ets:new(x,[set|Opts]), + ?line T = ets_new(x,[set|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{integer_to_list(N),N}), F(N-1,F) @@ -298,7 +299,7 @@ t_repair_continuation_do(Opts) -> ?line true = ets:delete(T) end)(), (fun() -> - ?line T = ets:new(x,[bag|Opts]), + ?line T = ets_new(x,[bag|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{integer_to_list(N),N}), F(N-1,F) @@ -313,7 +314,7 @@ t_repair_continuation_do(Opts) -> ?line true = ets:delete(T) end)(), (fun() -> - ?line T = ets:new(x,[duplicate_bag|Opts]), + ?line T = ets_new(x,[duplicate_bag|Opts]), ?line F = fun(0,_)->ok;(N,F) -> ets:insert(T,{integer_to_list(N),N}), F(N-1,F) @@ -334,18 +335,20 @@ t_repair_continuation_do(Opts) -> new(suite) -> [default,setbag,badnew,verybadnew,named,keypos2,privacy]. default(doc) -> - ["Test case to check that a new ets table is defined as a `set' and " - "`protected'"]; + ["Check correct default vaules of a new ets table"]; default(suite) -> []; default(Config) when is_list(Config) -> %% Default should be set,protected - repeat_for_opts(default_do). - -default_do(Opts) -> ?line EtsMem = etsmem(), - ?line Def = ets:new(def,Opts), + ?line Def = ets_new(def,[]), ?line set = ets:info(Def,type), ?line protected = ets:info(Def,protection), + Compressed = erlang:system_info(ets_always_compress), + ?line Compressed = ets:info(Def,compressed), + Self = self(), + ?line Self = ets:info(Def,owner), + ?line none = ets:info(Def, heir), + ?line false = ets:info(Def,named_table), ?line ets:delete(Def), ?line verify_etsmem(EtsMem). @@ -359,7 +362,7 @@ select_fail(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). select_fail_do(Opts) -> - ?line T = ets:new(x,Opts), + ?line T = ets_new(x,Opts), ?line ets:insert(T,{a,a}), ?line case (catch ets:select(T,[{{a,'_'},[],[{snuffla}]}])) of @@ -382,20 +385,27 @@ select_fail_do(Opts) -> -define(S(T),ets:info(T,memory)). -define(TAB_STRUCT_SZ, erts_debug:get_internal_state('DbTable_words')). --define(NORMAL_TAB_STRUCT_SZ, 26). %% SunOS5.8, 32-bit, non smp, private heap +%%-define(NORMAL_TAB_STRUCT_SZ, 26). %% SunOS5.8, 32-bit, non smp, private heap %% %% The hardcoded expected memory sizes (in words) are the ones we expect on: %% SunOS5.8, 32-bit, non smp, private heap %% -memory(doc) -> - ["Whitebox test of ets:info(X,memory)"]; -memory(suite) -> - []; +memory(doc) -> ["Whitebox test of ets:info(X,memory)"]; +memory(suite) -> []; memory(Config) when is_list(Config) -> ?line erts_debug:set_internal_state(available_internal_state, true), ?line ok = chk_normal_tab_struct_size(), - ?line L = [T1,T2,T3,T4] = fill_sets_int(1000), - ?line XRes1 = adjust_xmem(L, {13862,13072,13072,13078}), + repeat_for_opts(memory_do,[compressed]), + ?line catch erts_debug:set_internal_state(available_internal_state, false). + +memory_do(Opts) -> + ?line L = [T1,T2,T3,T4] = fill_sets_int(1000,Opts), + XR1 = case mem_mode(T1) of + {normal,_} -> {13836,13046,13046,13052}; %{13862,13072,13072,13078}; + {compressed,4} -> {11041,10251,10251,10252}; %{11067,10277,10277,10278}; + {compressed,8} -> {10050,9260,9260,9260} %{10076,9286,9286,9286} + end, + ?line XRes1 = adjust_xmem(L, XR1), ?line Res1 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> Before = ets:info(T,size), @@ -406,7 +416,12 @@ memory(Config) when is_list(Config) -> [Key, ets:info(T,type), Before, ets:info(T,size), Objs]) end, L), - ?line XRes2 = adjust_xmem(L, {13852,13063,13054,13060}), + XR2 = case mem_mode(T1) of + {normal,_} -> {13826,13037,13028,13034}; %{13852,13063,13054,13060}; + {compressed,4} -> {11031,10242,10233,10234}; %{11057,10268,10259,10260}; + {compressed,8} -> {10040,9251,9242,9242} %10066,9277,9268,9268} + end, + ?line XRes2 = adjust_xmem(L, XR2), ?line Res2 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> Before = ets:info(T,size), @@ -417,13 +432,18 @@ memory(Config) when is_list(Config) -> [Key, ets:info(T,type), Before, ets:info(T,size), Objs]) end, L), - ?line XRes3 = adjust_xmem(L, {13842,13054,13036,13042}), + XR3 = case mem_mode(T1) of + {normal,_} -> {13816,13028,13010,13016}; %{13842,13054,13036,13042}; + {compressed,4} -> {11021,10233,10215,10216}; %{11047,10259,10241,10242}; + {compressed,8} -> {10030,9242,9224,9224} %{10056,9268,9250,9250} + end, + ?line XRes3 = adjust_xmem(L, XR3), ?line Res3 = {?S(T1),?S(T2),?S(T3),?S(T4)}, ?line lists:foreach(fun(T) -> ?line ets:delete_all_objects(T) end, L), - ?line XRes4 = adjust_xmem(L, {76,286,286,286}), + ?line XRes4 = adjust_xmem(L, {50,260,260,260}), %{76,286,286,286}), ?line Res4 = {?S(T1),?S(T2),?S(T3),?S(T4)}, lists:foreach(fun(T) -> ?line ets:delete(T) @@ -434,9 +454,9 @@ memory(Config) when is_list(Config) -> ?line ets:select_delete(T,[{'_',[],[true]}]) end, L2), - ?line XRes5 = adjust_xmem(L2, {76,286,286,286}), + ?line XRes5 = adjust_xmem(L2, {50,260,260,260}), %{76,286,286,286}), ?line Res5 = {?S(T11),?S(T12),?S(T13),?S(T14)}, - ?line ?t:format("XRes1 = ~p~n" + ?line io:format("XRes1 = ~p~n" " Res1 = ~p~n~n" "XRes2 = ~p~n" " Res2 = ~p~n~n" @@ -456,9 +476,15 @@ memory(Config) when is_list(Config) -> ?line XRes3 = Res3, ?line XRes4 = Res4, ?line XRes5 = Res5, - ?line catch erts_debug:set_internal_state(available_internal_state, false), ?line ok. +mem_mode(T) -> + {case ets:info(T,compressed) of + true -> compressed; + false -> normal + end, + erlang:system_info(wordsize)}. + chk_normal_tab_struct_size() -> ?line System = {os:type(), os:version(), @@ -466,36 +492,58 @@ chk_normal_tab_struct_size() -> erlang:system_info(smp_support), erlang:system_info(heap_type)}, ?line ?t:format("System = ~p~n", [System]), - ?line ?t:format("?NORMAL_TAB_STRUCT_SZ=~p~n", [?NORMAL_TAB_STRUCT_SZ]), + %%?line ?t:format("?NORMAL_TAB_STRUCT_SZ=~p~n", [?NORMAL_TAB_STRUCT_SZ]), ?line ?t:format("?TAB_STRUCT_SZ=~p~n", [?TAB_STRUCT_SZ]), - ?line case System of - {{unix, sunos}, {5, 8, 0}, 4, false, private} -> - ?line ?NORMAL_TAB_STRUCT_SZ = ?TAB_STRUCT_SZ, - ?line ok; - _ -> - ?line ok - end. - -adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = Mem0) -> + ok. +% ?line case System of +% {{unix, sunos}, {5, 8, 0}, 4, false, private} -> +% ?line ?NORMAL_TAB_STRUCT_SZ = ?TAB_STRUCT_SZ, +% ?line ok; +% _ -> +% ?line ok +% end. + +-define(DB_TREE_STACK_NEED,50). % The static stack for a tree, in halfword pointers are two internal words + % so the stack gets twice as big +-define(DB_HASH_SIZEOF_EXTSEG,260). % The segment size in words, in halfword this will be twice as large. + +adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) -> %% Adjust for 64-bit, smp, and os: %% Table struct size may differ. - Mem1 = case ?TAB_STRUCT_SZ of - ?NORMAL_TAB_STRUCT_SZ -> - Mem0; - TabStructSz -> - TabDiff = TabStructSz - ?NORMAL_TAB_STRUCT_SZ, - {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff} - end, + +% Mem1 = case ?TAB_STRUCT_SZ of +% ?NORMAL_TAB_STRUCT_SZ -> +% Mem0; +% TabStructSz -> +% TabDiff = TabStructSz - ?NORMAL_TAB_STRUCT_SZ, +% {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff} +% end, + + TabDiff = ?TAB_STRUCT_SZ, + Mem1 = {A0+TabDiff, B0+TabDiff, C0+TabDiff, D0+TabDiff}, + + Mem2 = case {erlang:system_info({wordsize,internal}),erlang:system_info({wordsize,external})} of + %% Halfword, corrections for regular pointers occupying two internal words. + {4,8} -> + {A1,B1,C1,D1} = Mem1, + {A1+4*ets:info(T1, size)+?DB_TREE_STACK_NEED, + B1+3*ets:info(T2, size)+?DB_HASH_SIZEOF_EXTSEG, + C1+3*ets:info(T3, size)+?DB_HASH_SIZEOF_EXTSEG, + D1+3*ets:info(T4, size)+?DB_HASH_SIZEOF_EXTSEG}; + _ -> + Mem1 + end, + %% Adjust for hybrid and shared heaps: %% Each record is one word smaller. - Mem2 = case erlang:system_info(heap_type) of - private -> - Mem1; - _ -> - {A1,B1,C1,D1} = Mem1, - {A1-ets:info(T1, size),B1-ets:info(T2, size), - C1-ets:info(T3, size),D1-ets:info(T4, size)} - end, + %%Mem2 = case erlang:system_info(heap_type) of + %% private -> + %% Mem1; + %% _ -> + %% {A1,B1,C1,D1} = Mem1, + %% {A1-ets:info(T1, size),B1-ets:info(T2, size), + %% C1-ets:info(T3, size),D1-ets:info(T4, size)} + %% end, %%{Mem2,{ets:info(T1,stats),ets:info(T2,stats),ets:info(T3,stats),ets:info(T4,stats)}}. Mem2. @@ -514,7 +562,7 @@ t_whitebox(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). whitebox_1(Opts) -> - ?line T=ets:new(x,[bag | Opts]), + ?line T=ets_new(x,[bag | Opts]), ?line ets:insert(T,[{du,glade},{ta,en}]), ?line ets:insert(T,[{hej,hopp2},{du,glade2},{ta,en2}]), ?line {_,C}=ets:match(T,{ta,'$1'},1), @@ -524,8 +572,8 @@ whitebox_1(Opts) -> ok. whitebox_2(Opts) -> - ?line T=ets:new(x,[ordered_set, {keypos,2} | Opts]), - ?line T2=ets:new(x,[set, {keypos,2}| Opts]), + ?line T=ets_new(x,[ordered_set, {keypos,2} | Opts]), + ?line T2=ets_new(x,[set, {keypos,2}| Opts]), ?line 0 = ets:select_delete(T,[{{hej},[],[true]}]), ?line 0 = ets:select_delete(T,[{{hej,hopp},[],[true]}]), ?line 0 = ets:select_delete(T2,[{{hej},[],[true]}]), @@ -547,7 +595,7 @@ t_ets_dets(Config, Opts) -> ?line (catch file:delete(Fname)), ?line {ok,DTab} = dets:open_file(testdets_1, [{file, Fname}]), - ?line ETab = ets:new(x,Opts), + ?line ETab = ets_new(x,Opts), ?line filltabint(ETab,3000), ?line DTab = ets:to_dets(ETab,DTab), ?line ets:delete_all_objects(ETab), @@ -559,7 +607,7 @@ t_ets_dets(Config, Opts) -> (catch ets:to_dets(ETab,DTab)), ?line {'EXIT',{badarg,[{ets,from_dets,[ETab,DTab]}|_]}} = (catch ets:from_dets(ETab,DTab)), - ?line ETab2 = ets:new(x,Opts), + ?line ETab2 = ets_new(x,Opts), ?line filltabint(ETab2,3000), ?line dets:close(DTab), ?line {'EXIT',{badarg,[{ets,to_dets,[ETab2,DTab]}|_]}} = @@ -580,7 +628,7 @@ t_delete_all_objects(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). t_delete_all_objects_do(Opts) -> - ?line T=ets:new(x,Opts), + ?line T=ets_new(x,Opts), ?line filltabint(T,4000), ?line O=ets:first(T), ?line ets:next(T,O), @@ -609,7 +657,7 @@ t_delete_object(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). t_delete_object_do(Opts) -> - ?line T = ets:new(x,Opts), + ?line T = ets_new(x,Opts), ?line filltabint(T,4000), ?line del_one_by_one_set(T,1,4001), ?line filltabint(T,4000), @@ -626,19 +674,19 @@ t_delete_object_do(Opts) -> ?line 3999 = ets:info(T,size), ?line 0 = ets:info(T,kept_objects), ?line ets:delete(T), - ?line T1 = ets:new(x,[ordered_set | Opts]), + ?line T1 = ets_new(x,[ordered_set | Opts]), ?line filltabint(T1,4000), ?line del_one_by_one_set(T1,1,4001), ?line filltabint(T1,4000), ?line del_one_by_one_set(T1,4000,0), ?line ets:delete(T1), - ?line T2 = ets:new(x,[bag | Opts]), + ?line T2 = ets_new(x,[bag | Opts]), ?line filltabint2(T2,4000), ?line del_one_by_one_bag(T2,1,4001), ?line filltabint2(T2,4000), ?line del_one_by_one_bag(T2,4000,0), ?line ets:delete(T2), - ?line T3 = ets:new(x,[duplicate_bag | Opts]), + ?line T3 = ets_new(x,[duplicate_bag | Opts]), ?line filltabint3(T3,4000), ?line del_one_by_one_dbag_1(T3,1,4001), ?line filltabint3(T3,4000), @@ -685,7 +733,7 @@ t_init_table(Config) when is_list(Config)-> ?line verify_etsmem(EtsMem). t_init_table_do(Opts) -> - ?line T = ets:new(x,[duplicate_bag | Opts]), + ?line T = ets_new(x,[duplicate_bag | Opts]), ?line filltabint(T,4000), ?line ets:init_table(T, make_init_fun(1)), ?line del_one_by_one_dbag_1(T,4000,0), @@ -767,7 +815,7 @@ t_insert_list(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). t_insert_list_do(Opts) -> - ?line T = ets:new(x,[duplicate_bag | Opts]), + ?line T = ets_new(x,[duplicate_bag | Opts]), ?line do_fill_dbag_using_lists(T,4000), ?line del_one_by_one_dbag_2(T,4000,0), ?line ets:delete(T). @@ -795,7 +843,7 @@ t_select_reverse(doc) -> t_select_reverse(suite) -> []; t_select_reverse(Config) when is_list(Config) -> - ?line Table = ets:new(xxx, [ordered_set]), + ?line Table = ets_new(xxx, [ordered_set]), ?line filltabint(Table,1000), ?line A = lists:reverse(ets:select(Table,[{{'$1', '_'}, [{'>', @@ -817,11 +865,11 @@ t_select_reverse(Config) when is_list(Config) -> ['$_']}],3), % A set/bag/duplicate_bag should get the same result regardless % of select or select_reverse - ?line Table2 = ets:new(xxx, [set]), + ?line Table2 = ets_new(xxx, [set]), ?line filltabint(Table2,1000), - ?line Table3 = ets:new(xxx, [bag]), + ?line Table3 = ets_new(xxx, [bag]), ?line filltabint(Table3,1000), - ?line Table4 = ets:new(xxx, [duplicate_bag]), + ?line Table4 = ets_new(xxx, [duplicate_bag]), ?line filltabint(Table4,1000), ?line lists:map(fun(Tab) -> B = ets:select(Tab,[{{'$1', '_'}, @@ -1129,8 +1177,8 @@ random_test() -> do_random_test() -> ?line EtsMem = etsmem(), - ?line OrdSet = ets:new(xxx,[ordered_set]), - ?line Set = ets:new(xxx,[]), + ?line OrdSet = ets_new(xxx,[ordered_set]), + ?line Set = ets_new(xxx,[]), ?line do_n_times(fun() -> ?line Key = create_random_string(25), ?line Value = create_random_tuple(25), @@ -1334,8 +1382,8 @@ update_element_opts(Opts) -> update_element_opts(Tuple,KeyPos,UpdPos,Opts) -> - Set = ets:new(set,[{keypos,KeyPos} | Opts]), - OrdSet = ets:new(ordered_set,[ordered_set,{keypos,KeyPos} | Opts]), + Set = ets_new(set,[{keypos,KeyPos} | Opts]), + OrdSet = ets_new(ordered_set,[ordered_set,{keypos,KeyPos} | Opts]), update_element(Set,Tuple,KeyPos,UpdPos), update_element(OrdSet,Tuple,KeyPos,UpdPos), true = ets:delete(Set), @@ -1343,7 +1391,8 @@ update_element_opts(Tuple,KeyPos,UpdPos,Opts) -> ok. update_element(T,Tuple,KeyPos,UpdPos) -> - KeyList = [Key || Key <- lists:seq(1,100)], + KeyList = [Key || Key <- [17,"seventeen",<<"seventeen">>,{17},list_to_binary(lists:seq(1,100)), + make_ref(), self()]], lists:foreach(fun(Key) -> TupleWithKey = setelement(KeyPos,Tuple,Key), update_element_do(T,TupleWithKey,Key,UpdPos) @@ -1378,21 +1427,13 @@ update_element_do(Tab,Tuple,Key,UpdPos) -> {Pos, element(ToIx+1,Values)} % single {pos,value} arg end, - NewTupleF = fun({Pos,Val}, Tpl, _MeF) -> - setelement(Pos, Tpl, Val); - ([{Pos,Val} | Tail], Tpl, MeF) -> - MeF(Tail,setelement(Pos, Tpl, Val),MeF); - ([], Tpl, _MeF) -> - Tpl - end, - UpdateF = fun(ToIx,Rand) -> PosValArg = PosValArgF(ToIx,[],UpdPos,Rand,PosValArgF), %%io:format("update_element(~p)~n",[PosValArg]), ArgHash = erlang:phash2({Tab,Key,PosValArg}), ?line true = ets:update_element(Tab, Key, PosValArg), ?line ArgHash = erlang:phash2({Tab,Key,PosValArg}), - NewTuple = NewTupleF(PosValArg,Tuple,NewTupleF), + NewTuple = update_tuple(PosValArg,Tuple), ?line [NewTuple] = ets:lookup(Tab,Key) end, @@ -1420,9 +1461,18 @@ update_element_do(Tab,Tuple,Key,UpdPos) -> ?line Checksum = (Length-1)*Length*(Length+1) div 2, % if Length is a prime ok. +update_tuple({Pos,Val}, Tpl) -> + setelement(Pos, Tpl, Val); +update_tuple([{Pos,Val} | Tail], Tpl) -> + update_tuple(Tail,setelement(Pos, Tpl, Val)); +update_tuple([], Tpl) -> + Tpl. + + + update_element_neg(Opts) -> - Set = ets:new(set,Opts), - OrdSet = ets:new(ordered_set,[ordered_set | Opts]), + Set = ets_new(set,Opts), + OrdSet = ets_new(ordered_set,[ordered_set | Opts]), update_element_neg_do(Set), update_element_neg_do(OrdSet), ets:delete(Set), @@ -1430,8 +1480,8 @@ update_element_neg(Opts) -> ets:delete(OrdSet), ?line {'EXIT',{badarg,_}} = (catch ets:update_element(OrdSet,key,{2,1})), - ?line Bag = ets:new(bag,[bag | Opts]), - ?line DBag = ets:new(duplicate_bag,[duplicate_bag | Opts]), + ?line Bag = ets_new(bag,[bag | Opts]), + ?line DBag = ets_new(duplicate_bag,[duplicate_bag | Opts]), ?line {'EXIT',{badarg,_}} = (catch ets:update_element(Bag,key,{2,1})), ?line {'EXIT',{badarg,_}} = (catch ets:update_element(DBag,key,{2,1})), true = ets:delete(Bag), @@ -1481,8 +1531,8 @@ update_counter(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). update_counter_do(Opts) -> - Set = ets:new(set,Opts), - OrdSet = ets:new(ordered_set,[ordered_set | Opts]), + Set = ets_new(set,Opts), + OrdSet = ets_new(ordered_set,[ordered_set | Opts]), update_counter_for(Set), update_counter_for(OrdSet), ets:delete(Set), @@ -1628,8 +1678,8 @@ uc_adder(Init, {_Pos, Add, Thres, Warp}) -> end. update_counter_neg(Opts) -> - Set = ets:new(set,Opts), - OrdSet = ets:new(ordered_set,[ordered_set | Opts]), + Set = ets_new(set,Opts), + OrdSet = ets_new(ordered_set,[ordered_set | Opts]), update_counter_neg_for(Set), update_counter_neg_for(OrdSet), ets:delete(Set), @@ -1637,8 +1687,8 @@ update_counter_neg(Opts) -> ets:delete(OrdSet), ?line {'EXIT',{badarg,_}} = (catch ets:update_counter(OrdSet,key,1)), - ?line Bag = ets:new(bag,[bag | Opts]), - ?line DBag = ets:new(duplicate_bag,[duplicate_bag | Opts]), + ?line Bag = ets_new(bag,[bag | Opts]), + ?line DBag = ets_new(duplicate_bag,[duplicate_bag | Opts]), ?line {'EXIT',{badarg,_}} = (catch ets:update_counter(Bag,key,1)), ?line {'EXIT',{badarg,_}} = (catch ets:update_counter(DBag,key,1)), true = ets:delete(Bag), @@ -1711,7 +1761,7 @@ wait_for_all(Pids0) -> end. evil_counter(I,Opts) -> - T = ets:new(a, Opts), + T = ets_new(a, Opts), Start0 = case I rem 3 of 0 -> 16#12345678; 1 -> 16#12345678FFFFFFFF; @@ -1719,7 +1769,7 @@ evil_counter(I,Opts) -> end, Start = Start0 + random:uniform(100000), ets:insert(T, {dracula,Start}), - Iter = 90000, + Iter = 40000, End = Start + Iter, End = evil_counter_1(Iter, T), ets:delete(T). @@ -1740,7 +1790,7 @@ fixtable_next(Config) when is_list(Config) -> fixtable_next_do(Opts) -> ?line EtsMem = etsmem(), - ?line do_fixtable_next(ets:new(set,[public | Opts])), + ?line do_fixtable_next(ets_new(set,[public | Opts])), ?line verify_etsmem(EtsMem). do_fixtable_next(Tab) -> @@ -1821,24 +1871,24 @@ write_concurrency(doc) -> ["The 'write_concurrency' option"]; write_concurrency(suite) -> []; write_concurrency(Config) when is_list(Config) -> ?line EtsMem = etsmem(), - Yes1 = ets:new(foo,[public,{write_concurrency,true}]), - Yes2 = ets:new(foo,[protected,{write_concurrency,true}]), - No1 = ets:new(foo,[private,{write_concurrency,true}]), + Yes1 = ets_new(foo,[public,{write_concurrency,true}]), + Yes2 = ets_new(foo,[protected,{write_concurrency,true}]), + No1 = ets_new(foo,[private,{write_concurrency,true}]), - Yes3 = ets:new(foo,[bag,public,{write_concurrency,true}]), - Yes4 = ets:new(foo,[bag,protected,{write_concurrency,true}]), - No2 = ets:new(foo,[bag,private,{write_concurrency,true}]), + Yes3 = ets_new(foo,[bag,public,{write_concurrency,true}]), + Yes4 = ets_new(foo,[bag,protected,{write_concurrency,true}]), + No2 = ets_new(foo,[bag,private,{write_concurrency,true}]), - Yes5 = ets:new(foo,[duplicate_bag,public,{write_concurrency,true}]), - Yes6 = ets:new(foo,[duplicate_bag,protected,{write_concurrency,true}]), - No3 = ets:new(foo,[duplicate_bag,private,{write_concurrency,true}]), + Yes5 = ets_new(foo,[duplicate_bag,public,{write_concurrency,true}]), + Yes6 = ets_new(foo,[duplicate_bag,protected,{write_concurrency,true}]), + No3 = ets_new(foo,[duplicate_bag,private,{write_concurrency,true}]), - No4 = ets:new(foo,[ordered_set,public,{write_concurrency,true}]), - No5 = ets:new(foo,[ordered_set,protected,{write_concurrency,true}]), - No6 = ets:new(foo,[ordered_set,private,{write_concurrency,true}]), + No4 = ets_new(foo,[ordered_set,public,{write_concurrency,true}]), + No5 = ets_new(foo,[ordered_set,protected,{write_concurrency,true}]), + No6 = ets_new(foo,[ordered_set,private,{write_concurrency,true}]), - No7 = ets:new(foo,[public,{write_concurrency,false}]), - No8 = ets:new(foo,[protected,{write_concurrency,false}]), + No7 = ets_new(foo,[public,{write_concurrency,false}]), + No8 = ets_new(foo,[protected,{write_concurrency,false}]), ?line YesMem = ets:info(Yes1,memory), ?line NoHashMem = ets:info(No1,memory), @@ -1865,10 +1915,10 @@ write_concurrency(Config) when is_list(Config) -> ?line true = YesMem =:= NoHashMem end, - ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency,foo}])), - ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency}])), - ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,{write_concurrency,true,foo}])), - ?line {'EXIT',{badarg,_}} = (catch ets:new(foo,[public,write_concurrency])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency,foo}])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency}])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,{write_concurrency,true,foo}])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(foo,[public,write_concurrency])), lists:foreach(fun(T) -> ets:delete(T) end, [Yes1,Yes2,Yes3,Yes4,Yes5,Yes6, @@ -1945,7 +1995,7 @@ heir_founder(Master, HeirData, Opts) -> none -> {heir,none}; _ -> {heir, Heir, HeirData} end, - ?line T = ets:new(foo,[named_table, private, HeirTpl | Opts]), + ?line T = ets_new(foo,[named_table, private, HeirTpl | Opts]), ?line true = ets:insert(T,{key,1}), ?line [{key,1}] = ets:lookup(T,key), Self = self(), @@ -2017,7 +2067,7 @@ give_away(Config) when is_list(Config) -> repeat_for_opts(give_away_do). give_away_do(Opts) -> - ?line T = ets:new(foo,[named_table, private | Opts]), + ?line T = ets_new(foo,[named_table, private | Opts]), ?line true = ets:insert(T,{key,1}), ?line [{key,1}] = ets:lookup(T,key), Parent = self(), @@ -2043,7 +2093,7 @@ give_away_do(Opts) -> ?line undefined = ets:info(T), %% Give and then kill receiver to get back - ?line T2 = ets:new(foo,[private | Opts]), + ?line T2 = ets_new(foo,[private | Opts]), ?line true = ets:insert(T2,{key,1}), ?line ets:setopts(T2,{heir,self(),"Som en gummiboll..."}), ?line {Receiver2,Mref2} = spawn_monitor(fun()-> give_away_receiver(T2,Parent) end), @@ -2065,7 +2115,7 @@ give_away_do(Opts) -> ?line give_me = receive_any(), ?line {'EXIT',{badarg,_}} = (catch ets:give_away(T2,ReceiverNeg,"A deleted table")), - ?line T3 = ets:new(foo,[public | Opts]), + ?line T3 = ets_new(foo,[public | Opts]), spawn_link(fun()-> {'EXIT',{badarg,_}} = (catch ets:give_away(T3,ReceiverNeg,"From non owner")), Parent ! done end), @@ -2100,7 +2150,7 @@ setopts(Config) when is_list(Config) -> setopts_do(Opts) -> Self = self(), - ?line T = ets:new(foo,[named_table, private | Opts]), + ?line T = ets_new(foo,[named_table, private | Opts]), ?line none = ets:info(T,heir), Heir = spawn_link(fun()->heir_heir(Self) end), ?line ets:setopts(T,{heir,Heir,"Data"}), @@ -2153,10 +2203,10 @@ bad_table(Config) when is_list(Config) -> bad_table_do(Opts, DummyFile) -> Parent = self(), - {Pid,Mref} = spawn_opt(fun()-> ets:new(priv,[private,named_table | Opts]), - Priv = ets:new(priv,[private | Opts]), - ets:new(prot,[protected,named_table | Opts]), - Prot = ets:new(prot,[protected | Opts]), + {Pid,Mref} = spawn_opt(fun()-> ets_new(priv,[private,named_table | Opts]), + Priv = ets_new(priv,[private | Opts]), + ets_new(prot,[protected,named_table | Opts]), + Prot = ets_new(prot,[protected | Opts]), Parent ! {self(),Priv,Prot}, die_please = receive_any() end, @@ -2214,11 +2264,11 @@ bad_table_do(Opts, DummyFile) -> bad_table_op({Opts,Priv,Prot}, Op) -> %%io:format("Doing Op=~p on ~p's\n",[Op,Type]), - T1 = ets:new(noname,Opts), + T1 = ets_new(noname,Opts), bad_table_call(noname,Op), ets:delete(T1), bad_table_call(T1,Op), - T2 = ets:new(named,[named_table | Opts]), + T2 = ets_new(named,[named_table | Opts]), ets:delete(T2), bad_table_call(named,Op), bad_table_call(T2,Op), @@ -2252,7 +2302,7 @@ rename(Config) when is_list(Config) -> rename_do(Opts) -> ?line EtsMem = etsmem(), - ets:new(foobazz,[named_table, public | Opts]), + ets_new(foobazz,[named_table, public | Opts]), ets:insert(foobazz,{foo,bazz}), ungermanbazz = ets:rename(foobazz,ungermanbazz), {'EXIT',{badarg, _}} = (catch ets:lookup(foobazz,foo)), @@ -2270,7 +2320,7 @@ rename_unnamed(Config) when is_list(Config) -> rename_unnamed_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(bonkz,[public | Opts]), + ?line Tab = ets_new(bonkz,[public | Opts]), ?line {'EXIT',{badarg, _}} = (catch ets:insert(bonkz,{foo,bazz})), ?line bonkz = ets:info(Tab, name), ?line Tab = ets:rename(Tab, tjabonkz), @@ -2289,7 +2339,7 @@ evil_rename(Config) when is_list(Config) -> evil_rename_1(Old, New, Flags) -> ?line process_flag(trap_exit, true), - ?line Old = ets:new(Old, Flags), + ?line Old = ets_new(Old, Flags), ?line Fixer = fun() -> ets:safe_fixtable(Old, true) end, ?line crazy_fixtable(15000, Fixer), ?line erlang:yield(), @@ -2299,7 +2349,7 @@ evil_rename_1(Old, New, Flags) -> ok. crazy_fixtable(N, Fixer) -> - Dracula = ets:new(count_dracula, [public]), + Dracula = ets_new(count_dracula, [public]), ets:insert(Dracula, {count,0}), SpawnFun = fun() -> Fixer(), @@ -2333,7 +2383,7 @@ evil_creater_destroyer() -> ets:delete(T1). evil_create_fixed_tab() -> - T = ets:new(arne, [public]), + T = ets_new(arne, [public]), ets:safe_fixtable(T, true), T. @@ -2347,8 +2397,8 @@ interface_equality(Config) when is_list(Config) -> interface_equality_do(Opts) -> ?line EtsMem = etsmem(), - ?line Set = ets:new(set,[set | Opts]), - ?line OrderedSet = ets:new(ordered_set,[ordered_set | Opts]), + ?line Set = ets_new(set,[set | Opts]), + ?line OrderedSet = ets_new(ordered_set,[ordered_set | Opts]), ?line F = fun(X,T,FF) -> case X of 0 -> true; _ -> @@ -2427,7 +2477,7 @@ ordered_match_do(Opts) -> FF(X-1,T,FF) end end, - ?line T1 = ets:new(xxx,[ordered_set| Opts]), + ?line T1 = ets_new(xxx,[ordered_set| Opts]), ?line F(3000,T1,F), ?line [[3,3],[3,3],[3,3]] = ets:match(T1, {'_','_','$1','$2',3}), ?line F2 = fun(X,Rem,Res,FF) -> case X of @@ -2465,7 +2515,7 @@ ordered(Config) when is_list(Config) -> ordered_do(Opts) -> ?line EtsMem = etsmem(), - ?line T = ets:new(oset, [ordered_set | Opts]), + ?line T = ets_new(oset, [ordered_set | Opts]), ?line InsList = [ 25,26,27,28, 5,6,7,8, @@ -2526,8 +2576,8 @@ setbag(doc) -> ["Small test case for both set and bag type ets tables."]; setbag(suite) -> []; setbag(Config) when is_list(Config) -> ?line EtsMem = etsmem(), - ?line Set = ets:new(set,[set]), - ?line Bag = ets:new(bag,[bag]), + ?line Set = ets_new(set,[set]), + ?line Bag = ets_new(bag,[bag]), ?line Key = {foo,bar}, %% insert some value @@ -2547,15 +2597,15 @@ setbag(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). badnew(doc) -> - ["Test case to check proper return values for illegal ets:new() calls."]; + ["Test case to check proper return values for illegal ets_new() calls."]; badnew(suite) -> []; badnew(Config) when is_list(Config) -> ?line EtsMem = etsmem(), - ?line {'EXIT',{badarg,_}} = (catch ets:new(12,[])), - ?line {'EXIT',{badarg,_}} = (catch ets:new({a,b},[])), - ?line {'EXIT',{badarg,_}} = (catch ets:new(name,[foo])), - ?line {'EXIT',{badarg,_}} = (catch ets:new(name,{bag})), - ?line {'EXIT',{badarg,_}} = (catch ets:new(name,bag)), + ?line {'EXIT',{badarg,_}} = (catch ets_new(12,[])), + ?line {'EXIT',{badarg,_}} = (catch ets_new({a,b},[])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(name,[foo])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(name,{bag})), + ?line {'EXIT',{badarg,_}} = (catch ets_new(name,bag)), ?line verify_etsmem(EtsMem). verybadnew(doc) -> @@ -2564,7 +2614,7 @@ verybadnew(doc) -> verybadnew(suite) -> []; verybadnew(Config) when is_list(Config) -> ?line EtsMem = etsmem(), - ?line {'EXIT',{badarg,_}} = (catch ets:new(verybad,[set|protected])), + ?line {'EXIT',{badarg,_}} = (catch ets_new(verybad,[set|protected])), ?line verify_etsmem(EtsMem). named(doc) -> ["Small check to see if named tables work."]; @@ -2641,9 +2691,9 @@ privacy_check(Pub,Prot,Priv) -> ?line [] = ets:lookup(Prot,foo). privacy_owner(Boss, Opts) -> - ets:new(pub, [public,named_table | Opts]), - ets:new(prot,[protected,named_table | Opts]), - ets:new(priv,[private,named_table | Opts]), + ets_new(pub, [public,named_table | Opts]), + ets_new(prot,[protected,named_table | Opts]), + ets_new(priv,[private,named_table | Opts]), Boss ! ok, privacy_owner_loop(Boss). @@ -2681,7 +2731,7 @@ empty(Config) when is_list(Config) -> empty_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line [] = ets:lookup(Tab,key), ?line true = ets:insert(Tab,{key2,val}), ?line [] = ets:lookup(Tab,key), @@ -2698,10 +2748,10 @@ badinsert_do(Opts) -> ?line EtsMem = etsmem(), ?line {'EXIT',{badarg,_}} = (catch ets:insert(foo,{key,val})), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab,{})), - ?line Tab3 = ets:new(foo,[{keypos,3}| Opts]), + ?line Tab3 = ets_new(foo,[{keypos,3}| Opts]), ?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab3,{a,b})), ?line {'EXIT',{badarg,_}} = (catch ets:insert(Tab,[key,val2])), @@ -2725,7 +2775,7 @@ time_lookup(Config) when is_list(Config) -> "~p ets lookups/s",[Values]))}. time_lookup_do(Opts) -> - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line fill_tab(Tab,foo), ?line ets:insert(Tab,{{a,key},foo}), ?line {Time,_} = ?t:timecall(test_server,do_times, @@ -2740,7 +2790,7 @@ badlookup(suite) -> []; badlookup(Config) when is_list(Config) -> ?line EtsMem = etsmem(), ?line {'EXIT',{badarg,_}} = (catch ets:lookup(foo,key)), - ?line Tab = ets:new(foo,[]), + ?line Tab = ets_new(foo,[]), ?line ets:delete(Tab), ?line {'EXIT',{badarg,_}} = (catch ets:lookup(Tab,key)), ?line verify_etsmem(EtsMem). @@ -2765,7 +2815,7 @@ lookup_order_2(Opts, Fixed) -> Pair = [{A,B},{B,A},{A,C},{C,A},{B,C},{C,B}], Combos = [{D1,D2,D3} || D1<-ABC, D2<-Pair, D3<-Pair], lists:foreach(fun({D1,{D2a,D2b},{D3a,D3b}}) -> - T = ets:new(foo,Opts), + T = ets_new(foo,Opts), case Fixed of true -> ets:safe_fixtable(T,true); false -> ok @@ -2849,10 +2899,12 @@ lookup_element_mult(Config) when is_list(Config) -> lookup_element_mult_do(Opts) -> ?line EtsMem = etsmem(), - ?line T = ets:new(service, [bag, {keypos, 2} | Opts]), + ?line T = ets_new(service, [bag, {keypos, 2} | Opts]), ?line D = lists:reverse(lem_data()), ?line lists:foreach(fun(X) -> ets:insert(T, X) end, D), ?line ok = lem_crash_3(T), + ?line ets:insert(T, {0, "heap_key"}), + ?line ets:lookup_element(T, "heap_key", 2), ?line true = ets:delete(T), ?line verify_etsmem(EtsMem). @@ -2894,7 +2946,7 @@ delete_elem(Config) when is_list(Config) -> delete_elem_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line fill_tab(Tab,foo), ?line ets:insert(Tab,{{b,key},foo}), ?line ets:insert(Tab,{{c,key},foo}), @@ -2914,17 +2966,17 @@ delete_tab(Config) when is_list(Config) -> delete_tab_do(Opts) -> Name = foo, ?line EtsMem = etsmem(), - ?line Name = ets:new(Name, [named_table | Opts]), + ?line Name = ets_new(Name, [named_table | Opts]), ?line true = ets:delete(foo), %% The name should be available again. - ?line Name = ets:new(Name, [named_table | Opts]), + ?line Name = ets_new(Name, [named_table | Opts]), ?line true = ets:delete(Name), ?line verify_etsmem(EtsMem). delete_large_tab(doc) -> "Check that ets:delete/1 works and that other processes can run."; delete_large_tab(Config) when is_list(Config) -> - ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)], + ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 200000)], ?line EtsMem = etsmem(), repeat_for_opts(fun(Opts) -> delete_large_tab_do(Opts,Data) end), ?line verify_etsmem(EtsMem). @@ -2936,7 +2988,7 @@ delete_large_tab_do(Opts,Data) -> delete_large_tab_1(Name, Flags, Data, Fix) -> - ?line Tab = ets:new(Name, Flags), + ?line Tab = ets_new(Name, Flags), ?line ets:insert(Tab, Data), case Fix of @@ -3003,7 +3055,7 @@ delete_large_named_table_do(Opts,Data) -> ?line delete_large_named_table_1(foo_hash, [named_table | Opts], Data, true). delete_large_named_table_1(Name, Flags, Data, Fix) -> - ?line Tab = ets:new(Name, Flags), + ?line Tab = ets_new(Name, Flags), ?line ets:insert(Tab, Data), case Fix of @@ -3016,7 +3068,7 @@ delete_large_named_table_1(Name, Flags, Data, Fix) -> Pid = spawn_link(fun() -> receive {trace,Parent,call,_} -> - ets:new(Name, [named_table]) + ets_new(Name, [named_table]) end end), ?line erlang:trace(self(), true, [call,{tracer,Pid}]), @@ -3050,7 +3102,7 @@ evil_delete_do(Opts,Data) -> evil_delete_not_owner(Name, Flags, Data, Fix) -> io:format("Not owner: ~p, fix = ~p", [Name,Fix]), - ?line Tab = ets:new(Name, [public|Flags]), + ?line Tab = ets_new(Name, [public|Flags]), ?line ets:insert(Tab, Data), case Fix of false -> ok; @@ -3075,7 +3127,7 @@ evil_delete_not_owner(Name, Flags, Data, Fix) -> evil_delete_owner(Name, Flags, Data, Fix) -> ?line Fun = fun() -> - ?line Tab = ets:new(Name, [public|Flags]), + ?line Tab = ets_new(Name, [public|Flags]), ?line ets:insert(Tab, Data), case Fix of false -> ok; @@ -3102,48 +3154,60 @@ exit_large_table_owner(doc) -> exit_large_table_owner(suite) -> []; exit_large_table_owner(Config) when is_list(Config) -> - ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)], + %%?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)], + ?line FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok}; + (I) -> Do({erlang:phash2(I, 16#ffffff),I}), + {true, I+1} + end, 1) + end, ?line EtsMem = etsmem(), - repeat_for_opts(fun(Opts) -> exit_large_table_owner_do(Opts,Data,Config) end), + repeat_for_opts({exit_large_table_owner_do,{FEData,Config}}), ?line verify_etsmem(EtsMem). -exit_large_table_owner_do(Opts,Data,Config) -> - ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], true, 1, 1), - ?line verify_rescheduling_exit(Config, Data, Opts, false, 1, 1). +exit_large_table_owner_do(Opts,{FEData,Config}) -> + ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], true, 1, 1), + ?line verify_rescheduling_exit(Config, FEData, Opts, false, 1, 1). exit_many_large_table_owner(doc) -> []; exit_many_large_table_owner(suite) -> []; exit_many_large_table_owner(Config) when is_list(Config) -> - ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)], + %%?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 500000)], + ?line FEData = fun(Do) -> repeat_while(fun(500000) -> {false,ok}; + (I) -> Do({erlang:phash2(I, 16#ffffff),I}), + {true, I+1} + end, 1) + end, ?line EtsMem = etsmem(), - repeat_for_opts(fun(Opts) -> exit_many_large_table_owner_do(Opts,Data,Config) end), + repeat_for_opts(fun(Opts) -> exit_many_large_table_owner_do(Opts,FEData,Config) end), ?line verify_etsmem(EtsMem). -exit_many_large_table_owner_do(Opts,Data,Config) -> - ?line verify_rescheduling_exit(Config, Data, Opts, true, 1, 4), - ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], false, 1, 4). +exit_many_large_table_owner_do(Opts,FEData,Config) -> + ?line verify_rescheduling_exit(Config, FEData, Opts, true, 1, 4), + ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], false, 1, 4). exit_many_tables_owner(doc) -> []; exit_many_tables_owner(suite) -> []; exit_many_tables_owner(Config) when is_list(Config) -> + NoData = fun(_Do) -> ok end, ?line EtsMem = etsmem(), - ?line verify_rescheduling_exit(Config, [], [named_table], false, 1000, 1), - ?line verify_rescheduling_exit(Config, [], [named_table,{write_concurrency,true}], false, 1000, 1), + ?line verify_rescheduling_exit(Config, NoData, [named_table], false, 1000, 1), + ?line verify_rescheduling_exit(Config, NoData, [named_table,{write_concurrency,true}], false, 1000, 1), ?line verify_etsmem(EtsMem). exit_many_many_tables_owner(doc) -> []; exit_many_many_tables_owner(suite) -> []; exit_many_many_tables_owner(Config) when is_list(Config) -> ?line Data = [{erlang:phash2(I, 16#ffffff),I} || I <- lists:seq(1, 50)], - repeat_for_opts(fun(Opts) -> exit_many_many_tables_owner_do(Opts,Data,Config) end). + ?line FEData = fun(Do) -> lists:foreach(Do, Data) end, + repeat_for_opts(fun(Opts) -> exit_many_many_tables_owner_do(Opts,FEData,Config) end). -exit_many_many_tables_owner_do(Opts,Data,Config) -> - ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], true, 200, 5), - ?line verify_rescheduling_exit(Config, Data, Opts, false, 200, 5), +exit_many_many_tables_owner_do(Opts,FEData,Config) -> + ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], true, 200, 5), + ?line verify_rescheduling_exit(Config, FEData, Opts, false, 200, 5), ?line wait_for_test_procs(), ?line EtsMem = etsmem(), - ?line verify_rescheduling_exit(Config, Data, Opts, true, 200, 5), - ?line verify_rescheduling_exit(Config, Data, [named_table | Opts], false, 200, 5), + ?line verify_rescheduling_exit(Config, FEData, Opts, true, 200, 5), + ?line verify_rescheduling_exit(Config, FEData, [named_table | Opts], false, 200, 5), ?line verify_etsmem(EtsMem). @@ -3186,7 +3250,7 @@ vre_fix_tables(Tab) -> receive Go -> ok end, ok. -verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) -> +verify_rescheduling_exit(Config, ForEachData, Flags, Fix, NOTabs, NOProcs) -> ?line NoFix = 5, ?line TestCase = atom_to_list(?config(test_case, Config)), ?line Parent = self(), @@ -3201,8 +3265,8 @@ verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) -> ++ "-" ++ integer_to_list(A) ++ "-" ++ integer_to_list(B) ++ "-" ++ integer_to_list(C)), - Tab = ets:new(Name, Flags), - ets:insert(Tab, Data), + Tab = ets_new(Name, Flags), + ForEachData(fun(Data) -> ets:insert(Tab, Data) end), case Fix of false -> ok; true -> @@ -3210,10 +3274,10 @@ verify_rescheduling_exit(Config, Data, Flags, Fix, NOTabs, NOProcs) -> vre_fix_tables(Tab) end, lists:seq(1,NoFix)), - lists:foreach(fun({K,_}) -> - ets:delete(Tab, K) - end, - Data) + KeyPos = ets:info(Tab,keypos), + ForEachData(fun(Data) -> + ets:delete(Tab, element(KeyPos,Data)) + end) end end, NOTabs), @@ -3260,7 +3324,7 @@ table_leak(Config) when is_list(Config) -> table_leak_1(_,0) -> ok; table_leak_1(Opts,N) -> - ?line T = ets:new(fooflarf, Opts), + ?line T = ets_new(fooflarf, Opts), ?line true = ets:delete(T), table_leak_1(Opts,N-1). @@ -3270,7 +3334,7 @@ baddelete(suite) -> []; baddelete(Config) when is_list(Config) -> ?line EtsMem = etsmem(), ?line {'EXIT',{badarg,_}} = (catch ets:delete(foo)), - ?line Tab = ets:new(foo,[]), + ?line Tab = ets_new(foo,[]), ?line true = ets:delete(Tab), ?line {'EXIT',{badarg,_}} = (catch ets:delete(Tab)), ?line verify_etsmem(EtsMem). @@ -3285,7 +3349,7 @@ match_delete(Config) when is_list(Config) -> match_delete_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(kad,Opts), + ?line Tab = ets_new(kad,Opts), ?line fill_tab(Tab,foo), ?line ets:insert(Tab,{{c,key},bar}), ?line _ = ets:match_delete(Tab,{'_',foo}), @@ -3329,7 +3393,7 @@ firstnext(Config) when is_list(Config) -> firstnext_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line [] = firstnext_collect(Tab,ets:first(Tab),[]), ?line fill_tab(Tab,foo), ?line Len = length(ets:tab2list(Tab)), @@ -3355,7 +3419,7 @@ firstnext_concurrent(Config) when is_list(Config) -> end. ets_init(Tab, N) -> - ets:new(Tab, [named_table,public,ordered_set]), + ets_new(Tab, [named_table,public,ordered_set]), cycle(Tab, lists:seq(1,N+1)). cycle(_Tab, [H|T]) when H > length(T)-> ok; @@ -3388,7 +3452,7 @@ slot(Config) when is_list(Config) -> slot_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line fill_tab(Tab,foo), ?line Elts = ets:info(Tab,size), ?line Elts = slot_loop(Tab,0,0), @@ -3415,7 +3479,7 @@ match1(Config) when is_list(Config) -> match1_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line fill_tab(Tab,foo), ?line [] = ets:match(Tab,{}), ?line ets:insert(Tab,{{one,4},4}), @@ -3480,7 +3544,7 @@ match_object(Config) when is_list(Config) -> match_object_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foobar, Opts), + ?line Tab = ets_new(foobar, Opts), ?line fill_tab(Tab, foo), ?line ets:insert(Tab, {{one, 4}, 4}), ?line ets:insert(Tab,{{one,5},5}), @@ -3524,7 +3588,7 @@ match_object2(Config) when is_list(Config) -> match_object2_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo, [bag, {keypos, 2} | Opts]), + ?line Tab = ets_new(foo, [bag, {keypos, 2} | Opts]), ?line fill_tab2(Tab, 0, 13005), % match_db_object does 1000 % elements per pass, might % change in the future. @@ -3563,7 +3627,7 @@ misc1(Config) when is_list(Config) -> misc1_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo,Opts), + ?line Tab = ets_new(foo,Opts), ?line true = lists:member(Tab,ets:all()), ?line ets:delete(Tab), ?line false = lists:member(Tab,ets:all()), @@ -3582,7 +3646,7 @@ safe_fixtable(Config) when is_list(Config) -> safe_fixtable_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foo, Opts), + ?line Tab = ets_new(foo, Opts), ?line fill_tab(Tab, foobar), ?line true = ets:safe_fixtable(Tab, true), ?line receive after 1 -> ok end, @@ -3621,7 +3685,7 @@ info_do(Opts) -> ?line EtsMem = etsmem(), ?line MeMyselfI=self(), ?line ThisNode=node(), - ?line Tab = ets:new(foobar, [{keypos, 2} | Opts]), + ?line Tab = ets_new(foobar, [{keypos, 2} | Opts]), %% Note: ets:info/1 used to return a tuple, but from R11B onwards it %% returns a list. @@ -3675,7 +3739,7 @@ dups_do(Opts) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -files(suite) -> [tab2file, tab2file2, tab2file3, tabfile_ext1, tabfile_ext2, +files(suite) -> [tab2file, tab2file2, tabfile_ext1, tabfile_ext2, tabfile_ext3, tabfile_ext4]. tab2file(doc) -> ["Check the ets:tab2file function on an empty " @@ -3683,7 +3747,7 @@ tab2file(doc) -> ["Check the ets:tab2file function on an empty " tab2file(suite) -> []; tab2file(Config) when is_list(Config) -> %% Write an empty ets table to a file, read back and check properties. - ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, set, private, + ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, set, private, {keypos, 2}]), ?line FName = filename:join([?config(priv_dir, Config),"tab2file_case"]), ?line ok = ets:tab2file(Tab, FName), @@ -3699,51 +3763,36 @@ tab2file(Config) when is_list(Config) -> ?line verify_etsmem(EtsMem). tab2file2(doc) -> ["Check the ets:tab2file function on a ", - "filled set type ets table."]; + "filled set/bag type ets table."]; tab2file2(suite) -> []; -tab2file2(Config) when is_list(Config) -> - %% Try the same on a filled set table. - ?line EtsMem = etsmem(), - ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, set, private, - {keypos, 2}]), - ?line FName = filename:join([?config(priv_dir, Config),"tab2file2_case"]), - ?line ok = fill_tab2(Tab, 0, 10000), % Fill up the table (grucho mucho!) - ?line Len = length(ets:tab2list(Tab)), - ?line ok = ets:tab2file(Tab, FName), - ?line true = ets:delete(Tab), - % - ?line {ok, Tab2} = ets:file2tab(FName), - ?line private = ets:info(Tab2, protection), - ?line true = ets:info(Tab2, named_table), - ?line 2 = ets:info(Tab2, keypos), - ?line set = ets:info(Tab2, type), - ?line Len = length(ets:tab2list(Tab2)), - ?line true = ets:delete(Tab2), - ?line verify_etsmem(EtsMem). +tab2file2(Config) when is_list(Config) -> + repeat_for_opts({tab2file2_do,Config}, [[set,bag],compressed]). -tab2file3(doc) -> ["Check the ets:tab2file function on a ", - "filled bag type ets table."]; -tab2file3(suite) -> []; -tab2file3(Config) when is_list(Config) -> - %% Try the same on a filled bag table. +tab2file2_do(Opts, Config) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(ets_SUITE_foo_tab, [named_table, bag, private, - {keypos, 2}]), - ?line FName = filename:join([?config(priv_dir, Config),"tab2file3_case"]), + ?line Tab = ets_new(ets_SUITE_foo_tab, [named_table, private, + {keypos, 2} | Opts]), + ?line FName = filename:join([?config(priv_dir, Config),"tab2file2_case"]), ?line ok = fill_tab2(Tab, 0, 10000), % Fill up the table (grucho mucho!) ?line Len = length(ets:tab2list(Tab)), ?line Mem = ets:info(Tab, memory), + ?line Type = ets:info(Tab, type), + %%io:format("org tab: ~p\n",[ets:info(Tab)]), ?line ok = ets:tab2file(Tab, FName), ?line true = ets:delete(Tab), + ?line EtsMem4 = etsmem(), + ?line {ok, Tab2} = ets:file2tab(FName), + %%io:format("loaded tab: ~p\n",[ets:info(Tab2)]), ?line private = ets:info(Tab2, protection), ?line true = ets:info(Tab2, named_table), ?line 2 = ets:info(Tab2, keypos), - ?line bag = ets:info(Tab2, type), + ?line Type = ets:info(Tab2, type), ?line Len = length(ets:tab2list(Tab2)), ?line Mem = ets:info(Tab2, memory), ?line true = ets:delete(Tab2), + io:format("Between = ~p\n", [EtsMem4]), ?line verify_etsmem(EtsMem). -define(test_list, [8,5,4,1,58,125,255, 250, 245, 240, 235, @@ -3787,7 +3836,7 @@ tabfile_ext1_do(Opts,Config) -> ?line FName = filename:join([?config(priv_dir, Config),"nisse.dat"]), ?line FName2 = filename:join([?config(priv_dir, Config),"countflip.dat"]), L = lists:seq(1,10), - T = ets:new(x,Opts), + T = ets_new(x,Opts), Name = make_ref(), [ets:insert(T,{X,integer_to_list(X)}) || X <- L], ok = ets:tab2file(T,FName,[{extended_info,[object_count]}]), @@ -3827,7 +3876,7 @@ tabfile_ext2_do(Opts,Config) -> ?line FName = filename:join([?config(priv_dir, Config),"olle.dat"]), ?line FName2 = filename:join([?config(priv_dir, Config),"bitflip.dat"]), L = lists:seq(1,10), - T = ets:new(x,Opts), + T = ets_new(x,Opts), Name = make_ref(), [ets:insert(T,{X,integer_to_list(X)}) || X <- L], ok = ets:tab2file(T,FName,[{extended_info,[md5sum]}]), @@ -3865,7 +3914,7 @@ tabfile_ext3(Config) when is_list(Config) -> ?line FName2 = filename:join([?config(priv_dir, Config),"ncountflip.dat"]), L = lists:seq(1,10), Name = make_ref(), - ?MODULE = ets:new(?MODULE,[named_table]), + ?MODULE = ets_new(?MODULE,[named_table]), [ets:insert(?MODULE,{X,integer_to_list(X)}) || X <- L], ets:tab2file(?MODULE,FName), {error,cannot_create_table} = ets:file2tab(FName), @@ -3897,7 +3946,7 @@ tabfile_ext4(doc) -> tabfile_ext4(Config) when is_list(Config) -> ?line FName = filename:join([?config(priv_dir, Config),"bauta.dat"]), LL = lists:seq(1,10000), - TL = ets:new(x,[]), + TL = ets_new(x,[]), Name2 = make_ref(), [ets:insert(TL,{X,integer_to_list(X)}) || X <- LL], ok = ets:tab2file(TL,FName,[{extended_info,[md5sum]}]), @@ -3953,7 +4002,7 @@ heavy_lookup(Config) when is_list(Config) -> heavy_lookup_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foobar_table, [set, protected, {keypos, 2} | Opts]), + ?line Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]), ?line ok = fill_tab2(Tab, 0, 7000), ?line ?t:do_times(50, ?MODULE, do_lookup, [Tab, 6999]), ?line true = ets:delete(Tab), @@ -3976,7 +4025,7 @@ heavy_lookup_element(Config) when is_list(Config) -> heavy_lookup_element_do(Opts) -> ?line EtsMem = etsmem(), - ?line Tab = ets:new(foobar_table, [set, protected, {keypos, 2} | Opts]), + ?line Tab = ets_new(foobar_table, [set, protected, {keypos, 2} | Opts]), ?line ok = fill_tab2(Tab, 0, 7000), case os:type() of vxworks -> @@ -4009,9 +4058,9 @@ heavy_concurrent(_Config) -> repeat_for_opts(do_heavy_concurrent). do_heavy_concurrent(Opts) -> - ?line Size = 20000, + ?line Size = 10000, ?line EtsMem = etsmem(), - ?line Tab = ets:new(blupp, [set, public, {keypos, 2} | Opts]), + ?line Tab = ets_new(blupp, [set, public, {keypos, 2} | Opts]), ?line ok = fill_tab2(Tab, 0, Size), ?line Procs = lists:map( fun (N) -> @@ -4115,7 +4164,7 @@ member(Config) when is_list(Config) -> member_do(Opts) -> ?line EtsMem = etsmem(), - ?line T = ets:new(xxx, Opts), + ?line T = ets_new(xxx, Opts), ?line false = ets:member(T,hej), ?line E = fun(0,_F)->ok; (N,F) -> @@ -4140,7 +4189,7 @@ member_do(Opts) -> build_table(L1,L2,Num) -> - T = ets:new(xxx, [ordered_set] + T = ets_new(xxx, [ordered_set] ), lists:foreach( fun(X1) -> @@ -4162,7 +4211,7 @@ build_table(L1,L2,Num) -> T. build_table2(L1,L2,Num) -> - T = ets:new(xxx, [ordered_set] + T = ets_new(xxx, [ordered_set] ), lists:foreach( fun(X1) -> @@ -4293,7 +4342,7 @@ do_n_times(Fun,N) -> do_n_times(Fun,N-1). make_table(Name, Options, Elements) -> - T = ets:new(Name, Options), + T = ets_new(Name, Options), lists:foreach(fun(E) -> ets:insert(T, E) end, Elements), T. filltabint(Tab,0) -> @@ -4357,13 +4406,13 @@ xfilltabstr(Tab,N) -> fill_sets_int(N) -> fill_sets_int(N,[]). fill_sets_int(N,Opts) -> - Tab1 = ets:new(xxx, [ordered_set|Opts]), + Tab1 = ets_new(xxx, [ordered_set|Opts]), filltabint(Tab1,N), - Tab2 = ets:new(xxx, [set|Opts]), + Tab2 = ets_new(xxx, [set|Opts]), filltabint(Tab2,N), - Tab3 = ets:new(xxx, [bag|Opts]), + Tab3 = ets_new(xxx, [bag|Opts]), filltabint2(Tab3,N), - Tab4 = ets:new(xxx, [duplicate_bag|Opts]), + Tab4 = ets_new(xxx, [duplicate_bag|Opts]), filltabint3(Tab4,N), [Tab1,Tab2,Tab3,Tab4]. @@ -4515,7 +4564,7 @@ gen_dets_filename(Config,N) -> "testdets_" ++ integer_to_list(N) ++ ".dets"). otp_6842_select_1000(Config) when is_list(Config) -> - ?line Tab = ets:new(xxx,[ordered_set]), + ?line Tab = ets_new(xxx,[ordered_set]), ?line [ets:insert(Tab,{X,X}) || X <- lists:seq(1,10000)], ?line AllTrue = lists:duplicate(10,true), ?line AllTrue = @@ -4548,7 +4597,7 @@ check_seq(A,B,C) -> otp_6338(Config) when is_list(Config) -> L = binary_to_term(<<131,108,0,0,0,2,104,2,108,0,0,0,2,103,100,0,19,112,112,98,49,95,98,115,49,50,64,98,108,97,100,101,95,48,95,53,0,0,33,50,0,0,0,4,1,98,0,0,23,226,106,100,0,4,101,120,105,116,104,2,108,0,0,0,2,104,2,100,0,3,115,98,109,100,0,19,112,112,98,50,95,98,115,49,50,64,98,108,97,100,101,95,48,95,56,98,0,0,18,231,106,100,0,4,114,101,99,118,106>>), - T = ets:new(xxx,[ordered_set]), + T = ets_new(xxx,[ordered_set]), lists:foreach(fun(X) -> ets:insert(T,X) end,L), [[4839,recv]] = ets:match(T,{[{sbm,ppb2_bs12@blade_0_8},'$1'],'$2'}), ets:delete(T). @@ -4559,7 +4608,7 @@ otp_5340(Config) when is_list(Config) -> otp_5340_do(Opts) -> N = 3000, - T = ets:new(otp_5340, [bag,public | Opts]), + T = ets_new(otp_5340, [bag,public | Opts]), Ids = [1,2,3,4,5], [w(T, N, Id) || Id <- Ids], verify(T, Ids), @@ -4595,7 +4644,7 @@ otp_7665(Config) when is_list(Config) -> repeat_for_opts(otp_7665_do). otp_7665_do(Opts) -> - Tab = ets:new(otp_7665,[bag | Opts]), + Tab = ets_new(otp_7665,[bag | Opts]), Min = 0, Max = 10, lists:foreach(fun(N)-> otp_7665_act(Tab,Min,Max,N) end, @@ -4658,7 +4707,7 @@ meta_wb_do(Opts) -> Names). meta_wb_new(Name, _, Tabs, Opts) -> - case (catch ets:new(Name,[named_table|Opts])) of + case (catch ets_new(Name,[named_table|Opts])) of Name -> ?line false = lists:member(Name, Tabs), [Name | Tabs]; @@ -4706,7 +4755,7 @@ grow_shrink_0([N|Ns], EtsMem) -> grow_shrink_0([], _) -> ok. grow_shrink_1(N, Flags) -> - ?line T = ets:new(a, Flags), + ?line T = ets_new(a, Flags), ?line grow_shrink_2(N, N, T), ?line ets:delete(T). @@ -4736,7 +4785,7 @@ grow_pseudo_deleted_do() -> grow_pseudo_deleted_do(Type) -> process_flag(scheduler,1), Self = self(), - ?line T = ets:new(kalle,[Type,public,{write_concurrency,true}]), + ?line T = ets_new(kalle,[Type,public,{write_concurrency,true}]), Mod = 7, Mult = 10000, filltabint(T,Mod*Mult), ?line true = ets:safe_fixtable(T,true), @@ -4778,7 +4827,7 @@ shrink_pseudo_deleted_do() -> shrink_pseudo_deleted_do(Type) -> process_flag(scheduler,1), Self = self(), - ?line T = ets:new(kalle,[Type,public,{write_concurrency,true}]), + ?line T = ets_new(kalle,[Type,public,{write_concurrency,true}]), Half = 10000, filltabint(T,Half*2), ?line true = ets:safe_fixtable(T,true), @@ -4817,7 +4866,7 @@ meta_smp(suite) -> meta_lookup_unnamed_read(suite) -> []; meta_lookup_unnamed_read(Config) when is_list(Config) -> - InitF = fun(_) -> Tab = ets:new(unnamed,[]), + InitF = fun(_) -> Tab = ets_new(unnamed,[]), true = ets:insert(Tab,{key,data}), Tab end, @@ -4830,7 +4879,7 @@ meta_lookup_unnamed_read(Config) when is_list(Config) -> meta_lookup_unnamed_write(suite) -> []; meta_lookup_unnamed_write(Config) when is_list(Config) -> - InitF = fun(_) -> Tab = ets:new(unnamed,[]), + InitF = fun(_) -> Tab = ets_new(unnamed,[]), {Tab,0} end, ExecF = fun({Tab,N}) -> true = ets:insert(Tab,{key,N}), @@ -4843,7 +4892,7 @@ meta_lookup_unnamed_write(Config) when is_list(Config) -> meta_lookup_named_read(suite) -> []; meta_lookup_named_read(Config) when is_list(Config) -> InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)), - Tab = ets:new(Name,[named_table]), + Tab = ets_new(Name,[named_table]), true = ets:insert(Tab,{key,data}), Tab end, @@ -4857,7 +4906,7 @@ meta_lookup_named_read(Config) when is_list(Config) -> meta_lookup_named_write(suite) -> []; meta_lookup_named_write(Config) when is_list(Config) -> InitF = fun([ProcN|_]) -> Name = list_to_atom(integer_to_list(ProcN)), - Tab = ets:new(Name,[named_table]), + Tab = ets_new(Name,[named_table]), {Tab,0} end, ExecF = fun({Tab,N}) -> true = ets:insert(Tab,{key,N}), @@ -4870,7 +4919,7 @@ meta_lookup_named_write(Config) when is_list(Config) -> meta_newdel_unnamed(suite) -> []; meta_newdel_unnamed(Config) when is_list(Config) -> InitF = fun(_) -> ok end, - ExecF = fun(_) -> Tab = ets:new(unnamed,[]), + ExecF = fun(_) -> Tab = ets_new(unnamed,[]), true = ets:delete(Tab) end, FiniF = fun(_) -> ok end, @@ -4880,7 +4929,7 @@ meta_newdel_named(suite) -> []; meta_newdel_named(Config) when is_list(Config) -> InitF = fun([ProcN|_]) -> list_to_atom(integer_to_list(ProcN)) end, - ExecF = fun(Name) -> Name = ets:new(Name,[named_table]), + ExecF = fun(Name) -> Name = ets_new(Name,[named_table]), true = ets:delete(Name), Name end, @@ -4890,7 +4939,7 @@ meta_newdel_named(Config) when is_list(Config) -> smp_insert(doc) -> ["Concurrent insert's on same table"]; smp_insert(suite) -> []; smp_insert(Config) when is_list(Config) -> - ets:new(smp_insert,[named_table,public,{write_concurrency,true}]), + ets_new(smp_insert,[named_table,public,{write_concurrency,true}]), InitF = fun(_) -> ok end, ExecF = fun(_) -> true = ets:insert(smp_insert,{random:uniform(10000)}) end, @@ -4905,7 +4954,7 @@ smp_fixed_delete(Config) when is_list(Config) -> only_if_smp(fun()->smp_fixed_delete_do() end). smp_fixed_delete_do() -> - T = ets:new(foo,[public,{write_concurrency,true}]), + T = ets_new(foo,[public,{write_concurrency,true}]), %%Mem = ets:info(T,memory), NumOfObjs = 100000, filltabint(T,NumOfObjs), @@ -4941,7 +4990,7 @@ smp_unfix_fix(Config) when is_list(Config) -> smp_unfix_fix_do() -> process_flag(scheduler,1), Parent = self(), - T = ets:new(foo,[public,{write_concurrency,true}]), + T = ets_new(foo,[public,{write_concurrency,true}]), %%Mem = ets:info(T,memory), NumOfObjs = 100000, Deleted = 50000, @@ -5001,7 +5050,7 @@ otp_8166_do(WC) -> %% Bug scenario: One process segv while reading the table because another %% process is doing unfix without write-lock at the end of a trapping match_object. process_flag(scheduler,1), - T = ets:new(foo,[public, {write_concurrency,WC}]), + T = ets_new(foo,[public, {write_concurrency,WC}]), NumOfObjs = 3000, %% Need more than 1000 live objects for match_object to trap one time Deleted = NumOfObjs div 2, filltabint(T,NumOfObjs), @@ -5115,7 +5164,7 @@ verify_table_load(T) -> otp_8732(doc) -> ["ets:select on a tree with NIL key object"]; otp_8732(Config) when is_list(Config) -> - Tab = ets:new(noname,[ordered_set]), + Tab = ets_new(noname,[ordered_set]), filltabstr(Tab,999), ets:insert(Tab,{[],"nasty NIL object"}), ?line [] = ets:match(Tab,{'_',nomatch}), %% Will hang if bug not fixed @@ -5126,7 +5175,7 @@ smp_select_delete(suite) -> []; smp_select_delete(doc) -> ["Run concurrent select_delete (and inserts) on same table."]; smp_select_delete(Config) when is_list(Config) -> - T = ets:new(smp_select_delete,[named_table,public,{write_concurrency,true}]), + T = ets_new(smp_select_delete,[named_table,public,{write_concurrency,true}]), Mod = 17, Zeros = erlang:make_tuple(Mod,0), InitF = fun(_) -> Zeros end, @@ -5179,6 +5228,39 @@ smp_select_delete(Config) when is_list(Config) -> ?line false = ets:info(T,fixed), ets:delete(T). +types(doc) -> ["Test different types"]; +types(Config) when is_list(Config) -> + init_externals(), + repeat_for_opts(types_do,[[set,ordered_set],compressed]). + +types_do(Opts) -> + EtsMem = etsmem(), + ?line T = ets_new(xxx,Opts), + Fun = fun(Term) -> + ets:insert(T,{Term}), + ?line [{Term}] = ets:lookup(T,Term), + ets:insert(T,{Term,xxx}), + ?line [{Term,xxx}] = ets:lookup(T,Term), + ets:insert(T,{Term,"xxx"}), + ?line [{Term,"xxx"}] = ets:lookup(T,Term), + ets:insert(T,{xxx,Term}), + ?line [{xxx,Term}] = ets:lookup(T,xxx), + ets:insert(T,{"xxx",Term}), + ?line [{"xxx",Term}] = ets:lookup(T,"xxx"), + ets:delete_all_objects(T), + ?line 0 = ets:info(T,size) + end, + test_terms(Fun), + ets:delete(T), + ?line verify_etsmem(EtsMem). + + + + +% +% Utility functions: +% + add_lists(L1,L2) -> add_lists(L1,L2,[]). add_lists([],[],Acc) -> @@ -5244,6 +5326,10 @@ my_tab_to_list(Ts,Key, Acc) -> my_tab_to_list(Ts,ets:next(Ts,Key),[ets:lookup(Ts, Key)| Acc]). etsmem() -> + AllTabs = lists:map(fun(T) -> {T,ets:info(T,name),ets:info(T,size), + ets:info(T,memory),ets:info(T,type)} + end, ets:all()), + Mem = {try erlang:memory(ets) catch error:notsup -> notsup end, case erlang:system_info({allocator,ets_alloc}) of false -> undefined; @@ -5262,12 +5348,13 @@ etsmem() -> {value,{_,BlSz,_,_}} = lists:keysearch(blocks_size, 1, L), {Bl0+Bl,BlSz0+BlSz} end, {0,0}, MSBCS) - end}. + end}, + {Mem,AllTabs}. -verify_etsmem(MemInfo) -> +verify_etsmem({MemInfo,AllTabs}) -> wait_for_test_procs(), case etsmem() of - MemInfo -> + {MemInfo,_} -> io:format("Ets mem info: ~p", [MemInfo]), case MemInfo of {ErlMem,EtsAlloc} when ErlMem == notsup; EtsAlloc == undefined -> @@ -5276,12 +5363,15 @@ verify_etsmem(MemInfo) -> _ -> ok end; - Other -> + {MemInfo2, AllTabs2} -> io:format("Expected: ~p", [MemInfo]), - io:format("Actual: ~p", [Other]), + io:format("Actual: ~p", [MemInfo2]), + io:format("Changed tables before: ~p\n",[AllTabs -- AllTabs2]), + io:format("Changed tables after: ~p\n", [AllTabs2 -- AllTabs]), ?t:fail() end. + start_loopers(N, Prio, Fun, State) -> lists:map(fun (_) -> my_spawn_opt(fun () -> looper(Fun, State) end, @@ -5441,22 +5531,220 @@ only_if_smp(Schedulers, Func) -> {true,_} -> Func() end. +%% Copy-paste from emulator/test/binary_SUITE.erl +-define(heap_binary_size, 64). +test_terms(Test_Func) -> + garbage_collect(), + ?line Pib0 = process_info(self(),binary), + + ?line Test_Func(atom), + ?line Test_Func(''), + ?line Test_Func('a'), + ?line Test_Func('ab'), + ?line Test_Func('abc'), + ?line Test_Func('abcd'), + ?line Test_Func('abcde'), + ?line Test_Func('abcdef'), + ?line Test_Func('abcdefg'), + ?line Test_Func('abcdefgh'), + + ?line Test_Func(fun() -> ok end), + X = id([a,{b,c},c]), + Y = id({x,y,z}), + Z = id(1 bsl 8*257), + ?line Test_Func(fun() -> X end), + ?line Test_Func(fun() -> {X,Y} end), + ?line Test_Func([fun() -> {X,Y,Z} end, + fun() -> {Z,X,Y} end, + fun() -> {Y,Z,X} end]), + + ?line Test_Func({trace_ts,{even_bigger,{some_data,fun() -> ok end}},{1,2,3}}), + ?line Test_Func({trace_ts,{even_bigger,{some_data,<<1,2,3,4,5,6,7,8,9,10>>}}, + {1,2,3}}), + + ?line Test_Func(1), + ?line Test_Func(42), + ?line Test_Func(-23), + ?line Test_Func(256), + ?line Test_Func(25555), + ?line Test_Func(-3333), + + ?line Test_Func(1.0), + + ?line Test_Func(183749783987483978498378478393874), + ?line Test_Func(-37894183749783987483978498378478393874), + Very_Big = very_big_num(), + ?line Test_Func(Very_Big), + ?line Test_Func(-Very_Big+1), + + ?line Test_Func([]), + ?line Test_Func("abcdef"), + ?line Test_Func([a, b, 1, 2]), + ?line Test_Func([a|b]), + + ?line Test_Func({}), + ?line Test_Func({1}), + ?line Test_Func({a, b}), + ?line Test_Func({a, b, c}), + ?line Test_Func(list_to_tuple(lists:seq(0, 255))), + ?line Test_Func(list_to_tuple(lists:seq(0, 256))), + + ?line Test_Func(make_ref()), + ?line Test_Func([make_ref(), make_ref()]), + + ?line Test_Func(make_port()), + + ?line Test_Func(make_pid()), + ?line Test_Func(make_ext_pid()), + ?line Test_Func(make_ext_port()), + ?line Test_Func(make_ext_ref()), + + Bin0 = list_to_binary(lists:seq(0, 14)), + ?line Test_Func(Bin0), + Bin1 = list_to_binary(lists:seq(0, ?heap_binary_size)), + ?line Test_Func(Bin1), + Bin2 = list_to_binary(lists:seq(0, ?heap_binary_size+1)), + ?line Test_Func(Bin2), + Bin3 = list_to_binary(lists:seq(0, 255)), + garbage_collect(), + Pib = process_info(self(),binary), + ?line Test_Func(Bin3), + garbage_collect(), + ?line Pib = process_info(self(),binary), + + ?line Test_Func(make_unaligned_sub_binary(Bin0)), + ?line Test_Func(make_unaligned_sub_binary(Bin1)), + ?line Test_Func(make_unaligned_sub_binary(Bin2)), + ?line Test_Func(make_unaligned_sub_binary(Bin3)), + + ?line Test_Func(make_sub_binary(lists:seq(42, 43))), + ?line Test_Func(make_sub_binary([42,43,44])), + ?line Test_Func(make_sub_binary([42,43,44,45])), + ?line Test_Func(make_sub_binary([42,43,44,45,46])), + ?line Test_Func(make_sub_binary([42,43,44,45,46,47])), + ?line Test_Func(make_sub_binary([42,43,44,45,46,47,48])), + ?line Test_Func(make_sub_binary(lists:seq(42, 49))), + ?line Test_Func(make_sub_binary(lists:seq(0, 14))), + ?line Test_Func(make_sub_binary(lists:seq(0, ?heap_binary_size))), + ?line Test_Func(make_sub_binary(lists:seq(0, ?heap_binary_size+1))), + ?line Test_Func(make_sub_binary(lists:seq(0, 255))), + + ?line Test_Func(make_unaligned_sub_binary(lists:seq(42, 43))), + ?line Test_Func(make_unaligned_sub_binary([42,43,44])), + ?line Test_Func(make_unaligned_sub_binary([42,43,44,45])), + ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46])), + ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46,47])), + ?line Test_Func(make_unaligned_sub_binary([42,43,44,45,46,47,48])), + ?line Test_Func(make_unaligned_sub_binary(lists:seq(42, 49))), + ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, 14))), + ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, ?heap_binary_size))), + ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, ?heap_binary_size+1))), + ?line Test_Func(make_unaligned_sub_binary(lists:seq(0, 255))), + + %% Bit level binaries. + ?line Test_Func(<<1:1>>), + ?line Test_Func(<<2:2>>), + ?line Test_Func(<<42:10>>), + ?line Test_Func(list_to_bitstring([<<5:6>>|lists:seq(0, 255)])), + + ?line Test_Func(F = fun(A) -> 42*A end), + ?line Test_Func(lists:duplicate(32, F)), + + ?line Test_Func(FF = fun binary_SUITE:all/1), + ?line Test_Func(lists:duplicate(32, FF)), + + garbage_collect(), + ?line Pib0 = process_info(self(),binary), + ok. + +id(I) -> I. + +very_big_num() -> + very_big_num(33, 1). + +very_big_num(Left, Result) when Left > 0 -> + ?line very_big_num(Left-1, Result*256); +very_big_num(0, Result) -> + ?line Result. + +make_port() -> + ?line open_port({spawn, efile}, [eof]). + +make_pid() -> + ?line spawn_link(?MODULE, sleeper, []). + +sleeper() -> + ?line receive after infinity -> ok end. + +make_ext_pid() -> + {Pid, _, _} = get(externals), + Pid. + +make_ext_port() -> + {_, Port, _} = get(externals), + Port. +make_ext_ref() -> + {_, _, Ref} = get(externals), + Ref. + +init_externals() -> + SysDistSz = ets:info(sys_dist,size), + ?line Pa = filename:dirname(code:which(?MODULE)), + ?line {ok, Node} = test_server:start_node(plopp, slave, [{args, " -pa " ++ Pa}]), + ?line Res = case rpc:call(Node, ?MODULE, rpc_externals, []) of + {badrpc, {'EXIT', E}} -> + test_server:fail({rpcresult, E}); + R -> R + end, + ?line test_server:stop_node(Node), + + %% Wait for table 'sys_dist' to stabilize + repeat_while(fun() -> + case ets:info(sys_dist,size) of + SysDistSz -> false; + Sz -> + io:format("Waiting for sys_dist to revert size from ~p to size ~p\n", + [Sz, SysDistSz]), + receive after 1000 -> true end + end + end), + put(externals, Res). + +rpc_externals() -> + {self(), make_port(), make_ref()}. + +make_sub_binary(Bin) when is_binary(Bin) -> + {_,B} = split_binary(list_to_binary([0,1,3,Bin]), 3), + B; +make_sub_binary(List) -> + make_sub_binary(list_to_binary(List)). + +make_unaligned_sub_binary(Bin0) when is_binary(Bin0) -> + Bin1 = <<0:3,Bin0/binary,31:5>>, + Sz = size(Bin0), + <<0:3,Bin:Sz/binary,31:5>> = id(Bin1), + Bin; +make_unaligned_sub_binary(List) -> + make_unaligned_sub_binary(list_to_binary(List)). %% Repeat test function with different combination of table options %% repeat_for_opts(F) -> - repeat_for_opts(F, [write_concurrency, read_concurrency]). + repeat_for_opts(F, [write_concurrency, read_concurrency, compressed]). repeat_for_opts(F, OptGenList) when is_atom(F) -> repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts) end, OptGenList); +repeat_for_opts({F,Args}, OptGenList) when is_atom(F) -> + repeat_for_opts(fun(Opts) -> ?MODULE:F(Opts,Args) end, OptGenList); repeat_for_opts(F, OptGenList) -> repeat_for_opts(F, OptGenList, []). repeat_for_opts(F, [], Acc) -> - lists:map(fun(Opts) -> - io:format("Calling with options ~p\n",[Opts]), - F(Opts) - end, Acc); + lists:map(fun(Opts) -> + OptList = lists:filter(fun(E) -> E =/= void end, Opts), + io:format("Calling with options ~p\n",[OptList]), + F(OptList) + end, Acc); repeat_for_opts(F, [OptList | Tail], []) when is_list(OptList) -> repeat_for_opts(F, Tail, [[Opt] || Opt <- OptList]); repeat_for_opts(F, [OptList | Tail], AccList) when is_list(OptList) -> @@ -5466,6 +5754,9 @@ repeat_for_opts(F, [Atom | Tail], AccList) when is_atom(Atom) -> repeat_for_opts_atom2list(all_types) -> [set,ordered_set,bag,duplicate_bag]; repeat_for_opts_atom2list(write_concurrency) -> [{write_concurrency,false},{write_concurrency,true}]; -repeat_for_opts_atom2list(read_concurrency) -> [{read_concurrency,false},{read_concurrency,true}]. - +repeat_for_opts_atom2list(read_concurrency) -> [{read_concurrency,false},{read_concurrency,true}]; +repeat_for_opts_atom2list(compressed) -> [compressed,void]. +ets_new(Name, Opts) -> + %%ets:new(Name, [compressed | Opts]). + ets:new(Name, Opts). diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index d54741051f..5a279609c6 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -53,8 +53,11 @@ wildcard_one(Config) when is_list(Config) -> wildcard_two(Config) when is_list(Config) -> ?line Dir = filename:join(?config(priv_dir, Config), "wildcard_two"), + ?line DirB = unicode:characters_to_binary(Dir, file:native_name_encoding()), ?line ok = file:make_dir(Dir), - ?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir) end), + ?line do_wildcard_1(Dir, fun(Wc) -> io:format("~p~n",[{Wc,Dir, X = filelib:wildcard(Wc, Dir)}]),X end), + ?line do_wildcard_1(Dir, fun(Wc) -> io:format("~p~n",[{Wc,DirB, X = filelib:wildcard(Wc, DirB)}]), + [unicode:characters_to_list(Y,file:native_name_encoding()) || Y <- X] end), ?line do_wildcard_1(Dir, fun(Wc) -> filelib:wildcard(Wc, Dir++"/") end), case os:type() of {win32,_} -> @@ -253,5 +256,7 @@ ensure_dir_eexist(Config) when is_list(Config) -> %% There already is a file with the name of the directory %% we want to create. ?line NeedFile = filename:join(Name, "file"), + ?line NeedFileB = filename:join(Name, <<"file">>), ?line {error, eexist} = filelib:ensure_dir(NeedFile), + ?line {error, eexist} = filelib:ensure_dir(NeedFileB), ok. diff --git a/lib/stdlib/test/filename_SUITE.erl b/lib/stdlib/test/filename_SUITE.erl index ab6521f37b..dbce93600b 100644 --- a/lib/stdlib/test/filename_SUITE.erl +++ b/lib/stdlib/test/filename_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% 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 @@ -22,12 +22,19 @@ basename_1/1, basename_2/1, dirname/1, extension/1, join/1, t_nativename/1]). -export([pathtype/1,rootname/1,split/1,find_src/1]). +-export([absname_bin/1, absname_bin_2/1, + basename_bin_1/1, basename_bin_2/1, + dirname_bin/1, extension_bin/1, join_bin/1]). +-export([pathtype_bin/1,rootname_bin/1,split_bin/1]). -include("test_server.hrl"). all(suite) -> [absname, absname_2, basename_1, basename_2, dirname, extension, - join, pathtype, rootname, split, t_nativename, find_src]. + join, pathtype, rootname, split, t_nativename, find_src, + absname_bin, absname_bin_2, basename_bin_1, basename_bin_2, dirname_bin, + extension_bin, + join_bin, pathtype_bin, rootname_bin, split_bin]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -457,3 +464,307 @@ find_src(Config) when is_list(Config) -> %% Try to find the source for a preloaded module. ?line {error,{preloaded,init}} = filename:find_src(init), ok. + +%% +%% +%% With binaries +%% +%% + +absname_bin(Config) when is_list(Config) -> + case os:type() of + {win32, _} -> + ?line [Drive|_] = ?config(priv_dir, Config), + ?line Temp = filename:join([Drive|":/"], "temp"), + ?line case file:make_dir(Temp) of + ok -> ok; + {error,eexist} -> ok + end, + ?line {ok,Cwd} = file:get_cwd(), + ?line ok = file:set_cwd(Temp), + ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>), + ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>), + ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>), + ?line <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang/src">>), + ?line <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang\\src\\">>), + ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>), + + ?line file:set_cwd(<<Drive:8,":/">>), + ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>), + ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>), + ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>), + + ?line file:set_cwd(Cwd), + ok; + {unix, _} -> + ?line ok = file:set_cwd(<<"/usr">>), + ?line <<"/usr/foo">> = filename:absname(<<"foo">>), + ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>), + + ?line file:set_cwd(<<"/">>), + ?line <<"/foo">> = filename:absname(<<"foo">>), + ?line <<"/../ebin">> = filename:absname(<<"../ebin">>), + ?line <<"/erlang">> = filename:absname(<<"/erlang">>), + ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>), + ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>), + ok + end. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +absname_bin_2(Config) when is_list(Config) -> + case os:type() of + {win32, _} -> + ?line [Drive|_] = ?config(priv_dir, Config), + ?line <<Drive:8,":/temp/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/temp">>), + ?line <<Drive:8,":/temp/../ebin">> = filename:absname(<<"../ebin">>, + <<Drive:8,":/temp">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/temp">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, + <<Drive:8,":/temp">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\src">>, + <<Drive:8,":/temp">>), + ?line <<Drive:8,":/temp/erlang">> = filename:absname(<<Drive:8,":erlang">>, + <<Drive:8,":/temp">>), + ?line <<Drive:8,":/temp/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, + <<Drive:8,":/temp">>), + ?line <<Drive:8,":/temp/erlang/src">> = + filename:absname(<<Drive:8,":erlang\\src\\">>, <<Drive:8,":/temp">>), + ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/temp">>), + + ?line file:set_cwd(<<Drive:8,":/">>), + ?line <<Drive:8,":/foo">> = filename:absname(foo, <<Drive:8,":/">>), + ?line <<Drive:8,":/foo">> = filename:absname(<<"foo">>, <<Drive:8,":/">>), + ?line <<Drive:8,":/../ebin">> = filename:absname(<<"../ebin">>, <<Drive:8,":/">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<"/erlang">>, <<Drive:8,":/">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"/erlang/src">>, + <<Drive:8,":/">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<"\\erlang\\\\src">>, + <<Drive:8,":/">>), + ?line <<Drive:8,":/erlang">> = filename:absname(<<Drive:8,":erlang">>, + <<Drive:8,":/">>), + ?line <<Drive:8,":/erlang/src">> = filename:absname(<<Drive:8,":erlang/src">>, + <<Drive:8,":/">>), + ?line <<"a:/erlang">> = filename:absname(<<"a:erlang">>, <<Drive:8,":/">>), + + ok; + {unix, _} -> + ?line <<"/usr/foo">> = filename:absname(<<"foo">>, <<"/usr">>), + ?line <<"/usr/../ebin">> = filename:absname(<<"../ebin">>, <<"/usr">>), + + ?line <<"/foo">> = filename:absname(<<"foo">>, <<"/">>), + ?line <<"/../ebin">> = filename:absname(<<"../ebin">>, <<"/">>), + ?line <<"/erlang">> = filename:absname(<<"/erlang">>, <<"/">>), + ?line <<"/erlang/src">> = filename:absname(<<"/erlang/src">>, <<"/">>), + ?line <<"/erlang/src">> = filename:absname(<<"/erlang///src">>, <<"/">>), + ok + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +basename_bin_1(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(10)), + ?line <<".">> = filename:basename(<<".">>), + ?line <<"foo">> = filename:basename(<<"foo">>), + ?line <<"foo">> = filename:basename(<<"/usr/foo">>), + ?line <<"foo.erl">> = filename:basename(<<"A:usr/foo.erl">>), + ?line case os:type() of + {win32, _} -> + ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>), + ?line <<"foo">> = filename:basename(<<"A:foo">>); + {unix, _} -> + ?line <<"strange\\but\\true">> = + filename:basename(<<"strange\\but\\true">>) + end, + ?line test_server:timetrap_cancel(Dog), + ok. + +basename_bin_2(Config) when is_list(Config) -> + ?line Dog = test_server:timetrap(test_server:seconds(10)), + ?line <<".">> = filename:basename(<<".">>, <<".erl">>), + ?line <<"foo">> = filename:basename(<<"foo.erl">>, <<".erl">>), + ?line <<"foo.erl">> = filename:basename(<<"/usr/foo.erl">>, <<".hrl">>), + ?line <<"foo.erl">> = filename:basename(<<"/usr.hrl/foo.erl">>, <<".hrl">>), + ?line <<"foo">> = filename:basename(<<"/usr.hrl/foo">>, <<".hrl">>), + ?line <<"foo">> = filename:basename(<<"usr/foo/">>, <<".erl">>), + ?line <<"foo.erl">> = filename:basename(<<"usr/foo.erl/">>, <<".erl">>), + ?line case os:type() of + {win32, _} -> + ?line <<"foo">> = filename:basename(<<"A:foo">>, <<".erl">>), + ?line <<"foo.erl">> = filename:basename(<<"a:\\usr\\foo.erl">>, + <<".hrl">>), + ?line <<"foo.erl">> = filename:basename(<<"c:\\usr.hrl\\foo.erl">>, + <<".hrl">>), + ?line <<"foo">> = filename:basename(<<"A:\\usr\\foo">>, <<".hrl">>); + {unix, _} -> + ?line <<"strange\\but\\true">> = + filename:basename(<<"strange\\but\\true.erl">>, <<".erl">>), + ?line <<"strange\\but\\true">> = + filename:basename(<<"strange\\but\\true">>, <<".erl">>) + end, + ?line test_server:timetrap_cancel(Dog), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +dirname_bin(Config) when is_list(Config) -> + case os:type() of + {win32,_} -> + ?line <<"A:/usr">> = filename:dirname(<<"A:/usr/foo.erl">>), + ?line <<"A:usr">> = filename:dirname(<<"A:usr/foo.erl">>), + ?line <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>), + ?line <<"/">> = filename:dirname(<<"\\usr">>), + ?line <<"A:">> = filename:dirname(<<"A:">>); + vxworks -> + ?line <<"net:/usr">> = filename:dirname(<<"net:/usr/foo.erl">>), + ?line <<"/disk0:/usr">> = filename:dirname(<<"/disk0:/usr/foo.erl">>), + ?line <<"/usr">> = filename:dirname(<<"\\usr\\foo.erl">>), + ?line <<"/usr">> = filename:dirname(<<"\\usr">>), + ?line <<"net:">> = filename:dirname(<<"net:">>); + _ -> true + end, + ?line <<"usr">> = filename:dirname(<<"usr///foo.erl">>), + ?line <<".">> = filename:dirname(<<"foo.erl">>), + ?line <<".">> = filename:dirname(<<".">>), + case os:type() of + vxworks -> + ?line <<"/">> = filename:dirname(<<"/">>), + ?line <<"/usr">> = filename:dirname(<<"/usr">>); + _ -> + ?line <<"/">> = filename:dirname(<<"/">>), + ?line <<"/">> = filename:dirname(<<"/usr">>) + end, + ok. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +extension_bin(Config) when is_list(Config) -> + ?line <<".erl">> = filename:extension(<<"A:/usr/foo.erl">>), + ?line <<".erl">> = filename:extension(<<"A:/usr/foo.nisse.erl">>), + ?line <<".erl">> = filename:extension(<<"A:/usr.bar/foo.nisse.erl">>), + ?line <<"">> = filename:extension(<<"A:/usr.bar/foo">>), + ?line <<"">> = filename:extension(<<"A:/usr/foo">>), + ?line case os:type() of + {win32, _} -> + ?line <<"">> = filename:extension(<<"A:\\usr\\foo">>), + ?line <<".erl">> = + filename:extension(<<"A:/usr.bar/foo.nisse.erl">>), + ?line <<"">> = filename:extension(<<"A:/usr.bar/foo">>), + ok; + vxworks -> + ?line <<"">> = filename:extension(<<"/disk0:\\usr\\foo">>), + ?line <<".erl">> = + filename:extension(<<"net:/usr.bar/foo.nisse.erl">>), + ?line <<"">> = filename:extension(<<"net:/usr.bar/foo">>), + ok; + _ -> ok + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +join_bin(Config) when is_list(Config) -> + ?line <<"/">> = filename:join([<<"/">>]), + ?line <<"/">> = filename:join([<<"//">>]), + ?line <<"usr/foo.erl">> = filename:join(<<"usr">>,<<"foo.erl">>), + ?line <<"/src/foo.erl">> = filename:join(usr, <<"/src/foo.erl">>), + ?line <<"/src/foo.erl">> = filename:join([<<"/src/">>,'foo.erl']), + ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, ["/sr", 'c/foo.erl']), + ?line <<"/src/foo.erl">> = filename:join(<<"usr">>, <<"/src/foo.erl">>), + + %% Make sure that redundant slashes work too. + ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/////d//e/f/g">>]), + ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c/">>, <<"d//e/f/g">>]), + ?line <<"a/b/c/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"d//e/f/g">>]), + ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"/d//e/f/g">>]), + ?line <<"/d/e/f/g">> = filename:join([<<"a//b/c">>, <<"//d//e/f/g">>]), + + ?line <<"foo/bar">> = filename:join([$f,$o,$o,$/,[]], <<"bar">>), + + ?line case os:type() of + {win32, _} -> + ?line <<"d:/">> = filename:join([<<"D:/">>]), + ?line <<"d:/">> = filename:join([<<"D:\\">>]), + ?line <<"d:/abc">> = filename:join([<<"D:/">>, <<"abc">>]), + ?line <<"d:abc">> = filename:join([<<"D:">>, <<"abc">>]), + ?line <<"a/b/c/d/e/f/g">> = + filename:join([<<"a//b\\c//\\/\\d/\\e/f\\g">>]), + ?line <<"a:usr/foo.erl">> = + filename:join([<<"A:">>,<<"usr">>,<<"foo.erl">>]), + ?line <<"/usr/foo.erl">> = + filename:join([<<"A:">>,<<"/usr">>,<<"foo.erl">>]), + ?line <<"c:usr">> = filename:join(<<"A:">>,<<"C:usr">>), + ?line <<"a:usr">> = filename:join(<<"A:">>,<<"usr">>), + ?line <<"c:/usr">> = filename:join(<<"A:">>, <<"C:/usr">>), + ?line <<"c:/usr/foo.erl">> = + filename:join([<<"A:">>,<<"C:/usr">>,<<"foo.erl">>]), + ?line <<"c:usr/foo.erl">> = + filename:join([<<"A:">>,<<"C:usr">>,<<"foo.erl">>]), + ?line <<"d:/foo">> = filename:join([$D, $:, $/, []], <<"foo">>), + ok; + {unix, _} -> + ok + end. + +pathtype_bin(Config) when is_list(Config) -> + ?line relative = filename:pathtype(<<"..">>), + ?line relative = filename:pathtype(<<"foo">>), + ?line relative = filename:pathtype(<<"foo/bar">>), + ?line relative = filename:pathtype('foo/bar'), + case os:type() of + {win32, _} -> + ?line volumerelative = filename:pathtype(<<"/usr/local/bin">>), + ?line volumerelative = filename:pathtype(<<"A:usr/local/bin">>), + ok; + {unix, _} -> + ?line absolute = filename:pathtype(<<"/">>), + ?line absolute = filename:pathtype(<<"/usr/local/bin">>), + ok + end. + +rootname_bin(Config) when is_list(Config) -> + ?line <<"/jam.src/kalle">> = filename:rootname(<<"/jam.src/kalle">>), + ?line <<"/jam.src/foo">> = filename:rootname(<<"/jam.src/foo.erl">>), + ?line <<"/jam.src/foo">> = filename:rootname(<<"/jam.src/foo.erl">>, <<".erl">>), + ?line <<"/jam.src/foo.jam">> = filename:rootname(<<"/jam.src/foo.jam">>, <<".erl">>), + ?line <<"/jam.src/foo.jam">> = filename:rootname(["/jam.sr",'c/foo.j',"am"],<<".erl">>), + ?line <<"/jam.src/foo.jam">> = filename:rootname(["/jam.sr",'c/foo.j'|am],<<".erl">>), + ok. + +split_bin(Config) when is_list(Config) -> + case os:type() of + vxworks -> + ?line [<<"/usr">>,<<"local">>,<<"bin">>] = filename:split(<<"/usr/local/bin">>); + _ -> + ?line [<<"/">>,<<"usr">>,<<"local">>,<<"bin">>] = filename:split(<<"/usr/local/bin">>) + end, + ?line [<<"foo">>,<<"bar">>]= filename:split(<<"foo/bar">>), + ?line [<<"foo">>, <<"bar">>, <<"hello">>]= filename:split(<<"foo////bar//hello">>), + case os:type() of + {win32,_} -> + ?line [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:/msdev/include">>), + ?line [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"A:/msdev/include">>), + ?line [<<"msdev">>,<<"include">>] = + filename:split(<<"msdev\\include">>), + ?line [<<"a:/">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:\\msdev\\include">>), + ?line [<<"a:">>,<<"msdev">>,<<"include">>] = + filename:split(<<"a:msdev\\include">>), + ok; + _ -> + ok + end. + diff --git a/lib/stdlib/test/string_SUITE.erl b/lib/stdlib/test/string_SUITE.erl index 3171b87c44..452e048dd7 100644 --- a/lib/stdlib/test/string_SUITE.erl +++ b/lib/stdlib/test/string_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. +%% 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 @@ -240,7 +240,8 @@ copies(Config) when is_list(Config) -> ?line "." = string:copies(".", 1), ?line 30 = length(string:copies("123", 10)), %% invalid arg type - ?line {'EXIT',_} = (catch string:chars("hej", -1)), + ?line {'EXIT',_} = (catch string:copies("hej", -1)), + ?line {'EXIT',_} = (catch string:copies("hej", 2.0)), ok. words(suite) -> diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 1757d35160..db7954af04 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 1.17.1 +STDLIB_VSN = 1.17.2 diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl index 6b0f2034f8..9f6f7d815e 100644 --- a/lib/syntax_tools/src/epp_dodger.erl +++ b/lib/syntax_tools/src/epp_dodger.erl @@ -809,6 +809,8 @@ tokens_to_string([{atom,_,A} | Ts]) -> io_lib:write_atom(A) ++ " " ++ tokens_to_string(Ts); tokens_to_string([{string, _, S} | Ts]) -> io_lib:write_string(S) ++ " " ++ tokens_to_string(Ts); +tokens_to_string([{char, _, C} | Ts]) -> + io_lib:write_char(C) ++ " " ++ tokens_to_string(Ts); tokens_to_string([{float, _, F} | Ts]) -> float_to_list(F) ++ " " ++ tokens_to_string(Ts); tokens_to_string([{integer, _, N} | Ts]) -> diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl index c2c72d1ed2..7caf0b3db6 100644 --- a/lib/syntax_tools/src/erl_prettypr.erl +++ b/lib/syntax_tools/src/erl_prettypr.erl @@ -50,11 +50,15 @@ -type hook() :: 'none' | fun((erl_syntax:syntaxTree(), _, _) -> prettypr:document()). +-type clause_t() :: 'case_expr' | 'cond_expr' | 'fun_expr' + | 'if_expr' | 'receive_expr' | 'try_expr' + | {'function', prettypr:document()} + | {'rule', prettypr:document()}. -record(ctxt, {prec = 0 :: integer(), sub_indent = 2 :: non_neg_integer(), break_indent = 4 :: non_neg_integer(), - clause = undefined, + clause = undefined :: clause_t() | 'undefined', hook = ?NOHOOK :: hook(), paper = ?PAPER :: integer(), ribbon = ?RIBBON :: integer(), @@ -599,9 +603,8 @@ lay_2(Node, Ctxt) -> case_expr -> Ctxt1 = reset_prec(Ctxt), D1 = lay(erl_syntax:case_expr_argument(Node), Ctxt1), - D2 = lay_clauses( - erl_syntax:case_expr_clauses(Node), - case_expr, Ctxt1), + D2 = lay_clauses(erl_syntax:case_expr_clauses(Node), + case_expr, Ctxt1), sep([par([follow(text("case"), D1, Ctxt1#ctxt.sub_indent), text("of")], Ctxt1#ctxt.break_indent), @@ -819,9 +822,8 @@ lay_2(Node, Ctxt) -> receive_expr -> Ctxt1 = reset_prec(Ctxt), - D1 = lay_clauses( - erl_syntax:receive_expr_clauses(Node), - receive_expr, Ctxt1), + D1 = lay_clauses(erl_syntax:receive_expr_clauses(Node), + receive_expr, Ctxt1), D2 = case erl_syntax:receive_expr_timeout(Node) of none -> D1; diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl index 94e760dad7..919e9cfc5d 100644 --- a/lib/syntax_tools/src/erl_recomment.erl +++ b/lib/syntax_tools/src/erl_recomment.erl @@ -215,7 +215,8 @@ comment_delta(Text) -> %% the source file itself, but have been included by preprocessing. This %% way, comments will not be inserted into such parts by mistake. --record(filter, {file = undefined, line = 0 :: integer()}). +-record(filter, {file = undefined :: file:filename() | 'undefined', + line = 0 :: integer()}). filter_forms(Fs) -> filter_forms(Fs, false, #filter{}). @@ -721,8 +722,6 @@ tree_node_attrs(#tree{attrs = Attrs}) -> %% ===================================================================== %% General utility functions -%% Just the generic "maximum" function - %% Return the least positive integer of X and Y, or zero if none of them %% are positive. (This is necessary for computing minimum source line %% numbers, since zero (or negative) numbers may occur, but they diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl index a40bf83c5a..9df5f26454 100644 --- a/lib/syntax_tools/src/erl_syntax.erl +++ b/lib/syntax_tools/src/erl_syntax.erl @@ -1818,7 +1818,7 @@ char_value(Node) -> %% %% @see char/1 --spec char_literal(syntaxTree()) -> string(). +-spec char_literal(syntaxTree()) -> nonempty_string(). char_literal(Node) -> io_lib:write_char(char_value(Node)). @@ -1908,7 +1908,7 @@ string_value(Node) -> %% %% @see string/1 --spec string_literal(syntaxTree()) -> string(). +-spec string_literal(syntaxTree()) -> nonempty_string(). string_literal(Node) -> io_lib:write_string(string_value(Node)). diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl index 4808971a59..97dfbfd7cd 100644 --- a/lib/syntax_tools/src/erl_syntax_lib.erl +++ b/lib/syntax_tools/src/erl_syntax_lib.erl @@ -49,10 +49,6 @@ -export_type([info_pair/0]). %% ===================================================================== - --type ordset(X) :: [X]. % XXX: TAKE ME OUT - -%% ===================================================================== %% @spec map(Function, Tree::syntaxTree()) -> syntaxTree() %% %% Function = (syntaxTree()) -> syntaxTree() @@ -480,7 +476,7 @@ new_variable_names(0, Names, _, _, _) -> %% @see annotate_bindings/1 %% @see //stdlib/ordsets --spec annotate_bindings(erl_syntax:syntaxTree(), ordset(atom())) -> +-spec annotate_bindings(erl_syntax:syntaxTree(), ordsets:ordset(atom())) -> erl_syntax:syntaxTree(). annotate_bindings(Tree, Env) -> @@ -1134,21 +1130,21 @@ collect_attribute(_, {N, V}, Info) -> %% Abstract datatype for collecting module information. --record(forms, {module, exports, module_imports, imports, attributes, - records, errors, warnings, functions, rules}). +-record(forms, {module = none :: 'none' | {'value', atom()}, + exports = [] :: [{atom(), arity()}], + module_imports = [] :: [atom()], + imports = [] :: [{atom(), [{atom(), arity()}]}], + attributes = [] :: [{atom(), term()}], + records = [] :: [{atom(), [{atom(), field_default()}]}], + errors = [] :: [term()], + warnings = [] :: [term()], + functions = [] :: [{atom(), arity()}], + rules = [] :: [{atom(), arity()}]}). + +-type field_default() :: 'none' | erl_syntax:syntaxTree(). new_finfo() -> - #forms{module = none, - exports = [], - module_imports = [], - imports = [], - attributes = [], - records = [], - errors = [], - warnings = [], - functions = [], - rules = [] - }. + #forms{}. finfo_set_module(Name, Info) -> case Info#forms.module of diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl index 021ab18736..1cfdc7234a 100644 --- a/lib/syntax_tools/src/erl_tidy.erl +++ b/lib/syntax_tools/src/erl_tidy.erl @@ -935,12 +935,13 @@ hidden_uses_2(Tree, Used) -> Used end. +-type fa() :: {atom(), arity()}. -type context() :: 'guard_expr' | 'guard_test' | 'normal'. -record(env, {file :: file:filename(), - module, - current, - imports, + module :: atom(), + current :: fa(), + imports = dict:new() :: dict(), context = normal :: context(), verbosity = 1 :: 0 | 1 | 2, quiet = false :: boolean(), @@ -951,7 +952,13 @@ hidden_uses_2(Tree, Used) -> new_guard_tests = true :: boolean(), old_guard_tests = false :: boolean()}). --record(st, {varc, used, imported, vars, functions, new_forms, rename}). +-record(st, {varc :: non_neg_integer(), + used = sets:new() :: set(), + imported :: set(), + vars :: set(), + functions :: set(), + new_forms = [] :: [erl_syntax:syntaxTree()], + rename :: dict()}). visit_used(Names, Defs, Roots, Imports, Module, Opts) -> File = proplists:get_value(file, Opts, ""), diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl index 702b399615..aa933eb54b 100644 --- a/lib/syntax_tools/src/igor.erl +++ b/lib/syntax_tools/src/igor.erl @@ -119,20 +119,16 @@ %% ===================================================================== --type ordset(X) :: [X]. % XXX: TAKE ME OUT - -%% ===================================================================== - %% Data structure for module information -record(module, {name :: atom(), vars = none :: [atom()] | 'none', - functions :: ordset({atom(), arity()}), - exports :: ordset({atom(), arity()}) - | ordset({{atom(), arity()}, term()}), - aliases :: ordset({{atom(), arity()}, - {atom(), {atom(), arity()}}}), - attributes :: ordset({atom(), term()}), + functions :: ordsets:ordset({atom(), arity()}), + exports :: ordsets:ordset({atom(), arity()}) + | ordsets:ordset({{atom(), arity()}, term()}), + aliases :: ordsets:ordset({{atom(), arity()}, + {atom(), {atom(), arity()}}}), + attributes :: ordsets:ordset({atom(), term()}), records :: [{atom(), [{atom(), term()}]}] }). @@ -149,7 +145,7 @@ default_printer(Tree, Options) -> -type moduleName() :: atom(). -type functionName() :: {atom(), arity()}. -type functionPair() :: {functionName(), {moduleName(), functionName()}}. --type stubDescriptor() :: [{moduleName(), [functionPair()], [attribute()]}]. +-type stubDescriptor() :: {moduleName(), [functionPair()], [attribute()]}. -type notes() :: 'always' | 'yes' | 'no'. @@ -209,7 +205,7 @@ parse_transform(Forms, Options) -> %% @spec merge(Name::atom(), Files::[filename()]) -> [filename()] %% @equiv merge(Name, Files, []) --spec merge(atom(), [file:filename()]) -> [file:filename()]. +-spec merge(atom(), [file:filename()]) -> [file:filename(),...]. merge(Name, Files) -> merge(Name, Files, []). @@ -343,7 +339,7 @@ merge(Name, Files) -> {suffix, ?DEFAULT_SUFFIX}, {verbose, false}]). --spec merge(atom(), [file:filename()], [option()]) -> [file:filename()]. +-spec merge(atom(), [file:filename()], [option()]) -> [file:filename(),...]. merge(Name, Files, Opts) -> Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS, @@ -484,7 +480,7 @@ merge_files(Name, Trees, Files, Opts) -> %% %% Forms = syntaxTree() | [syntaxTree()] %% -%% @type stubDescriptor() = [{ModuleName, Functions, [Attribute]}] +%% @type stubDescriptor() = {ModuleName, Functions, [Attribute]} %% ModuleName = atom() %% Functions = [{FunctionName, {ModuleName, FunctionName}}] %% FunctionName = {atom(), integer()} @@ -687,15 +683,15 @@ merge_files(Name, Trees, Files, Opts) -> %% Data structure for merging environment. -record(merge, {target :: atom(), - sources :: ordset(atom()), - export :: ordset(atom()), - static :: ordset(atom()), - safe :: ordset(atom()), + sources :: ordsets:ordset(atom()), + export :: ordsets:ordset(atom()), + static :: ordsets:ordset(atom()), + safe :: ordsets:ordset(atom()), preserved :: boolean(), no_headers :: boolean(), notes :: notes(), redirect :: dict(), % = dict(atom(), atom()) - no_imports :: ordset(atom()), + no_imports :: ordsets:ordset(atom()), options :: [option()] }). @@ -1035,7 +1031,12 @@ make_stub(M, Map, Env) -> %% Removing and/or out-commenting program forms. The returned form %% sequence tree is not necessarily flat. --record(filter, {records :: set(), file_attributes, attributes}). +-type atts() :: 'delete' | 'kill'. +-type file_atts() :: 'delete' | 'keep' | 'kill'. + +-record(filter, {records :: set(), + file_attributes :: file_atts(), + attributes :: atts()}). filter_forms(Tree, Env) -> Forms = erl_syntax:form_list_elements( @@ -1576,6 +1577,8 @@ alias_expansions_2(Modules, Table) -> %% --------------------------------------------------------------------- %% Merging the source code. +-type map_fun() :: fun(({atom(), integer()}) -> {atom(), integer()}). + %% Data structure for code transformation environment. -record(code, {module :: atom(), @@ -1586,11 +1589,10 @@ alias_expansions_2(Modules, Table) -> preserved :: boolean(), no_headers :: boolean(), notes :: notes(), - map, % = ({atom(), int()}) -> {atom(), int()} - renaming, % = (atom()) -> ({atom(), int()}) -> - % {atom(), int()} - expand :: dict(), % = dict({atom(), int()}, - % {atom(), {atom(), int()}}) + map :: map_fun(), + renaming :: fun((atom()) -> map_fun()), + expand :: dict(), % = dict({atom(), integer()}, + % {atom(), {atom(), integer()}}) redirect :: dict() % = dict(atom(), atom()) }). diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl index bbbb7883db..2ddffccf5b 100644 --- a/lib/test_server/src/ts_install.erl +++ b/lib/test_server/src/ts_install.erl @@ -226,9 +226,11 @@ to_upper(String) -> String). word_size() -> - case erlang:system_info(wordsize) of - 4 -> ""; - 8 -> "/64" + case {erlang:system_info({wordsize,external}), + erlang:system_info({wordsize,internal})} of + {4,4} -> ""; + {8,8} -> "/64"; + {8,4} -> "/Halfword" end. linux_dist() -> diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index 91acfdf2b6..ed825a298f 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -1481,7 +1481,23 @@ Other commands: erlang-font-lock-keywords-3 erlang-font-lock-keywords-4) nil nil ((?_ . "w")) erlang-beginning-of-clause - (font-lock-mark-block-function . erlang-mark-clause)))) + (font-lock-mark-block-function . erlang-mark-clause) + (font-lock-syntactic-keywords + ;; A dollar sign right before the double quote that ends a + ;; string is not a character escape. + ;; + ;; And a "string" has with a double quote not escaped by a + ;; dollar sign, any number of non-backslash non-newline + ;; characters or escaped backslashes, a dollar sign + ;; (otherwise we wouldn't care) and a double quote. This + ;; doesn't match multi-line strings, but this is probably + ;; the best we can get, since while font-locking we don't + ;; know whether matching started inside a string: limiting + ;; search to a single line keeps things sane. + . (("\\(?:^\\|[^$]\\)\"\\(?:[^\"\n]\\|\\\\\"\\)*\\(\\$\\)\"" 1 "w") + ;; And the dollar sign in $\" escapes two characters, not + ;; just one. + ("\\(\\$\\)\\\\\\\"" 1 "'")))))) diff --git a/lib/tools/src/eprof.erl b/lib/tools/src/eprof.erl index f7c1b76364..87fdc1fa34 100644 --- a/lib/tools/src/eprof.erl +++ b/lib/tools/src/eprof.erl @@ -136,7 +136,7 @@ handle_call({analyze, procs, Opts}, _, #state{ bpd = #bpd{ p = Ps, us = Tus} = B lists:foreach(fun ({Pid, Mfas}) -> {Pn, Pus} = sum_bp_total_n_us(Mfas), - format(Fd, "~n****** Process ~w -- ~s % of profiled time *** ~n", [Pid, s("~.2f", [100.0*(Pus/Tus)])]), + format(Fd, "~n****** Process ~w -- ~s % of profiled time *** ~n", [Pid, s("~.2f", [100.0*divide(Pus,Tus)])]), print_bp_mfa(Mfas, {Pn,Pus}, Fd, Opts), ok end, gb_trees:to_list(Ps)), @@ -415,15 +415,15 @@ sort_mfa(Bpfs, mfa) when is_list(Bpfs) -> end, Bpfs); sort_mfa(Bpfs, time) when is_list(Bpfs) -> lists:sort(fun - ({_,{A,_}}, {_,{B,_}}) when A < B -> true; + ({_,{_,A}}, {_,{_,B}}) when A < B -> true; (_, _) -> false end, Bpfs); sort_mfa(Bpfs, calls) when is_list(Bpfs) -> lists:sort(fun - ({_,{_,A}}, {_,{_,B}}) when A < B -> true; + ({_,{A,_}}, {_,{B,_}}) when A < B -> true; (_, _) -> false end, Bpfs); -sort_mfa(Bpfs, _) when is_list(Bpfs) -> sort_mfa(Bpfs, calls). +sort_mfa(Bpfs, _) when is_list(Bpfs) -> sort_mfa(Bpfs, time). filter_mfa(Bpfs, Ts) when is_list(Ts) -> filter_mfa(Bpfs, [], proplists:get_value(calls, Ts, 0), proplists:get_value(time, Ts, 0)); @@ -443,8 +443,8 @@ string_bp_mfa([{Mfa, {Count, Time}}|Mfas], Tus, {MfaW, CountW, PercW, TimeW, TpC Smfa = s(Mfa), Scount = s(Count), Stime = s(Time), - Sperc = s("~.2f", [100*(Time/Tus)]), - Stpc = s("~.2f", [Time/Count]), + Sperc = s("~.2f", [100*divide(Time,Tus)]), + Stpc = s("~.2f", [divide(Time,Count)]), string_bp_mfa(Mfas, Tus, { erlang:max(MfaW, length(Smfa)), @@ -484,3 +484,6 @@ format(Fd, Format, Strings) -> io:format(Fd, Format, Strings), io:format(Format, Strings), ok. + +divide(_,0) -> 0.0; +divide(T,N) -> T/N. diff --git a/lib/wx/Makefile b/lib/wx/Makefile index 83f545b662..0bc89e08ad 100644 --- a/lib/wx/Makefile +++ b/lib/wx/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2009. All Rights Reserved. +# Copyright Ericsson AB 2008-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 @@ -23,7 +23,7 @@ SUBDIRS = src ifeq ($(CAN_BUILD_DRIVER), true) SUBDIRS += c_src endif -SUBDIRS += examples demos doc/src +SUBDIRS += examples doc/src CLEANDIRS = $(SUBDIRS) api_gen ifeq ($(INSIDE_ERLSRC),true) diff --git a/lib/wx/api_gen/Makefile b/lib/wx/api_gen/Makefile index c6b65b60bc..756ec598ce 100644 --- a/lib/wx/api_gen/Makefile +++ b/lib/wx/api_gen/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2008-2009. All Rights Reserved. +# Copyright Ericsson AB 2008-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 @@ -39,14 +39,14 @@ TARGET_CDIR = ../c_src/gen C_TARGETS = wxe_funcs.cpp GL_C_TARGETS = gl_funcs.cpp -WX = $(TARGET_CDIR)/$(C_TARGETS) +WX = wx_code_generated -GL = $(TARGET_CDIR)/$(GL_C_TARGETS) +GL = gl_code_generated opt: $(WX) $(GL) $(WX): wxxml_generated $(COMPILER_T) wxapi.conf $(wildcard wx_extra/wx*.c_src) $(wildcard wx_extra/wx*.erl) - erl -noshell -run wx_gen code + erl -noshell -run wx_gen code && touch wx_code_generated wxxml_generated: wx_doxygen.conf wx_extra/bugs.h wx_extra/wxe_evth.h sed -e 's|@WXGTK_DIR@|$(WXGTK_DIR)|g' wx_doxygen.conf > wx_doxygen @@ -56,9 +56,8 @@ glxml_generated: gl_doxygen.conf sed -e 's|@GL_DIR@|$(GL_DIR)|g' gl_doxygen.conf > gl_doxygen doxygen gl_doxygen && touch glxml_generated - $(GL): glxml_generated $(GL_COMP_T) glapi.conf - erl -noshell -run gl_gen code + erl -noshell -run gl_gen code && touch gl_code_generated %.beam: %.erl wx_gen.hrl gl_gen.hrl $(ERLC) -W $(ERL_FLAGS) $(ERL_COMPILE_FLAGS) $< -o$(EBIN) @@ -66,7 +65,7 @@ $(GL): glxml_generated $(GL_COMP_T) glapi.conf # TODO split cleans into separate targets? complete_clean: rm -f gl_doxygen wx_doxygen wx_xml/*.x* gl_xml/*.x* - rm -f glxml_generated wxxml_generated + rm -f *_generated $(MAKE) clean clean: rm -f *~ diff --git a/lib/wx/api_gen/gen_util.erl b/lib/wx/api_gen/gen_util.erl index 859317bdef..b53f817ce0 100644 --- a/lib/wx/api_gen/gen_util.erl +++ b/lib/wx/api_gen/gen_util.erl @@ -40,6 +40,10 @@ strip_name([H|R1],[H|R2]) -> strip_name(R1,R2); strip_name(String,[]) -> String. + +get_hook(_Type, undefined) -> ignore; +get_hook(Type, List) -> proplists:get_value(Type, List, ignore). + open_write(File) -> %% io:format("Generating ~s~n",[File]), {ok, Fd} = file:open(File++".temp", [write]), @@ -58,10 +62,10 @@ close() -> [] -> ok = file:delete(File ++ ".temp"), %% So that make understands that we have made this - case os:getenv("CLEARCASE_ROOT") of - false -> os:cmd("touch " ++ File); - _ -> ignore - end, + %% case os:getenv("CLEARCASE_ROOT") of + %% false -> os:cmd("touch " ++ File); + %% _ -> ignore + %% end, ok; Diff -> case check_diff(Diff) of diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl index 42802c6de7..374e0bd12b 100644 --- a/lib/wx/api_gen/gl_gen.erl +++ b/lib/wx/api_gen/gl_gen.erl @@ -67,7 +67,7 @@ gen_code() -> gl_gen_erl:gl_defines(GLDefines), gl_gen_erl:gl_api(GLFuncs), - gl_gen_erl:gen_debug(GLFuncs,GLUFuncs), + %%gl_gen_erl:gen_debug(GLFuncs,GLUFuncs), gl_gen_c:gen(GLFuncs,GLUFuncs), ok. @@ -206,10 +206,10 @@ parse_define([], D, _Opts) -> parse_func(Xml, Opts) -> {Func,_} = foldl(fun(X,Acc) -> parse_func(X,Acc,Opts) end, {#func{},1}, Xml), + put(current_func, Func#func.name), #func{params=Args0,type=Type0} = Func, Args = filter(fun(#arg{type=void}) -> false; (_) -> true end, Args0), - #arg{type=Type} = - patch_param(Func#func.name,#arg{name="result",type=Type0},Opts), + #arg{type=Type} = patch_param(Func#func.name,#arg{name="result",type=Type0},Opts), Func#func{params=reverse(Args), type=Type}. parse_func(#xmlElement{name=type, content=C}, {F,AC}, Os) -> @@ -220,6 +220,7 @@ parse_func(#xmlElement{name=name, content=[#xmlText{value=C}]},{F,AC},Os) -> put(current_func, Func), {F#func{name=name(Func,Os)},AC}; parse_func(#xmlElement{name=param, content=C},{F,AC},Os) -> + put(current_func, F#func.name), Parse = fun(Con, Ac) -> parse_param(Con, Ac, Os) end, Param0 = foldl(Parse, #arg{}, drop_empty(C)), Param = fix_param_name(Param0, F, AC), @@ -314,11 +315,17 @@ handle_arg_opt(both, P) -> P#arg{in=both}; handle_arg_opt(binary, P=#arg{type=T}) -> P#arg{type=T#type{size=undefined,base=binary}}; handle_arg_opt({binary,Sz}, P=#arg{type=T}) -> - P#arg{type=T#type{size=Sz,base=binary}}; + P#arg{type=T#type{size={Sz, Sz},base=binary}}; +handle_arg_opt({binary,Max, Sz}, P=#arg{type=T}) -> + P#arg{type=T#type{size={Max, Sz},base=binary}}; handle_arg_opt({type,Type}, P=#arg{type=T}) -> P#arg{type=T#type{name=Type}}; handle_arg_opt({single,Opt},P=#arg{type=T}) -> P#arg{type=T#type{single=Opt}}; +handle_arg_opt({base,{Opt, Sz}}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt, size=Sz}}; handle_arg_opt({base,Opt}, P=#arg{type=T}) -> P#arg{type=T#type{base=Opt}}; -handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt}. +handle_arg_opt({c_only,Opt},P) -> P#arg{where=c, alt=Opt}; +handle_arg_opt(string, P=#arg{type=T}) -> P#arg{type=T#type{base=string}}; +handle_arg_opt({string,Max,Sz}, P=#arg{type=T}) -> + P#arg{type=T#type{base=string, size={Max,Sz}}}. parse_type([], _Os) -> void; parse_type(C, Os) -> @@ -367,6 +374,8 @@ parse_type2([N="GLbitfield"|R],T,Opts) -> parse_type2(R,T#type{name=N, size=4, base=int},Opts); parse_type2([N="GLvoid"|R],T,Opts) -> parse_type2(R,T#type{name=N, base=idx_binary},Opts); +parse_type2([N="GLsync"|R],T,Opts) -> + parse_type2(R,T#type{name=N, base=int, size=8},Opts); parse_type2([N="GLbyte"|R],T,Opts) -> parse_type2(R,T#type{name=N, size=1, base=int},Opts); @@ -378,6 +387,11 @@ parse_type2([N="GLushort"|R],T,Opts) -> parse_type2(R,T#type{name=N, size=2, base=int},Opts); parse_type2([N="GLint"|R],T,Opts) -> parse_type2(R,T#type{name=N, size=4, base=int},Opts); +parse_type2([N="GLint64"|R],T,Opts) -> + parse_type2(R,T#type{name=N, size=8, base=int},Opts); +parse_type2([N="GLuint64"|R],T,Opts) -> + parse_type2(R,T#type{name=N, size=8, base=int},Opts); + parse_type2([N="GLuint"|R],T,Opts) -> parse_type2(R,T#type{name=N, size=4, base=int},Opts); parse_type2([N="GLsizei"|R],T,Opts) -> @@ -548,8 +562,10 @@ setup_idx_binary(Name,Ext,_Opts) -> %% Ok warn if single is undefined lists:foreach(fun(#arg{type=#type{base=memory}}) -> ok; + (#arg{type=#type{base=string}}) -> ok; (#arg{type=#type{base=idx_binary}}) -> ok; (#arg{type=#type{name="GLUquadric"}}) -> ok; + (#arg{type=#type{base=binary, size=Sz}}) when Sz =/= undefined -> ok; (A=#arg{type=#type{single=undefined}}) -> ?warning("~p Unknown size of~n ~p~n", [get(current_func),A]), diff --git a/lib/wx/api_gen/gl_gen_c.erl b/lib/wx/api_gen/gl_gen_c.erl index 3293050ab9..0f5cb0e1f4 100644 --- a/lib/wx/api_gen/gl_gen_c.erl +++ b/lib/wx/api_gen/gl_gen_c.erl @@ -47,34 +47,29 @@ gen(GLFuncs, GLUFuncs) -> w("/***** This file is generated do not edit ****/~n~n", []), w("#include <stdio.h>~n", []), w("#include <string.h>~n", []), - w("#include \"../wxe_impl.h\"~n", []), - w("#include \"../wxe_gl.h\"~n", []), - w("#include \"gl_fdefs.h\"~n", []), + w("#include \"../egl_impl.h\"~n", []), + w("#include \"gl_fdefs.h\"~n~n", []), + w("extern gl_fns_t gl_fns[];~n~n", []), - w("~nint gl_error_op;~n", []), - w("void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){~n", + w("void egl_dispatch(int op, char *bp, ErlDrvPort port, " + "ErlDrvTermData caller, char *bins[], int bins_sz[]){~n", []), - w(" gl_error_op = op;~n", []), - w(" if(caller != gl_active) {~n", []), - w(" wxGLCanvas * current = glc[caller];~n", []), - w(" if(current) { gl_active = caller; current->SetCurrent();}~n", []), - w(" else {~n " - " ErlDrvTermData rt[] = // Error msg~n" - " {ERL_DRV_ATOM, driver_mk_atom((char *) \"_wxe_error_\"),~n" - " ERL_DRV_INT, op,~n" - " ERL_DRV_ATOM, driver_mk_atom((char *) \"no_gl_context\"),~n" - " ERL_DRV_TUPLE,3};~n" - " driver_send_term(WXE_DRV_PORT,caller,rt,8);~n" - " return ;~n }~n };~n~n", []), - + w(" try {~n",[]), w(" switch(op)~n{~n",[]), - w(" case 5000:~n wxe_tess_impl(bp, caller);~n break;~n", []), - w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(bins[0]->bin);~n break;~n",[]), - w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(bins[0]->bin);~n break;~n",[]), + w(" case 5000:~n erl_tess_impl(bp, port, caller);~n break;~n", []), [funcs(F) || F <- GLUFuncs], [funcs(F) || F <- GLFuncs], + w("}} catch (char *err_msg) {\n" + "int AP = 0; ErlDrvTermData rt[12];\n" + "rt[AP++] = ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_egl_error_\");\n" + "rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) op;\n" + "rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) err_msg);\n" + "// rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) gl_fns[op-GLE_GL_FUNC_START].name);\n" + "// rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;\n" + "rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3;\n" + "driver_send_term(port,caller,rt,AP);\n", []), w("}} /* The End */~n~n",[]), close(). @@ -123,25 +118,53 @@ declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={tuple,Sz}}}) true = is_number(Sz), %% Assert w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]), A; -declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}}) when is_number(Sz) -> +declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=B,single={list,Sz}}}) + when is_number(Sz) -> w(" ~s ~s[~p] = {~s};~n", [T,N,Sz,args(fun zero/1,",",lists:duplicate(Sz,B))]), A; +declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=string,size={Max,_}, single=Single}}) -> + case is_integer(Max) of + true -> + w(" ~s ~s[~p];~n", [T,N,Max]); + false -> + %% w(" ~s ~s[*~s];~n", [T,N,Max]), + w(" ~s *~s;~n", [T,N]), + w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,Max]), + store_free(N) + %% case Single of + %% {list, _, _} -> + %% w(" ~s *~s_p = ~s;~n", [T,N,N]); + %% _ -> ok + %% end + end, + A; +declare_var(A=#arg{name=N,in=false,type=#type{base=binary,size={MaxSz, _}}}) -> + MaxSz == undefined andalso error({assert, A}), + case is_integer(MaxSz) of + true -> + w(" ErlDrvBinary *~s = driver_alloc_binary(~p);~n", [N,MaxSz]); + false -> + w(" ErlDrvBinary *~s = driver_alloc_binary(*~s);~n", [N,MaxSz]) + end, + A; declare_var(A=#arg{name=N,in=false,type=#type{name=T,single={list,ASz,_USz},mod=[]}}) -> true = is_list(ASz), %% Assert w(" ~s *~s;~n", [T,N]), w(" ~s = (~s *) driver_alloc(sizeof(~s) * *~s);~n", [N,T,T,ASz]), store_free(N), - A; -declare_var(A=#arg{name=N,in=false,type=#type{name=T,base=binary,size=Sz}}) -> - true = is_number(Sz), %% Assert - w(" ~s ~s[~p];~n", [T,N,Sz]), + %% w(" ~s ~s[*~s];~n", [T,N,ASz]), A; declare_var(A=#arg{in=false, type=#type{name="GLUquadric",by_val=false,single=true}}) -> A; +declare_var(A=#arg{in=false, type=#type{base=string,by_val=false,single=true}}) -> + A; declare_var(A=#arg{name=N,in=false, type=#type{name=T,base=B,by_val=false,single=true}}) -> w(" ~s ~s[1] = {~s};~n", [T,N,zero(B)]), A; +declare_var(A=#arg{where=c, type=#type{name=T}, alt={size,Var}}) -> + w(" ~s ~s_size = bins_sz[~p];~n", [T, Var, get(bin_count)]), + A; declare_var(A=#arg{where=_}) -> A. @@ -171,10 +194,10 @@ decode_arg(P=#arg{where=c},A) -> {P,A}; decode_arg(P=#arg{in=false},A) -> {P,A}; decode_arg(P=#arg{name=Name,type=#type{name=Type,base=binary}},A0) -> - w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]), + w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]), {P, A0}; decode_arg(P=#arg{name=Name,type=#type{name=Type,base=memory}},A0) -> - w(" ~s *~s = (~s *) bins[~p]->base;~n", [Type,Name,Type,next_id(bin_count)]), + w(" ~s *~s = (~s *) bins[~p];~n", [Type,Name,Type,next_id(bin_count)]), {P, A0}; decode_arg(P=#arg{name=Name,type=#type{name=T,base=string,single=list}},A0) -> A = align(4,A0), @@ -219,7 +242,7 @@ decode_arg(P=#arg{name=Name,type=#type{name=Type,base=guard_int}},A0) -> {P, A}; decode_arg(P=#arg{name=Name,type=#type{name=Type,base=string,single=true}},A0) -> w(" ~s *~s = (~s *) bp;~n", [Type,Name,Type]), - w(" int ~sLen = strlen((char *)~s); bp += ~sLen+1+((8-((1+~sLen+~p)%8))%8);~n", + w(" int ~sLen[1] = {strlen((char *)~s)}; bp += ~sLen[0]+1+((8-((1+~sLen[0]+~p)%8))%8);~n", [Name,Name,Name,Name,A0]), {P, 0}; decode_arg(P=#arg{name=Name, @@ -288,6 +311,8 @@ result_type(#type{name=T, ref=undefined}) -> T; result_type(#type{name=T, ref={pointer,1}, mod=Mods}) -> mod(Mods) ++ T ++ " * ". +call_arg(#arg{alt={size,Alt},type=#type{}}) -> + Alt ++ "_size"; call_arg(#arg{alt={length,Alt},type=#type{}}) -> "*" ++ Alt ++ "Len"; call_arg(#arg{alt={constant,Alt},type=#type{}}) -> @@ -298,6 +323,8 @@ call_arg(#arg{name=Name,type=#type{single={list, _}}}) -> Name; call_arg(#arg{name=Name,type=#type{size=8,base=int,ref=undefined}}) -> Name; +call_arg(#arg{name=Name,in=false,type=#type{name=T, base=binary}}) -> + "(" ++ T ++ "*) " ++ Name ++ "->orig_bytes"; call_arg(#arg{name=Name,type=#type{ref=undefined}}) -> "*" ++ Name; call_arg(#arg{name=Name,type=#type{base=guard_int}}) -> @@ -318,27 +345,27 @@ build_return_vals(Type,As) -> true -> w(" int AP = 0; ErlDrvTermData rt[6];~n",[]), w(" rt[AP++]=ERL_DRV_ATOM;" - " rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]), + " rt[AP++]=driver_mk_atom((char *) \"_egl_result_\");~n",[]), w(" rt[AP++]=ERL_DRV_ATOM;" " rt[AP++]=driver_mk_atom((char *) \"ok\");~n",[]), w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]), - w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]), + w(" driver_send_term(port,caller,rt,AP);~n",[]), ok end; {Val,Vars,Cnt} -> ExtraTuple = if Cnt > 1 -> 2; true -> 0 end, - CSize = if Vars =:= none -> - Sz = integer_to_list(Val+4+ExtraTuple), - w(" int AP = 0; ErlDrvTermData rt[~s];~n",[Sz]), - Sz; - true -> - Sz = integer_to_list(Val+4+ExtraTuple) ++ " + " ++ Vars, - w(" int AP = 0; ErlDrvTermData *rt;~n",[]), - w(" rt = (ErlDrvTermData *) " - "driver_alloc(sizeof(ErlDrvTermData)*(~s));~n", [Sz]), - Sz - end, - w(" rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_wxe_result_\");~n",[]), + if Vars =:= none -> + Sz = integer_to_list(Val+4+ExtraTuple), + w(" int AP = 0; ErlDrvTermData rt[~s];~n",[Sz]), + Sz; + true -> + Sz = integer_to_list(Val+4+ExtraTuple) ++ " + " ++ Vars, + w(" int AP = 0; ErlDrvTermData *rt;~n",[]), + w(" rt = (ErlDrvTermData *) " + "driver_alloc(sizeof(ErlDrvTermData)*(~s));~n", [Sz]), + Sz + end, + w(" rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) \"_egl_result_\");~n",[]), FreeList = build_ret_types(Type,As), case Cnt of 1 -> ok; @@ -346,9 +373,9 @@ build_return_vals(Type,As) -> w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Cnt]) end, w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2;~n",[]), - w(" if (AP != ~s ) fprintf(stderr, \"%d: ERROR AP mismatch %d %d\\r\\n\",__LINE__,AP,~s);~n", - [CSize,CSize]), - w(" driver_send_term(WXE_DRV_PORT,caller,rt,AP);~n",[]), + %%w(" if (AP != ~s ) fprintf(stderr, \"%d: ERROR AP mismatch %d %d\\r\\n\",__LINE__,AP,~s);~n", + %% [CSize,CSize]), + w(" driver_send_term(port,caller,rt,AP);~n",[]), case Vars of none -> ignore; _ -> @@ -371,7 +398,7 @@ calc_sizes(Type,As) -> {Val, none} -> {Sz+Val, Vars, Cnt+1}; {Val, Var} when Vars =:= none -> {Sz+Val, Var,Cnt+1}; - {Val, Var} when Vars =:= none -> + {Val, Var} -> {Sz+Val, Var ++ " + " ++ Vars,Cnt+1} end; (_,Acc) -> Acc @@ -379,13 +406,16 @@ calc_sizes(Type,As) -> foldl(Calc, TSz, As). return_size(_N,void) -> {0, none}; -return_size(_N,#type{base=binary}) -> {4, none}; -return_size(_N,#type{single=true}) -> {2,none}; return_size(_N,#type{single={tuple,Sz}}) -> {Sz*2+2, none}; -return_size(_N,#type{name="GLubyte",single={list,null}}) ->{3, none}; return_size(_N,#type{single={list,Sz}}) -> {Sz*2+3, none}; -return_size(_N,#type{base=string,single={list,_,_}}) -> {3, none}; -return_size(_N,#type{single={list,_,Sz}}) -> {3, "(*" ++Sz++")*2"}. +return_size(_N,#type{base=string,single=true}) -> {3, none}; +return_size(_N,#type{base=string,single=undefined}) -> {3, none}; +return_size(_N,#type{base=string,single={list,_,"result"}}) -> {3, "result*3"}; +return_size(_N,#type{base=string,single={list,_,Sz}}) -> {3, "(*" ++Sz++")*3"}; +return_size(_N,#type{single={list,_,"result"}}) -> {3, "result*2"}; +return_size(_N,#type{single={list,_,Sz}}) -> {3, "(*" ++Sz++")*2"}; +return_size(_N,#type{base=binary}) -> {4, none}; +return_size(_N,#type{single=true}) -> {2, none}. build_ret_types(void,Ps) -> @@ -444,17 +474,27 @@ build_ret(Name,_Q,#type{name=T,base=_,single={tuple,Sz}}) -> [w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *~s++;~n", [Temp]) || _ <- lists:seq(1,Sz)], w(" rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = ~p;~n",[Sz]); -build_ret(Name,_Q,#type{name="GLubyte",single={list,null}}) -> +build_ret(Name,_Q,#type{base=string,size=1,single=true}) -> w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;" " rt[AP++] = strlen((char *) ~s);\n", [Name, Name]); -build_ret(Name,_Q,#type{base=string,single={list,_,Sz}}) -> +build_ret(Name,_Q,#type{base=string, size={_Max,Sz}, single=S}) + when S == true; S == undefined -> w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;" " rt[AP++] = *~s;\n", [Name, Sz]); +build_ret(Name,_Q,#type{name=_T,base=string,size={_, SSz}, single={list,_,Sz}}) -> + P = if Sz == "result" -> ["(int) "]; true -> "*" end, + w(" for(int i=0; i < ~s~s; i++) {\n", [P,Sz]), + w(" rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) ~s;" + " rt[AP++] = ~s[i]-1;\n", [Name, SSz]), + w(" ~s += ~s[i]; }~n", [Name, SSz]), + w(" rt[AP++] = ERL_DRV_NIL;", []), + w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (~s~s)+1;~n",[P,Sz]); build_ret(Name,_Q,#type{name=_T,base=B,single={list,_,Sz}}) when B =/= float -> - w(" for(int i=0; i < *~s; i++) {\n", [Sz]), + P = if Sz == "result" -> ["(int) "]; true -> "*" end, + w(" for(int i=0; i < ~s~s; i++) {\n", [P,Sz]), w(" rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ~s[i];}~n", [Name]), w(" rt[AP++] = ERL_DRV_NIL;", []), - w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*~s)+1;~n",[Sz]); + w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = (~s~s)+1;~n",[P,Sz]); build_ret(Name,_Q,#type{name=_T,size=FSz,base=float,single={list,Sz}}) -> Temp = Name ++ "Tmp", case FSz of @@ -475,12 +515,14 @@ build_ret(Name,_Q,#type{name=T,base=_,single={list,Sz}}) -> || _ <- lists:seq(1,Sz)], w(" rt[AP++] = ERL_DRV_NIL;", []), w(" rt[AP++] = ERL_DRV_LIST; rt[AP++] = ~p+1;~n",[Sz]); -build_ret(Name,_Q,#type{name="GLubyte",base=binary,size=Sz}) -> - w(" ErlDrvBinary * BinCopy = driver_alloc_binary(~p);~n", [Sz]), - w(" memcpy(BinCopy->orig_bytes, ~s, ~p);~n", [Name,Sz]), - w(" rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) BinCopy;", []), - w(" rt[AP++] = ~p; rt[AP++] = 0;~n", [Sz]), - "driver_free_binary(BinCopy);"; +build_ret(Name,_Q,#type{base=binary,size={_,Sz}}) -> + w(" rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) ~s;", [Name]), + if is_integer(Sz) -> + w(" rt[AP++] = ~p; rt[AP++] = 0;~n", [Sz]); + is_list(Sz) -> + w(" rt[AP++] = *~s; rt[AP++] = 0;~n", [Sz]) + end, + "driver_free_binary(" ++ Name ++ ");"; build_ret(Name,_Q,T=#type{}) -> io:format("{~p, {~p, {single,{tuple,X}}}}.~n", [get(current_func),Name]), io:format(" ~p~n",[T]). @@ -496,6 +538,19 @@ gen_defines(GLFuncs,GLUFuncs) -> w("# define WXE_EXTERN~n", []), w("#else~n# define WXE_EXTERN extern~n", []), w("#endif~n~n", []), + + w("typedef struct {\n" + " const char * name;\n" + " const char * alt;\n" + " void * func;\n" + "} gl_fns_t;\n\n", []), + + GLFirst = case hd(GLFuncs) of + [First|_] when is_list(First) -> get(First); + First -> get(First) + end, + w("#define GLE_GL_FUNC_START ~p~n", [GLFirst#func.id]), + [fdefs(F) || F <- GLFuncs], [fdefs(F) || F <- GLUFuncs], close(). @@ -543,11 +598,7 @@ gl_gen_init(Funcs) -> open_write("../c_src/gen/gl_finit.h"), c_copyright(), w("/***** This file is generated do not edit ****/~n~n", []), - w("static struct {\n" - " const char * name;\n" - " const char * alt;\n" - " void * func;\n" - "} gl_fns[] = \n" + w("gl_fns_t gl_fns[] = \n" "{\n", []), [finits(F) || F <- Funcs], w(" { NULL, NULL, NULL}};\n",[]), diff --git a/lib/wx/api_gen/gl_gen_erl.erl b/lib/wx/api_gen/gl_gen_erl.erl index ce35484561..f292c8723e 100644 --- a/lib/wx/api_gen/gl_gen_erl.erl +++ b/lib/wx/api_gen/gl_gen_erl.erl @@ -49,7 +49,7 @@ glu_defines(Defs) -> w("~n%% GLU DEFINITIONS~n~n", []), w("%% This file is generated DO NOT EDIT~n~n", []), [gen_define(Def) || Def=#def{} <- Defs], - close(), + close(), ok. gen_define(#def{name=N, val=Val, type=int}) -> @@ -78,7 +78,11 @@ types() -> {"GLsizeiptr","64/native-unsigned"}, % 64 bits int, convert on c-side {"GLintptr", "64/native-unsigned"}, % 64 bits int, convert on c-sidew {"GLUquadric", "64/native-unsigned"},% Handle 32bits aargh 64bits on mac64 - {"GLhandleARB","64/native-unsigned"} % Handle 32bits aargh 64bits on mac64 + {"GLhandleARB","64/native-unsigned"},% Handle 32bits aargh 64bits on mac64 + + {"GLsync", "64/native-unsigned"}, % Pointer to record + {"GLuint64", "64/native-unsigned"}, + {"GLint64", "64/native-signed"} ]. gl_api(Fs) -> @@ -90,22 +94,53 @@ gl_api(Fs) -> w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]), w("%%~n", []), w("%% Booleans are represented by integers 0 and 1.~n~n", []), - w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []), + w("%% @type mem(). memory block~n", []), w("%% @type enum(). An integer defined in gl.hrl~n", []), w("%% @type offset(). An integer which is an offset in an array~n", []), w("%% @type clamp(). A float clamped between 0.0 - 1.0~n", []), w("-module(gl).~n~n",[]), w("-compile(inline).~n", []), - %% w("-compile(export_all).~n~n", []), - %% w("-compile(binary_comprehension).~n~n", []), - w("-include(\"wxe.hrl\").~n", []), +%% w("-include(\"wxe.hrl\").~n", []), [w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()], - + + gen_types(gl), + Exp = fun(F) -> gen_export(F) end, ExportList = lists:map(Exp,Fs), w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]), - + w("-export([call/2, cast/2, send_bin/1]).~n",[]), + w("%% @hidden~n", []), + w("call(Op, Args) ->~n", []), + w(" Port = get(opengl_port), ~n", []), + w(" _ = erlang:port_control(Port,Op,Args),~n", []), + w(" rec().~n", []), + w(" ~n", []), + w("%% @hidden~n", []), + w("cast(Op, Args) ->~n", []), + w(" Port = get(opengl_port), ~n", []), + w(" _ = erlang:port_control(Port,Op,Args),~n", []), + w(" ok.~n", []), + w(" ~n", []), + w("%% @hidden~n", []), + w("rec() ->~n", []), + w(" receive ~n", []), + w(" {'_egl_result_', Res} -> Res;~n", []), + w(" {'_egl_error_', Op, Res} -> error({error,Res,Op})~n", []), + w(" end. ~n", []), + w("~n", []), + w("%% @hidden~n", []), + w("send_bin(Bin) when is_binary(Bin) ->~n", []), + w(" Port = get(opengl_port), ~n", []), + w(" erlang:port_command(Port,Bin);~n", []), + w("send_bin(Tuple) when is_tuple(Tuple) ->~n", []), + w(" Port = get(opengl_port), ~n", []), + w(" case element(2, Tuple) of~n", []), + w(" Bin when is_binary(Bin) ->~n", []), + w(" erlang:port_command(Port,Bin)~n", []), + w(" end.~n", []), + w("~n", []), + w("~n%% API~n~n", []), [gen_funcs(F) || F <- Fs], close(), @@ -120,20 +155,22 @@ glu_api(Fs) -> w("%% See <a href=\"http://www.opengl.org/sdk/docs/man/\">www.opengl.org</a>~n",[]), w("%%~n", []), w("%% Booleans are represented by integers 0 and 1.~n~n", []), - w("%% @type wx_mem(). see wx.erl on memory allocation functions~n", []), + w("%% @type mem(). memory block~n", []), w("%% @type enum(). An integer defined in gl.hrl~n", []), w("%% @type offset(). An integer which is an offset in an array~n", []), w("%% @type clamp(). A float clamped between 0.0 - 1.0~n~n", []), w("-module(glu).~n",[]), w("-compile(inline).~n", []), - w("-include(\"wxe.hrl\").~n", []), + %%w("-include(\"wxe.hrl\").~n", []), [w("-define(~s,~s).~n", [GL,Erl]) || {GL,Erl} <- types()], + gen_types(glu), + Exp = fun(F) -> gen_export(F) end, ExportList = ["tesselate/2" | lists:map(Exp,Fs)], w("~n-export([~s]).~n~n", [args(fun(EF) -> EF end, ",", ExportList, 60)]), - + w("-import(gl, [call/2,cast/2,send_bin/1]).", []), w("~n%% API~n~n", []), w("%% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos}~n",[]), @@ -148,13 +185,13 @@ glu_api(Fs) -> "%% may contain newly created vertices in the end.~n", []), w("tesselate({Nx,Ny,Nz}, Vs) ->~n",[]), - w(" wxe_util:call(5000, <<(length(Vs)):32/native,0:32,~n" + w(" call(5000, <<(length(Vs)):32/native,0:32,~n" " Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble,~n" " (<< <<Vx:?GLdouble,Vy:?GLdouble,Vz:?GLdouble >>~n" " || {Vx,Vy,Vz} <- Vs>>)/binary >>).~n~n", []), [gen_funcs(F) || F <- Fs], - close(), + close(), ok. gen_funcs([F]) when is_list(F) -> @@ -178,6 +215,17 @@ gen_funcs(F) -> erase(current_func), w(".~n~n",[]). +gen_types(Where) -> + case Where of + glu -> ignore; + gl -> + w("-type clamp() :: float().~n", []), + w("-type offset() :: non_neg_integer().~n", []) + end, + w("-type enum() :: non_neg_integer().~n", []), + w("-type mem() :: binary() | tuple().~n", []), + ok. + gen_export(F) -> try gen_export_1(F) catch E:R -> @@ -199,19 +247,27 @@ gen_export2(#func{name=Name,params=As0}) -> Args = lists:filter(fun(Arg) -> func_arg(Arg) =/= skip end, As0), erl_func_name(Name) ++ "/" ++ integer_to_list(length(Args)). - -gen_doc([#func{alt={vector,VecPos,Vec}}]) -> +gen_doc([#func{name=Name, alt={vector,VecPos,Vec}}]) -> #func{type=T,params=As} = get(Vec), {As1,As2} = lists:split(VecPos, As), Args1 = case args(fun func_arg/1, ",", As1) of [] -> []; Else -> Else++"," end, Args2 = args(fun func_arg/1, ",", As2), - w("%% @spec (~s{~s}) -> ~s~n",[Args1,Args2,doc_return_types(T,As)]), - w("%% @equiv ~s(~s)~n",[erl_func_name(Vec), Args1++Args2]); + w("%% @spec (~s{~s}) -> ~s~n",[Args1,Args2,doc_return_types(T,As, doc)]), + w("%% @equiv ~s(~s)~n",[erl_func_name(Vec), Args1++Args2]), + SA1 = case doc_arg_types(As1, spec) of [] -> []; E -> E++"," end, + SA2 = doc_arg_types(As2, spec), + w("-spec ~s(~s{~s}) -> ~s.~n", + [erl_func_name(Name), SA1, SA2, + doc_return_types(T,As, spec)]); + gen_doc([#func{name=Name,type=T,params=As,alt=Alt}|_]) -> - w("%% @spec (~s) -> ~s~n", [doc_arg_types(As),doc_return_types(T,As)]), + w("%% @spec (~s) -> ~s~n", [doc_arg_types(As, doc),doc_return_types(T,As, doc)]), GLDoc = "http://www.opengl.org/sdk/docs/man/xhtml/", w("%% @doc See <a href=\"~s~s.xml\">external</a> documentation.~n", - [GLDoc, doc_name(Name,Alt)]). + [GLDoc, doc_name(Name,Alt)]), + w("-spec ~s(~s) -> ~s.~n", + [erl_func_name(Name), doc_arg_types(As, spec), doc_return_types(T,As, spec)]). + gen_func(#func{name=Name,alt={vector,VecPos,Vec}}) -> #func{params=As} = get(Vec), @@ -229,9 +285,9 @@ gen_func(_F=#func{name=Name,type=T,params=As,id=MId}) -> {StrArgs,_} = marshal_args(PreAs), case have_return_vals(T,As) of true -> - w(" wxe_util:call(~p, <<~s>>)", [MId, StrArgs]); + w(" call(~p, <<~s>>)", [MId, StrArgs]); false -> - w(" wxe_util:cast(~p, <<~s>>)", [MId, StrArgs]) + w(" cast(~p, <<~s>>)", [MId, StrArgs]) end. func_arg(#arg{in=In,where=W,name=Name,type=Type}) @@ -249,60 +305,65 @@ func_arg(#arg{in=In,where=W,name=Name,type=Type}) end; func_arg(_) -> skip. -doc_arg_types(Ps0) -> +doc_arg_types(Ps0, Type) -> Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= false, Where =/= c], - args(fun doc_arg_type/1, ",", Ps). + args(fun(Arg) -> doc_arg_type(Arg, Type) end, ",", Ps). -doc_return_types(T, Ps0) -> +doc_return_types(T, Ps0, Type) -> Ps = [P || P=#arg{in=In, where=Where} <- Ps0,In =/= true, Where =/= c], - doc_return_types2(T, Ps). - -doc_return_types2(void, []) -> "ok"; -doc_return_types2(void, [#arg{type=T}]) -> doc_arg_type2(T); -doc_return_types2(T, []) -> doc_arg_type2(T); -doc_return_types2(void, Ps) -> - "{" ++ args(fun doc_arg_type/1,",",Ps) ++ "}"; -doc_return_types2(T, Ps) -> - "{" ++ doc_arg_type2(T) ++ "," ++ args(fun doc_arg_type/1,",",Ps) ++ "}". - -doc_arg_type(#arg{name=Name,type=T}) -> + doc_return_types2(T, Ps, Type). + +doc_return_types2(void, [], _) -> "ok"; +doc_return_types2(void, [#arg{type=T}], _) -> doc_arg_type2(T); +doc_return_types2(T, [], _) -> doc_arg_type2(T); +doc_return_types2(void, Ps, Type) -> + "{" ++ args(fun(Arg) -> doc_arg_type(Arg, Type) end,",",Ps) ++ "}"; +doc_return_types2(T, Ps, Type) -> + "{" ++ doc_arg_type2(T) ++ "," ++ + args(fun(Arg) -> doc_arg_type(Arg, Type) end,",",Ps) ++ "}". + +doc_arg_type(#arg{name=Name,type=T}, doc) -> try erl_arg_name(Name) ++ "::" ++ doc_arg_type2(T) catch _:Error -> io:format("Error: ~p ~p~n~p~n",[Name, Error, erlang:get_stacktrace()]), exit(error) + end; +doc_arg_type(#arg{name=Name,type=T}, spec) -> + try + doc_arg_type2(T) + catch _:Error -> + io:format("Error spec: ~p ~p~n~p~n",[Name, Error, erlang:get_stacktrace()]), + exit(error) end. + doc_arg_type2(T=#type{single=true}) -> doc_arg_type3(T); doc_arg_type2(T=#type{single=undefined}) -> doc_arg_type3(T); doc_arg_type2(T=#type{single={tuple,undefined}}) -> "{" ++ doc_arg_type3(T) ++ "}"; -doc_arg_type2(T=#type{single={tuple,_Sz}}) -> - "{" ++ doc_arg_type3(T) ++ "}"; +doc_arg_type2(T=#type{single={tuple,Sz}}) -> + "{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}"; doc_arg_type2(T=#type{single=list}) -> "[" ++ doc_arg_type3(T) ++ "]"; -doc_arg_type2(T=#type{single={list, Max}}) when is_integer(Max) -> +doc_arg_type2(T=#type{single={list, _Max}}) -> "[" ++ doc_arg_type3(T) ++ "]"; -doc_arg_type2(_T=#type{single={list,null}}) -> - "string()"; -doc_arg_type2(T=#type{base=string}) -> - doc_arg_type3(T); doc_arg_type2(T=#type{single={list,_,_}}) -> "[" ++ doc_arg_type3(T) ++ "]"; -doc_arg_type2(T=#type{single={tuple_list,_TSz}}) -> - "[{" ++ doc_arg_type3(T) ++ "}]". +doc_arg_type2(T=#type{single={tuple_list,Sz}}) -> + "[{" ++ args(fun doc_arg_type3/1, ",", lists:duplicate(Sz,T)) ++ "}]". doc_arg_type3(#type{name="GLenum"}) -> "enum()"; doc_arg_type3(#type{name="GLclamp"++_}) -> "clamp()"; doc_arg_type3(#type{base=int}) -> "integer()"; doc_arg_type3(#type{base=float}) -> "float()"; -doc_arg_type3(#type{base=guard_int}) -> "offset()|binary()"; +doc_arg_type3(#type{base=guard_int}) -> "offset()|mem()"; doc_arg_type3(#type{base=string}) -> "string()"; doc_arg_type3(#type{base=bool}) -> "0|1"; doc_arg_type3(#type{base=binary}) -> "binary()"; -doc_arg_type3(#type{base=memory}) -> "wx:wx_mem()". +doc_arg_type3(#type{base=memory}) -> "mem()". guard_test(As) -> Str = args(fun(#arg{name=N,type=#type{base=guard_int}}) -> @@ -316,10 +377,10 @@ guard_test(As) -> end. pre_marshal([#arg{name=N,in=true,type=#type{base=binary}}|R]) -> - w(" wxe_util:send_bin(~s),~n", [erl_arg_name(N)]), + w(" send_bin(~s),~n", [erl_arg_name(N)]), pre_marshal(R); pre_marshal([#arg{name=N,type=#type{base=memory}}|R]) -> - w(" wxe_util:send_bin(~s#wx_mem.bin),~n", [erl_arg_name(N)]), + w(" send_bin(~s),~n", [erl_arg_name(N)]), pre_marshal(R); pre_marshal([A=#arg{name=N,type=#type{base=string,single=list}}|R]) -> %% With null terminations @@ -595,6 +656,7 @@ gen_debug(GL, GLU) -> w("].~n~n", []), close(). + printd([F|R],Mod) when is_list(F) -> printd(F,Mod), printd(R,Mod); diff --git a/lib/wx/api_gen/glapi.conf b/lib/wx/api_gen/glapi.conf index f9ed7a1065..525ccf8b68 100644 --- a/lib/wx/api_gen/glapi.conf +++ b/lib/wx/api_gen/glapi.conf @@ -29,8 +29,35 @@ "glMatrixIndexPointerARB", "glPixelTransformParameter", %% OpengGL 3.0 - %"glGetTransformFeedbackVarying", %% Jobbiga - %"glTransformFeedbackVaryings", + + %% ARB + "glCreateSyncFromCLeventARB", % _cl_context _cl_event ?? + "glDebugMessageCallbackARB", + + "glGetn", %* + "glReadnPixels", %* + + "glVertexP2", %* + "glVertexP3", %* + "glVertexP4", %* + "glTexCoordP1", %* + "glTexCoordP2", %* + "glTexCoordP3", %* + "glTexCoordP4", %* + "glMultiTexCoordP1", %* + "glMultiTexCoordP2", %* + "glMultiTexCoordP3", %* + "glMultiTexCoordP4", %* + "glNormalP3", %* + "glColorP3", %* + "glColorP4", %* + "glSecondaryColorP3", %* + "glVertexAttribP1", %* + "glVertexAttribP2", %* + "glVertexAttribP3", %* + "glVertexAttribP4", %* + + "glGetActiveSubroutineUniformiv", %% Bad API don't know what to allocate needs to ask %% EXT %% By default skip these extensions @@ -136,11 +163,12 @@ {"glRect", [{"v1", {single,{tuple,2}}},{"v2", {single,{tuple,2}}}]}. -{"glGetString", {"result", {single,{list,null}}}}. +{"glGetString", {"result", string}}. {"glGetBooleanv", {"params", {single,{list,16}}}}. {"glGetDoublev", {"params", {single,{list,16}}}}. {"glGetFloatv", {"params", {single,{list,16}}}}. {"glGetIntegerv", {"params", {single,{list,16}}}}. +{"glGetInteger64v", {"params", {single,{list,16}}}}. {"glFeedbackBuffer", {"buffer", [{base,memory}, in]}}. {"glSelectBuffer", {"buffer", [{base,memory}, in]}}. @@ -174,24 +202,24 @@ {"glGetActiveAttribARB", [{"length",[skip,{single, true}]}, {"size", {single, true}}, {"type", {single, true}}, - {"name", {single, {list,"maxLength","length"}}} + {"name", {string,"maxLength","length"}} ]}. {"glGetActiveAttrib", [{"length",[skip,{single, true}]}, {"size", {single, true}}, {"type", {single, true}}, - {"name", {single, {list,"bufSize","length"}}} + {"name", {string,"bufSize","length"}} ]}. {"glGetActiveUniformARB", [{"length",[skip,{single, true}]}, {"size", {single, true}}, {"type", {single, true}}, - {"name", {single, {list,"maxLength","length"}}} + {"name", {string,"maxLength","length"}} ]}. {"glGetActiveUniform", [{"length",[skip,{single, true}]}, {"size", {single, true}}, {"type", {single, true}}, - {"name", {single, {list,"bufSize","length"}}} + {"name", {string,"bufSize","length"}} ]}. {"glGetAttachedShaders", [{"count", [skip,{single,true}]}, @@ -201,18 +229,18 @@ {"glGetProgramiv", {"params", {single,true}}}. {"glGetProgramInfoLog", [{"length", [skip,{single,true}]}, - {"infoLog", {single, {list,"bufSize","length"}}} + {"infoLog", {string,"bufSize","length"}} ]}. {"glGetShaderiv", {"params", {single,true}}}. {"glGetShaderInfoLog", [{"length", [skip,{single,true}]}, - {"infoLog", {single, {list,"bufSize","length"}}} + {"infoLog", {string,"bufSize","length"}} ]}. {"glGetShaderSourceARB", [{"length", [skip,{single,true}]}, - {"source", {single, {list,"maxLength","length"}}} + {"source", {string,"maxLength","length"}} ]}. {"glGetShaderSource", [{"length", [skip,{single,true}]}, - {"source", {single, {list,"bufSize","length"}}} + {"source", {string,"bufSize","length"}} ]}. @@ -239,7 +267,7 @@ {"glMatrixIndex", [{"size",{c_only,{length,"indices"}}}, {"indices", {single,list}}]}. -{"glProgramStringARB", [{"len",{c_only,{constant,"stringLen"}}}, +{"glProgramStringARB", [{"len",{c_only,{length,"string"}}}, {"string",[{base,string},{single,true}]}]}. {"glGetProgramStringARB", {"string", [in,{base,memory}]}}. {"glGenProgramsARB", {"programs", {single,{list,"n","n"}}}}. @@ -250,7 +278,7 @@ {"glGetProgramLocalParameter", {"params", {single,{tuple,4}}}}. {"glGetObjectParameter", {"params", {single,true}}}. {"glGetInfoLogARB", [{"length", [skip,{single,true}]}, - {"infoLog", {single, {list,"maxLength","length"}}} + {"infoLog", {string,"maxLength","length"}} ]}. {"glGetAttachedObjectsARB", [{"count", [skip,{single,true}]}, {"obj", {single, {list,"maxCount","count"}}} @@ -280,9 +308,10 @@ {"objW",[{single,true},out]}]}. {"gluBuild", {"data", [binary]}}. {"gluScaleImage", [{"dataIn", [in, binary]}, {"dataOut", [in, {base, memory}]}]}. -{"gluCheckExtension", [{"extName", {single, list}}, {"extString", {single, list}}]}. -{"gluErrorString", {"result", {single, {list,null}}}}. -{"gluGetString", {"result", {single, {list,null}}}}. +{"gluCheckExtension", [{"extName", string}, + {"extString", string}]}. +{"gluErrorString", {"result", string}}. +{"gluGetString", {"result", string}}. {"gluDeleteQuadric", {"quad", in}}. {"gluQuadric", {"quad", in}}. @@ -291,15 +320,21 @@ {"gluDisk", {"quad", in}}. {"gluCylinder", {"quad", in}}. -%% OpenGL 3.0 +%% OpenGL 3.0 and later {"glGetBooleani_v", {"data", {single,{list,16}}}}. {"glGetIntegeri_v", {"data", {single,{list,16}}}}. +{"glGetFloati_v", {"data", {single,{list,16}}}}. +{"glGetDoublei_v", {"data", {single,{list,16}}}}. +{"glGetInteger64i_v", {"data", {single,{list,16}}}}. + +{"glGetBufferParameteriv", {"params", {single,{list,16}}}}. +{"glGetBufferParameteri64v", {"params", {single,{list,16}}}}. {"glTransformFeedbackVaryings", [{"count", {c_only,{length,"varyings"}}}, {"varyings", [{base,string}, {single,list}]}]}. -{"glGetTransformFeedbackVarying", [{"size", {single, true}},{"type", {single, true}}, +{"glGetTransformFeedbackVarying", [{"size", {single, true}},{"type", {single, true}}, {"length", [skip, {single, true}]}, - {"name", {single, {list,"bufSize","length"}}}]}. + {"name", {string,"bufSize","length"}}]}. {"glGenRenderbuffers", {"renderbuffers", {single,{list,"n","n"}}}}. @@ -327,7 +362,133 @@ {"params", [out, {single, {list, "uniformIndicesLen", "uniformIndicesLen"}}]}]}. {"glGetActiveUniformName", [{"length",[skip,{single, true}]}, - {"uniformName", {single, {list,"bufSize","length"}}}]}. + {"uniformName", {string,"bufSize","length"}}]}. {"glGetActiveUniformBlockName", [{"length",[skip,{single, true}]}, - {"uniformBlockName", {single, {list,"bufSize","length"}}}]}. + {"uniformBlockName", {string,"bufSize","length"}}]}. {"glGetActiveUniformBlockiv", {"params", [in, {base,memory}]}}. + + +{"glGetSynciv", [{"values", {single, {list, "bufSize","length"}}}, + {"length", [skip,{single, true}]}]}. + +{"glGetMultisamplefv", {"val", [out, {single, {tuple,2}}]}}. + + +{"glNamedStringARB", [{"stringlen", {c_only, {length, "string"}}}, + {"namelen", {c_only, {length, "name"}}}]}. +{"glDeleteNamedStringARB", [{"namelen", {c_only, {length, "name"}}}]}. +{"glIsNamedStringARB", [{"namelen", {c_only, {length, "name"}}}]}. +{"glGetNamedStringARB",[{"namelen", {c_only, {length, "name"}}}, + {"stringlen",[skip,{single, true}]}, + {"string", {string,"bufSize","stringlen"}}]}. +{"glGetNamedStringivARB",[{"namelen", {c_only, {length, "name"}}}, + {"params", [out, {single, true}]}]}. +{"glCompileShaderIncludeARB", [{"length", {c_only,{constant,"NULL"}}}, + {"count", {c_only,{length,"path"}}}, + {"path", {single,list}}]}. + + +{"glGenSamplers", {"samplers", {single, {list,"count","count"}}}}. +{"glDeleteSamplers", [{"count", {c_only, {length, "samplers"}}}, + {"samplers", {single, list}}]}. +{"glGetSamplerParameter", {"params", {single, {list, 4}}}}. +{"glSamplerParameterI", {"param", {single, list}}}. +{"glSamplerParameterfv", {"param", {single, list}}}. +{"glSamplerParameteriv", {"param", {single, list}}}. + +%{"glGetActiveSubroutineUniformiv", {"values", }}. +{"glGetActiveSubroutineUniformName", [{"length",[skip,{single, true}]}, + {"name", {string,"bufsize","length"}}]}. +{"glGetActiveSubroutineName", [{"length",[skip,{single, true}]}, + {"name", {string,"bufsize","length"}}]}. +{"glGetProgramStageiv", {"values", {single, true}}}. +{"glUniformSubroutinesuiv", [{"count",{c_only,{length,"indices"}}},{"indices", {single, list}}]}. + +{"glGenTransformFeedbacks", {"ids", {single, {list,"n","n"}}}}. +{"glDeleteTransformFeedbacks", [{"n", {c_only, {length, "ids"}}}, + {"ids", {single, list}}]}. + +{"glPatchParameterfv", {"values", {single, list}}}. + + +{"glGetQueryIndexediv", {"params", {single, true} }}. +{"glShaderBinary", [{"count", {c_only, {length, "shaders"}}}, + {"length", {c_only, {size, "binary"}}}, + {"shaders", {single, list}}, + {"binary", binary} + ]}. +{"glGetShaderPrecisionFormat", [{"range", {single, {tuple, 2}}}, + {"precision", {single, true}}]}. + +{"glGetProgramBinary", [{"length",[skip,{single, true}]}, + {"binary", [out, {binary, "bufSize", "length"}]}, + {"binaryFormat", {single, true}}]}. +{"glProgramBinary", [{"binary", binary}, {"length", {c_only, {size, "binary"}}}]}. + +{"glGenProgramPipelines", {"pipelines", {single, {list,"n","n"}}}}. +{"glDeleteProgramPipelines", [{"n", {c_only, {length, "pipelines"}}}, + {"pipelines", {single, list}}]}. + +{"glCreateShaderProgramv", [{"count", {c_only, {length, "strings"}}}, + {"strings", {single, list}}]}. +{"glGetProgramPipelineInfoLog", [{"length", [skip,{single, true}]}, + {"infoLog", {string,"bufSize","length"}}]}. +{"glGetProgramPipelineiv", {"params", {single, true}}}. + + +%% {"glCreateSyncFromCLeventARB", {"context", }}. + +{"glDebugMessageControlARB", [{"count", {c_only, {length, "ids"}}}, + {"ids", {single, list}}]}. +{"glDebugMessageInsertARB", {"length", {c_only, {length, "buf"}}}}. +{"glGetDebugMessageLogARB", [{"sources", {single, {list, "count", "result"}}}, + {"types", {single, {list, "count", "result"}}}, + {"ids", {single, {list, "count", "result"}}}, + {"severities", {single, {list, "count", "result"}}}, + {"lengths", [{c_only, undefined}, {single, {list, "count", "result"}}]}, + {"messageLog", [{string, "bufsize", "lengths"}, + {single, {list, "bufsize", "result"}}]}]}. + + +{"glUniformMatrix2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}. +{"glUniformMatrix3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}. +{"glUniformMatrix4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}. +{"glUniformMatrix2x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glUniformMatrix3x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glUniformMatrix2x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glUniformMatrix4x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glUniformMatrix3x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. +{"glUniformMatrix4x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. + +{"glProgramUniform1", [{"count",{c_only,{length,"value"}}}, {"value", [{single,list}]}]}. +{"glProgramUniform2", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,2}}]}]}. +{"glProgramUniform3", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,3}}]}]}. +{"glProgramUniform4", [{"count",{c_only,{length,"value"}}}, {"value", [{single,{tuple_list,4}}]}]}. + +{"glProgramUniformMatrix2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}. +{"glProgramUniformMatrix2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,4}}]}]}. +{"glProgramUniformMatrix3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}. +{"glProgramUniformMatrix3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,9}}]}]}. +{"glProgramUniformMatrix4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}. +{"glProgramUniformMatrix4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,16}}]}]}. +{"glProgramUniformMatrix2x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glProgramUniformMatrix3x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glProgramUniformMatrix2x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glProgramUniformMatrix4x2fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glProgramUniformMatrix3x4fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. +{"glProgramUniformMatrix4x3fv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. + +{"glProgramUniformMatrix2x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glProgramUniformMatrix3x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,6}}]}]}. +{"glProgramUniformMatrix2x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glProgramUniformMatrix4x2dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,8}}]}]}. +{"glProgramUniformMatrix3x4dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. +{"glProgramUniformMatrix4x3dv", [{"count",{c_only,{length,"value"}}},{"value", [{single,{tuple_list,12}}]}]}. + +{"glViewportArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,4}}]}]}. +{"glViewportIndexedfv", {"v", {single,{tuple,4}}}}. +{"glScissorArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,4}}]}]}. +{"glScissorIndexedv", {"v", {single,{tuple,4}}}}. +{"glDepthRangeArrayv", [{"count",{c_only,{length,"v"}}}, {"v", [{single,{tuple_list,2}}]}]}. + + diff --git a/lib/wx/api_gen/wx_gen.erl b/lib/wx/api_gen/wx_gen.erl index c075324c1f..2f20c42a5d 100644 --- a/lib/wx/api_gen/wx_gen.erl +++ b/lib/wx/api_gen/wx_gen.erl @@ -887,7 +887,7 @@ add_method2(M0=#method{name=Name,params=Ps0,type=T0},#class{name=CName,parent=Pa id = next_id(func_id), pre_hook = get_opt(pre_hook, Name, length(Ps), Opts), post_hook = get_opt(post_hook, Name, length(Ps), Opts), - doc = get_opt(doc, Name, length(Ps), Opts) + doc = get_opt(doc, Name, length(Ps), Opts) }, M = case Name of CName -> diff --git a/lib/wx/api_gen/wx_gen.hrl b/lib/wx/api_gen/wx_gen.hrl index 17265a2842..426e3adfae 100644 --- a/lib/wx/api_gen/wx_gen.hrl +++ b/lib/wx/api_gen/wx_gen.hrl @@ -43,9 +43,9 @@ id = undefined, % Id (integer) doc, % Extra documentation virtual, % Is virtual? - pre_hook, % Pre hook before call in c-code - post_hook % Post hook after call in c-code - } + pre_hook = [], % Pre hook before call in c-code + post_hook = [] % Post hook after call in c-code + } ). -record(param, diff --git a/lib/wx/api_gen/wx_gen_cpp.erl b/lib/wx/api_gen/wx_gen_cpp.erl index 846cec46c4..4b33068d8f 100644 --- a/lib/wx/api_gen/wx_gen_cpp.erl +++ b/lib/wx/api_gen/wx_gen_cpp.erl @@ -152,6 +152,7 @@ gen_funcs(Defs) -> w("#include \"../wxe_impl.h\"~n"), w("#include \"../wxe_events.h\"~n"), w("#include \"../wxe_return.h\"~n"), + w("#include \"../wxe_gl.h\"~n"), w("#include \"wxe_macros.h\"~n"), w("#include \"wxe_derived_dest.h\"~n~n"), @@ -176,6 +177,9 @@ gen_funcs(Defs) -> " rt.addAtom(\"ok\");~n" " break;~n" " }~n"), + w(" case WXE_BIN_INCR:~n driver_binary_inc_refc(Ecmd.bin[0]->bin);~n break;~n",[]), + w(" case WXE_BIN_DECR:~n driver_binary_dec_refc(Ecmd.bin[0]->bin);~n break;~n",[]), + w(" case WXE_INIT_OPENGL:~n wxe_initOpenGL(rt, bp);~n break;~n",[]), Res = [gen_class(Class) || Class <- Defs], @@ -265,13 +269,13 @@ gen_method(CName, M=#method{name=N,params=Ps0,type=T,method_type=MT,id=MethodId Opts = [Opt || Opt = #param{def=Def,in=In,where=Where} <- Ps2, Def =/= none, In =/= false, Where =/= c], decode_options(Opts, Align), - case M#method.pre_hook of - undefined -> skip; + case gen_util:get_hook(c, M#method.pre_hook) of + ignore -> skip; Pre -> w(" ~s;~n", [Pre]) end, Ps3 = call_wx(N,{MT,CName},T,Ps2), - case M#method.post_hook of - undefined -> skip; + case gen_util:get_hook(c, M#method.post_hook) of + ignore -> skip; Post -> w(" ~s;~n", [Post]) end, free_args(), diff --git a/lib/wx/api_gen/wx_gen_erl.erl b/lib/wx/api_gen/wx_gen_erl.erl index 7962dd9fbf..e1201ab0d4 100644 --- a/lib/wx/api_gen/wx_gen_erl.erl +++ b/lib/wx/api_gen/wx_gen_erl.erl @@ -270,6 +270,16 @@ gen_method2(M=#method{name=N,alias=A,params=Ps,type=T,method_type=MT,id=MethodId MId = arg_type_tests(Args, "?" ++ get_unique_name(MethodId)), {MArgs,Align} = marshal_args(Args), MOpts = marshal_opts(Optional, Align, Args), + case gen_util:get_hook(erl, M#method.pre_hook) of + ignore -> skip; + Pre -> w(" ~s~n", [Pre]) + end, + + case gen_util:get_hook(erl, M#method.post_hook) of + ignore -> skip; + _ -> w(" _Result =", []) + end, + case have_return_vals(T, Ps) of _ when MT =:= constructor -> w(" wxe_util:construct(~s,~n <<~s~s>>)", [MId, MArgs,MOpts]); @@ -278,6 +288,13 @@ gen_method2(M=#method{name=N,alias=A,params=Ps,type=T,method_type=MT,id=MethodId false -> w(" wxe_util:cast(~s,~n <<~s~s>>)", [MId, MArgs,MOpts]) end, + case gen_util:get_hook(erl, M#method.post_hook) of + ignore -> skip; + Post -> + w(",~n ~s~n", [Post]), + w(" _Result", []) + end, + erase(current_func), M. diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf index 6bafda5b9d..aec8a4944a 100644 --- a/lib/wx/api_gen/wxapi.conf +++ b/lib/wx/api_gen/wxapi.conf @@ -505,15 +505,15 @@ {"data",[in,{base,binary}]}, {"alpha",[in,{base,binary}]}, {{4,pre_hook}, - "if(!static_data) {" - "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" - "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}, + [{c, "if(!static_data) {" + "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" + "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}, {{5,pre_hook}, - "if(!static_data) {" - " data = (unsigned char *) malloc(Ecmd.bin[0]->size);" - " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);" - " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);" - " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"} + [{c, "if(!static_data) {" + " data = (unsigned char *) malloc(Ecmd.bin[0]->size);" + " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);" + " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);" + " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]} ]}, '~wxImage',%'AddHandler', 'Blur','BlurHorizontal','BlurVertical', @@ -524,15 +524,15 @@ {"data",[in,{base,binary}]}, {"alpha",[in,{base,binary}]}, {{4,pre_hook}, - "if(!static_data) {" - "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" - "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}, + [{c, "if(!static_data) {" + "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" + "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]}, {{5,pre_hook}, - "if(!static_data) {" - " data = (unsigned char *) malloc(Ecmd.bin[0]->size);" - " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);" - " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);" - " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"} + [{c, "if(!static_data) {" + " data = (unsigned char *) malloc(Ecmd.bin[0]->size);" + " alpha = (unsigned char *) malloc(Ecmd.bin[1]->size);" + " memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);" + " memcpy(alpha,Ecmd.bin[1]->base,Ecmd.bin[1]->size);}"}]} ]}, 'Destroy','FindFirstUnusedColour', % 'FindHandler', 'GetImageExtWildcard', @@ -551,15 +551,15 @@ 'Rotate90','SaveFile','Scale','Size', {'SetAlpha', [{{2,"alpha"},[in,{base,binary}, {def, none}]}, {{2,pre_hook}, - "if(!static_data) {" - "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);" - "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"} + [{c, "if(!static_data) {" + "alpha = (unsigned char *) malloc(Ecmd.bin[0]->size);" + "memcpy(alpha,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]} ]}, {'SetData', [{"data",[in,{base,binary}]}, {pre_hook, - "if(!static_data) {" - "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" - "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"} + [{c, "if(!static_data) {" + "data = (unsigned char *) malloc(Ecmd.bin[0]->size);" + "memcpy(data,Ecmd.bin[0]->base,Ecmd.bin[0]->size);}"}]} ]}, 'SetMask','SetMaskColour','SetMaskFromImage','SetOption', 'SetPalette', @@ -1148,7 +1148,8 @@ [{skip, [{'SetCurrent', 2}]}], %% NA MAC [{'wxGLCanvas', [{"attribList", [in, {single,array}]}]}, 'GetContext', - {'SetCurrent', [{post_hook,"if(This->GetContext()) setActiveGL(Ecmd.caller,This)"}]}, + {'SetCurrent', [{post_hook,[{c, "if(This->GetContext()) setActiveGL(Ecmd.caller,This)"}, + {erl, "{ok, _} = wxe_master:init_opengl(),"}]}]}, %%{'SetColour', [{"colour", [in, {single,array}]}]}, 'SwapBuffers']}. diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in index 8710641b57..69418f62ef 100644 --- a/lib/wx/c_src/Makefile.in +++ b/lib/wx/c_src/Makefile.in @@ -32,14 +32,16 @@ endif SO_EXT = @SO_EXT@ -GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return +GENERAL = wxe_driver wxe_ps_init wxe_impl wxePrintout wxe_return wxe_gl GENERAL_H = wxe_driver.h wxe_impl.h wxe_return.h GENERATED_F = wxe_funcs wxe_events wxe_init -GENERATED_H = gen/wxe_macros.h gen/glu_finit.h gen/gl_finit.h gen/gl_fdefs.h +GENERATED_H = gen/wxe_macros.h + +GL_H = egl_impl.h gen/glu_finit.h gen/gl_finit.h gen/gl_fdefs.h HAVE_OPENGL = true -OPENGL_F = gl_funcs wxe_gl +OPENGL_F = gl_funcs egl_impl ifneq ($(INSIDE_ERLSRC),true) @@ -60,9 +62,9 @@ SYS_TYPE = @WXERL_SYS_TYPE@ GENERAL_O = $(GENERAL:%=$(SYS_TYPE)/%.o) GENERATED_O = $(GENERATED_F:%=$(SYS_TYPE)/%.o) ifeq ($(HAVE_OPENGL), true) - OPENGL_O = $(OPENGL_F:%=$(SYS_TYPE)/%.o) + GL_OBJECTS = $(OPENGL_F:%=$(SYS_TYPE)/%.o) else - OPENGL_O = + GL_OBJECTS = endif RC_FILE_EXT = @RC_FILE_TYPE@ @@ -72,10 +74,12 @@ else RC_FILE = endif -OBJECTS = $(GENERAL_O) $(GENERATED_O) $(OPENGL_O) $(RC_FILE) +WX_OBJECTS = $(GENERAL_O) $(GENERATED_O) $(RC_FILE) + +OBJECTS = $(WX_OBJECTS) $(GL_OBJECTS) -TARGET_API = wxe_driver -TARGET_DIR = ../priv/$(SYS_TYPE) +TARGET_APIS = wxe_driver erl_gl +TARGET_DIR = ../priv # -O2 -funroll-loops -ffast-math -fomit-frame-pointer @@ -87,31 +91,36 @@ LD = $(CPP) LDFLAGS = @LDFLAGS@ RESCOMP = @WX_RESCOMP@ - ifeq (@WX_HAVE_STATIC_LIBS@,true) -WX_LIBS = @WX_LIBS_STATIC@ +OPT_WX_LIBS = @WX_LIBS_STATIC@ DEBUG_WX_LIBS = @DEBUG_WX_LIBS_STATIC@ else -WX_LIBS = @WX_LIBS@ +OPT_WX_LIBS = @WX_LIBS@ DEBUG_WX_LIBS = @DEBUG_WX_LIBS@ endif ifeq ($(TYPE),debug) -CFLAGS = @DEBUG_WX_CFLAGS@ @DEBUG_CFLAGS@ -CPP_FLAGS = @DEBUG_WX_CXXFLAGS@ @DEBUG_CXXFLAGS@ -LIBS = $(DEBUG_WX_LIBS) +WX_CFLAGS = @DEBUG_WX_CFLAGS@ +CFLAGS = @DEBUG_CFLAGS@ +WX_CXX_FLAGS = @DEBUG_WX_CXXFLAGS@ +CXX_FLAGS = @DEBUG_CXXFLAGS@ +WX_LIBS = $(DEBUG_WX_LIBS) else -CFLAGS = @WX_CFLAGS@ @CFLAGS@ -CPP_FLAGS = @WX_CXXFLAGS@ @CXXFLAGS@ -LIBS = $(WX_LIBS) +WX_CFLAGS = @WX_CFLAGS@ +CFLAGS = @CFLAGS@ +WX_CXX_FLAGS = @WX_CXXFLAGS@ +CXX_FLAGS = @CXXFLAGS@ +WX_LIBS = $(OPT_WX_LIBS) endif -CC_O = $(CC) -c $(CFLAGS) $(COMMON_CFLAGS) -CPP_O = $(CPP) -c $(CPP_FLAGS) $(COMMON_CFLAGS) +GL_LIBS = @GL_LIBS@ + +CC_O = $(CC) -c $(CFLAGS) $(WX_CFLAGS) $(COMMON_CFLAGS) +CPP_O = $(CPP) -c $(CXX_FLAGS) $(WX_CXX_FLAGS) $(COMMON_CFLAGS) # Targets -opt: $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) +opt: $(TARGET_DIR)/wxe_driver$(SO_EXT) $(TARGET_DIR)/erl_gl$(SO_EXT) debug: @${MAKE} TYPE=debug @@ -132,20 +141,22 @@ complete_clean: docs: +$(GL_OBJECTS): $(GL_H) +$(WX_OBJECTS): $(GENERATED_H) $(GENERAL_H) -$(SYS_TYPE)/%.o: %.cpp $(GENERATED_H) $(GENERAL_H) +$(SYS_TYPE)/%.o: %.cpp mkdir -p $(SYS_TYPE) $(CPP_O) $< -o $@ -$(SYS_TYPE)/%.o: %.c $(GENERATED_H) $(GENERAL_H) +$(SYS_TYPE)/%.o: %.c mkdir -p $(SYS_TYPE) $(CC_O) $< -o $@ -$(SYS_TYPE)/%.o: gen/%.cpp $(GENERATED_H) $(GENERAL_H) +$(SYS_TYPE)/%.o: gen/%.cpp mkdir -p $(SYS_TYPE) $(CPP_O) $< -o $@ -$(SYS_TYPE)/%.o: gen/%.c $(GENERATED_H) $(GENERAL_H) +$(SYS_TYPE)/%.o: gen/%.c mkdir -p $(SYS_TYPE) $(CC_O) $< -o $@ @@ -153,9 +164,13 @@ $(SYS_TYPE)/wxe_win32.$(RC_FILE_EXT): wxe_win32.rc mkdir -p $(SYS_TYPE) $(RESCOMP) -o $@ $< -$(TARGET_DIR)/$(TARGET_API)$(SO_EXT): $(OBJECTS) +$(TARGET_DIR)/wxe_driver$(SO_EXT): $(WX_OBJECTS) + mkdir -p $(TARGET_DIR) + $(LD) $(LDFLAGS) $(WX_OBJECTS) $(WX_LIBS) -o $@ + +$(TARGET_DIR)/erl_gl$(SO_EXT): $(GL_OBJECTS) mkdir -p $(TARGET_DIR) - $(LD) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + $(CC) $(LDFLAGS) $(GL_OBJECTS) $(GL_LIBS) -o $@ # ---------------------------------------------------- @@ -164,10 +179,11 @@ $(TARGET_DIR)/$(TARGET_API)$(SO_EXT): $(OBJECTS) ifeq ($(INSIDE_ERLSRC),true) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/$(SYS_TYPE) + $(INSTALL_DIR) $(RELSYSDIR)/priv $(INSTALL_DATA) ../priv/erlang-logo32.png $(RELSYSDIR)/priv/ $(INSTALL_DATA) ../priv/erlang-logo64.png $(RELSYSDIR)/priv/ - $(INSTALL_PROGRAM) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE) + $(INSTALL_PROGRAM) $(TARGET_DIR)/wxe_driver$(SO_EXT) $(RELSYSDIR)/priv/ + $(INSTALL_PROGRAM) $(TARGET_DIR)/erl_gl$(SO_EXT) $(RELSYSDIR)/priv/ release_docs_spec: diff --git a/lib/wx/c_src/egl_impl.cpp b/lib/wx/c_src/egl_impl.cpp new file mode 100644 index 0000000000..e2dbbb73c4 --- /dev/null +++ b/lib/wx/c_src/egl_impl.cpp @@ -0,0 +1,306 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#include <stdio.h> +#include <string.h> + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include "egl_impl.h" + +#define WX_DEF_EXTS +#include "gen/gl_fdefs.h" +#include "gen/gl_finit.h" +#include "gen/glu_finit.h" + +void init_tess(); +void exit_tess(); +int load_gl_functions(); + +/* **************************************************************************** + * OPENGL INITIALIZATION + *****************************************************************************/ + +int egl_initiated = 0; + +#ifdef _WIN32 +#define RTLD_LAZY 0 +#define OPENGL_LIB L"opengl32.dll" +#define OPENGLU_LIB L"glu32.dll" +typedef HMODULE DL_LIB_P; +typedef WCHAR DL_CHAR; +void * dlsym(HMODULE Lib, const char *func) { + void * funcp; + if((funcp = (void *) GetProcAddress(Lib, func))) + return funcp; + else + return (void *) wglGetProcAddress(func); +} + +HMODULE dlopen(const WCHAR *DLL, int unused) { + return LoadLibrary(DLL); +} + +void dlclose(HMODULE Lib) { + FreeLibrary(Lib); +} + +#else +typedef void * DL_LIB_P; +typedef char DL_CHAR; +# ifdef _MACOSX +# define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib" +# define OPENGLU_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib" +# else +# define OPENGL_LIB "libGL.so" +# define OPENGLU_LIB "libGLU.so" +# endif +#endif +extern "C" { +DRIVER_INIT(EGL_DRIVER) { + return NULL; +} +} + +int egl_init_opengl(void *erlCallbacks) +{ +#ifdef _WIN32 + driver_init((TWinDynDriverCallbacks *) erlCallbacks); +#endif + if(egl_initiated == 0) { + if(load_gl_functions()) { + init_tess(); + egl_initiated = 1; + } + } + return 1; +} + +int load_gl_functions() { + DL_CHAR * DLName = OPENGL_LIB; + DL_LIB_P LIBhandle = dlopen(DLName, RTLD_LAZY); + //fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName); + void * func = NULL; + int i; + + if(LIBhandle) { + for(i=0; gl_fns[i].name != NULL; i++) { + if((func = dlsym(LIBhandle, gl_fns[i].name))) { + * (void **) (gl_fns[i].func) = func; + // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].name); + } else { + if(gl_fns[i].alt != NULL) { + if((func = dlsym(LIBhandle, gl_fns[i].alt))) { + * (void **) (gl_fns[i].func) = func; + // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].alt); + } else { + * (void **) (gl_fns[i].func) = (void *) &gl_error; + // fprintf(stderr, "GL Skipped %s and %s \r\n", gl_fns[i].name, gl_fns[i].alt); + }; + } else { + * (void **) (gl_fns[i].func) = (void *) &gl_error; + // fprintf(stderr, "GL Skipped %s \r\n", gl_fns[i].name); + } + } + } + dlclose(LIBhandle); + // fprintf(stderr, "OPENGL library is loaded\r\n"); + } else { + fprintf(stderr, "Could NOT load OpenGL library: %s\r\n", DLName); + }; + + DLName = OPENGLU_LIB; + LIBhandle = dlopen(DLName, RTLD_LAZY); + // fprintf(stderr, "Loading GLU: %s\r\n", (const char*)DLName); + func = NULL; + + if(LIBhandle) { + for(i=0; glu_fns[i].name != NULL; i++) { + if((func = dlsym(LIBhandle, glu_fns[i].name))) { + * (void **) (glu_fns[i].func) = func; + } else { + if(glu_fns[i].alt != NULL) { + if((func = dlsym(LIBhandle, glu_fns[i].alt))) { + * (void **) (glu_fns[i].func) = func; + } else { + * (void **) (glu_fns[i].func) = (void *) &gl_error; + // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].alt); + }; + } else { + * (void **) (glu_fns[i].func) = (void *) &gl_error; + // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].name); + } + } + } + dlclose(LIBhandle); + // fprintf(stderr, "GLU library is loaded\r\n"); + } else { + fprintf(stderr, "Could NOT load OpenGL GLU library: %s\r\n", DLName); + }; + + return 1; +} + +void gl_error() { + // fprintf(stderr, "OpenGL Extension not available \r\n"); + throw "undef_extension"; +} + +/* ******************************************************************************* + * GLU Tesselation special + * ******************************************************************************/ + +static GLUtesselator* tess; +static GLdouble* tess_coords; +static GLdouble* tess_alloc_vertex; +static int* tess_vertices; + +void CALLBACK +egl_ogla_vertex(GLdouble* coords) +{ + /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */ + + *tess_vertices++ = (int) (coords - tess_coords) / 3; +} + +void CALLBACK +egl_ogla_edge_flag(GLboolean flag) +{ +} + +void CALLBACK +egl_ogla_error(GLenum errorCode) +{ + const GLubyte *err; + err = gluErrorString(errorCode); + // wxString msg; + // msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode); + // msg += wxString::FromAscii((char *) err); + // send_msg("error", &msg); + fprintf(stderr, "Tesselation error: %d\r\n", (int) errorCode); +} + +void CALLBACK +egl_ogla_combine(GLdouble coords[3], + void* vertex_data[4], + GLfloat w[4], + void **dataOut) +{ + GLdouble* vertex = tess_alloc_vertex; + + tess_alloc_vertex += 3; + +#if 0 + fprintf(stderr, "combine: "); + int i; + for (i = 0; i < 4; i++) { + if (w[i] > 0.0) { + fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]); + } + } + fprintf(stderr, "\r\n"); + fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]); +#endif + + vertex[0] = coords[0]; + vertex[1] = coords[1]; + vertex[2] = coords[2]; + *dataOut = vertex; +} + +void init_tess() +{ + tess = gluNewTess(); + + gluTessCallback(tess, GLU_TESS_VERTEX, (GLUfuncptr) egl_ogla_vertex); + gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (GLUfuncptr) egl_ogla_edge_flag); + gluTessCallback(tess, GLU_TESS_COMBINE, (GLUfuncptr) egl_ogla_combine); + gluTessCallback(tess, GLU_TESS_ERROR, (GLUfuncptr) egl_ogla_error); + +} + +void exit_tess() +{ + gluDeleteTess(tess); +} + +int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) +{ + ErlDrvBinary* bin; + int i; + GLdouble* new_vertices; + int *vertices; + int num_vertices; + GLdouble *n; + int n_pos, AP, res; + + num_vertices = * (int *) buff; buff += 8; /* Align */ + n = (double *) buff; buff += 8*3; + + bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble)); + new_vertices = tess_coords = (double *) bin->orig_bytes; + memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble)); + tess_alloc_vertex = tess_coords + num_vertices*3; + +#if 0 + fprintf(stderr, "n=%d\r\n", num_vertices); +#endif + vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices); + + tess_vertices = vertices; + + gluTessNormal(tess, n[0], n[1], n[2]); + gluTessBeginPolygon(tess, 0); + gluTessBeginContour(tess); + for (i = 0; i < num_vertices; i++) { + gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i); + } + gluTessEndContour(tess); + gluTessEndPolygon(tess); + + n_pos = (tess_vertices - vertices); + + AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + + for(i=0; i < n_pos; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i]; + }; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1; + + rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; + rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0; + + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple + + res = driver_send_term(port,caller,rt,AP); + /* fprintf(stderr, "List %d: %d %d %d \r\n", */ + /* res, */ + /* n_pos, */ + /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */ + /* num_vertices*6*sizeof(GLdouble)); */ + driver_free_binary(bin); + driver_free(vertices); + driver_free(rt); + return 0; +} diff --git a/lib/wx/c_src/egl_impl.h b/lib/wx/c_src/egl_impl.h new file mode 100644 index 0000000000..e93e4caefd --- /dev/null +++ b/lib/wx/c_src/egl_impl.h @@ -0,0 +1,149 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2010. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +#include "erl_driver.h" + +/* Wrap everything from glext.h so we are not dependent on the user version of it */ + +#ifndef _WIN32 +# include <dlfcn.h> +#endif + +#ifdef _WIN32 +#include <windows.h> +#include <gl/gl.h> +#include <gl/glu.h> +#elif defined(HAVE_GL_GL_H) +#include <GL/gl.h> +# include <GL/glu.h> +#elif defined(HAVE_OPENGL_GL_H) +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif + +#ifndef CALLBACK +# define CALLBACK +#endif + +#ifdef _WIN32 +# ifndef _GLUfuncptr +// Visual studio CPP ++ compiler +# define _GLUfuncptr void (_stdcall *)() +# endif +#endif + +#ifdef _GLUfuncptr +# define GLUfuncptr _GLUfuncptr +#elif defined(TESS_CB_TIGER_STYLE) +# define GLUfuncptr GLvoid (*)(...) +#else +# define GLUfuncptr GLvoid (*)() +#endif + +/* Some new GL types (eliminates the need for glext.h) */ + +#ifndef HAVE_GLINTPTR +#ifndef HAVE_GLINTPTRARB +# include <stddef.h> +/* GL types for handling large vertex buffer objects */ +typedef ptrdiff_t GLintptrARB; +typedef ptrdiff_t GLsizeiptrARB; +#endif /* HAVE_GLINTPTRARB */ +typedef GLintptrARB GLintptr; +typedef GLsizeiptrARB GLsizeiptr; +#endif /* HAVE_GLINTPTR */ + +#ifndef HAVE_GLCHAR +# ifndef HAVE_GLCHARARB +/* GL types for handling shader object handles and characters */ +typedef char GLcharARB; /* native character */ +typedef unsigned int GLhandleARB; /* shader object handle */ +#endif /* HAVE_GLCHARARB */ +typedef GLcharARB GLchar; +#endif + +#ifndef HAVE_GLHALFARB +/* GL types for "half" precision (s10e5) float data in host memory */ +typedef unsigned short GLhalfARB; +#endif + +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GLX_OML_sync_control extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +#elif defined(__sun__) +#include <inttypes.h> +#if defined(__STDC__) +#if defined(__arch64__) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) +#include <inttypes.h> +#elif defined(__SCO__) || defined(__USLC__) +#include <stdint.h> +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(WIN32) && defined(_MSC_VER) +typedef long int int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#elif defined(WIN32) && defined(__GNUC__) +#include <stdint.h> +#else +#include <inttypes.h> /* Fallback option */ +#endif + +#ifndef HAVE_GLINT64EXT +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + +#ifndef GL_ARB_sync +typedef int64_t GLint64; +typedef uint64_t GLuint64; +typedef struct __GLsync *GLsync; +#endif + +/* External Api */ + +#ifdef _WIN32 +extern "C" __declspec(dllexport) int egl_init_opengl(void *); +extern "C" __declspec(dllexport) void egl_dispatch(int, char *, ErlDrvPort, ErlDrvTermData, char **, int *); +#else +extern "C" int egl_init_opengl(void *); +extern "C" void egl_dispatch(int, char *, ErlDrvPort, ErlDrvTermData, char **, int *); +#endif + +/* internal */ +int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller); +void gl_error(); +extern int gl_error_op; +extern ErlDrvTermData gl_active; + diff --git a/lib/wx/c_src/gen/gl_fdefs.h b/lib/wx/c_src/gen/gl_fdefs.h index 2096f7a413..a45896d30d 100644 --- a/lib/wx/c_src/gen/gl_fdefs.h +++ b/lib/wx/c_src/gen/gl_fdefs.h @@ -24,6 +24,13 @@ # define WXE_EXTERN extern #endif +typedef struct { + const char * name; + const char * alt; + void * func; +} gl_fns_t; + +#define GLE_GL_FUNC_START 5037 typedef void (APIENTRY * WXEGLACCUM)(GLenum,GLfloat); WXE_EXTERN WXEGLACCUM weglAccum; typedef void (APIENTRY * WXEGLALPHAFUNC)(GLenum,GLclampf); @@ -684,7 +691,7 @@ typedef void (APIENTRY * WXEGLMULTTRANSPOSEMATRIXD)(const GLdouble *); WXE_EXTERN WXEGLMULTTRANSPOSEMATRIXD weglMultTransposeMatrixd; typedef void (APIENTRY * WXEGLBLENDFUNCSEPARATE)(GLenum,GLenum,GLenum,GLenum); WXE_EXTERN WXEGLBLENDFUNCSEPARATE weglBlendFuncSeparate; -typedef void (APIENTRY * WXEGLMULTIDRAWARRAYS)(GLenum,GLint *,GLsizei *,GLsizei); +typedef void (APIENTRY * WXEGLMULTIDRAWARRAYS)(GLenum,const GLint *,const GLsizei *,GLsizei); WXE_EXTERN WXEGLMULTIDRAWARRAYS weglMultiDrawArrays; typedef void (APIENTRY * WXEGLPOINTPARAMETERF)(GLenum,GLfloat); WXE_EXTERN WXEGLPOINTPARAMETERF weglPointParameterf; @@ -972,6 +979,30 @@ typedef void (APIENTRY * WXEGLGETVERTEXATTRIBIIV)(GLuint,GLenum,GLint *); WXE_EXTERN WXEGLGETVERTEXATTRIBIIV weglGetVertexAttribIiv; typedef void (APIENTRY * WXEGLGETVERTEXATTRIBIUIV)(GLuint,GLenum,GLuint *); WXE_EXTERN WXEGLGETVERTEXATTRIBIUIV weglGetVertexAttribIuiv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI1IV)(GLuint,const GLint *); +WXE_EXTERN WXEGLVERTEXATTRIBI1IV weglVertexAttribI1iv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI2IV)(GLuint,const GLint *); +WXE_EXTERN WXEGLVERTEXATTRIBI2IV weglVertexAttribI2iv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI3IV)(GLuint,const GLint *); +WXE_EXTERN WXEGLVERTEXATTRIBI3IV weglVertexAttribI3iv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4IV)(GLuint,const GLint *); +WXE_EXTERN WXEGLVERTEXATTRIBI4IV weglVertexAttribI4iv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI1UIV)(GLuint,const GLuint *); +WXE_EXTERN WXEGLVERTEXATTRIBI1UIV weglVertexAttribI1uiv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI2UIV)(GLuint,const GLuint *); +WXE_EXTERN WXEGLVERTEXATTRIBI2UIV weglVertexAttribI2uiv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI3UIV)(GLuint,const GLuint *); +WXE_EXTERN WXEGLVERTEXATTRIBI3UIV weglVertexAttribI3uiv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UIV)(GLuint,const GLuint *); +WXE_EXTERN WXEGLVERTEXATTRIBI4UIV weglVertexAttribI4uiv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4BV)(GLuint,const GLbyte *); +WXE_EXTERN WXEGLVERTEXATTRIBI4BV weglVertexAttribI4bv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4SV)(GLuint,const GLshort *); +WXE_EXTERN WXEGLVERTEXATTRIBI4SV weglVertexAttribI4sv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UBV)(GLuint,const GLubyte *); +WXE_EXTERN WXEGLVERTEXATTRIBI4UBV weglVertexAttribI4ubv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBI4USV)(GLuint,const GLushort *); +WXE_EXTERN WXEGLVERTEXATTRIBI4USV weglVertexAttribI4usv; typedef void (APIENTRY * WXEGLGETUNIFORMUIV)(GLuint,GLint,GLuint *); WXE_EXTERN WXEGLGETUNIFORMUIV weglGetUniformuiv; typedef void (APIENTRY * WXEGLBINDFRAGDATALOCATION)(GLuint,GLuint,const GLchar *); @@ -1012,30 +1043,6 @@ typedef void (APIENTRY * WXEGLCLEARBUFFERFI)(GLenum,GLint,GLfloat,GLint); WXE_EXTERN WXEGLCLEARBUFFERFI weglClearBufferfi; typedef const GLubyte * (APIENTRY * WXEGLGETSTRINGI)(GLenum,GLuint); WXE_EXTERN WXEGLGETSTRINGI weglGetStringi; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI1IV)(GLuint,const GLint *); -WXE_EXTERN WXEGLVERTEXATTRIBI1IV weglVertexAttribI1iv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI2IV)(GLuint,const GLint *); -WXE_EXTERN WXEGLVERTEXATTRIBI2IV weglVertexAttribI2iv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI3IV)(GLuint,const GLint *); -WXE_EXTERN WXEGLVERTEXATTRIBI3IV weglVertexAttribI3iv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4IV)(GLuint,const GLint *); -WXE_EXTERN WXEGLVERTEXATTRIBI4IV weglVertexAttribI4iv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI1UIV)(GLuint,const GLuint *); -WXE_EXTERN WXEGLVERTEXATTRIBI1UIV weglVertexAttribI1uiv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI2UIV)(GLuint,const GLuint *); -WXE_EXTERN WXEGLVERTEXATTRIBI2UIV weglVertexAttribI2uiv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI3UIV)(GLuint,const GLuint *); -WXE_EXTERN WXEGLVERTEXATTRIBI3UIV weglVertexAttribI3uiv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UIV)(GLuint,const GLuint *); -WXE_EXTERN WXEGLVERTEXATTRIBI4UIV weglVertexAttribI4uiv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4BV)(GLuint,const GLbyte *); -WXE_EXTERN WXEGLVERTEXATTRIBI4BV weglVertexAttribI4bv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4SV)(GLuint,const GLshort *); -WXE_EXTERN WXEGLVERTEXATTRIBI4SV weglVertexAttribI4sv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4UBV)(GLuint,const GLubyte *); -WXE_EXTERN WXEGLVERTEXATTRIBI4UBV weglVertexAttribI4ubv; -typedef void (APIENTRY * WXEGLVERTEXATTRIBI4USV)(GLuint,const GLushort *); -WXE_EXTERN WXEGLVERTEXATTRIBI4USV weglVertexAttribI4usv; typedef void (APIENTRY * WXEGLDRAWARRAYSINSTANCED)(GLenum,GLint,GLsizei,GLsizei); WXE_EXTERN WXEGLDRAWARRAYSINSTANCED weglDrawArraysInstanced; typedef void (APIENTRY * WXEGLDRAWELEMENTSINSTANCED)(GLenum,GLsizei,GLenum,const GLvoid *,GLsizei); @@ -1044,6 +1051,24 @@ typedef void (APIENTRY * WXEGLTEXBUFFER)(GLenum,GLenum,GLuint); WXE_EXTERN WXEGLTEXBUFFER weglTexBuffer; typedef void (APIENTRY * WXEGLPRIMITIVERESTARTINDEX)(GLuint); WXE_EXTERN WXEGLPRIMITIVERESTARTINDEX weglPrimitiveRestartIndex; +typedef void (APIENTRY * WXEGLGETINTEGER64I_V)(GLenum,GLuint,GLint64 *); +WXE_EXTERN WXEGLGETINTEGER64I_V weglGetInteger64i_v; +typedef void (APIENTRY * WXEGLGETBUFFERPARAMETERI64V)(GLenum,GLenum,GLint64 *); +WXE_EXTERN WXEGLGETBUFFERPARAMETERI64V weglGetBufferParameteri64v; +typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTURE)(GLenum,GLenum,GLuint,GLint); +WXE_EXTERN WXEGLFRAMEBUFFERTEXTURE weglFramebufferTexture; +typedef void (APIENTRY * WXEGLVERTEXATTRIBDIVISOR)(GLuint,GLuint); +WXE_EXTERN WXEGLVERTEXATTRIBDIVISOR weglVertexAttribDivisor; +typedef void (APIENTRY * WXEGLMINSAMPLESHADING)(GLclampf); +WXE_EXTERN WXEGLMINSAMPLESHADING weglMinSampleShading; +typedef void (APIENTRY * WXEGLBLENDEQUATIONI)(GLuint,GLenum); +WXE_EXTERN WXEGLBLENDEQUATIONI weglBlendEquationi; +typedef void (APIENTRY * WXEGLBLENDEQUATIONSEPARATEI)(GLuint,GLenum,GLenum); +WXE_EXTERN WXEGLBLENDEQUATIONSEPARATEI weglBlendEquationSeparatei; +typedef void (APIENTRY * WXEGLBLENDFUNCI)(GLuint,GLenum,GLenum); +WXE_EXTERN WXEGLBLENDFUNCI weglBlendFunci; +typedef void (APIENTRY * WXEGLBLENDFUNCSEPARATEI)(GLuint,GLenum,GLenum,GLenum,GLenum); +WXE_EXTERN WXEGLBLENDFUNCSEPARATEI weglBlendFuncSeparatei; typedef void (APIENTRY * WXEGLLOADTRANSPOSEMATRIXFARB)(const GLfloat *); WXE_EXTERN WXEGLLOADTRANSPOSEMATRIXFARB weglLoadTransposeMatrixfARB; typedef void (APIENTRY * WXEGLLOADTRANSPOSEMATRIXDARB)(const GLdouble *); @@ -1112,6 +1137,8 @@ typedef void (APIENTRY * WXEGLGETPROGRAMLOCALPARAMETERFVARB)(GLenum,GLuint,GLflo WXE_EXTERN WXEGLGETPROGRAMLOCALPARAMETERFVARB weglGetProgramLocalParameterfvARB; typedef void (APIENTRY * WXEGLGETPROGRAMSTRINGARB)(GLenum,GLenum,GLvoid *); WXE_EXTERN WXEGLGETPROGRAMSTRINGARB weglGetProgramStringARB; +typedef void (APIENTRY * WXEGLGETBUFFERPARAMETERIVARB)(GLenum,GLenum,GLint *); +WXE_EXTERN WXEGLGETBUFFERPARAMETERIVARB weglGetBufferParameterivARB; typedef void (APIENTRY * WXEGLDELETEOBJECTARB)(GLhandleARB); WXE_EXTERN WXEGLDELETEOBJECTARB weglDeleteObjectARB; typedef GLhandleARB (APIENTRY * WXEGLGETHANDLEARB)(GLenum); @@ -1198,14 +1225,8 @@ typedef void (APIENTRY * WXEGLRENDERBUFFERSTORAGEMULTISAMPLE)(GLenum,GLsizei,GLe WXE_EXTERN WXEGLRENDERBUFFERSTORAGEMULTISAMPLE weglRenderbufferStorageMultisample; typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTURELAYER)(GLenum,GLenum,GLuint,GLint,GLint); WXE_EXTERN WXEGLFRAMEBUFFERTEXTURELAYER weglFramebufferTextureLayer; -typedef void (APIENTRY * WXEGLPROGRAMPARAMETERIARB)(GLuint,GLenum,GLint); -WXE_EXTERN WXEGLPROGRAMPARAMETERIARB weglProgramParameteriARB; -typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTUREARB)(GLenum,GLenum,GLuint,GLint); -WXE_EXTERN WXEGLFRAMEBUFFERTEXTUREARB weglFramebufferTextureARB; typedef void (APIENTRY * WXEGLFRAMEBUFFERTEXTUREFACEARB)(GLenum,GLenum,GLuint,GLint,GLenum); WXE_EXTERN WXEGLFRAMEBUFFERTEXTUREFACEARB weglFramebufferTextureFaceARB; -typedef void (APIENTRY * WXEGLVERTEXATTRIBDIVISORARB)(GLuint,GLuint); -WXE_EXTERN WXEGLVERTEXATTRIBDIVISORARB weglVertexAttribDivisorARB; typedef void (APIENTRY * WXEGLFLUSHMAPPEDBUFFERRANGE)(GLenum,GLintptr,GLsizeiptr); WXE_EXTERN WXEGLFLUSHMAPPEDBUFFERRANGE weglFlushMappedBufferRange; typedef void (APIENTRY * WXEGLBINDVERTEXARRAY)(GLuint); @@ -1232,6 +1253,342 @@ typedef void (APIENTRY * WXEGLUNIFORMBLOCKBINDING)(GLuint,GLuint,GLuint); WXE_EXTERN WXEGLUNIFORMBLOCKBINDING weglUniformBlockBinding; typedef void (APIENTRY * WXEGLCOPYBUFFERSUBDATA)(GLenum,GLenum,GLintptr,GLintptr,GLsizeiptr); WXE_EXTERN WXEGLCOPYBUFFERSUBDATA weglCopyBufferSubData; +typedef void (APIENTRY * WXEGLDRAWELEMENTSBASEVERTEX)(GLenum,GLsizei,GLenum,const GLvoid *,GLint); +WXE_EXTERN WXEGLDRAWELEMENTSBASEVERTEX weglDrawElementsBaseVertex; +typedef void (APIENTRY * WXEGLDRAWRANGEELEMENTSBASEVERTEX)(GLenum,GLuint,GLuint,GLsizei,GLenum,const GLvoid *,GLint); +WXE_EXTERN WXEGLDRAWRANGEELEMENTSBASEVERTEX weglDrawRangeElementsBaseVertex; +typedef void (APIENTRY * WXEGLDRAWELEMENTSINSTANCEDBASEVERTEX)(GLenum,GLsizei,GLenum,const GLvoid *,GLsizei,GLint); +WXE_EXTERN WXEGLDRAWELEMENTSINSTANCEDBASEVERTEX weglDrawElementsInstancedBaseVertex; +typedef void (APIENTRY * WXEGLPROVOKINGVERTEX)(GLenum); +WXE_EXTERN WXEGLPROVOKINGVERTEX weglProvokingVertex; +typedef GLsync (APIENTRY * WXEGLFENCESYNC)(GLenum,GLbitfield); +WXE_EXTERN WXEGLFENCESYNC weglFenceSync; +typedef GLboolean (APIENTRY * WXEGLISSYNC)(GLsync); +WXE_EXTERN WXEGLISSYNC weglIsSync; +typedef void (APIENTRY * WXEGLDELETESYNC)(GLsync); +WXE_EXTERN WXEGLDELETESYNC weglDeleteSync; +typedef GLenum (APIENTRY * WXEGLCLIENTWAITSYNC)(GLsync,GLbitfield,GLuint64); +WXE_EXTERN WXEGLCLIENTWAITSYNC weglClientWaitSync; +typedef void (APIENTRY * WXEGLWAITSYNC)(GLsync,GLbitfield,GLuint64); +WXE_EXTERN WXEGLWAITSYNC weglWaitSync; +typedef void (APIENTRY * WXEGLGETINTEGER64V)(GLenum,GLint64 *); +WXE_EXTERN WXEGLGETINTEGER64V weglGetInteger64v; +typedef void (APIENTRY * WXEGLGETSYNCIV)(GLsync,GLenum,GLsizei,GLsizei *,GLint *); +WXE_EXTERN WXEGLGETSYNCIV weglGetSynciv; +typedef void (APIENTRY * WXEGLTEXIMAGE2DMULTISAMPLE)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLboolean); +WXE_EXTERN WXEGLTEXIMAGE2DMULTISAMPLE weglTexImage2DMultisample; +typedef void (APIENTRY * WXEGLTEXIMAGE3DMULTISAMPLE)(GLenum,GLsizei,GLint,GLsizei,GLsizei,GLsizei,GLboolean); +WXE_EXTERN WXEGLTEXIMAGE3DMULTISAMPLE weglTexImage3DMultisample; +typedef void (APIENTRY * WXEGLGETMULTISAMPLEFV)(GLenum,GLuint,GLfloat *); +WXE_EXTERN WXEGLGETMULTISAMPLEFV weglGetMultisamplefv; +typedef void (APIENTRY * WXEGLSAMPLEMASKI)(GLuint,GLbitfield); +WXE_EXTERN WXEGLSAMPLEMASKI weglSampleMaski; +typedef void (APIENTRY * WXEGLNAMEDSTRINGARB)(GLenum,GLint,const GLchar *,GLint,const GLchar *); +WXE_EXTERN WXEGLNAMEDSTRINGARB weglNamedStringARB; +typedef void (APIENTRY * WXEGLDELETENAMEDSTRINGARB)(GLint,const GLchar *); +WXE_EXTERN WXEGLDELETENAMEDSTRINGARB weglDeleteNamedStringARB; +typedef void (APIENTRY * WXEGLCOMPILESHADERINCLUDEARB)(GLuint,GLsizei,const GLchar **,const GLint *); +WXE_EXTERN WXEGLCOMPILESHADERINCLUDEARB weglCompileShaderIncludeARB; +typedef GLboolean (APIENTRY * WXEGLISNAMEDSTRINGARB)(GLint,const GLchar *); +WXE_EXTERN WXEGLISNAMEDSTRINGARB weglIsNamedStringARB; +typedef void (APIENTRY * WXEGLGETNAMEDSTRINGARB)(GLint,const GLchar *,GLsizei,GLint *,GLchar *); +WXE_EXTERN WXEGLGETNAMEDSTRINGARB weglGetNamedStringARB; +typedef void (APIENTRY * WXEGLGETNAMEDSTRINGIVARB)(GLint,const GLchar *,GLenum,GLint *); +WXE_EXTERN WXEGLGETNAMEDSTRINGIVARB weglGetNamedStringivARB; +typedef void (APIENTRY * WXEGLBINDFRAGDATALOCATIONINDEXED)(GLuint,GLuint,GLuint,const GLchar *); +WXE_EXTERN WXEGLBINDFRAGDATALOCATIONINDEXED weglBindFragDataLocationIndexed; +typedef GLint (APIENTRY * WXEGLGETFRAGDATAINDEX)(GLuint,const GLchar *); +WXE_EXTERN WXEGLGETFRAGDATAINDEX weglGetFragDataIndex; +typedef void (APIENTRY * WXEGLGENSAMPLERS)(GLsizei,GLuint *); +WXE_EXTERN WXEGLGENSAMPLERS weglGenSamplers; +typedef void (APIENTRY * WXEGLDELETESAMPLERS)(GLsizei,const GLuint *); +WXE_EXTERN WXEGLDELETESAMPLERS weglDeleteSamplers; +typedef GLboolean (APIENTRY * WXEGLISSAMPLER)(GLuint); +WXE_EXTERN WXEGLISSAMPLER weglIsSampler; +typedef void (APIENTRY * WXEGLBINDSAMPLER)(GLuint,GLuint); +WXE_EXTERN WXEGLBINDSAMPLER weglBindSampler; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERI)(GLuint,GLenum,GLint); +WXE_EXTERN WXEGLSAMPLERPARAMETERI weglSamplerParameteri; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIV)(GLuint,GLenum,const GLint *); +WXE_EXTERN WXEGLSAMPLERPARAMETERIV weglSamplerParameteriv; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERF)(GLuint,GLenum,GLfloat); +WXE_EXTERN WXEGLSAMPLERPARAMETERF weglSamplerParameterf; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERFV)(GLuint,GLenum,const GLfloat *); +WXE_EXTERN WXEGLSAMPLERPARAMETERFV weglSamplerParameterfv; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIIV)(GLuint,GLenum,const GLint *); +WXE_EXTERN WXEGLSAMPLERPARAMETERIIV weglSamplerParameterIiv; +typedef void (APIENTRY * WXEGLSAMPLERPARAMETERIUIV)(GLuint,GLenum,const GLuint *); +WXE_EXTERN WXEGLSAMPLERPARAMETERIUIV weglSamplerParameterIuiv; +typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIV)(GLuint,GLenum,GLint *); +WXE_EXTERN WXEGLGETSAMPLERPARAMETERIV weglGetSamplerParameteriv; +typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIIV)(GLuint,GLenum,GLint *); +WXE_EXTERN WXEGLGETSAMPLERPARAMETERIIV weglGetSamplerParameterIiv; +typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERFV)(GLuint,GLenum,GLfloat *); +WXE_EXTERN WXEGLGETSAMPLERPARAMETERFV weglGetSamplerParameterfv; +typedef void (APIENTRY * WXEGLGETSAMPLERPARAMETERIUIV)(GLuint,GLenum,GLuint *); +WXE_EXTERN WXEGLGETSAMPLERPARAMETERIUIV weglGetSamplerParameterIuiv; +typedef void (APIENTRY * WXEGLQUERYCOUNTER)(GLuint,GLenum); +WXE_EXTERN WXEGLQUERYCOUNTER weglQueryCounter; +typedef void (APIENTRY * WXEGLGETQUERYOBJECTI64V)(GLuint,GLenum,GLint64 *); +WXE_EXTERN WXEGLGETQUERYOBJECTI64V weglGetQueryObjecti64v; +typedef void (APIENTRY * WXEGLGETQUERYOBJECTUI64V)(GLuint,GLenum,GLuint64 *); +WXE_EXTERN WXEGLGETQUERYOBJECTUI64V weglGetQueryObjectui64v; +typedef void (APIENTRY * WXEGLDRAWARRAYSINDIRECT)(GLenum,const GLvoid *); +WXE_EXTERN WXEGLDRAWARRAYSINDIRECT weglDrawArraysIndirect; +typedef void (APIENTRY * WXEGLDRAWELEMENTSINDIRECT)(GLenum,GLenum,const GLvoid *); +WXE_EXTERN WXEGLDRAWELEMENTSINDIRECT weglDrawElementsIndirect; +typedef void (APIENTRY * WXEGLUNIFORM1D)(GLint,GLdouble); +WXE_EXTERN WXEGLUNIFORM1D weglUniform1d; +typedef void (APIENTRY * WXEGLUNIFORM2D)(GLint,GLdouble,GLdouble); +WXE_EXTERN WXEGLUNIFORM2D weglUniform2d; +typedef void (APIENTRY * WXEGLUNIFORM3D)(GLint,GLdouble,GLdouble,GLdouble); +WXE_EXTERN WXEGLUNIFORM3D weglUniform3d; +typedef void (APIENTRY * WXEGLUNIFORM4D)(GLint,GLdouble,GLdouble,GLdouble,GLdouble); +WXE_EXTERN WXEGLUNIFORM4D weglUniform4d; +typedef void (APIENTRY * WXEGLUNIFORM1DV)(GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLUNIFORM1DV weglUniform1dv; +typedef void (APIENTRY * WXEGLUNIFORM2DV)(GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLUNIFORM2DV weglUniform2dv; +typedef void (APIENTRY * WXEGLUNIFORM3DV)(GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLUNIFORM3DV weglUniform3dv; +typedef void (APIENTRY * WXEGLUNIFORM4DV)(GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLUNIFORM4DV weglUniform4dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX2DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX2DV weglUniformMatrix2dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX3DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX3DV weglUniformMatrix3dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX4DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX4DV weglUniformMatrix4dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX2X3DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX2X3DV weglUniformMatrix2x3dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX2X4DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX2X4DV weglUniformMatrix2x4dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX3X2DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX3X2DV weglUniformMatrix3x2dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX3X4DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX3X4DV weglUniformMatrix3x4dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX4X2DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX4X2DV weglUniformMatrix4x2dv; +typedef void (APIENTRY * WXEGLUNIFORMMATRIX4X3DV)(GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLUNIFORMMATRIX4X3DV weglUniformMatrix4x3dv; +typedef void (APIENTRY * WXEGLGETUNIFORMDV)(GLuint,GLint,GLdouble *); +WXE_EXTERN WXEGLGETUNIFORMDV weglGetUniformdv; +typedef GLint (APIENTRY * WXEGLGETSUBROUTINEUNIFORMLOCATION)(GLuint,GLenum,const GLchar *); +WXE_EXTERN WXEGLGETSUBROUTINEUNIFORMLOCATION weglGetSubroutineUniformLocation; +typedef GLuint (APIENTRY * WXEGLGETSUBROUTINEINDEX)(GLuint,GLenum,const GLchar *); +WXE_EXTERN WXEGLGETSUBROUTINEINDEX weglGetSubroutineIndex; +typedef void (APIENTRY * WXEGLGETACTIVESUBROUTINEUNIFORMNAME)(GLuint,GLenum,GLuint,GLsizei,GLsizei *,GLchar *); +WXE_EXTERN WXEGLGETACTIVESUBROUTINEUNIFORMNAME weglGetActiveSubroutineUniformName; +typedef void (APIENTRY * WXEGLGETACTIVESUBROUTINENAME)(GLuint,GLenum,GLuint,GLsizei,GLsizei *,GLchar *); +WXE_EXTERN WXEGLGETACTIVESUBROUTINENAME weglGetActiveSubroutineName; +typedef void (APIENTRY * WXEGLUNIFORMSUBROUTINESUIV)(GLenum,GLsizei,const GLuint *); +WXE_EXTERN WXEGLUNIFORMSUBROUTINESUIV weglUniformSubroutinesuiv; +typedef void (APIENTRY * WXEGLGETUNIFORMSUBROUTINEUIV)(GLenum,GLint,GLuint *); +WXE_EXTERN WXEGLGETUNIFORMSUBROUTINEUIV weglGetUniformSubroutineuiv; +typedef void (APIENTRY * WXEGLGETPROGRAMSTAGEIV)(GLuint,GLenum,GLenum,GLint *); +WXE_EXTERN WXEGLGETPROGRAMSTAGEIV weglGetProgramStageiv; +typedef void (APIENTRY * WXEGLPATCHPARAMETERI)(GLenum,GLint); +WXE_EXTERN WXEGLPATCHPARAMETERI weglPatchParameteri; +typedef void (APIENTRY * WXEGLPATCHPARAMETERFV)(GLenum,const GLfloat *); +WXE_EXTERN WXEGLPATCHPARAMETERFV weglPatchParameterfv; +typedef void (APIENTRY * WXEGLBINDTRANSFORMFEEDBACK)(GLenum,GLuint); +WXE_EXTERN WXEGLBINDTRANSFORMFEEDBACK weglBindTransformFeedback; +typedef void (APIENTRY * WXEGLDELETETRANSFORMFEEDBACKS)(GLsizei,const GLuint *); +WXE_EXTERN WXEGLDELETETRANSFORMFEEDBACKS weglDeleteTransformFeedbacks; +typedef void (APIENTRY * WXEGLGENTRANSFORMFEEDBACKS)(GLsizei,GLuint *); +WXE_EXTERN WXEGLGENTRANSFORMFEEDBACKS weglGenTransformFeedbacks; +typedef GLboolean (APIENTRY * WXEGLISTRANSFORMFEEDBACK)(GLuint); +WXE_EXTERN WXEGLISTRANSFORMFEEDBACK weglIsTransformFeedback; +typedef void (APIENTRY * WXEGLPAUSETRANSFORMFEEDBACK)(); +WXE_EXTERN WXEGLPAUSETRANSFORMFEEDBACK weglPauseTransformFeedback; +typedef void (APIENTRY * WXEGLRESUMETRANSFORMFEEDBACK)(); +WXE_EXTERN WXEGLRESUMETRANSFORMFEEDBACK weglResumeTransformFeedback; +typedef void (APIENTRY * WXEGLDRAWTRANSFORMFEEDBACK)(GLenum,GLuint); +WXE_EXTERN WXEGLDRAWTRANSFORMFEEDBACK weglDrawTransformFeedback; +typedef void (APIENTRY * WXEGLDRAWTRANSFORMFEEDBACKSTREAM)(GLenum,GLuint,GLuint); +WXE_EXTERN WXEGLDRAWTRANSFORMFEEDBACKSTREAM weglDrawTransformFeedbackStream; +typedef void (APIENTRY * WXEGLBEGINQUERYINDEXED)(GLenum,GLuint,GLuint); +WXE_EXTERN WXEGLBEGINQUERYINDEXED weglBeginQueryIndexed; +typedef void (APIENTRY * WXEGLENDQUERYINDEXED)(GLenum,GLuint); +WXE_EXTERN WXEGLENDQUERYINDEXED weglEndQueryIndexed; +typedef void (APIENTRY * WXEGLGETQUERYINDEXEDIV)(GLenum,GLuint,GLenum,GLint *); +WXE_EXTERN WXEGLGETQUERYINDEXEDIV weglGetQueryIndexediv; +typedef void (APIENTRY * WXEGLRELEASESHADERCOMPILER)(); +WXE_EXTERN WXEGLRELEASESHADERCOMPILER weglReleaseShaderCompiler; +typedef void (APIENTRY * WXEGLSHADERBINARY)(GLsizei,const GLuint *,GLenum,const GLvoid *,GLsizei); +WXE_EXTERN WXEGLSHADERBINARY weglShaderBinary; +typedef void (APIENTRY * WXEGLGETSHADERPRECISIONFORMAT)(GLenum,GLenum,GLint *,GLint *); +WXE_EXTERN WXEGLGETSHADERPRECISIONFORMAT weglGetShaderPrecisionFormat; +typedef void (APIENTRY * WXEGLDEPTHRANGEF)(GLclampf,GLclampf); +WXE_EXTERN WXEGLDEPTHRANGEF weglDepthRangef; +typedef void (APIENTRY * WXEGLCLEARDEPTHF)(GLclampf); +WXE_EXTERN WXEGLCLEARDEPTHF weglClearDepthf; +typedef void (APIENTRY * WXEGLGETPROGRAMBINARY)(GLuint,GLsizei,GLsizei *,GLenum *,GLvoid *); +WXE_EXTERN WXEGLGETPROGRAMBINARY weglGetProgramBinary; +typedef void (APIENTRY * WXEGLPROGRAMBINARY)(GLuint,GLenum,const GLvoid *,GLsizei); +WXE_EXTERN WXEGLPROGRAMBINARY weglProgramBinary; +typedef void (APIENTRY * WXEGLPROGRAMPARAMETERI)(GLuint,GLenum,GLint); +WXE_EXTERN WXEGLPROGRAMPARAMETERI weglProgramParameteri; +typedef void (APIENTRY * WXEGLUSEPROGRAMSTAGES)(GLuint,GLbitfield,GLuint); +WXE_EXTERN WXEGLUSEPROGRAMSTAGES weglUseProgramStages; +typedef void (APIENTRY * WXEGLACTIVESHADERPROGRAM)(GLuint,GLuint); +WXE_EXTERN WXEGLACTIVESHADERPROGRAM weglActiveShaderProgram; +typedef GLuint (APIENTRY * WXEGLCREATESHADERPROGRAMV)(GLenum,GLsizei,const GLchar **); +WXE_EXTERN WXEGLCREATESHADERPROGRAMV weglCreateShaderProgramv; +typedef void (APIENTRY * WXEGLBINDPROGRAMPIPELINE)(GLuint); +WXE_EXTERN WXEGLBINDPROGRAMPIPELINE weglBindProgramPipeline; +typedef void (APIENTRY * WXEGLDELETEPROGRAMPIPELINES)(GLsizei,const GLuint *); +WXE_EXTERN WXEGLDELETEPROGRAMPIPELINES weglDeleteProgramPipelines; +typedef void (APIENTRY * WXEGLGENPROGRAMPIPELINES)(GLsizei,GLuint *); +WXE_EXTERN WXEGLGENPROGRAMPIPELINES weglGenProgramPipelines; +typedef GLboolean (APIENTRY * WXEGLISPROGRAMPIPELINE)(GLuint); +WXE_EXTERN WXEGLISPROGRAMPIPELINE weglIsProgramPipeline; +typedef void (APIENTRY * WXEGLGETPROGRAMPIPELINEIV)(GLuint,GLenum,GLint *); +WXE_EXTERN WXEGLGETPROGRAMPIPELINEIV weglGetProgramPipelineiv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1I)(GLuint,GLint,GLint); +WXE_EXTERN WXEGLPROGRAMUNIFORM1I weglProgramUniform1i; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1IV)(GLuint,GLint,GLsizei,const GLint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM1IV weglProgramUniform1iv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1F)(GLuint,GLint,GLfloat); +WXE_EXTERN WXEGLPROGRAMUNIFORM1F weglProgramUniform1f; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1FV)(GLuint,GLint,GLsizei,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORM1FV weglProgramUniform1fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1D)(GLuint,GLint,GLdouble); +WXE_EXTERN WXEGLPROGRAMUNIFORM1D weglProgramUniform1d; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1DV)(GLuint,GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORM1DV weglProgramUniform1dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1UI)(GLuint,GLint,GLuint); +WXE_EXTERN WXEGLPROGRAMUNIFORM1UI weglProgramUniform1ui; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM1UIV)(GLuint,GLint,GLsizei,const GLuint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM1UIV weglProgramUniform1uiv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2I)(GLuint,GLint,GLint,GLint); +WXE_EXTERN WXEGLPROGRAMUNIFORM2I weglProgramUniform2i; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2IV)(GLuint,GLint,GLsizei,const GLint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM2IV weglProgramUniform2iv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2F)(GLuint,GLint,GLfloat,GLfloat); +WXE_EXTERN WXEGLPROGRAMUNIFORM2F weglProgramUniform2f; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2FV)(GLuint,GLint,GLsizei,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORM2FV weglProgramUniform2fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2D)(GLuint,GLint,GLdouble,GLdouble); +WXE_EXTERN WXEGLPROGRAMUNIFORM2D weglProgramUniform2d; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2DV)(GLuint,GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORM2DV weglProgramUniform2dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2UI)(GLuint,GLint,GLuint,GLuint); +WXE_EXTERN WXEGLPROGRAMUNIFORM2UI weglProgramUniform2ui; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM2UIV)(GLuint,GLint,GLsizei,const GLuint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM2UIV weglProgramUniform2uiv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3I)(GLuint,GLint,GLint,GLint,GLint); +WXE_EXTERN WXEGLPROGRAMUNIFORM3I weglProgramUniform3i; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3IV)(GLuint,GLint,GLsizei,const GLint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM3IV weglProgramUniform3iv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3F)(GLuint,GLint,GLfloat,GLfloat,GLfloat); +WXE_EXTERN WXEGLPROGRAMUNIFORM3F weglProgramUniform3f; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3FV)(GLuint,GLint,GLsizei,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORM3FV weglProgramUniform3fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3D)(GLuint,GLint,GLdouble,GLdouble,GLdouble); +WXE_EXTERN WXEGLPROGRAMUNIFORM3D weglProgramUniform3d; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3DV)(GLuint,GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORM3DV weglProgramUniform3dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3UI)(GLuint,GLint,GLuint,GLuint,GLuint); +WXE_EXTERN WXEGLPROGRAMUNIFORM3UI weglProgramUniform3ui; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM3UIV)(GLuint,GLint,GLsizei,const GLuint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM3UIV weglProgramUniform3uiv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4I)(GLuint,GLint,GLint,GLint,GLint,GLint); +WXE_EXTERN WXEGLPROGRAMUNIFORM4I weglProgramUniform4i; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4IV)(GLuint,GLint,GLsizei,const GLint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM4IV weglProgramUniform4iv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4F)(GLuint,GLint,GLfloat,GLfloat,GLfloat,GLfloat); +WXE_EXTERN WXEGLPROGRAMUNIFORM4F weglProgramUniform4f; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4FV)(GLuint,GLint,GLsizei,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORM4FV weglProgramUniform4fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4D)(GLuint,GLint,GLdouble,GLdouble,GLdouble,GLdouble); +WXE_EXTERN WXEGLPROGRAMUNIFORM4D weglProgramUniform4d; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4DV)(GLuint,GLint,GLsizei,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORM4DV weglProgramUniform4dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4UI)(GLuint,GLint,GLuint,GLuint,GLuint,GLuint); +WXE_EXTERN WXEGLPROGRAMUNIFORM4UI weglProgramUniform4ui; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORM4UIV)(GLuint,GLint,GLsizei,const GLuint *); +WXE_EXTERN WXEGLPROGRAMUNIFORM4UIV weglProgramUniform4uiv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2FV weglProgramUniformMatrix2fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3FV weglProgramUniformMatrix3fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4FV weglProgramUniformMatrix4fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2DV weglProgramUniformMatrix2dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3DV weglProgramUniformMatrix3dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4DV weglProgramUniformMatrix4dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X3FV weglProgramUniformMatrix2x3fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X2FV weglProgramUniformMatrix3x2fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X4FV weglProgramUniformMatrix2x4fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X2FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X2FV weglProgramUniformMatrix4x2fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X4FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X4FV weglProgramUniformMatrix3x4fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X3FV)(GLuint,GLint,GLsizei,GLboolean,const GLfloat *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X3FV weglProgramUniformMatrix4x3fv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X3DV weglProgramUniformMatrix2x3dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X2DV weglProgramUniformMatrix3x2dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX2X4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX2X4DV weglProgramUniformMatrix2x4dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X2DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X2DV weglProgramUniformMatrix4x2dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX3X4DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX3X4DV weglProgramUniformMatrix3x4dv; +typedef void (APIENTRY * WXEGLPROGRAMUNIFORMMATRIX4X3DV)(GLuint,GLint,GLsizei,GLboolean,const GLdouble *); +WXE_EXTERN WXEGLPROGRAMUNIFORMMATRIX4X3DV weglProgramUniformMatrix4x3dv; +typedef void (APIENTRY * WXEGLVALIDATEPROGRAMPIPELINE)(GLuint); +WXE_EXTERN WXEGLVALIDATEPROGRAMPIPELINE weglValidateProgramPipeline; +typedef void (APIENTRY * WXEGLGETPROGRAMPIPELINEINFOLOG)(GLuint,GLsizei,GLsizei *,GLchar *); +WXE_EXTERN WXEGLGETPROGRAMPIPELINEINFOLOG weglGetProgramPipelineInfoLog; +typedef void (APIENTRY * WXEGLVERTEXATTRIBL1DV)(GLuint,const GLdouble *); +WXE_EXTERN WXEGLVERTEXATTRIBL1DV weglVertexAttribL1dv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBL2DV)(GLuint,const GLdouble *); +WXE_EXTERN WXEGLVERTEXATTRIBL2DV weglVertexAttribL2dv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBL3DV)(GLuint,const GLdouble *); +WXE_EXTERN WXEGLVERTEXATTRIBL3DV weglVertexAttribL3dv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBL4DV)(GLuint,const GLdouble *); +WXE_EXTERN WXEGLVERTEXATTRIBL4DV weglVertexAttribL4dv; +typedef void (APIENTRY * WXEGLVERTEXATTRIBLPOINTER)(GLuint,GLint,GLenum,GLsizei,const GLvoid *); +WXE_EXTERN WXEGLVERTEXATTRIBLPOINTER weglVertexAttribLPointer; +typedef void (APIENTRY * WXEGLGETVERTEXATTRIBLDV)(GLuint,GLenum,GLdouble *); +WXE_EXTERN WXEGLGETVERTEXATTRIBLDV weglGetVertexAttribLdv; +typedef void (APIENTRY * WXEGLVIEWPORTARRAYV)(GLuint,GLsizei,const GLfloat *); +WXE_EXTERN WXEGLVIEWPORTARRAYV weglViewportArrayv; +typedef void (APIENTRY * WXEGLVIEWPORTINDEXEDF)(GLuint,GLfloat,GLfloat,GLfloat,GLfloat); +WXE_EXTERN WXEGLVIEWPORTINDEXEDF weglViewportIndexedf; +typedef void (APIENTRY * WXEGLVIEWPORTINDEXEDFV)(GLuint,const GLfloat *); +WXE_EXTERN WXEGLVIEWPORTINDEXEDFV weglViewportIndexedfv; +typedef void (APIENTRY * WXEGLSCISSORARRAYV)(GLuint,GLsizei,const GLint *); +WXE_EXTERN WXEGLSCISSORARRAYV weglScissorArrayv; +typedef void (APIENTRY * WXEGLSCISSORINDEXED)(GLuint,GLint,GLint,GLsizei,GLsizei); +WXE_EXTERN WXEGLSCISSORINDEXED weglScissorIndexed; +typedef void (APIENTRY * WXEGLSCISSORINDEXEDV)(GLuint,const GLint *); +WXE_EXTERN WXEGLSCISSORINDEXEDV weglScissorIndexedv; +typedef void (APIENTRY * WXEGLDEPTHRANGEARRAYV)(GLuint,GLsizei,const GLclampd *); +WXE_EXTERN WXEGLDEPTHRANGEARRAYV weglDepthRangeArrayv; +typedef void (APIENTRY * WXEGLDEPTHRANGEINDEXED)(GLuint,GLclampd,GLclampd); +WXE_EXTERN WXEGLDEPTHRANGEINDEXED weglDepthRangeIndexed; +typedef void (APIENTRY * WXEGLGETFLOATI_V)(GLenum,GLuint,GLfloat *); +WXE_EXTERN WXEGLGETFLOATI_V weglGetFloati_v; +typedef void (APIENTRY * WXEGLGETDOUBLEI_V)(GLenum,GLuint,GLdouble *); +WXE_EXTERN WXEGLGETDOUBLEI_V weglGetDoublei_v; +typedef void (APIENTRY * WXEGLDEBUGMESSAGECONTROLARB)(GLenum,GLenum,GLenum,GLsizei,const GLuint *,GLboolean); +WXE_EXTERN WXEGLDEBUGMESSAGECONTROLARB weglDebugMessageControlARB; +typedef void (APIENTRY * WXEGLDEBUGMESSAGEINSERTARB)(GLenum,GLenum,GLuint,GLenum,GLsizei,const GLchar *); +WXE_EXTERN WXEGLDEBUGMESSAGEINSERTARB weglDebugMessageInsertARB; +typedef GLuint (APIENTRY * WXEGLGETDEBUGMESSAGELOGARB)(GLuint,GLsizei,GLenum *,GLenum *,GLuint *,GLenum *,GLsizei *,GLchar *); +WXE_EXTERN WXEGLGETDEBUGMESSAGELOGARB weglGetDebugMessageLogARB; +typedef GLenum (APIENTRY * WXEGLGETGRAPHICSRESETSTATUSARB)(); +WXE_EXTERN WXEGLGETGRAPHICSRESETSTATUSARB weglGetGraphicsResetStatusARB; typedef void (APIENTRY * WXEGLRESIZEBUFFERSMESA)(); WXE_EXTERN WXEGLRESIZEBUFFERSMESA weglResizeBuffersMESA; typedef void (APIENTRY * WXEGLWINDOWPOS4DVMESA)(const GLdouble *); diff --git a/lib/wx/c_src/gen/gl_finit.h b/lib/wx/c_src/gen/gl_finit.h index ef29f05c4d..583e36faf7 100644 --- a/lib/wx/c_src/gen/gl_finit.h +++ b/lib/wx/c_src/gen/gl_finit.h @@ -18,11 +18,7 @@ */ /***** This file is generated do not edit ****/ -static struct { - const char * name; - const char * alt; - void * func; -} gl_fns[] = +gl_fns_t gl_fns[] = { {"glAccum", NULL, &weglAccum}, {"glAlphaFunc", NULL, &weglAlphaFunc}, @@ -394,7 +390,7 @@ static struct { {"glBufferData", "glBufferDataARB", &weglBufferData}, {"glBufferSubData", "glBufferSubDataARB", &weglBufferSubData}, {"glGetBufferSubData", "glGetBufferSubDataARB", &weglGetBufferSubData}, - {"glGetBufferParameteriv", "glGetBufferParameterivARB", &weglGetBufferParameteriv}, + {"glGetBufferParameteriv", NULL, &weglGetBufferParameteriv}, {"glBlendEquationSeparate", "glBlendEquationSeparateEXT", &weglBlendEquationSeparate}, {"glDrawBuffers", "glDrawBuffersARB", &weglDrawBuffers}, {"glStencilOpSeparate", "glStencilOpSeparateATI", &weglStencilOpSeparate}, @@ -498,6 +494,18 @@ static struct { {"glVertexAttribIPointer", NULL, &weglVertexAttribIPointer}, {"glGetVertexAttribIiv", NULL, &weglGetVertexAttribIiv}, {"glGetVertexAttribIuiv", NULL, &weglGetVertexAttribIuiv}, + {"glVertexAttribI1iv", NULL, &weglVertexAttribI1iv}, + {"glVertexAttribI2iv", NULL, &weglVertexAttribI2iv}, + {"glVertexAttribI3iv", NULL, &weglVertexAttribI3iv}, + {"glVertexAttribI4iv", NULL, &weglVertexAttribI4iv}, + {"glVertexAttribI1uiv", NULL, &weglVertexAttribI1uiv}, + {"glVertexAttribI2uiv", NULL, &weglVertexAttribI2uiv}, + {"glVertexAttribI3uiv", NULL, &weglVertexAttribI3uiv}, + {"glVertexAttribI4uiv", NULL, &weglVertexAttribI4uiv}, + {"glVertexAttribI4bv", NULL, &weglVertexAttribI4bv}, + {"glVertexAttribI4sv", NULL, &weglVertexAttribI4sv}, + {"glVertexAttribI4ubv", NULL, &weglVertexAttribI4ubv}, + {"glVertexAttribI4usv", NULL, &weglVertexAttribI4usv}, {"glGetUniformuiv", NULL, &weglGetUniformuiv}, {"glBindFragDataLocation", NULL, &weglBindFragDataLocation}, {"glGetFragDataLocation", NULL, &weglGetFragDataLocation}, @@ -518,22 +526,19 @@ static struct { {"glClearBufferfv", NULL, &weglClearBufferfv}, {"glClearBufferfi", NULL, &weglClearBufferfi}, {"glGetStringi", NULL, &weglGetStringi}, - {"glVertexAttribI1iv", NULL, &weglVertexAttribI1iv}, - {"glVertexAttribI2iv", NULL, &weglVertexAttribI2iv}, - {"glVertexAttribI3iv", NULL, &weglVertexAttribI3iv}, - {"glVertexAttribI4iv", NULL, &weglVertexAttribI4iv}, - {"glVertexAttribI1uiv", NULL, &weglVertexAttribI1uiv}, - {"glVertexAttribI2uiv", NULL, &weglVertexAttribI2uiv}, - {"glVertexAttribI3uiv", NULL, &weglVertexAttribI3uiv}, - {"glVertexAttribI4uiv", NULL, &weglVertexAttribI4uiv}, - {"glVertexAttribI4bv", NULL, &weglVertexAttribI4bv}, - {"glVertexAttribI4sv", NULL, &weglVertexAttribI4sv}, - {"glVertexAttribI4ubv", NULL, &weglVertexAttribI4ubv}, - {"glVertexAttribI4usv", NULL, &weglVertexAttribI4usv}, {"glDrawArraysInstanced", "glDrawArraysInstancedARB", &weglDrawArraysInstanced}, {"glDrawElementsInstanced", "glDrawElementsInstancedARB", &weglDrawElementsInstanced}, {"glTexBuffer", "glTexBufferARB", &weglTexBuffer}, {"glPrimitiveRestartIndex", NULL, &weglPrimitiveRestartIndex}, + {"glGetInteger64i_v", NULL, &weglGetInteger64i_v}, + {"glGetBufferParameteri64v", NULL, &weglGetBufferParameteri64v}, + {"glFramebufferTexture", "glFramebufferTextureARB", &weglFramebufferTexture}, + {"glVertexAttribDivisor", "glVertexAttribDivisorARB", &weglVertexAttribDivisor}, + {"glMinSampleShading", "glMinSampleShadingARB", &weglMinSampleShading}, + {"glBlendEquationi", "glBlendEquationiARB", &weglBlendEquationi}, + {"glBlendEquationSeparatei", "glBlendEquationSeparateiARB", &weglBlendEquationSeparatei}, + {"glBlendFunci", "glBlendFunciARB", &weglBlendFunci}, + {"glBlendFuncSeparatei", "glBlendFuncSeparateiARB", &weglBlendFuncSeparatei}, {"glLoadTransposeMatrixfARB", NULL, &weglLoadTransposeMatrixfARB}, {"glLoadTransposeMatrixdARB", NULL, &weglLoadTransposeMatrixdARB}, {"glMultTransposeMatrixfARB", NULL, &weglMultTransposeMatrixfARB}, @@ -568,6 +573,7 @@ static struct { {"glGetProgramLocalParameterdvARB", NULL, &weglGetProgramLocalParameterdvARB}, {"glGetProgramLocalParameterfvARB", NULL, &weglGetProgramLocalParameterfvARB}, {"glGetProgramStringARB", NULL, &weglGetProgramStringARB}, + {"glGetBufferParameterivARB", NULL, &weglGetBufferParameterivARB}, {"glDeleteObjectARB", NULL, &weglDeleteObjectARB}, {"glGetHandleARB", NULL, &weglGetHandleARB}, {"glDetachObjectARB", NULL, &weglDetachObjectARB}, @@ -611,10 +617,7 @@ static struct { {"glBlitFramebuffer", "glBlitFramebufferEXT", &weglBlitFramebuffer}, {"glRenderbufferStorageMultisample", "glRenderbufferStorageMultisampleEXT", &weglRenderbufferStorageMultisample}, {"glFramebufferTextureLayer", "glFramebufferTextureLayerARB", &weglFramebufferTextureLayer}, - {"glProgramParameteriARB", NULL, &weglProgramParameteriARB}, - {"glFramebufferTextureARB", NULL, &weglFramebufferTextureARB}, {"glFramebufferTextureFaceARB", NULL, &weglFramebufferTextureFaceARB}, - {"glVertexAttribDivisorARB", NULL, &weglVertexAttribDivisorARB}, {"glFlushMappedBufferRange", NULL, &weglFlushMappedBufferRange}, {"glBindVertexArray", NULL, &weglBindVertexArray}, {"glDeleteVertexArrays", NULL, &weglDeleteVertexArrays}, @@ -628,6 +631,174 @@ static struct { {"glGetActiveUniformBlockName", NULL, &weglGetActiveUniformBlockName}, {"glUniformBlockBinding", NULL, &weglUniformBlockBinding}, {"glCopyBufferSubData", NULL, &weglCopyBufferSubData}, + {"glDrawElementsBaseVertex", NULL, &weglDrawElementsBaseVertex}, + {"glDrawRangeElementsBaseVertex", NULL, &weglDrawRangeElementsBaseVertex}, + {"glDrawElementsInstancedBaseVertex", NULL, &weglDrawElementsInstancedBaseVertex}, + {"glProvokingVertex", NULL, &weglProvokingVertex}, + {"glFenceSync", NULL, &weglFenceSync}, + {"glIsSync", NULL, &weglIsSync}, + {"glDeleteSync", NULL, &weglDeleteSync}, + {"glClientWaitSync", NULL, &weglClientWaitSync}, + {"glWaitSync", NULL, &weglWaitSync}, + {"glGetInteger64v", NULL, &weglGetInteger64v}, + {"glGetSynciv", NULL, &weglGetSynciv}, + {"glTexImage2DMultisample", NULL, &weglTexImage2DMultisample}, + {"glTexImage3DMultisample", NULL, &weglTexImage3DMultisample}, + {"glGetMultisamplefv", NULL, &weglGetMultisamplefv}, + {"glSampleMaski", NULL, &weglSampleMaski}, + {"glNamedStringARB", NULL, &weglNamedStringARB}, + {"glDeleteNamedStringARB", NULL, &weglDeleteNamedStringARB}, + {"glCompileShaderIncludeARB", NULL, &weglCompileShaderIncludeARB}, + {"glIsNamedStringARB", NULL, &weglIsNamedStringARB}, + {"glGetNamedStringARB", NULL, &weglGetNamedStringARB}, + {"glGetNamedStringivARB", NULL, &weglGetNamedStringivARB}, + {"glBindFragDataLocationIndexed", NULL, &weglBindFragDataLocationIndexed}, + {"glGetFragDataIndex", NULL, &weglGetFragDataIndex}, + {"glGenSamplers", NULL, &weglGenSamplers}, + {"glDeleteSamplers", NULL, &weglDeleteSamplers}, + {"glIsSampler", NULL, &weglIsSampler}, + {"glBindSampler", NULL, &weglBindSampler}, + {"glSamplerParameteri", NULL, &weglSamplerParameteri}, + {"glSamplerParameteriv", NULL, &weglSamplerParameteriv}, + {"glSamplerParameterf", NULL, &weglSamplerParameterf}, + {"glSamplerParameterfv", NULL, &weglSamplerParameterfv}, + {"glSamplerParameterIiv", NULL, &weglSamplerParameterIiv}, + {"glSamplerParameterIuiv", NULL, &weglSamplerParameterIuiv}, + {"glGetSamplerParameteriv", NULL, &weglGetSamplerParameteriv}, + {"glGetSamplerParameterIiv", NULL, &weglGetSamplerParameterIiv}, + {"glGetSamplerParameterfv", NULL, &weglGetSamplerParameterfv}, + {"glGetSamplerParameterIuiv", NULL, &weglGetSamplerParameterIuiv}, + {"glQueryCounter", NULL, &weglQueryCounter}, + {"glGetQueryObjecti64v", NULL, &weglGetQueryObjecti64v}, + {"glGetQueryObjectui64v", NULL, &weglGetQueryObjectui64v}, + {"glDrawArraysIndirect", NULL, &weglDrawArraysIndirect}, + {"glDrawElementsIndirect", NULL, &weglDrawElementsIndirect}, + {"glUniform1d", NULL, &weglUniform1d}, + {"glUniform2d", NULL, &weglUniform2d}, + {"glUniform3d", NULL, &weglUniform3d}, + {"glUniform4d", NULL, &weglUniform4d}, + {"glUniform1dv", NULL, &weglUniform1dv}, + {"glUniform2dv", NULL, &weglUniform2dv}, + {"glUniform3dv", NULL, &weglUniform3dv}, + {"glUniform4dv", NULL, &weglUniform4dv}, + {"glUniformMatrix2dv", NULL, &weglUniformMatrix2dv}, + {"glUniformMatrix3dv", NULL, &weglUniformMatrix3dv}, + {"glUniformMatrix4dv", NULL, &weglUniformMatrix4dv}, + {"glUniformMatrix2x3dv", NULL, &weglUniformMatrix2x3dv}, + {"glUniformMatrix2x4dv", NULL, &weglUniformMatrix2x4dv}, + {"glUniformMatrix3x2dv", NULL, &weglUniformMatrix3x2dv}, + {"glUniformMatrix3x4dv", NULL, &weglUniformMatrix3x4dv}, + {"glUniformMatrix4x2dv", NULL, &weglUniformMatrix4x2dv}, + {"glUniformMatrix4x3dv", NULL, &weglUniformMatrix4x3dv}, + {"glGetUniformdv", NULL, &weglGetUniformdv}, + {"glGetSubroutineUniformLocation", NULL, &weglGetSubroutineUniformLocation}, + {"glGetSubroutineIndex", NULL, &weglGetSubroutineIndex}, + {"glGetActiveSubroutineUniformName", NULL, &weglGetActiveSubroutineUniformName}, + {"glGetActiveSubroutineName", NULL, &weglGetActiveSubroutineName}, + {"glUniformSubroutinesuiv", NULL, &weglUniformSubroutinesuiv}, + {"glGetUniformSubroutineuiv", NULL, &weglGetUniformSubroutineuiv}, + {"glGetProgramStageiv", NULL, &weglGetProgramStageiv}, + {"glPatchParameteri", NULL, &weglPatchParameteri}, + {"glPatchParameterfv", NULL, &weglPatchParameterfv}, + {"glBindTransformFeedback", NULL, &weglBindTransformFeedback}, + {"glDeleteTransformFeedbacks", NULL, &weglDeleteTransformFeedbacks}, + {"glGenTransformFeedbacks", NULL, &weglGenTransformFeedbacks}, + {"glIsTransformFeedback", NULL, &weglIsTransformFeedback}, + {"glPauseTransformFeedback", NULL, &weglPauseTransformFeedback}, + {"glResumeTransformFeedback", NULL, &weglResumeTransformFeedback}, + {"glDrawTransformFeedback", NULL, &weglDrawTransformFeedback}, + {"glDrawTransformFeedbackStream", NULL, &weglDrawTransformFeedbackStream}, + {"glBeginQueryIndexed", NULL, &weglBeginQueryIndexed}, + {"glEndQueryIndexed", NULL, &weglEndQueryIndexed}, + {"glGetQueryIndexediv", NULL, &weglGetQueryIndexediv}, + {"glReleaseShaderCompiler", NULL, &weglReleaseShaderCompiler}, + {"glShaderBinary", NULL, &weglShaderBinary}, + {"glGetShaderPrecisionFormat", NULL, &weglGetShaderPrecisionFormat}, + {"glDepthRangef", NULL, &weglDepthRangef}, + {"glClearDepthf", NULL, &weglClearDepthf}, + {"glGetProgramBinary", NULL, &weglGetProgramBinary}, + {"glProgramBinary", NULL, &weglProgramBinary}, + {"glProgramParameteri", "glProgramParameteriARB", &weglProgramParameteri}, + {"glUseProgramStages", NULL, &weglUseProgramStages}, + {"glActiveShaderProgram", NULL, &weglActiveShaderProgram}, + {"glCreateShaderProgramv", NULL, &weglCreateShaderProgramv}, + {"glBindProgramPipeline", NULL, &weglBindProgramPipeline}, + {"glDeleteProgramPipelines", NULL, &weglDeleteProgramPipelines}, + {"glGenProgramPipelines", NULL, &weglGenProgramPipelines}, + {"glIsProgramPipeline", NULL, &weglIsProgramPipeline}, + {"glGetProgramPipelineiv", NULL, &weglGetProgramPipelineiv}, + {"glProgramUniform1i", NULL, &weglProgramUniform1i}, + {"glProgramUniform1iv", NULL, &weglProgramUniform1iv}, + {"glProgramUniform1f", NULL, &weglProgramUniform1f}, + {"glProgramUniform1fv", NULL, &weglProgramUniform1fv}, + {"glProgramUniform1d", NULL, &weglProgramUniform1d}, + {"glProgramUniform1dv", NULL, &weglProgramUniform1dv}, + {"glProgramUniform1ui", NULL, &weglProgramUniform1ui}, + {"glProgramUniform1uiv", NULL, &weglProgramUniform1uiv}, + {"glProgramUniform2i", NULL, &weglProgramUniform2i}, + {"glProgramUniform2iv", NULL, &weglProgramUniform2iv}, + {"glProgramUniform2f", NULL, &weglProgramUniform2f}, + {"glProgramUniform2fv", NULL, &weglProgramUniform2fv}, + {"glProgramUniform2d", NULL, &weglProgramUniform2d}, + {"glProgramUniform2dv", NULL, &weglProgramUniform2dv}, + {"glProgramUniform2ui", NULL, &weglProgramUniform2ui}, + {"glProgramUniform2uiv", NULL, &weglProgramUniform2uiv}, + {"glProgramUniform3i", NULL, &weglProgramUniform3i}, + {"glProgramUniform3iv", NULL, &weglProgramUniform3iv}, + {"glProgramUniform3f", NULL, &weglProgramUniform3f}, + {"glProgramUniform3fv", NULL, &weglProgramUniform3fv}, + {"glProgramUniform3d", NULL, &weglProgramUniform3d}, + {"glProgramUniform3dv", NULL, &weglProgramUniform3dv}, + {"glProgramUniform3ui", NULL, &weglProgramUniform3ui}, + {"glProgramUniform3uiv", NULL, &weglProgramUniform3uiv}, + {"glProgramUniform4i", NULL, &weglProgramUniform4i}, + {"glProgramUniform4iv", NULL, &weglProgramUniform4iv}, + {"glProgramUniform4f", NULL, &weglProgramUniform4f}, + {"glProgramUniform4fv", NULL, &weglProgramUniform4fv}, + {"glProgramUniform4d", NULL, &weglProgramUniform4d}, + {"glProgramUniform4dv", NULL, &weglProgramUniform4dv}, + {"glProgramUniform4ui", NULL, &weglProgramUniform4ui}, + {"glProgramUniform4uiv", NULL, &weglProgramUniform4uiv}, + {"glProgramUniformMatrix2fv", NULL, &weglProgramUniformMatrix2fv}, + {"glProgramUniformMatrix3fv", NULL, &weglProgramUniformMatrix3fv}, + {"glProgramUniformMatrix4fv", NULL, &weglProgramUniformMatrix4fv}, + {"glProgramUniformMatrix2dv", NULL, &weglProgramUniformMatrix2dv}, + {"glProgramUniformMatrix3dv", NULL, &weglProgramUniformMatrix3dv}, + {"glProgramUniformMatrix4dv", NULL, &weglProgramUniformMatrix4dv}, + {"glProgramUniformMatrix2x3fv", NULL, &weglProgramUniformMatrix2x3fv}, + {"glProgramUniformMatrix3x2fv", NULL, &weglProgramUniformMatrix3x2fv}, + {"glProgramUniformMatrix2x4fv", NULL, &weglProgramUniformMatrix2x4fv}, + {"glProgramUniformMatrix4x2fv", NULL, &weglProgramUniformMatrix4x2fv}, + {"glProgramUniformMatrix3x4fv", NULL, &weglProgramUniformMatrix3x4fv}, + {"glProgramUniformMatrix4x3fv", NULL, &weglProgramUniformMatrix4x3fv}, + {"glProgramUniformMatrix2x3dv", NULL, &weglProgramUniformMatrix2x3dv}, + {"glProgramUniformMatrix3x2dv", NULL, &weglProgramUniformMatrix3x2dv}, + {"glProgramUniformMatrix2x4dv", NULL, &weglProgramUniformMatrix2x4dv}, + {"glProgramUniformMatrix4x2dv", NULL, &weglProgramUniformMatrix4x2dv}, + {"glProgramUniformMatrix3x4dv", NULL, &weglProgramUniformMatrix3x4dv}, + {"glProgramUniformMatrix4x3dv", NULL, &weglProgramUniformMatrix4x3dv}, + {"glValidateProgramPipeline", NULL, &weglValidateProgramPipeline}, + {"glGetProgramPipelineInfoLog", NULL, &weglGetProgramPipelineInfoLog}, + {"glVertexAttribL1dv", NULL, &weglVertexAttribL1dv}, + {"glVertexAttribL2dv", NULL, &weglVertexAttribL2dv}, + {"glVertexAttribL3dv", NULL, &weglVertexAttribL3dv}, + {"glVertexAttribL4dv", NULL, &weglVertexAttribL4dv}, + {"glVertexAttribLPointer", NULL, &weglVertexAttribLPointer}, + {"glGetVertexAttribLdv", NULL, &weglGetVertexAttribLdv}, + {"glViewportArrayv", NULL, &weglViewportArrayv}, + {"glViewportIndexedf", NULL, &weglViewportIndexedf}, + {"glViewportIndexedfv", NULL, &weglViewportIndexedfv}, + {"glScissorArrayv", NULL, &weglScissorArrayv}, + {"glScissorIndexed", NULL, &weglScissorIndexed}, + {"glScissorIndexedv", NULL, &weglScissorIndexedv}, + {"glDepthRangeArrayv", NULL, &weglDepthRangeArrayv}, + {"glDepthRangeIndexed", NULL, &weglDepthRangeIndexed}, + {"glGetFloati_v", NULL, &weglGetFloati_v}, + {"glGetDoublei_v", NULL, &weglGetDoublei_v}, + {"glDebugMessageControlARB", NULL, &weglDebugMessageControlARB}, + {"glDebugMessageInsertARB", NULL, &weglDebugMessageInsertARB}, + {"glGetDebugMessageLogARB", NULL, &weglGetDebugMessageLogARB}, + {"glGetGraphicsResetStatusARB", NULL, &weglGetGraphicsResetStatusARB}, {"glResizeBuffersMESA", NULL, &weglResizeBuffersMESA}, {"glWindowPos4dvMESA", NULL, &weglWindowPos4dvMESA}, {"glWindowPos4fvMESA", NULL, &weglWindowPos4fvMESA}, diff --git a/lib/wx/c_src/gen/gl_funcs.cpp b/lib/wx/c_src/gen/gl_funcs.cpp index 95d3c23b23..30542a0f02 100644 --- a/lib/wx/c_src/gen/gl_funcs.cpp +++ b/lib/wx/c_src/gen/gl_funcs.cpp @@ -20,37 +20,17 @@ #include <stdio.h> #include <string.h> -#include "../wxe_impl.h" -#include "../wxe_gl.h" +#include "../egl_impl.h" #include "gl_fdefs.h" -int gl_error_op; -void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ - gl_error_op = op; - if(caller != gl_active) { - wxGLCanvas * current = glc[caller]; - if(current) { gl_active = caller; current->SetCurrent();} - else { - ErlDrvTermData rt[] = // Error msg - {ERL_DRV_ATOM, driver_mk_atom((char *) "_wxe_error_"), - ERL_DRV_INT, op, - ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"), - ERL_DRV_TUPLE,3}; - driver_send_term(WXE_DRV_PORT,caller,rt,8); - return ; - } - }; +extern gl_fns_t gl_fns[]; +void egl_dispatch(int op, char *bp, ErlDrvPort port, ErlDrvTermData caller, char *bins[], int bins_sz[]){ + try { switch(op) { case 5000: - wxe_tess_impl(bp, caller); - break; - case WXE_BIN_INCR: - driver_binary_inc_refc(bins[0]->bin); - break; - case WXE_BIN_DECR: - driver_binary_dec_refc(bins[0]->bin); + erl_tess_impl(bp, port, caller); break; case 5010: { // gluBuild1DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; @@ -61,14 +41,13 @@ case 5010: { // gluBuild1DMipmapLevels GLint *level = (GLint *) bp; bp += 4; GLint *base = (GLint *) bp; bp += 4; GLint *max = (GLint *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild1DMipmapLevels(*target,*internalFormat,*width,*format,*type,*level,*base,*max,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5011: { // gluBuild1DMipmaps GLenum *target = (GLenum *) bp; bp += 4; @@ -76,14 +55,13 @@ case 5011: { // gluBuild1DMipmaps GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild1DMipmaps(*target,*internalFormat,*width,*format,*type,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5012: { // gluBuild2DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; @@ -95,14 +73,13 @@ case 5012: { // gluBuild2DMipmapLevels GLint *level = (GLint *) bp; bp += 4; GLint *base = (GLint *) bp; bp += 4; GLint *max = (GLint *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild2DMipmapLevels(*target,*internalFormat,*width,*height,*format,*type,*level,*base,*max,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5013: { // gluBuild2DMipmaps GLenum *target = (GLenum *) bp; bp += 4; @@ -111,14 +88,13 @@ case 5013: { // gluBuild2DMipmaps GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild2DMipmaps(*target,*internalFormat,*width,*height,*format,*type,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5014: { // gluBuild3DMipmapLevels GLenum *target = (GLenum *) bp; bp += 4; @@ -131,14 +107,13 @@ case 5014: { // gluBuild3DMipmapLevels GLint *level = (GLint *) bp; bp += 4; GLint *base = (GLint *) bp; bp += 4; GLint *max = (GLint *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild3DMipmapLevels(*target,*internalFormat,*width,*height,*depth,*format,*type,*level,*base,*max,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5015: { // gluBuild3DMipmaps GLenum *target = (GLenum *) bp; bp += 4; @@ -148,27 +123,25 @@ case 5015: { // gluBuild3DMipmaps GLsizei *depth = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - void *data = (void *) bins[0]->base; + void *data = (void *) bins[0]; GLint result = wegluBuild3DMipmaps(*target,*internalFormat,*width,*height,*depth,*format,*type,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5016: { // gluCheckExtension - int * extNameLen = (int *) bp; bp += 4; - GLubyte * extName = (GLubyte *) bp; bp += (8-((*extNameLen*1+4)%8))%8; - int * extStringLen = (int *) bp; bp += 4; - GLubyte * extString = (GLubyte *) bp; bp += (8-((*extStringLen*1+4)%8))%8; + GLubyte *extName = (GLubyte *) bp; + int extNameLen[1] = {strlen((char *)extName)}; bp += extNameLen[0]+1+((8-((1+extNameLen[0]+0)%8))%8); + GLubyte *extString = (GLubyte *) bp; + int extStringLen[1] = {strlen((char *)extString)}; bp += extStringLen[0]+1+((8-((1+extStringLen[0]+0)%8))%8); GLboolean result = wegluCheckExtension(extName,extString); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5017: { // gluCylinder GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; @@ -195,21 +168,19 @@ case 5020: { // gluErrorString GLenum *error = (GLenum *) bp; bp += 4; const GLubyte * result = wegluErrorString(*error); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5021: { // gluGetString GLenum *name = (GLenum *) bp; bp += 4; const GLubyte * result = wegluGetString(*name); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5022: { // gluLookAt GLdouble *eyeX = (GLdouble *) bp; bp += 8; @@ -226,11 +197,10 @@ case 5022: { // gluLookAt case 5023: { // gluNewQuadric GLUquadric * result = wegluNewQuadric(); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5024: { // gluOrtho2D GLdouble *left = (GLdouble *) bp; bp += 8; @@ -276,15 +246,14 @@ case 5028: { // gluProject GLdouble winZ[1] = {0.0}; GLint result = wegluProject(*objX,*objY,*objZ,model,proj,view,winX,winY,winZ); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winX; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winY; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) winZ; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5029: { // gluQuadricDrawStyle GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; @@ -311,18 +280,17 @@ case 5033: { // gluScaleImage GLsizei *wIn = (GLsizei *) bp; bp += 4; GLsizei *hIn = (GLsizei *) bp; bp += 4; GLenum *typeIn = (GLenum *) bp; bp += 4; - void *dataIn = (void *) bins[0]->base; + void *dataIn = (void *) bins[0]; GLsizei *wOut = (GLsizei *) bp; bp += 4; GLsizei *hOut = (GLsizei *) bp; bp += 4; GLenum *typeOut = (GLenum *) bp; bp += 4; - GLvoid *dataOut = (GLvoid *) bins[1]->base; + GLvoid *dataOut = (GLvoid *) bins[1]; GLint result = wegluScaleImage(*format,*wIn,*hIn,*typeIn,dataIn,*wOut,*hOut,*typeOut,dataOut); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5034: { // gluSphere GLUquadric * quad = (GLUquadric *) * (GLuint64EXT *) bp; bp += 8; @@ -343,15 +311,14 @@ case 5035: { // gluUnProject GLdouble objZ[1] = {0.0}; GLint result = wegluUnProject(*winX,*winY,*winZ,model,proj,view,objX,objY,objZ); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objX; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objY; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objZ; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5036: { // gluUnProject4 GLdouble *winX = (GLdouble *) bp; bp += 8; @@ -369,7 +336,7 @@ case 5036: { // gluUnProject4 GLdouble objW[1] = {0.0}; GLint result = wegluUnProject4(*winX,*winY,*winZ,*clipW,model,proj,view,*nearVal,*farVal,objX,objY,objZ,objW); int AP = 0; ErlDrvTermData rt[16]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objX; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objY; @@ -377,8 +344,7 @@ case 5036: { // gluUnProject4 rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) objW; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 5; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 16 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,16); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5037: { // glAccum GLenum *op = (GLenum *) bp; bp += 4; @@ -398,15 +364,14 @@ case 5039: { // glAreTexturesResident GLboolean result = weglAreTexturesResident(*texturesLen,textures,residences); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(11 + (*texturesLen)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; for(int i=0; i < *texturesLen; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) residences[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*texturesLen)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 11 + (*texturesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,11 + (*texturesLen)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(residences); }; break; @@ -440,7 +405,7 @@ case 5044: { // glBitmap GLfloat *yorig = (GLfloat *) bp; bp += 4; GLfloat *xmove = (GLfloat *) bp; bp += 4; GLfloat *ymove = (GLfloat *) bp; bp += 4; - GLubyte *bitmap = (GLubyte *) bins[0]->base; + GLubyte *bitmap = (GLubyte *) bins[0]; weglBitmap(*width,*height,*xorig,*yorig,*xmove,*ymove,bitmap); }; break; case 5045: { // glBlendFunc @@ -580,7 +545,7 @@ case 5074: { // glColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglColorPointer(*size,*type,*stride,pointer); }; break; case 5075: { // glCopyPixels @@ -688,7 +653,7 @@ case 5091: { // glDrawElements GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *indices = (GLvoid *) bins[0]->base; + GLvoid *indices = (GLvoid *) bins[0]; weglDrawElements(*mode,*count,*type,indices); }; break; case 5092: { // glDrawPixels @@ -704,7 +669,7 @@ case 5093: { // glDrawPixels GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglDrawPixels(*width,*height,*format,*type,pixels); }; break; case 5094: { // glEdgeFlagv @@ -718,7 +683,7 @@ case 5095: { // glEdgeFlagPointer }; break; case 5096: { // glEdgeFlagPointer GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglEdgeFlagPointer(*stride,pointer); }; break; case 5097: { // glEnable @@ -777,13 +742,13 @@ case 5108: { // glEvalPoint2 case 5109: { // glFeedbackBuffer GLsizei *size = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLfloat *buffer = (GLfloat *) bins[0]->base; + GLfloat *buffer = (GLfloat *) bins[0]; weglFeedbackBuffer(*size,*type,buffer); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5110: { // glFinish weglFinish(); @@ -830,11 +795,10 @@ case 5118: { // glGenLists GLsizei *range = (GLsizei *) bp; bp += 4; GLuint result = weglGenLists(*range); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5119: { // glGenTextures GLsizei *n = (GLsizei *) bp; bp += 4; @@ -843,13 +807,12 @@ case 5119: { // glGenTextures weglGenTextures(*n,textures); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) textures[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(textures); }; break; @@ -858,7 +821,7 @@ case 5120: { // glGetBooleanv GLboolean params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetBooleanv(*pname,params); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLboolean *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -878,15 +841,14 @@ case 5120: { // glGetBooleanv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5121: { // glGetClipPlane GLenum *plane = (GLenum *) bp; bp += 4; GLdouble equation[4] = {0.0,0.0,0.0,0.0}; weglGetClipPlane(*plane,equation); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *equationTmp = equation; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++; @@ -894,15 +856,14 @@ case 5121: { // glGetClipPlane rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) equationTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5122: { // glGetDoublev GLenum *pname = (GLenum *) bp; bp += 4; GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetDoublev(*pname,params); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *paramsTmp = params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -922,24 +883,22 @@ case 5122: { // glGetDoublev rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5123: { // glGetError GLenum result = weglGetError(); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5124: { // glGetFloatv GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetFloatv(*pname,params); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[16], *paramsTmp = paramsConv; for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -960,15 +919,14 @@ case 5124: { // glGetFloatv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5125: { // glGetIntegerv GLenum *pname = (GLenum *) bp; bp += 4; GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetIntegerv(*pname,params); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -988,8 +946,7 @@ case 5125: { // glGetIntegerv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5126: { // glGetLightfv GLenum *light = (GLenum *) bp; bp += 4; @@ -997,7 +954,7 @@ case 5126: { // glGetLightfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetLightfv(*light,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1006,8 +963,7 @@ case 5126: { // glGetLightfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5127: { // glGetLightiv GLenum *light = (GLenum *) bp; bp += 4; @@ -1015,7 +971,7 @@ case 5127: { // glGetLightiv GLint params[4] = {0,0,0,0}; weglGetLightiv(*light,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -1023,41 +979,40 @@ case 5127: { // glGetLightiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5128: { // glGetMapdv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; - GLdouble *v = (GLdouble *) bins[0]->base; + GLdouble *v = (GLdouble *) bins[0]; weglGetMapdv(*target,*query,v); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5129: { // glGetMapfv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; - GLfloat *v = (GLfloat *) bins[0]->base; + GLfloat *v = (GLfloat *) bins[0]; weglGetMapfv(*target,*query,v); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5130: { // glGetMapiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *query = (GLenum *) bp; bp += 4; - GLint *v = (GLint *) bins[0]->base; + GLint *v = (GLint *) bins[0]; weglGetMapiv(*target,*query,v); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5131: { // glGetMaterialfv GLenum *face = (GLenum *) bp; bp += 4; @@ -1065,7 +1020,7 @@ case 5131: { // glGetMaterialfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetMaterialfv(*face,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1074,8 +1029,7 @@ case 5131: { // glGetMaterialfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5132: { // glGetMaterialiv GLenum *face = (GLenum *) bp; bp += 4; @@ -1083,7 +1037,7 @@ case 5132: { // glGetMaterialiv GLint params[4] = {0,0,0,0}; weglGetMaterialiv(*face,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -1091,61 +1045,56 @@ case 5132: { // glGetMaterialiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5133: { // glGetPixelMapfv GLenum *map = (GLenum *) bp; bp += 4; - GLfloat *values = (GLfloat *) bins[0]->base; + GLfloat *values = (GLfloat *) bins[0]; weglGetPixelMapfv(*map,values); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5134: { // glGetPixelMapuiv GLenum *map = (GLenum *) bp; bp += 4; - GLuint *values = (GLuint *) bins[0]->base; + GLuint *values = (GLuint *) bins[0]; weglGetPixelMapuiv(*map,values); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5135: { // glGetPixelMapusv GLenum *map = (GLenum *) bp; bp += 4; - GLushort *values = (GLushort *) bins[0]->base; + GLushort *values = (GLushort *) bins[0]; weglGetPixelMapusv(*map,values); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5136: { // glGetPolygonStipple - GLubyte mask[128]; - weglGetPolygonStipple(mask); + ErlDrvBinary *mask = driver_alloc_binary(128); + weglGetPolygonStipple((GLubyte*) mask->orig_bytes); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); - ErlDrvBinary * BinCopy = driver_alloc_binary(128); - memcpy(BinCopy->orig_bytes, mask, 128); - rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) BinCopy; rt[AP++] = 128; rt[AP++] = 0; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) mask; rt[AP++] = 128; rt[AP++] = 0; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); - driver_free_binary(BinCopy); + driver_send_term(port,caller,rt,AP); + driver_free_binary(mask); }; break; case 5137: { // glGetString GLenum *name = (GLenum *) bp; bp += 4; const GLubyte * result = weglGetString(*name); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5138: { // glGetTexEnvfv GLenum *target = (GLenum *) bp; bp += 4; @@ -1153,7 +1102,7 @@ case 5138: { // glGetTexEnvfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetTexEnvfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1162,8 +1111,7 @@ case 5138: { // glGetTexEnvfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5139: { // glGetTexEnviv GLenum *target = (GLenum *) bp; bp += 4; @@ -1171,7 +1119,7 @@ case 5139: { // glGetTexEnviv GLint params[4] = {0,0,0,0}; weglGetTexEnviv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -1179,8 +1127,7 @@ case 5139: { // glGetTexEnviv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5140: { // glGetTexGendv GLenum *coord = (GLenum *) bp; bp += 4; @@ -1188,7 +1135,7 @@ case 5140: { // glGetTexGendv GLdouble params[4] = {0.0,0.0,0.0,0.0}; weglGetTexGendv(*coord,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *paramsTmp = params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1196,8 +1143,7 @@ case 5140: { // glGetTexGendv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5141: { // glGetTexGenfv GLenum *coord = (GLenum *) bp; bp += 4; @@ -1205,7 +1151,7 @@ case 5141: { // glGetTexGenfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetTexGenfv(*coord,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1214,8 +1160,7 @@ case 5141: { // glGetTexGenfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5142: { // glGetTexGeniv GLenum *coord = (GLenum *) bp; bp += 4; @@ -1223,7 +1168,7 @@ case 5142: { // glGetTexGeniv GLint params[4] = {0,0,0,0}; weglGetTexGeniv(*coord,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -1231,21 +1176,20 @@ case 5142: { // glGetTexGeniv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5143: { // glGetTexImage GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglGetTexImage(*target,*level,*format,*type,pixels); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5144: { // glGetTexLevelParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -1254,14 +1198,13 @@ case 5144: { // glGetTexLevelParameterfv GLfloat params[1] = {0.0}; weglGetTexLevelParameterfv(*target,*level,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[1], *paramsTmp = paramsConv; for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5145: { // glGetTexLevelParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -1270,13 +1213,12 @@ case 5145: { // glGetTexLevelParameteriv GLint params[1] = {0}; weglGetTexLevelParameteriv(*target,*level,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5146: { // glGetTexParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -1284,7 +1226,7 @@ case 5146: { // glGetTexParameterfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetTexParameterfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -1293,8 +1235,7 @@ case 5146: { // glGetTexParameterfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5147: { // glGetTexParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -1302,7 +1243,7 @@ case 5147: { // glGetTexParameteriv GLint params[4] = {0,0,0,0}; weglGetTexParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -1310,8 +1251,7 @@ case 5147: { // glGetTexParameteriv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5148: { // glHint GLenum *target = (GLenum *) bp; bp += 4; @@ -1331,7 +1271,7 @@ case 5150: { // glIndexPointer case 5151: { // glIndexPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglIndexPointer(*type,*stride,pointer); }; break; case 5152: { // glIndexdv @@ -1366,38 +1306,35 @@ case 5158: { // glInterleavedArrays case 5159: { // glInterleavedArrays GLenum *format = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglInterleavedArrays(*format,*stride,pointer); }; break; case 5160: { // glIsEnabled GLenum *cap = (GLenum *) bp; bp += 4; GLboolean result = weglIsEnabled(*cap); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5161: { // glIsList GLuint *list = (GLuint *) bp; bp += 4; GLboolean result = weglIsList(*list); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5162: { // glIsTexture GLuint *texture = (GLuint *) bp; bp += 4; GLboolean result = weglIsTexture(*texture); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5163: { // glLightModelf GLenum *pname = (GLenum *) bp; bp += 4; @@ -1486,7 +1423,7 @@ case 5179: { // glMap1d GLdouble *u2 = (GLdouble *) bp; bp += 8; GLint *stride = (GLint *) bp; bp += 4; GLint *order = (GLint *) bp; bp += 4; - GLdouble *points = (GLdouble *) bins[0]->base; + GLdouble *points = (GLdouble *) bins[0]; weglMap1d(*target,*u1,*u2,*stride,*order,points); }; break; case 5180: { // glMap1f @@ -1495,7 +1432,7 @@ case 5180: { // glMap1f GLfloat *u2 = (GLfloat *) bp; bp += 4; GLint *stride = (GLint *) bp; bp += 4; GLint *order = (GLint *) bp; bp += 4; - GLfloat *points = (GLfloat *) bins[0]->base; + GLfloat *points = (GLfloat *) bins[0]; weglMap1f(*target,*u1,*u2,*stride,*order,points); }; break; case 5181: { // glMap2d @@ -1509,7 +1446,7 @@ case 5181: { // glMap2d GLdouble *v2 = (GLdouble *) bp; bp += 8; GLint *vstride = (GLint *) bp; bp += 4; GLint *vorder = (GLint *) bp; bp += 4; - GLdouble *points = (GLdouble *) bins[0]->base; + GLdouble *points = (GLdouble *) bins[0]; weglMap2d(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points); }; break; case 5182: { // glMap2f @@ -1522,7 +1459,7 @@ case 5182: { // glMap2f GLfloat *v2 = (GLfloat *) bp; bp += 4; GLint *vstride = (GLint *) bp; bp += 4; GLint *vorder = (GLint *) bp; bp += 4; - GLfloat *points = (GLfloat *) bins[0]->base; + GLfloat *points = (GLfloat *) bins[0]; weglMap2f(*target,*u1,*u2,*ustride,*uorder,*v1,*v2,*vstride,*vorder,points); }; break; case 5183: { // glMapGrid1d @@ -1630,7 +1567,7 @@ case 5200: { // glNormalPointer case 5201: { // glNormalPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglNormalPointer(*type,*stride,pointer); }; break; case 5202: { // glOrtho @@ -1649,19 +1586,19 @@ case 5203: { // glPassThrough case 5204: { // glPixelMapfv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; - GLfloat *values = (GLfloat *) bins[0]->base; + GLfloat *values = (GLfloat *) bins[0]; weglPixelMapfv(*map,*mapsize,values); }; break; case 5205: { // glPixelMapuiv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; - GLuint *values = (GLuint *) bins[0]->base; + GLuint *values = (GLuint *) bins[0]; weglPixelMapuiv(*map,*mapsize,values); }; break; case 5206: { // glPixelMapusv GLenum *map = (GLenum *) bp; bp += 4; GLsizei *mapsize = (GLsizei *) bp; bp += 4; - GLushort *values = (GLushort *) bins[0]->base; + GLushort *values = (GLushort *) bins[0]; weglPixelMapusv(*map,*mapsize,values); }; break; case 5207: { // glPixelStoref @@ -1704,7 +1641,7 @@ case 5214: { // glPolygonOffset weglPolygonOffset(*factor,*units); }; break; case 5215: { // glPolygonStipple - GLubyte *mask = (GLubyte *) bins[0]->base; + GLubyte *mask = (GLubyte *) bins[0]; weglPolygonStipple(mask); }; break; case 5216: { // glPopAttrib @@ -1800,13 +1737,13 @@ case 5238: { // glReadPixels GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglReadPixels(*x,*y,*width,*height,*format,*type,pixels); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5239: { // glRectd GLdouble *x1 = (GLdouble *) bp; bp += 8; @@ -1860,11 +1797,10 @@ case 5247: { // glRenderMode GLenum *mode = (GLenum *) bp; bp += 4; GLint result = weglRenderMode(*mode); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5248: { // glRotated GLdouble *angle = (GLdouble *) bp; bp += 8; @@ -1901,13 +1837,13 @@ case 5252: { // glScissor }; break; case 5253: { // glSelectBuffer GLsizei *size = (GLsizei *) bp; bp += 4; - GLuint *buffer = (GLuint *) bins[0]->base; + GLuint *buffer = (GLuint *) bins[0]; weglSelectBuffer(*size,buffer); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5254: { // glShadeModel GLenum *mode = (GLenum *) bp; bp += 4; @@ -2004,7 +1940,7 @@ case 5275: { // glTexCoordPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglTexCoordPointer(*size,*type,*stride,pointer); }; break; case 5276: { // glTexEnvf @@ -2091,7 +2027,7 @@ case 5287: { // glTexImage1D GLint *border = (GLint *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexImage1D(*target,*level,*internalformat,*width,*border,*format,*type,pixels); }; break; case 5288: { // glTexImage2D @@ -2115,7 +2051,7 @@ case 5289: { // glTexImage2D GLint *border = (GLint *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexImage2D(*target,*level,*internalformat,*width,*height,*border,*format,*type,pixels); }; break; case 5290: { // glTexParameterf @@ -2161,7 +2097,7 @@ case 5295: { // glTexSubImage1D GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexSubImage1D(*target,*level,*xoffset,*width,*format,*type,pixels); }; break; case 5296: { // glTexSubImage2D @@ -2185,7 +2121,7 @@ case 5297: { // glTexSubImage2D GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*type,pixels); }; break; case 5298: { // glTranslated @@ -2259,7 +2195,7 @@ case 5313: { // glVertexPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglVertexPointer(*size,*type,*stride,pointer); }; break; case 5314: { // glViewport @@ -2295,7 +2231,7 @@ case 5318: { // glDrawRangeElements GLuint *end = (GLuint *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *indices = (GLvoid *) bins[0]->base; + GLvoid *indices = (GLvoid *) bins[0]; weglDrawRangeElements(*mode,*start,*end,*count,*type,indices); }; break; case 5319: { // glTexImage3D @@ -2321,7 +2257,7 @@ case 5320: { // glTexImage3D GLint *border = (GLint *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*format,*type,pixels); }; break; case 5321: { // glTexSubImage3D @@ -2349,7 +2285,7 @@ case 5322: { // glTexSubImage3D GLsizei *depth = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *pixels = (GLvoid *) bins[0]->base; + GLvoid *pixels = (GLvoid *) bins[0]; weglTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*type,pixels); }; break; case 5323: { // glCopyTexSubImage3D @@ -2379,7 +2315,7 @@ case 5325: { // glColorTable GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *table = (GLvoid *) bins[0]->base; + GLvoid *table = (GLvoid *) bins[0]; weglColorTable(*target,*internalformat,*width,*format,*type,table); }; break; case 5326: { // glColorTableParameterfv @@ -2406,13 +2342,13 @@ case 5329: { // glGetColorTable GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *table = (GLvoid *) bins[0]->base; + GLvoid *table = (GLvoid *) bins[0]; weglGetColorTable(*target,*format,*type,table); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5330: { // glGetColorTableParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -2420,7 +2356,7 @@ case 5330: { // glGetColorTableParameterfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetColorTableParameterfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -2429,8 +2365,7 @@ case 5330: { // glGetColorTableParameterfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5331: { // glGetColorTableParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -2438,7 +2373,7 @@ case 5331: { // glGetColorTableParameteriv GLint params[4] = {0,0,0,0}; weglGetColorTableParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -2446,8 +2381,7 @@ case 5331: { // glGetColorTableParameteriv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5332: { // glColorSubTable GLenum *target = (GLenum *) bp; bp += 4; @@ -2464,7 +2398,7 @@ case 5333: { // glColorSubTable GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglColorSubTable(*target,*start,*count,*format,*type,data); }; break; case 5334: { // glCopyColorSubTable @@ -2490,7 +2424,7 @@ case 5336: { // glConvolutionFilter1D GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *image = (GLvoid *) bins[0]->base; + GLvoid *image = (GLvoid *) bins[0]; weglConvolutionFilter1D(*target,*internalformat,*width,*format,*type,image); }; break; case 5337: { // glConvolutionFilter2D @@ -2510,7 +2444,7 @@ case 5338: { // glConvolutionFilter2D GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *image = (GLvoid *) bins[0]->base; + GLvoid *image = (GLvoid *) bins[0]; weglConvolutionFilter2D(*target,*internalformat,*width,*height,*format,*type,image); }; break; case 5339: { // glConvolutionParameterfv @@ -2548,13 +2482,13 @@ case 5343: { // glGetConvolutionFilter GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *image = (GLvoid *) bins[0]->base; + GLvoid *image = (GLvoid *) bins[0]; weglGetConvolutionFilter(*target,*format,*type,image); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5344: { // glGetConvolutionParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -2562,7 +2496,7 @@ case 5344: { // glGetConvolutionParameterfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetConvolutionParameterfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -2571,8 +2505,7 @@ case 5344: { // glGetConvolutionParameterfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5345: { // glGetConvolutionParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -2580,7 +2513,7 @@ case 5345: { // glGetConvolutionParameteriv GLint params[4] = {0,0,0,0}; weglGetConvolutionParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -2588,8 +2521,7 @@ case 5345: { // glGetConvolutionParameteriv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5346: { // glSeparableFilter2D GLenum *target = (GLenum *) bp; bp += 4; @@ -2609,8 +2541,8 @@ case 5347: { // glSeparableFilter2D GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *row = (GLvoid *) bins[0]->base; - GLvoid *column = (GLvoid *) bins[1]->base; + GLvoid *row = (GLvoid *) bins[0]; + GLvoid *column = (GLvoid *) bins[1]; weglSeparableFilter2D(*target,*internalformat,*width,*height,*format,*type,row,column); }; break; case 5348: { // glGetHistogram @@ -2619,13 +2551,13 @@ case 5348: { // glGetHistogram bp += 3; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *values = (GLvoid *) bins[0]->base; + GLvoid *values = (GLvoid *) bins[0]; weglGetHistogram(*target,*reset,*format,*type,values); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5349: { // glGetHistogramParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -2633,14 +2565,13 @@ case 5349: { // glGetHistogramParameterfv GLfloat params[1] = {0.0}; weglGetHistogramParameterfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[1], *paramsTmp = paramsConv; for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5350: { // glGetHistogramParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -2648,13 +2579,12 @@ case 5350: { // glGetHistogramParameteriv GLint params[1] = {0}; weglGetHistogramParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5351: { // glGetMinmax GLenum *target = (GLenum *) bp; bp += 4; @@ -2662,13 +2592,13 @@ case 5351: { // glGetMinmax bp += 3; GLenum *format = (GLenum *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *values = (GLvoid *) bins[0]->base; + GLvoid *values = (GLvoid *) bins[0]; weglGetMinmax(*target,*reset,*format,*type,values); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5352: { // glGetMinmaxParameterfv GLenum *target = (GLenum *) bp; bp += 4; @@ -2676,14 +2606,13 @@ case 5352: { // glGetMinmaxParameterfv GLfloat params[1] = {0.0}; weglGetMinmaxParameterfv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[1], *paramsTmp = paramsConv; for(int i=0; i < 1; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5353: { // glGetMinmaxParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -2691,13 +2620,12 @@ case 5353: { // glGetMinmaxParameteriv GLint params[1] = {0}; weglGetMinmaxParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[8]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 8 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,8); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5354: { // glHistogram GLenum *target = (GLenum *) bp; bp += 4; @@ -2750,7 +2678,7 @@ case 5361: { // glCompressedTexImage3D GLsizei *depth = (GLsizei *) bp; bp += 4; GLint *border = (GLint *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexImage3D(*target,*level,*internalformat,*width,*height,*depth,*border,*imageSize,data); }; break; case 5362: { // glCompressedTexImage2D @@ -2772,7 +2700,7 @@ case 5363: { // glCompressedTexImage2D GLsizei *height = (GLsizei *) bp; bp += 4; GLint *border = (GLint *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexImage2D(*target,*level,*internalformat,*width,*height,*border,*imageSize,data); }; break; case 5364: { // glCompressedTexImage1D @@ -2792,7 +2720,7 @@ case 5365: { // glCompressedTexImage1D GLsizei *width = (GLsizei *) bp; bp += 4; GLint *border = (GLint *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexImage1D(*target,*level,*internalformat,*width,*border,*imageSize,data); }; break; case 5366: { // glCompressedTexSubImage3D @@ -2820,7 +2748,7 @@ case 5367: { // glCompressedTexSubImage3D GLsizei *depth = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexSubImage3D(*target,*level,*xoffset,*yoffset,*zoffset,*width,*height,*depth,*format,*imageSize,data); }; break; case 5368: { // glCompressedTexSubImage2D @@ -2844,7 +2772,7 @@ case 5369: { // glCompressedTexSubImage2D GLsizei *height = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexSubImage2D(*target,*level,*xoffset,*yoffset,*width,*height,*format,*imageSize,data); }; break; case 5370: { // glCompressedTexSubImage1D @@ -2864,19 +2792,19 @@ case 5371: { // glCompressedTexSubImage1D GLsizei *width = (GLsizei *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLsizei *imageSize = (GLsizei *) bp; bp += 4; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglCompressedTexSubImage1D(*target,*level,*xoffset,*width,*format,*imageSize,data); }; break; case 5372: { // glGetCompressedTexImage GLenum *target = (GLenum *) bp; bp += 4; GLint *level = (GLint *) bp; bp += 4; - GLvoid *img = (GLvoid *) bins[0]->base; + GLvoid *img = (GLvoid *) bins[0]; weglGetCompressedTexImage(*target,*level,img); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5373: { // glClientActiveTexture GLenum *texture = (GLenum *) bp; bp += 4; @@ -3036,7 +2964,7 @@ case 5402: { // glFogCoordPointer case 5403: { // glFogCoordPointer GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglFogCoordPointer(*type,*stride,pointer); }; break; case 5404: { // glSecondaryColor3bv @@ -3082,7 +3010,7 @@ case 5413: { // glSecondaryColorPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglSecondaryColorPointer(*size,*type,*stride,pointer); }; break; case 5414: { // glWindowPos2dv @@ -3124,13 +3052,12 @@ case 5422: { // glGenQueries weglGenQueries(*n,ids); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(ids); }; break; @@ -3143,11 +3070,10 @@ case 5424: { // glIsQuery GLuint *id = (GLuint *) bp; bp += 4; GLboolean result = weglIsQuery(*id); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5425: { // glBeginQuery GLenum *target = (GLenum *) bp; bp += 4; @@ -3164,11 +3090,10 @@ case 5427: { // glGetQueryiv GLint params[1] = {0}; weglGetQueryiv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5428: { // glGetQueryObjectiv GLuint *id = (GLuint *) bp; bp += 4; @@ -3176,11 +3101,10 @@ case 5428: { // glGetQueryObjectiv GLint params[1] = {0}; weglGetQueryObjectiv(*id,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5429: { // glGetQueryObjectuiv GLuint *id = (GLuint *) bp; bp += 4; @@ -3188,11 +3112,10 @@ case 5429: { // glGetQueryObjectuiv GLuint params[1] = {0}; weglGetQueryObjectuiv(*id,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5430: { // glBindBuffer GLenum *target = (GLenum *) bp; bp += 4; @@ -3211,13 +3134,12 @@ case 5432: { // glGenBuffers weglGenBuffers(*n,buffers); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) buffers[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(buffers); }; break; @@ -3225,11 +3147,10 @@ case 5433: { // glIsBuffer GLuint *buffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsBuffer(*buffer); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5434: { // glBufferData GLenum *target = (GLenum *) bp; bp += 4; @@ -3243,7 +3164,7 @@ case 5435: { // glBufferData GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; GLenum *usage = (GLenum *) bp; bp += 4; weglBufferData(*target,size,data,*usage); }; break; @@ -3260,7 +3181,7 @@ case 5437: { // glBufferSubData bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglBufferSubData(*target,offset,size,data); }; break; case 5438: { // glGetBufferSubData @@ -3268,13 +3189,13 @@ case 5438: { // glGetBufferSubData bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; - GLvoid *data = (GLvoid *) bins[0]->base; + GLvoid *data = (GLvoid *) bins[0]; weglGetBufferSubData(*target,offset,size,data); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5439: { // glGetBufferParameteriv GLenum *target = (GLenum *) bp; bp += 4; @@ -3282,11 +3203,10 @@ case 5439: { // glGetBufferParameteriv GLint params[1] = {0}; weglGetBufferParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5440: { // glBlendEquationSeparate GLenum *modeRGB = (GLenum *) bp; bp += 4; @@ -3306,11 +3226,11 @@ case 5442: { // glStencilOpSeparate weglStencilOpSeparate(*face,*sfail,*dpfail,*dppass); }; break; case 5443: { // glStencilFuncSeparate - GLenum *frontfunc = (GLenum *) bp; bp += 4; - GLenum *backfunc = (GLenum *) bp; bp += 4; + GLenum *face = (GLenum *) bp; bp += 4; + GLenum *func = (GLenum *) bp; bp += 4; GLint *ref = (GLint *) bp; bp += 4; GLuint *mask = (GLuint *) bp; bp += 4; - weglStencilFuncSeparate(*frontfunc,*backfunc,*ref,*mask); + weglStencilFuncSeparate(*face,*func,*ref,*mask); }; break; case 5444: { // glStencilMaskSeparate GLenum *face = (GLenum *) bp; bp += 4; @@ -3326,7 +3246,7 @@ case 5446: { // glBindAttribLocation GLuint *program = (GLuint *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); weglBindAttribLocation(*program,*index,name); }; break; case 5447: { // glCompileShader @@ -3336,21 +3256,19 @@ case 5447: { // glCompileShader case 5448: { // glCreateProgram GLuint result = weglCreateProgram(); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5449: { // glCreateShader GLenum *type = (GLenum *) bp; bp += 4; GLuint result = weglCreateShader(*type); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5450: { // glDeleteProgram GLuint *program = (GLuint *) bp; bp += 4; @@ -3384,14 +3302,13 @@ case 5455: { // glGetActiveAttrib name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetActiveAttrib(*program,*index,*bufSize,length,size,type,name); int AP = 0; ErlDrvTermData rt[13]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type; rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(name); }; break; case 5456: { // glGetActiveUniform @@ -3405,14 +3322,13 @@ case 5456: { // glGetActiveUniform name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetActiveUniform(*program,*index,*bufSize,length,size,type,name); int AP = 0; ErlDrvTermData rt[13]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type; rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(name); }; break; case 5457: { // glGetAttachedShaders @@ -3424,27 +3340,25 @@ case 5457: { // glGetAttachedShaders weglGetAttachedShaders(*program,*maxCount,count,obj); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *count; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) obj[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(obj); }; break; case 5458: { // glGetAttribLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); GLint result = weglGetAttribLocation(*program,name); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5459: { // glGetProgramiv GLuint *program = (GLuint *) bp; bp += 4; @@ -3452,11 +3366,10 @@ case 5459: { // glGetProgramiv GLint params[1] = {0}; weglGetProgramiv(*program,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5460: { // glGetProgramInfoLog GLuint *program = (GLuint *) bp; bp += 4; @@ -3466,11 +3379,10 @@ case 5460: { // glGetProgramInfoLog infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetProgramInfoLog(*program,*bufSize,length,infoLog); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(infoLog); }; break; case 5461: { // glGetShaderiv @@ -3479,11 +3391,10 @@ case 5461: { // glGetShaderiv GLint params[1] = {0}; weglGetShaderiv(*shader,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5462: { // glGetShaderInfoLog GLuint *shader = (GLuint *) bp; bp += 4; @@ -3493,11 +3404,10 @@ case 5462: { // glGetShaderInfoLog infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetShaderInfoLog(*shader,*bufSize,length,infoLog); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(infoLog); }; break; case 5463: { // glGetShaderSource @@ -3508,24 +3418,22 @@ case 5463: { // glGetShaderSource source = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetShaderSource(*shader,*bufSize,length,source); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) source; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(source); }; break; case 5464: { // glGetUniformLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); GLint result = weglGetUniformLocation(*program,name); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5465: { // glGetUniformfv GLuint *program = (GLuint *) bp; bp += 4; @@ -3533,7 +3441,7 @@ case 5465: { // glGetUniformfv GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetUniformfv(*program,*location,params); int AP = 0; ErlDrvTermData rt[38]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[16], *paramsTmp = paramsConv; for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -3554,8 +3462,7 @@ case 5465: { // glGetUniformfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5466: { // glGetUniformiv GLuint *program = (GLuint *) bp; bp += 4; @@ -3563,7 +3470,7 @@ case 5466: { // glGetUniformiv GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetUniformiv(*program,*location,params); int AP = 0; ErlDrvTermData rt[38]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -3583,8 +3490,7 @@ case 5466: { // glGetUniformiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5467: { // glGetVertexAttribdv GLuint *index = (GLuint *) bp; bp += 4; @@ -3592,7 +3498,7 @@ case 5467: { // glGetVertexAttribdv GLdouble params[4] = {0.0,0.0,0.0,0.0}; weglGetVertexAttribdv(*index,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *paramsTmp = params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -3600,8 +3506,7 @@ case 5467: { // glGetVertexAttribdv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5468: { // glGetVertexAttribfv GLuint *index = (GLuint *) bp; bp += 4; @@ -3609,7 +3514,7 @@ case 5468: { // glGetVertexAttribfv GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetVertexAttribfv(*index,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -3618,8 +3523,7 @@ case 5468: { // glGetVertexAttribfv rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5469: { // glGetVertexAttribiv GLuint *index = (GLuint *) bp; bp += 4; @@ -3627,7 +3531,7 @@ case 5469: { // glGetVertexAttribiv GLint params[4] = {0,0,0,0}; weglGetVertexAttribiv(*index,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -3635,28 +3539,25 @@ case 5469: { // glGetVertexAttribiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5470: { // glIsProgram GLuint *program = (GLuint *) bp; bp += 4; GLboolean result = weglIsProgram(*program); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5471: { // glIsShader GLuint *shader = (GLuint *) bp; bp += 4; GLboolean result = weglIsShader(*shader); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5472: { // glLinkProgram GLuint *program = (GLuint *) bp; bp += 4; @@ -3942,7 +3843,7 @@ case 5519: { // glVertexAttribPointer GLboolean *normalized = (GLboolean *) bp; bp += 1; bp += 3; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglVertexAttribPointer(*index,*size,*type,*normalized,*stride,pointer); }; break; case 5520: { // glUniformMatrix2x3fv @@ -4007,7 +3908,7 @@ case 5527: { // glGetBooleani_v GLboolean data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetBooleani_v(*target,*index,data); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLboolean *dataTmp = data; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; @@ -4027,8 +3928,7 @@ case 5527: { // glGetBooleani_v rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5528: { // glGetIntegeri_v GLenum *target = (GLenum *) bp; bp += 4; @@ -4036,7 +3936,7 @@ case 5528: { // glGetIntegeri_v GLint data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetIntegeri_v(*target,*index,data); int AP = 0; ErlDrvTermData rt[39]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *dataTmp = data; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; @@ -4056,8 +3956,7 @@ case 5528: { // glGetIntegeri_v rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 39 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,39); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5529: { // glEnablei GLenum *target = (GLenum *) bp; bp += 4; @@ -4074,11 +3973,10 @@ case 5531: { // glIsEnabledi GLuint *index = (GLuint *) bp; bp += 4; GLboolean result = weglIsEnabledi(*target,*index); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5532: { // glBeginTransformFeedback GLenum *primitiveMode = (GLenum *) bp; bp += 4; @@ -4126,14 +4024,13 @@ case 5537: { // glGetTransformFeedbackVarying name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetTransformFeedbackVarying(*program,*index,*bufSize,length,size,type,name); int AP = 0; ErlDrvTermData rt[13]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type; rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(name); }; break; case 5538: { // glClampColor @@ -4162,7 +4059,7 @@ case 5542: { // glVertexAttribIPointer GLint *size = (GLint *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; GLsizei *stride = (GLsizei *) bp; bp += 4; - GLvoid *pointer = (GLvoid *) bins[0]->base; + GLvoid *pointer = (GLvoid *) bins[0]; weglVertexAttribIPointer(*index,*size,*type,*stride,pointer); }; break; case 5543: { // glGetVertexAttribIiv @@ -4171,7 +4068,7 @@ case 5543: { // glGetVertexAttribIiv GLint params[4] = {0,0,0,0}; weglGetVertexAttribIiv(*index,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4179,8 +4076,7 @@ case 5543: { // glGetVertexAttribIiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; case 5544: { // glGetVertexAttribIuiv GLuint *index = (GLuint *) bp; bp += 4; @@ -4188,7 +4084,7 @@ case 5544: { // glGetVertexAttribIuiv GLuint params[4] = {0,0,0,0}; weglGetVertexAttribIuiv(*index,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLuint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4196,16 +4092,75 @@ case 5544: { // glGetVertexAttribIuiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); +}; break; +case 5545: { // glVertexAttribI1iv + GLuint *index = (GLuint *) bp; bp += 4; + GLint *v = (GLint *) bp; bp += 4; + weglVertexAttribI1iv(*index,v); +}; break; +case 5546: { // glVertexAttribI2iv + GLuint *index = (GLuint *) bp; bp += 4; + GLint *v = (GLint *) bp; bp += 4; + weglVertexAttribI2iv(*index,v); +}; break; +case 5547: { // glVertexAttribI3iv + GLuint *index = (GLuint *) bp; bp += 4; + GLint *v = (GLint *) bp; bp += 4; + weglVertexAttribI3iv(*index,v); +}; break; +case 5548: { // glVertexAttribI4iv + GLuint *index = (GLuint *) bp; bp += 4; + GLint * v = (GLint *) bp; bp += 16; + weglVertexAttribI4iv(*index,v); +}; break; +case 5549: { // glVertexAttribI1uiv + GLuint *index = (GLuint *) bp; bp += 4; + GLuint *v = (GLuint *) bp; bp += 4; + weglVertexAttribI1uiv(*index,v); +}; break; +case 5550: { // glVertexAttribI2uiv + GLuint *index = (GLuint *) bp; bp += 4; + GLuint *v = (GLuint *) bp; bp += 4; + weglVertexAttribI2uiv(*index,v); +}; break; +case 5551: { // glVertexAttribI3uiv + GLuint *index = (GLuint *) bp; bp += 4; + GLuint *v = (GLuint *) bp; bp += 4; + weglVertexAttribI3uiv(*index,v); }; break; -case 5545: { // glGetUniformuiv +case 5552: { // glVertexAttribI4uiv + GLuint *index = (GLuint *) bp; bp += 4; + GLuint * v = (GLuint *) bp; bp += 16; + weglVertexAttribI4uiv(*index,v); +}; break; +case 5553: { // glVertexAttribI4bv + GLuint *index = (GLuint *) bp; bp += 4; + GLbyte * v = (GLbyte *) bp; bp += 4; + weglVertexAttribI4bv(*index,v); +}; break; +case 5554: { // glVertexAttribI4sv + GLuint *index = (GLuint *) bp; bp += 4; + GLshort * v = (GLshort *) bp; bp += 8; + weglVertexAttribI4sv(*index,v); +}; break; +case 5555: { // glVertexAttribI4ubv + GLuint *index = (GLuint *) bp; bp += 4; + GLubyte * v = (GLubyte *) bp; bp += 4; + weglVertexAttribI4ubv(*index,v); +}; break; +case 5556: { // glVertexAttribI4usv + GLuint *index = (GLuint *) bp; bp += 4; + GLushort * v = (GLushort *) bp; bp += 8; + weglVertexAttribI4usv(*index,v); +}; break; +case 5557: { // glGetUniformuiv GLuint *program = (GLuint *) bp; bp += 4; GLint *location = (GLint *) bp; bp += 4; GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetUniformuiv(*program,*location,params); int AP = 0; ErlDrvTermData rt[38]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLuint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4225,47 +4180,45 @@ case 5545: { // glGetUniformuiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5546: { // glBindFragDataLocation +case 5558: { // glBindFragDataLocation GLuint *program = (GLuint *) bp; bp += 4; GLuint *color = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); weglBindFragDataLocation(*program,*color,name); }; break; -case 5547: { // glGetFragDataLocation +case 5559: { // glGetFragDataLocation GLuint *program = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); GLint result = weglGetFragDataLocation(*program,name); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5548: { // glUniform1ui +case 5560: { // glUniform1ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; weglUniform1ui(*location,*v0); }; break; -case 5549: { // glUniform2ui +case 5561: { // glUniform2ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; weglUniform2ui(*location,*v0,*v1); }; break; -case 5550: { // glUniform3ui +case 5562: { // glUniform3ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; GLuint *v2 = (GLuint *) bp; bp += 4; weglUniform3ui(*location,*v0,*v1,*v2); }; break; -case 5551: { // glUniform4ui +case 5563: { // glUniform4ui GLint *location = (GLint *) bp; bp += 4; GLuint *v0 = (GLuint *) bp; bp += 4; GLuint *v1 = (GLuint *) bp; bp += 4; @@ -4273,51 +4226,51 @@ case 5551: { // glUniform4ui GLuint *v3 = (GLuint *) bp; bp += 4; weglUniform4ui(*location,*v0,*v1,*v2,*v3); }; break; -case 5552: { // glUniform1uiv +case 5564: { // glUniform1uiv GLint *location = (GLint *) bp; bp += 4; int * valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+0)%8))%8; weglUniform1uiv(*location,*valueLen,value); }; break; -case 5553: { // glUniform2uiv +case 5565: { // glUniform2uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*8; weglUniform2uiv(*location,*valueLen,value); }; break; -case 5554: { // glUniform3uiv +case 5566: { // glUniform3uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*12; weglUniform3uiv(*location,*valueLen,value); }; break; -case 5555: { // glUniform4uiv +case 5567: { // glUniform4uiv GLint *location = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint * value = (GLuint *) bp; bp += *valueLen*16; weglUniform4uiv(*location,*valueLen,value); }; break; -case 5556: { // glTexParameterIiv +case 5568: { // glTexParameterIiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLint *params = (GLint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameterIiv(*target,*pname,params); }; break; -case 5557: { // glTexParameterIuiv +case 5569: { // glTexParameterIuiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; int *paramsLen = (int *) bp; bp += 4; GLuint *params = (GLuint *) bp; bp += *paramsLen*4+((*paramsLen)+1)%2*4; weglTexParameterIuiv(*target,*pname,params); }; break; -case 5558: { // glGetTexParameterIiv +case 5570: { // glGetTexParameterIiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[4] = {0,0,0,0}; weglGetTexParameterIiv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4325,16 +4278,15 @@ case 5558: { // glGetTexParameterIiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5559: { // glGetTexParameterIuiv +case 5571: { // glGetTexParameterIuiv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLuint params[4] = {0,0,0,0}; weglGetTexParameterIuiv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLuint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4342,107 +4294,45 @@ case 5559: { // glGetTexParameterIuiv rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5560: { // glClearBufferiv +case 5572: { // glClearBufferiv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLint *value = (GLint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferiv(*buffer,*drawbuffer,value); }; break; -case 5561: { // glClearBufferuiv +case 5573: { // glClearBufferuiv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLuint *value = (GLuint *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferuiv(*buffer,*drawbuffer,value); }; break; -case 5562: { // glClearBufferfv +case 5574: { // glClearBufferfv GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; int *valueLen = (int *) bp; bp += 4; GLfloat *value = (GLfloat *) bp; bp += *valueLen*4+((*valueLen)+1)%2*4; weglClearBufferfv(*buffer,*drawbuffer,value); }; break; -case 5563: { // glClearBufferfi +case 5575: { // glClearBufferfi GLenum *buffer = (GLenum *) bp; bp += 4; GLint *drawbuffer = (GLint *) bp; bp += 4; GLfloat *depth = (GLfloat *) bp; bp += 4; GLint *stencil = (GLint *) bp; bp += 4; weglClearBufferfi(*buffer,*drawbuffer,*depth,*stencil); }; break; -case 5564: { // glGetStringi +case 5576: { // glGetStringi GLenum *name = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; const GLubyte * result = weglGetStringi(*name,*index); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) result; rt[AP++] = strlen((char *) result); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); -}; break; -case 5565: { // glVertexAttribI1iv - GLuint *index = (GLuint *) bp; bp += 4; - GLint *v = (GLint *) bp; bp += 4; - weglVertexAttribI1iv(*index,v); -}; break; -case 5566: { // glVertexAttribI2iv - GLuint *index = (GLuint *) bp; bp += 4; - GLint *v = (GLint *) bp; bp += 4; - weglVertexAttribI2iv(*index,v); -}; break; -case 5567: { // glVertexAttribI3iv - GLuint *index = (GLuint *) bp; bp += 4; - GLint *v = (GLint *) bp; bp += 4; - weglVertexAttribI3iv(*index,v); -}; break; -case 5568: { // glVertexAttribI4iv - GLuint *index = (GLuint *) bp; bp += 4; - GLint * v = (GLint *) bp; bp += 16; - weglVertexAttribI4iv(*index,v); -}; break; -case 5569: { // glVertexAttribI1uiv - GLuint *index = (GLuint *) bp; bp += 4; - GLuint *v = (GLuint *) bp; bp += 4; - weglVertexAttribI1uiv(*index,v); -}; break; -case 5570: { // glVertexAttribI2uiv - GLuint *index = (GLuint *) bp; bp += 4; - GLuint *v = (GLuint *) bp; bp += 4; - weglVertexAttribI2uiv(*index,v); -}; break; -case 5571: { // glVertexAttribI3uiv - GLuint *index = (GLuint *) bp; bp += 4; - GLuint *v = (GLuint *) bp; bp += 4; - weglVertexAttribI3uiv(*index,v); -}; break; -case 5572: { // glVertexAttribI4uiv - GLuint *index = (GLuint *) bp; bp += 4; - GLuint * v = (GLuint *) bp; bp += 16; - weglVertexAttribI4uiv(*index,v); -}; break; -case 5573: { // glVertexAttribI4bv - GLuint *index = (GLuint *) bp; bp += 4; - GLbyte * v = (GLbyte *) bp; bp += 4; - weglVertexAttribI4bv(*index,v); -}; break; -case 5574: { // glVertexAttribI4sv - GLuint *index = (GLuint *) bp; bp += 4; - GLshort * v = (GLshort *) bp; bp += 8; - weglVertexAttribI4sv(*index,v); -}; break; -case 5575: { // glVertexAttribI4ubv - GLuint *index = (GLuint *) bp; bp += 4; - GLubyte * v = (GLubyte *) bp; bp += 4; - weglVertexAttribI4ubv(*index,v); -}; break; -case 5576: { // glVertexAttribI4usv - GLuint *index = (GLuint *) bp; bp += 4; - GLushort * v = (GLushort *) bp; bp += 8; - weglVertexAttribI4usv(*index,v); + driver_send_term(port,caller,rt,AP); }; break; case 5577: { // glDrawArraysInstanced GLenum *mode = (GLenum *) bp; bp += 4; @@ -4463,7 +4353,7 @@ case 5579: { // glDrawElementsInstanced GLenum *mode = (GLenum *) bp; bp += 4; GLsizei *count = (GLsizei *) bp; bp += 4; GLenum *type = (GLenum *) bp; bp += 4; - GLvoid *indices = (GLvoid *) bins[0]->base; + GLvoid *indices = (GLvoid *) bins[0]; GLsizei *primcount = (GLsizei *) bp; bp += 4; weglDrawElementsInstanced(*mode,*count,*type,indices,*primcount); }; break; @@ -4477,120 +4367,216 @@ case 5581: { // glPrimitiveRestartIndex GLuint *index = (GLuint *) bp; bp += 4; weglPrimitiveRestartIndex(*index); }; break; -case 5582: { // glLoadTransposeMatrixfARB +case 5582: { // glGetInteger64i_v + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLint64 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + weglGetInteger64i_v(*target,*index,data); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint64 *dataTmp = data; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *dataTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5583: { // glGetBufferParameteri64v + GLenum *target = (GLenum *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + weglGetBufferParameteri64v(*target,*pname,params); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint64 *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5584: { // glFramebufferTexture + GLenum *target = (GLenum *) bp; bp += 4; + GLenum *attachment = (GLenum *) bp; bp += 4; + GLuint *texture = (GLuint *) bp; bp += 4; + GLint *level = (GLint *) bp; bp += 4; + weglFramebufferTexture(*target,*attachment,*texture,*level); +}; break; +case 5585: { // glVertexAttribDivisor + GLuint *index = (GLuint *) bp; bp += 4; + GLuint *divisor = (GLuint *) bp; bp += 4; + weglVertexAttribDivisor(*index,*divisor); +}; break; +case 5586: { // glMinSampleShading + GLclampf *value = (GLclampf *) bp; bp += 4; + weglMinSampleShading(*value); +}; break; +case 5587: { // glBlendEquationi + GLuint *buf = (GLuint *) bp; bp += 4; + GLenum *mode = (GLenum *) bp; bp += 4; + weglBlendEquationi(*buf,*mode); +}; break; +case 5588: { // glBlendEquationSeparatei + GLuint *buf = (GLuint *) bp; bp += 4; + GLenum *modeRGB = (GLenum *) bp; bp += 4; + GLenum *modeAlpha = (GLenum *) bp; bp += 4; + weglBlendEquationSeparatei(*buf,*modeRGB,*modeAlpha); +}; break; +case 5589: { // glBlendFunci + GLuint *buf = (GLuint *) bp; bp += 4; + GLenum *src = (GLenum *) bp; bp += 4; + GLenum *dst = (GLenum *) bp; bp += 4; + weglBlendFunci(*buf,*src,*dst); +}; break; +case 5590: { // glBlendFuncSeparatei + GLuint *buf = (GLuint *) bp; bp += 4; + GLenum *srcRGB = (GLenum *) bp; bp += 4; + GLenum *dstRGB = (GLenum *) bp; bp += 4; + GLenum *srcAlpha = (GLenum *) bp; bp += 4; + GLenum *dstAlpha = (GLenum *) bp; bp += 4; + weglBlendFuncSeparatei(*buf,*srcRGB,*dstRGB,*srcAlpha,*dstAlpha); +}; break; +case 5591: { // glLoadTransposeMatrixfARB GLfloat * m = (GLfloat *) bp; bp += 64; weglLoadTransposeMatrixfARB(m); }; break; -case 5583: { // glLoadTransposeMatrixdARB +case 5592: { // glLoadTransposeMatrixdARB GLdouble * m = (GLdouble *) bp; bp += 128; weglLoadTransposeMatrixdARB(m); }; break; -case 5584: { // glMultTransposeMatrixfARB +case 5593: { // glMultTransposeMatrixfARB GLfloat * m = (GLfloat *) bp; bp += 64; weglMultTransposeMatrixfARB(m); }; break; -case 5585: { // glMultTransposeMatrixdARB +case 5594: { // glMultTransposeMatrixdARB GLdouble * m = (GLdouble *) bp; bp += 128; weglMultTransposeMatrixdARB(m); }; break; -case 5586: { // glWeightbvARB +case 5595: { // glWeightbvARB int * weightsLen = (int *) bp; bp += 4; GLbyte * weights = (GLbyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8; weglWeightbvARB(*weightsLen,weights); }; break; -case 5587: { // glWeightsvARB +case 5596: { // glWeightsvARB int * weightsLen = (int *) bp; bp += 4; GLshort * weights = (GLshort *) bp; bp += (8-((*weightsLen*2+4)%8))%8; weglWeightsvARB(*weightsLen,weights); }; break; -case 5588: { // glWeightivARB +case 5597: { // glWeightivARB int * weightsLen = (int *) bp; bp += 4; GLint * weights = (GLint *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightivARB(*weightsLen,weights); }; break; -case 5589: { // glWeightfvARB +case 5598: { // glWeightfvARB int * weightsLen = (int *) bp; bp += 4; GLfloat * weights = (GLfloat *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightfvARB(*weightsLen,weights); }; break; -case 5590: { // glWeightdvARB +case 5599: { // glWeightdvARB int * weightsLen = (int *) bp; bp += 8; GLdouble * weights = (GLdouble *) bp; bp += (8-((*weightsLen*8+0)%8))%8; weglWeightdvARB(*weightsLen,weights); }; break; -case 5591: { // glWeightubvARB +case 5600: { // glWeightubvARB int * weightsLen = (int *) bp; bp += 4; GLubyte * weights = (GLubyte *) bp; bp += (8-((*weightsLen*1+4)%8))%8; weglWeightubvARB(*weightsLen,weights); }; break; -case 5592: { // glWeightusvARB +case 5601: { // glWeightusvARB int * weightsLen = (int *) bp; bp += 4; GLushort * weights = (GLushort *) bp; bp += (8-((*weightsLen*2+4)%8))%8; weglWeightusvARB(*weightsLen,weights); }; break; -case 5593: { // glWeightuivARB +case 5602: { // glWeightuivARB int * weightsLen = (int *) bp; bp += 4; GLuint * weights = (GLuint *) bp; bp += (8-((*weightsLen*4+4)%8))%8; weglWeightuivARB(*weightsLen,weights); }; break; -case 5594: { // glVertexBlendARB +case 5603: { // glVertexBlendARB GLint *count = (GLint *) bp; bp += 4; weglVertexBlendARB(*count); }; break; -case 5595: { // glCurrentPaletteMatrixARB +case 5604: { // glCurrentPaletteMatrixARB GLint *index = (GLint *) bp; bp += 4; weglCurrentPaletteMatrixARB(*index); }; break; -case 5596: { // glMatrixIndexubvARB +case 5605: { // glMatrixIndexubvARB int * indicesLen = (int *) bp; bp += 4; GLubyte * indices = (GLubyte *) bp; bp += (8-((*indicesLen*1+4)%8))%8; weglMatrixIndexubvARB(*indicesLen,indices); }; break; -case 5597: { // glMatrixIndexusvARB +case 5606: { // glMatrixIndexusvARB int * indicesLen = (int *) bp; bp += 4; GLushort * indices = (GLushort *) bp; bp += (8-((*indicesLen*2+4)%8))%8; weglMatrixIndexusvARB(*indicesLen,indices); }; break; -case 5598: { // glMatrixIndexuivARB +case 5607: { // glMatrixIndexuivARB int * indicesLen = (int *) bp; bp += 4; GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+4)%8))%8; weglMatrixIndexuivARB(*indicesLen,indices); }; break; -case 5599: { // glProgramStringARB +case 5608: { // glProgramStringARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *format = (GLenum *) bp; bp += 4; GLvoid *string = (GLvoid *) bp; - int stringLen = strlen((char *)string); bp += stringLen+1+((8-((1+stringLen+0)%8))%8); - weglProgramStringARB(*target,*format,stringLen,string); + int stringLen[1] = {strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8); + weglProgramStringARB(*target,*format,*stringLen,string); }; break; -case 5600: { // glBindProgramARB +case 5609: { // glBindProgramARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *program = (GLuint *) bp; bp += 4; weglBindProgramARB(*target,*program); }; break; -case 5601: { // glDeleteProgramsARB +case 5610: { // glDeleteProgramsARB int * programsLen = (int *) bp; bp += 4; GLuint * programs = (GLuint *) bp; bp += (8-((*programsLen*4+4)%8))%8; weglDeleteProgramsARB(*programsLen,programs); }; break; -case 5602: { // glGenProgramsARB +case 5611: { // glGenProgramsARB GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *programs; programs = (GLuint *) driver_alloc(sizeof(GLuint) * *n); weglGenProgramsARB(*n,programs); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) programs[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(programs); }; break; -case 5603: { // glProgramEnvParameter4dARB +case 5612: { // glProgramEnvParameter4dARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble *x = (GLdouble *) bp; bp += 8; @@ -4599,13 +4585,13 @@ case 5603: { // glProgramEnvParameter4dARB GLdouble *w = (GLdouble *) bp; bp += 8; weglProgramEnvParameter4dARB(*target,*index,*x,*y,*z,*w); }; break; -case 5604: { // glProgramEnvParameter4dvARB +case 5613: { // glProgramEnvParameter4dvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble * params = (GLdouble *) bp; bp += 32; weglProgramEnvParameter4dvARB(*target,*index,params); }; break; -case 5605: { // glProgramEnvParameter4fARB +case 5614: { // glProgramEnvParameter4fARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat *x = (GLfloat *) bp; bp += 4; @@ -4614,13 +4600,13 @@ case 5605: { // glProgramEnvParameter4fARB GLfloat *w = (GLfloat *) bp; bp += 4; weglProgramEnvParameter4fARB(*target,*index,*x,*y,*z,*w); }; break; -case 5606: { // glProgramEnvParameter4fvARB +case 5615: { // glProgramEnvParameter4fvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat * params = (GLfloat *) bp; bp += 16; weglProgramEnvParameter4fvARB(*target,*index,params); }; break; -case 5607: { // glProgramLocalParameter4dARB +case 5616: { // glProgramLocalParameter4dARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble *x = (GLdouble *) bp; bp += 8; @@ -4629,13 +4615,13 @@ case 5607: { // glProgramLocalParameter4dARB GLdouble *w = (GLdouble *) bp; bp += 8; weglProgramLocalParameter4dARB(*target,*index,*x,*y,*z,*w); }; break; -case 5608: { // glProgramLocalParameter4dvARB +case 5617: { // glProgramLocalParameter4dvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble * params = (GLdouble *) bp; bp += 32; weglProgramLocalParameter4dvARB(*target,*index,params); }; break; -case 5609: { // glProgramLocalParameter4fARB +case 5618: { // glProgramLocalParameter4fARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat *x = (GLfloat *) bp; bp += 4; @@ -4644,19 +4630,19 @@ case 5609: { // glProgramLocalParameter4fARB GLfloat *w = (GLfloat *) bp; bp += 4; weglProgramLocalParameter4fARB(*target,*index,*x,*y,*z,*w); }; break; -case 5610: { // glProgramLocalParameter4fvARB +case 5619: { // glProgramLocalParameter4fvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat * params = (GLfloat *) bp; bp += 16; weglProgramLocalParameter4fvARB(*target,*index,params); }; break; -case 5611: { // glGetProgramEnvParameterdvARB +case 5620: { // glGetProgramEnvParameterdvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; weglGetProgramEnvParameterdvARB(*target,*index,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *paramsTmp = params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -4664,16 +4650,15 @@ case 5611: { // glGetProgramEnvParameterdvARB rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5612: { // glGetProgramEnvParameterfvARB +case 5621: { // glGetProgramEnvParameterfvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetProgramEnvParameterfvARB(*target,*index,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -4682,16 +4667,15 @@ case 5612: { // glGetProgramEnvParameterfvARB rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5613: { // glGetProgramLocalParameterdvARB +case 5622: { // glGetProgramLocalParameterdvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLdouble params[4] = {0.0,0.0,0.0,0.0}; weglGetProgramLocalParameterdvARB(*target,*index,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble *paramsTmp = params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -4699,16 +4683,15 @@ case 5613: { // glGetProgramLocalParameterdvARB rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5614: { // glGetProgramLocalParameterfvARB +case 5623: { // glGetProgramLocalParameterfvARB GLenum *target = (GLenum *) bp; bp += 4; GLuint *index = (GLuint *) bp; bp += 4; GLfloat params[4] = {0.0,0.0,0.0,0.0}; weglGetProgramLocalParameterfvARB(*target,*index,params); int AP = 0; ErlDrvTermData rt[14]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[4], *paramsTmp = paramsConv; for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -4717,50 +4700,75 @@ case 5614: { // glGetProgramLocalParameterfvARB rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 14 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,14); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5615: { // glGetProgramStringARB +case 5624: { // glGetProgramStringARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; - GLvoid *string = (GLvoid *) bins[0]->base; + GLvoid *string = (GLvoid *) bins[0]; weglGetProgramStringARB(*target,*pname,string); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); +}; break; +case 5625: { // glGetBufferParameterivARB + GLenum *target = (GLenum *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + weglGetBufferParameterivARB(*target,*pname,params); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); }; break; -case 5616: { // glDeleteObjectARB +case 5626: { // glDeleteObjectARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglDeleteObjectARB(obj); }; break; -case 5617: { // glGetHandleARB +case 5627: { // glGetHandleARB GLenum *pname = (GLenum *) bp; bp += 4; GLhandleARB result = weglGetHandleARB(*pname); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5618: { // glDetachObjectARB +case 5628: { // glDetachObjectARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLhandleARB attachedObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglDetachObjectARB(containerObj,attachedObj); }; break; -case 5619: { // glCreateShaderObjectARB +case 5629: { // glCreateShaderObjectARB GLenum *shaderType = (GLenum *) bp; bp += 4; GLhandleARB result = weglCreateShaderObjectARB(*shaderType); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5620: { // glShaderSourceARB +case 5630: { // glShaderSourceARB GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; int * stringLen = (int *) bp; bp += 4; int * stringTotSize = (int *) bp; bp += 4; @@ -4772,62 +4780,59 @@ case 5620: { // glShaderSourceARB weglShaderSourceARB(shaderObj,*stringLen,(const GLchar **) string,NULL); driver_free(string); }; break; -case 5621: { // glCompileShaderARB +case 5631: { // glCompileShaderARB GLhandleARB shaderObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglCompileShaderARB(shaderObj); }; break; -case 5622: { // glCreateProgramObjectARB +case 5632: { // glCreateProgramObjectARB GLhandleARB result = weglCreateProgramObjectARB(); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5623: { // glAttachObjectARB +case 5633: { // glAttachObjectARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglAttachObjectARB(containerObj,obj); }; break; -case 5624: { // glLinkProgramARB +case 5634: { // glLinkProgramARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglLinkProgramARB(programObj); }; break; -case 5625: { // glUseProgramObjectARB +case 5635: { // glUseProgramObjectARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglUseProgramObjectARB(programObj); }; break; -case 5626: { // glValidateProgramARB +case 5636: { // glValidateProgramARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; weglValidateProgramARB(programObj); }; break; -case 5627: { // glGetObjectParameterfvARB +case 5637: { // glGetObjectParameterfvARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLenum *pname = (GLenum *) bp; bp += 4; GLfloat params[1] = {0.0}; weglGetObjectParameterfvARB(obj,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv = (double) *params; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) ¶msConv; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5628: { // glGetObjectParameterivARB +case 5638: { // glGetObjectParameterivARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; weglGetObjectParameterivARB(obj,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5629: { // glGetInfoLogARB +case 5639: { // glGetInfoLogARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxLength = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -4835,14 +4840,13 @@ case 5629: { // glGetInfoLogARB infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength); weglGetInfoLogARB(obj,*maxLength,length,infoLog); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(infoLog); }; break; -case 5630: { // glGetAttachedObjectsARB +case 5640: { // glGetAttachedObjectsARB GLhandleARB containerObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxCount = (GLsizei *) bp; bp += 4; GLsizei count[1] = {0}; @@ -4851,29 +4855,27 @@ case 5630: { // glGetAttachedObjectsARB weglGetAttachedObjectsARB(containerObj,*maxCount,count,obj); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *count; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) obj[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*count)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*count)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(obj); }; break; -case 5631: { // glGetUniformLocationARB +case 5641: { // glGetUniformLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); GLint result = weglGetUniformLocationARB(programObj,name); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5632: { // glGetActiveUniformARB +case 5642: { // glGetActiveUniformARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *maxLength = (GLsizei *) bp; bp += 4; @@ -4884,23 +4886,22 @@ case 5632: { // glGetActiveUniformARB name = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength); weglGetActiveUniformARB(programObj,*index,*maxLength,length,size,type,name); int AP = 0; ErlDrvTermData rt[13]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type; rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(name); }; break; -case 5633: { // glGetUniformfvARB +case 5643: { // glGetUniformfvARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLint *location = (GLint *) bp; bp += 4; GLfloat params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; weglGetUniformfvARB(programObj,*location,params); int AP = 0; ErlDrvTermData rt[38]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLdouble paramsConv[16], *paramsTmp = paramsConv; for(int i=0; i < 16; i++) paramsConv[i] = (GLdouble) params[i]; rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; @@ -4921,16 +4922,15 @@ case 5633: { // glGetUniformfvARB rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5634: { // glGetUniformivARB +case 5644: { // glGetUniformivARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLint *location = (GLint *) bp; bp += 4; GLint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; weglGetUniformivARB(programObj,*location,params); int AP = 0; ErlDrvTermData rt[38]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); GLint *paramsTmp = params; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; @@ -4950,10 +4950,9 @@ case 5634: { // glGetUniformivARB rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 38 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,38); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5635: { // glGetShaderSourceARB +case 5645: { // glGetShaderSourceARB GLhandleARB obj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLsizei *maxLength = (GLsizei *) bp; bp += 4; GLsizei length[1] = {0}; @@ -4961,21 +4960,20 @@ case 5635: { // glGetShaderSourceARB source = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength); weglGetShaderSourceARB(obj,*maxLength,length,source); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) source; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(source); }; break; -case 5636: { // glBindAttribLocationARB +case 5646: { // glBindAttribLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+4)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); weglBindAttribLocationARB(programObj,*index,name); }; break; -case 5637: { // glGetActiveAttribARB +case 5647: { // glGetActiveAttribARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLuint *index = (GLuint *) bp; bp += 4; GLsizei *maxLength = (GLsizei *) bp; bp += 4; @@ -4986,132 +4984,124 @@ case 5637: { // glGetActiveAttribARB name = (GLchar *) driver_alloc(sizeof(GLchar) * *maxLength); weglGetActiveAttribARB(programObj,*index,*maxLength,length,size,type,name); int AP = 0; ErlDrvTermData rt[13]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *size; rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *type; rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 13 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,13); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(name); }; break; -case 5638: { // glGetAttribLocationARB +case 5648: { // glGetAttribLocationARB GLhandleARB programObj = (GLhandleARB) * (GLuint64EXT *) bp; bp += 8; GLchar *name = (GLchar *) bp; - int nameLen = strlen((char *)name); bp += nameLen+1+((8-((1+nameLen+0)%8))%8); + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); GLint result = weglGetAttribLocationARB(programObj,name); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5639: { // glIsRenderbuffer +case 5649: { // glIsRenderbuffer GLuint *renderbuffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsRenderbuffer(*renderbuffer); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5640: { // glBindRenderbuffer +case 5650: { // glBindRenderbuffer GLenum *target = (GLenum *) bp; bp += 4; GLuint *renderbuffer = (GLuint *) bp; bp += 4; weglBindRenderbuffer(*target,*renderbuffer); }; break; -case 5641: { // glDeleteRenderbuffers +case 5651: { // glDeleteRenderbuffers int * renderbuffersLen = (int *) bp; bp += 4; GLuint * renderbuffers = (GLuint *) bp; bp += (8-((*renderbuffersLen*4+4)%8))%8; weglDeleteRenderbuffers(*renderbuffersLen,renderbuffers); }; break; -case 5642: { // glGenRenderbuffers +case 5652: { // glGenRenderbuffers GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *renderbuffers; renderbuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n); weglGenRenderbuffers(*n,renderbuffers); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) renderbuffers[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(renderbuffers); }; break; -case 5643: { // glRenderbufferStorage +case 5653: { // glRenderbufferStorage GLenum *target = (GLenum *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; GLsizei *width = (GLsizei *) bp; bp += 4; GLsizei *height = (GLsizei *) bp; bp += 4; weglRenderbufferStorage(*target,*internalformat,*width,*height); }; break; -case 5644: { // glGetRenderbufferParameteriv +case 5654: { // glGetRenderbufferParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; weglGetRenderbufferParameteriv(*target,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5645: { // glIsFramebuffer +case 5655: { // glIsFramebuffer GLuint *framebuffer = (GLuint *) bp; bp += 4; GLboolean result = weglIsFramebuffer(*framebuffer); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5646: { // glBindFramebuffer +case 5656: { // glBindFramebuffer GLenum *target = (GLenum *) bp; bp += 4; GLuint *framebuffer = (GLuint *) bp; bp += 4; weglBindFramebuffer(*target,*framebuffer); }; break; -case 5647: { // glDeleteFramebuffers +case 5657: { // glDeleteFramebuffers int * framebuffersLen = (int *) bp; bp += 4; GLuint * framebuffers = (GLuint *) bp; bp += (8-((*framebuffersLen*4+4)%8))%8; weglDeleteFramebuffers(*framebuffersLen,framebuffers); }; break; -case 5648: { // glGenFramebuffers +case 5658: { // glGenFramebuffers GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *framebuffers; framebuffers = (GLuint *) driver_alloc(sizeof(GLuint) * *n); weglGenFramebuffers(*n,framebuffers); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) framebuffers[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(framebuffers); }; break; -case 5649: { // glCheckFramebufferStatus +case 5659: { // glCheckFramebufferStatus GLenum *target = (GLenum *) bp; bp += 4; GLenum result = weglCheckFramebufferStatus(*target); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5650: { // glFramebufferTexture1D +case 5660: { // glFramebufferTexture1D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; @@ -5119,7 +5109,7 @@ case 5650: { // glFramebufferTexture1D GLint *level = (GLint *) bp; bp += 4; weglFramebufferTexture1D(*target,*attachment,*textarget,*texture,*level); }; break; -case 5651: { // glFramebufferTexture2D +case 5661: { // glFramebufferTexture2D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; @@ -5127,7 +5117,7 @@ case 5651: { // glFramebufferTexture2D GLint *level = (GLint *) bp; bp += 4; weglFramebufferTexture2D(*target,*attachment,*textarget,*texture,*level); }; break; -case 5652: { // glFramebufferTexture3D +case 5662: { // glFramebufferTexture3D GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *textarget = (GLenum *) bp; bp += 4; @@ -5136,31 +5126,30 @@ case 5652: { // glFramebufferTexture3D GLint *zoffset = (GLint *) bp; bp += 4; weglFramebufferTexture3D(*target,*attachment,*textarget,*texture,*level,*zoffset); }; break; -case 5653: { // glFramebufferRenderbuffer +case 5663: { // glFramebufferRenderbuffer GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *renderbuffertarget = (GLenum *) bp; bp += 4; GLuint *renderbuffer = (GLuint *) bp; bp += 4; weglFramebufferRenderbuffer(*target,*attachment,*renderbuffertarget,*renderbuffer); }; break; -case 5654: { // glGetFramebufferAttachmentParameteriv +case 5664: { // glGetFramebufferAttachmentParameteriv GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; GLint params[1] = {0}; weglGetFramebufferAttachmentParameteriv(*target,*attachment,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5655: { // glGenerateMipmap +case 5665: { // glGenerateMipmap GLenum *target = (GLenum *) bp; bp += 4; weglGenerateMipmap(*target); }; break; -case 5656: { // glBlitFramebuffer +case 5666: { // glBlitFramebuffer GLint *srcX0 = (GLint *) bp; bp += 4; GLint *srcY0 = (GLint *) bp; bp += 4; GLint *srcX1 = (GLint *) bp; bp += 4; @@ -5173,7 +5162,7 @@ case 5656: { // glBlitFramebuffer GLenum *filter = (GLenum *) bp; bp += 4; weglBlitFramebuffer(*srcX0,*srcY0,*srcX1,*srcY1,*dstX0,*dstY0,*dstX1,*dstY1,*mask,*filter); }; break; -case 5657: { // glRenderbufferStorageMultisample +case 5667: { // glRenderbufferStorageMultisample GLenum *target = (GLenum *) bp; bp += 4; GLsizei *samples = (GLsizei *) bp; bp += 4; GLenum *internalformat = (GLenum *) bp; bp += 4; @@ -5181,7 +5170,7 @@ case 5657: { // glRenderbufferStorageMultisample GLsizei *height = (GLsizei *) bp; bp += 4; weglRenderbufferStorageMultisample(*target,*samples,*internalformat,*width,*height); }; break; -case 5658: { // glFramebufferTextureLayer +case 5668: { // glFramebufferTextureLayer GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; @@ -5189,20 +5178,7 @@ case 5658: { // glFramebufferTextureLayer GLint *layer = (GLint *) bp; bp += 4; weglFramebufferTextureLayer(*target,*attachment,*texture,*level,*layer); }; break; -case 5659: { // glProgramParameteriARB - GLuint *program = (GLuint *) bp; bp += 4; - GLenum *pname = (GLenum *) bp; bp += 4; - GLint *value = (GLint *) bp; bp += 4; - weglProgramParameteriARB(*program,*pname,*value); -}; break; -case 5660: { // glFramebufferTextureARB - GLenum *target = (GLenum *) bp; bp += 4; - GLenum *attachment = (GLenum *) bp; bp += 4; - GLuint *texture = (GLuint *) bp; bp += 4; - GLint *level = (GLint *) bp; bp += 4; - weglFramebufferTextureARB(*target,*attachment,*texture,*level); -}; break; -case 5661: { // glFramebufferTextureFaceARB +case 5669: { // glFramebufferTextureFaceARB GLenum *target = (GLenum *) bp; bp += 4; GLenum *attachment = (GLenum *) bp; bp += 4; GLuint *texture = (GLuint *) bp; bp += 4; @@ -5210,55 +5186,48 @@ case 5661: { // glFramebufferTextureFaceARB GLenum *face = (GLenum *) bp; bp += 4; weglFramebufferTextureFaceARB(*target,*attachment,*texture,*level,*face); }; break; -case 5662: { // glVertexAttribDivisorARB - GLuint *index = (GLuint *) bp; bp += 4; - GLuint *divisor = (GLuint *) bp; bp += 4; - weglVertexAttribDivisorARB(*index,*divisor); -}; break; -case 5663: { // glFlushMappedBufferRange +case 5670: { // glFlushMappedBufferRange GLenum *target = (GLenum *) bp; bp += 4; bp += 4; GLintptr offset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; GLsizeiptr length = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; weglFlushMappedBufferRange(*target,offset,length); }; break; -case 5664: { // glBindVertexArray +case 5671: { // glBindVertexArray GLuint *array = (GLuint *) bp; bp += 4; weglBindVertexArray(*array); }; break; -case 5665: { // glDeleteVertexArrays +case 5672: { // glDeleteVertexArrays int * arraysLen = (int *) bp; bp += 4; GLuint * arrays = (GLuint *) bp; bp += (8-((*arraysLen*4+4)%8))%8; weglDeleteVertexArrays(*arraysLen,arrays); }; break; -case 5666: { // glGenVertexArrays +case 5673: { // glGenVertexArrays GLsizei *n = (GLsizei *) bp; bp += 4; GLuint *arrays; arrays = (GLuint *) driver_alloc(sizeof(GLuint) * *n); weglGenVertexArrays(*n,arrays); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) arrays[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*n)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*n)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(arrays); }; break; -case 5667: { // glIsVertexArray +case 5674: { // glIsVertexArray GLuint *array = (GLuint *) bp; bp += 4; GLboolean result = weglIsVertexArray(*array); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5668: { // glGetUniformIndices +case 5675: { // glGetUniformIndices GLuint *program = (GLuint *) bp; bp += 4; int * uniformNamesLen = (int *) bp; bp += 4; int * uniformNamesTotSize = (int *) bp; bp += 4; @@ -5272,18 +5241,17 @@ case 5668: { // glGetUniformIndices weglGetUniformIndices(*program,*uniformNamesLen,(const GLchar **) uniformNames,uniformIndices); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*uniformNamesLen)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *uniformNamesLen; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) uniformIndices[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*uniformNamesLen)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*uniformNamesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformNamesLen)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(uniformIndices); driver_free(uniformNames); }; break; -case 5669: { // glGetActiveUniformsiv +case 5676: { // glGetActiveUniformsiv GLuint *program = (GLuint *) bp; bp += 4; int * uniformIndicesLen = (int *) bp; bp += 4; GLuint * uniformIndices = (GLuint *) bp; bp += (8-((*uniformIndicesLen*4+0)%8))%8; @@ -5293,17 +5261,16 @@ case 5669: { // glGetActiveUniformsiv weglGetActiveUniformsiv(*program,*uniformIndicesLen,uniformIndices,*pname,params); int AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*uniformIndicesLen)*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(int i=0; i < *uniformIndicesLen; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) params[i];} rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*uniformIndicesLen)+1; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 + (*uniformIndicesLen)*2 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7 + (*uniformIndicesLen)*2); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(rt); driver_free(params); }; break; -case 5670: { // glGetActiveUniformName +case 5677: { // glGetActiveUniformName GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformIndex = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -5312,38 +5279,36 @@ case 5670: { // glGetActiveUniformName uniformName = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetActiveUniformName(*program,*uniformIndex,*bufSize,length,uniformName); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) uniformName; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(uniformName); }; break; -case 5671: { // glGetUniformBlockIndex +case 5678: { // glGetUniformBlockIndex GLuint *program = (GLuint *) bp; bp += 4; GLchar *uniformBlockName = (GLchar *) bp; - int uniformBlockNameLen = strlen((char *)uniformBlockName); bp += uniformBlockNameLen+1+((8-((1+uniformBlockNameLen+4)%8))%8); + int uniformBlockNameLen[1] = {strlen((char *)uniformBlockName)}; bp += uniformBlockNameLen[0]+1+((8-((1+uniformBlockNameLen[0]+4)%8))%8); GLuint result = weglGetUniformBlockIndex(*program,uniformBlockName); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 6 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,6); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5672: { // glGetActiveUniformBlockiv +case 5679: { // glGetActiveUniformBlockiv GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLenum *pname = (GLenum *) bp; bp += 4; - GLint *params = (GLint *) bins[0]->base; + GLint *params = (GLint *) bins[0]; weglGetActiveUniformBlockiv(*program,*uniformBlockIndex,*pname,params); int AP = 0; ErlDrvTermData rt[6]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "ok"); rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); }; break; -case 5673: { // glGetActiveUniformBlockName +case 5680: { // glGetActiveUniformBlockName GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLsizei *bufSize = (GLsizei *) bp; bp += 4; @@ -5352,20 +5317,19 @@ case 5673: { // glGetActiveUniformBlockName uniformBlockName = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); weglGetActiveUniformBlockName(*program,*uniformBlockIndex,*bufSize,length,uniformBlockName); int AP = 0; ErlDrvTermData rt[7]; - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) uniformBlockName; rt[AP++] = *length; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; - if (AP != 7 ) fprintf(stderr, "%d: ERROR AP mismatch %d %d\r\n",__LINE__,AP,7); - driver_send_term(WXE_DRV_PORT,caller,rt,AP); + driver_send_term(port,caller,rt,AP); driver_free(uniformBlockName); }; break; -case 5674: { // glUniformBlockBinding +case 5681: { // glUniformBlockBinding GLuint *program = (GLuint *) bp; bp += 4; GLuint *uniformBlockIndex = (GLuint *) bp; bp += 4; GLuint *uniformBlockBinding = (GLuint *) bp; bp += 4; weglUniformBlockBinding(*program,*uniformBlockIndex,*uniformBlockBinding); }; break; -case 5675: { // glCopyBufferSubData +case 5682: { // glCopyBufferSubData GLenum *readTarget = (GLenum *) bp; bp += 4; GLenum *writeTarget = (GLenum *) bp; bp += 4; GLintptr readOffset = (GLintptr) * (GLuint64EXT *) bp; bp += 8; @@ -5373,34 +5337,1633 @@ case 5675: { // glCopyBufferSubData GLsizeiptr size = (GLsizeiptr) * (GLuint64EXT *) bp; bp += 8; weglCopyBufferSubData(*readTarget,*writeTarget,readOffset,writeOffset,size); }; break; -case 5676: { // glResizeBuffersMESA +case 5683: { // glDrawElementsBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex); +}; break; +case 5684: { // glDrawElementsBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) bins[0]; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawElementsBaseVertex(*mode,*count,*type,indices,*basevertex); +}; break; +case 5685: { // glDrawRangeElementsBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLuint *start = (GLuint *) bp; bp += 4; + GLuint *end = (GLuint *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex); +}; break; +case 5686: { // glDrawRangeElementsBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLuint *start = (GLuint *) bp; bp += 4; + GLuint *end = (GLuint *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) bins[0]; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawRangeElementsBaseVertex(*mode,*start,*end,*count,*type,indices,*basevertex); +}; break; +case 5687: { // glDrawElementsInstancedBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) * (int *) bp; bp += 4; + GLsizei *primcount = (GLsizei *) bp; bp += 4; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex); +}; break; +case 5688: { // glDrawElementsInstancedBaseVertex + GLenum *mode = (GLenum *) bp; bp += 4; + GLsizei *count = (GLsizei *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indices = (GLvoid *) bins[0]; + GLsizei *primcount = (GLsizei *) bp; bp += 4; + GLint *basevertex = (GLint *) bp; bp += 4; + weglDrawElementsInstancedBaseVertex(*mode,*count,*type,indices,*primcount,*basevertex); +}; break; +case 5689: { // glProvokingVertex + GLenum *mode = (GLenum *) bp; bp += 4; + weglProvokingVertex(*mode); +}; break; +case 5690: { // glFenceSync + GLenum *condition = (GLenum *) bp; bp += 4; + GLbitfield *flags = (GLbitfield *) bp; bp += 4; + GLsync result = weglFenceSync(*condition,*flags); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5691: { // glIsSync + GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8; + GLboolean result = weglIsSync(sync); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5692: { // glDeleteSync + GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8; + weglDeleteSync(sync); +}; break; +case 5693: { // glClientWaitSync + GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8; + GLbitfield *flags = (GLbitfield *) bp; bp += 4; + bp += 4; + GLuint64 timeout = (GLuint64) * (GLuint64EXT *) bp; bp += 8; + GLenum result = weglClientWaitSync(sync,*flags,timeout); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5694: { // glWaitSync + GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8; + GLbitfield *flags = (GLbitfield *) bp; bp += 4; + bp += 4; + GLuint64 timeout = (GLuint64) * (GLuint64EXT *) bp; bp += 8; + weglWaitSync(sync,*flags,timeout); +}; break; +case 5695: { // glGetInteger64v + GLenum *pname = (GLenum *) bp; bp += 4; + GLint64 params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + weglGetInteger64v(*pname,params); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint64 *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5696: { // glGetSynciv + GLsync sync = (GLsync) * (GLuint64EXT *) bp; bp += 8; + GLenum *pname = (GLenum *) bp; bp += 4; + GLsizei *bufSize = (GLsizei *) bp; bp += 4; + GLsizei length[1] = {0}; + GLint *values; + values = (GLint *) driver_alloc(sizeof(GLint) * *bufSize); + weglGetSynciv(sync,*pname,*bufSize,length,values); + int AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*length)*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + for(int i=0; i < *length; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) values[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*length)+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(rt); + driver_free(values); +}; break; +case 5697: { // glTexImage2DMultisample + GLenum *target = (GLenum *) bp; bp += 4; + GLsizei *samples = (GLsizei *) bp; bp += 4; + GLint *internalformat = (GLint *) bp; bp += 4; + GLsizei *width = (GLsizei *) bp; bp += 4; + GLsizei *height = (GLsizei *) bp; bp += 4; + GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1; + weglTexImage2DMultisample(*target,*samples,*internalformat,*width,*height,*fixedsamplelocations); +}; break; +case 5698: { // glTexImage3DMultisample + GLenum *target = (GLenum *) bp; bp += 4; + GLsizei *samples = (GLsizei *) bp; bp += 4; + GLint *internalformat = (GLint *) bp; bp += 4; + GLsizei *width = (GLsizei *) bp; bp += 4; + GLsizei *height = (GLsizei *) bp; bp += 4; + GLsizei *depth = (GLsizei *) bp; bp += 4; + GLboolean *fixedsamplelocations = (GLboolean *) bp; bp += 1; + weglTexImage3DMultisample(*target,*samples,*internalformat,*width,*height,*depth,*fixedsamplelocations); +}; break; +case 5699: { // glGetMultisamplefv + GLenum *pname = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLfloat val[2] = {0.0,0.0}; + weglGetMultisamplefv(*pname,*index,val); + int AP = 0; ErlDrvTermData rt[10]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble valConv[2], *valTmp = valConv; + for(int i=0; i < 2; i++) valConv[i] = (GLdouble) val[i]; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) valTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) valTmp++; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5700: { // glSampleMaski + GLuint *index = (GLuint *) bp; bp += 4; + GLbitfield *mask = (GLbitfield *) bp; bp += 4; + weglSampleMaski(*index,*mask); +}; break; +case 5701: { // glNamedStringARB + GLenum *type = (GLenum *) bp; bp += 4; + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); + GLchar *string = (GLchar *) bp; + int stringLen[1] = {strlen((char *)string)}; bp += stringLen[0]+1+((8-((1+stringLen[0]+0)%8))%8); + weglNamedStringARB(*type,*nameLen,name,*stringLen,string); +}; break; +case 5702: { // glDeleteNamedStringARB + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + weglDeleteNamedStringARB(*nameLen,name); +}; break; +case 5703: { // glCompileShaderIncludeARB + GLuint *shader = (GLuint *) bp; bp += 4; + int * pathLen = (int *) bp; bp += 4; + int * pathTotSize = (int *) bp; bp += 4; + GLchar **path; + path = (GLchar **) driver_alloc(sizeof(GLchar *) * *pathLen); + for(int i=0;i<*pathLen;i++) { + path[i] = (GLchar *) bp; bp += 1+strlen(bp);}; + bp += (8 - ((0 + *pathTotSize) % 8)) % 8; + weglCompileShaderIncludeARB(*shader,*pathLen,(const GLchar **) path,NULL); + driver_free(path); +}; break; +case 5704: { // glIsNamedStringARB + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + GLboolean result = weglIsNamedStringARB(*nameLen,name); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5705: { // glGetNamedStringARB + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + GLsizei *bufSize = (GLsizei *) bp; bp += 4; + GLint stringlen[1] = {0}; + GLchar *string; + string = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); + weglGetNamedStringARB(*nameLen,name,*bufSize,stringlen,string); + int AP = 0; ErlDrvTermData rt[7]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) string; rt[AP++] = *stringlen; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(string); +}; break; +case 5706: { // glGetNamedStringivARB + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[1] = {0}; + weglGetNamedStringivARB(*nameLen,name,*pname,params); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5707: { // glBindFragDataLocationIndexed + GLuint *program = (GLuint *) bp; bp += 4; + GLuint *colorNumber = (GLuint *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); + weglBindFragDataLocationIndexed(*program,*colorNumber,*index,name); +}; break; +case 5708: { // glGetFragDataIndex + GLuint *program = (GLuint *) bp; bp += 4; + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+4)%8))%8); + GLint result = weglGetFragDataIndex(*program,name); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5709: { // glGenSamplers + GLsizei *count = (GLsizei *) bp; bp += 4; + GLuint *samplers; + samplers = (GLuint *) driver_alloc(sizeof(GLuint) * *count); + weglGenSamplers(*count,samplers); + int AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*count)*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + for(int i=0; i < *count; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) samplers[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*count)+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(rt); + driver_free(samplers); +}; break; +case 5710: { // glDeleteSamplers + int * samplersLen = (int *) bp; bp += 4; + GLuint * samplers = (GLuint *) bp; bp += (8-((*samplersLen*4+4)%8))%8; + weglDeleteSamplers(*samplersLen,samplers); +}; break; +case 5711: { // glIsSampler + GLuint *sampler = (GLuint *) bp; bp += 4; + GLboolean result = weglIsSampler(*sampler); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5712: { // glBindSampler + GLuint *unit = (GLuint *) bp; bp += 4; + GLuint *sampler = (GLuint *) bp; bp += 4; + weglBindSampler(*unit,*sampler); +}; break; +case 5713: { // glSamplerParameteri + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint *param = (GLint *) bp; bp += 4; + weglSamplerParameteri(*sampler,*pname,*param); +}; break; +case 5714: { // glSamplerParameteriv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + int * paramLen = (int *) bp; bp += 4; + GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8; + weglSamplerParameteriv(*sampler,*pname,param); +}; break; +case 5715: { // glSamplerParameterf + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLfloat *param = (GLfloat *) bp; bp += 4; + weglSamplerParameterf(*sampler,*pname,*param); +}; break; +case 5716: { // glSamplerParameterfv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + int * paramLen = (int *) bp; bp += 4; + GLfloat * param = (GLfloat *) bp; bp += (8-((*paramLen*4+4)%8))%8; + weglSamplerParameterfv(*sampler,*pname,param); +}; break; +case 5717: { // glSamplerParameterIiv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + int * paramLen = (int *) bp; bp += 4; + GLint * param = (GLint *) bp; bp += (8-((*paramLen*4+4)%8))%8; + weglSamplerParameterIiv(*sampler,*pname,param); +}; break; +case 5718: { // glSamplerParameterIuiv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + int * paramLen = (int *) bp; bp += 4; + GLuint * param = (GLuint *) bp; bp += (8-((*paramLen*4+4)%8))%8; + weglSamplerParameterIuiv(*sampler,*pname,param); +}; break; +case 5719: { // glGetSamplerParameteriv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[4] = {0,0,0,0}; + weglGetSamplerParameteriv(*sampler,*pname,params); + int AP = 0; ErlDrvTermData rt[15]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5720: { // glGetSamplerParameterIiv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[4] = {0,0,0,0}; + weglGetSamplerParameterIiv(*sampler,*pname,params); + int AP = 0; ErlDrvTermData rt[15]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5721: { // glGetSamplerParameterfv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLfloat params[4] = {0.0,0.0,0.0,0.0}; + weglGetSamplerParameterfv(*sampler,*pname,params); + int AP = 0; ErlDrvTermData rt[15]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble paramsConv[4], *paramsTmp = paramsConv; + for(int i=0; i < 4; i++) paramsConv[i] = (GLdouble) params[i]; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5722: { // glGetSamplerParameterIuiv + GLuint *sampler = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLuint params[4] = {0,0,0,0}; + weglGetSamplerParameterIuiv(*sampler,*pname,params); + int AP = 0; ErlDrvTermData rt[15]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLuint *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 4+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5723: { // glQueryCounter + GLuint *id = (GLuint *) bp; bp += 4; + GLenum *target = (GLenum *) bp; bp += 4; + weglQueryCounter(*id,*target); +}; break; +case 5724: { // glGetQueryObjecti64v + GLuint *id = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint64 params[1] = {0}; + weglGetQueryObjecti64v(*id,*pname,params); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5725: { // glGetQueryObjectui64v + GLuint *id = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLuint64 params[1] = {0}; + weglGetQueryObjectui64v(*id,*pname,params); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5726: { // glDrawArraysIndirect + GLenum *mode = (GLenum *) bp; bp += 4; + GLvoid *indirect = (GLvoid *) * (int *) bp; bp += 4; + weglDrawArraysIndirect(*mode,indirect); +}; break; +case 5727: { // glDrawArraysIndirect + GLenum *mode = (GLenum *) bp; bp += 4; + GLvoid *indirect = (GLvoid *) bins[0]; + weglDrawArraysIndirect(*mode,indirect); +}; break; +case 5728: { // glDrawElementsIndirect + GLenum *mode = (GLenum *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indirect = (GLvoid *) * (int *) bp; bp += 4; + weglDrawElementsIndirect(*mode,*type,indirect); +}; break; +case 5729: { // glDrawElementsIndirect + GLenum *mode = (GLenum *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLvoid *indirect = (GLvoid *) bins[0]; + weglDrawElementsIndirect(*mode,*type,indirect); +}; break; +case 5730: { // glUniform1d + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + GLdouble *x = (GLdouble *) bp; bp += 8; + weglUniform1d(*location,*x); +}; break; +case 5731: { // glUniform2d + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + GLdouble *x = (GLdouble *) bp; bp += 8; + GLdouble *y = (GLdouble *) bp; bp += 8; + weglUniform2d(*location,*x,*y); +}; break; +case 5732: { // glUniform3d + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + GLdouble *x = (GLdouble *) bp; bp += 8; + GLdouble *y = (GLdouble *) bp; bp += 8; + GLdouble *z = (GLdouble *) bp; bp += 8; + weglUniform3d(*location,*x,*y,*z); +}; break; +case 5733: { // glUniform4d + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + GLdouble *x = (GLdouble *) bp; bp += 8; + GLdouble *y = (GLdouble *) bp; bp += 8; + GLdouble *z = (GLdouble *) bp; bp += 8; + GLdouble *w = (GLdouble *) bp; bp += 8; + weglUniform4d(*location,*x,*y,*z,*w); +}; break; +case 5734: { // glUniform1dv + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + int * valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8; + weglUniform1dv(*location,*valueLen,value); +}; break; +case 5735: { // glUniform2dv + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*16; + weglUniform2dv(*location,*valueLen,value); +}; break; +case 5736: { // glUniform3dv + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*24; + weglUniform3dv(*location,*valueLen,value); +}; break; +case 5737: { // glUniform4dv + GLint *location = (GLint *) bp; bp += 4; + bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*32; + weglUniform4dv(*location,*valueLen,value); +}; break; +case 5738: { // glUniformMatrix2dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*32; + weglUniformMatrix2dv(*location,*valueLen,*transpose,value); +}; break; +case 5739: { // glUniformMatrix3dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*72; + weglUniformMatrix3dv(*location,*valueLen,*transpose,value); +}; break; +case 5740: { // glUniformMatrix4dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*128; + weglUniformMatrix4dv(*location,*valueLen,*transpose,value); +}; break; +case 5741: { // glUniformMatrix2x3dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*48; + weglUniformMatrix2x3dv(*location,*valueLen,*transpose,value); +}; break; +case 5742: { // glUniformMatrix2x4dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*64; + weglUniformMatrix2x4dv(*location,*valueLen,*transpose,value); +}; break; +case 5743: { // glUniformMatrix3x2dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*48; + weglUniformMatrix3x2dv(*location,*valueLen,*transpose,value); +}; break; +case 5744: { // glUniformMatrix3x4dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*96; + weglUniformMatrix3x4dv(*location,*valueLen,*transpose,value); +}; break; +case 5745: { // glUniformMatrix4x2dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*64; + weglUniformMatrix4x2dv(*location,*valueLen,*transpose,value); +}; break; +case 5746: { // glUniformMatrix4x3dv + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*96; + weglUniformMatrix4x3dv(*location,*valueLen,*transpose,value); +}; break; +case 5747: { // glGetUniformdv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLdouble params[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + weglGetUniformdv(*program,*location,params); + int AP = 0; ErlDrvTermData rt[38]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble *paramsTmp = params; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5748: { // glGetSubroutineUniformLocation + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + GLint result = weglGetSubroutineUniformLocation(*program,*shadertype,name); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5749: { // glGetSubroutineIndex + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLchar *name = (GLchar *) bp; + int nameLen[1] = {strlen((char *)name)}; bp += nameLen[0]+1+((8-((1+nameLen[0]+0)%8))%8); + GLuint result = weglGetSubroutineIndex(*program,*shadertype,name); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5750: { // glGetActiveSubroutineUniformName + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLsizei *bufsize = (GLsizei *) bp; bp += 4; + GLsizei length[1] = {0}; + GLchar *name; + name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize); + weglGetActiveSubroutineUniformName(*program,*shadertype,*index,*bufsize,length,name); + int AP = 0; ErlDrvTermData rt[7]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(name); +}; break; +case 5751: { // glGetActiveSubroutineName + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLsizei *bufsize = (GLsizei *) bp; bp += 4; + GLsizei length[1] = {0}; + GLchar *name; + name = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize); + weglGetActiveSubroutineName(*program,*shadertype,*index,*bufsize,length,name); + int AP = 0; ErlDrvTermData rt[7]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) name; rt[AP++] = *length; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(name); +}; break; +case 5752: { // glUniformSubroutinesuiv + GLenum *shadertype = (GLenum *) bp; bp += 4; + int * indicesLen = (int *) bp; bp += 4; + GLuint * indices = (GLuint *) bp; bp += (8-((*indicesLen*4+0)%8))%8; + weglUniformSubroutinesuiv(*shadertype,*indicesLen,indices); +}; break; +case 5753: { // glGetUniformSubroutineuiv + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLuint params[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + weglGetUniformSubroutineuiv(*shadertype,*location,params); + int AP = 0; ErlDrvTermData rt[38]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLuint *paramsTmp = params; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *paramsTmp++; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 16; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5754: { // glGetProgramStageiv + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint values[1] = {0}; + weglGetProgramStageiv(*program,*shadertype,*pname,values); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *values; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5755: { // glPatchParameteri + GLenum *pname = (GLenum *) bp; bp += 4; + GLint *value = (GLint *) bp; bp += 4; + weglPatchParameteri(*pname,*value); +}; break; +case 5756: { // glPatchParameterfv + GLenum *pname = (GLenum *) bp; bp += 4; + int * valuesLen = (int *) bp; bp += 4; + GLfloat * values = (GLfloat *) bp; bp += (8-((*valuesLen*4+0)%8))%8; + weglPatchParameterfv(*pname,values); +}; break; +case 5757: { // glBindTransformFeedback + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *id = (GLuint *) bp; bp += 4; + weglBindTransformFeedback(*target,*id); +}; break; +case 5758: { // glDeleteTransformFeedbacks + int * idsLen = (int *) bp; bp += 4; + GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+4)%8))%8; + weglDeleteTransformFeedbacks(*idsLen,ids); +}; break; +case 5759: { // glGenTransformFeedbacks + GLsizei *n = (GLsizei *) bp; bp += 4; + GLuint *ids; + ids = (GLuint *) driver_alloc(sizeof(GLuint) * *n); + weglGenTransformFeedbacks(*n,ids); + int AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + for(int i=0; i < *n; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(rt); + driver_free(ids); +}; break; +case 5760: { // glIsTransformFeedback + GLuint *id = (GLuint *) bp; bp += 4; + GLboolean result = weglIsTransformFeedback(*id); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5761: { // glPauseTransformFeedback + weglPauseTransformFeedback(); +}; break; +case 5762: { // glResumeTransformFeedback + weglResumeTransformFeedback(); +}; break; +case 5763: { // glDrawTransformFeedback + GLenum *mode = (GLenum *) bp; bp += 4; + GLuint *id = (GLuint *) bp; bp += 4; + weglDrawTransformFeedback(*mode,*id); +}; break; +case 5764: { // glDrawTransformFeedbackStream + GLenum *mode = (GLenum *) bp; bp += 4; + GLuint *id = (GLuint *) bp; bp += 4; + GLuint *stream = (GLuint *) bp; bp += 4; + weglDrawTransformFeedbackStream(*mode,*id,*stream); +}; break; +case 5765: { // glBeginQueryIndexed + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLuint *id = (GLuint *) bp; bp += 4; + weglBeginQueryIndexed(*target,*index,*id); +}; break; +case 5766: { // glEndQueryIndexed + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + weglEndQueryIndexed(*target,*index); +}; break; +case 5767: { // glGetQueryIndexediv + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[1] = {0}; + weglGetQueryIndexediv(*target,*index,*pname,params); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5768: { // glReleaseShaderCompiler + weglReleaseShaderCompiler(); +}; break; +case 5769: { // glShaderBinary + int * shadersLen = (int *) bp; bp += 4; + GLuint * shaders = (GLuint *) bp; bp += (8-((*shadersLen*4+4)%8))%8; + GLenum *binaryformat = (GLenum *) bp; bp += 4; + GLvoid *binary = (GLvoid *) bins[0]; + GLsizei binary_size = bins_sz[0]; + weglShaderBinary(*shadersLen,shaders,*binaryformat,binary,binary_size); +}; break; +case 5770: { // glGetShaderPrecisionFormat + GLenum *shadertype = (GLenum *) bp; bp += 4; + GLenum *precisiontype = (GLenum *) bp; bp += 4; + GLint range[2] = {0,0}; + GLint precision[1] = {0}; + weglGetShaderPrecisionFormat(*shadertype,*precisiontype,range,precision); + int AP = 0; ErlDrvTermData rt[14]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLint *rangeTmp = range; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *rangeTmp++; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *rangeTmp++; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *precision; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5771: { // glDepthRangef + GLclampf *n = (GLclampf *) bp; bp += 4; + GLclampf *f = (GLclampf *) bp; bp += 4; + weglDepthRangef(*n,*f); +}; break; +case 5772: { // glClearDepthf + GLclampf *d = (GLclampf *) bp; bp += 4; + weglClearDepthf(*d); +}; break; +case 5773: { // glGetProgramBinary + GLuint *program = (GLuint *) bp; bp += 4; + GLsizei *bufSize = (GLsizei *) bp; bp += 4; + GLsizei length[1] = {0}; + GLenum binaryFormat[1] = {0}; + ErlDrvBinary *binary = driver_alloc_binary(*bufSize); + weglGetProgramBinary(*program,*bufSize,length,binaryFormat,(GLvoid*) binary->orig_bytes); + int AP = 0; ErlDrvTermData rt[12]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *binaryFormat; + rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) binary; rt[AP++] = *length; rt[AP++] = 0; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free_binary(binary); +}; break; +case 5774: { // glProgramBinary + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *binaryFormat = (GLenum *) bp; bp += 4; + GLvoid *binary = (GLvoid *) bins[0]; + GLsizei binary_size = bins_sz[0]; + weglProgramBinary(*program,*binaryFormat,binary,binary_size); +}; break; +case 5775: { // glProgramParameteri + GLuint *program = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint *value = (GLint *) bp; bp += 4; + weglProgramParameteri(*program,*pname,*value); +}; break; +case 5776: { // glUseProgramStages + GLuint *pipeline = (GLuint *) bp; bp += 4; + GLbitfield *stages = (GLbitfield *) bp; bp += 4; + GLuint *program = (GLuint *) bp; bp += 4; + weglUseProgramStages(*pipeline,*stages,*program); +}; break; +case 5777: { // glActiveShaderProgram + GLuint *pipeline = (GLuint *) bp; bp += 4; + GLuint *program = (GLuint *) bp; bp += 4; + weglActiveShaderProgram(*pipeline,*program); +}; break; +case 5778: { // glCreateShaderProgramv + GLenum *type = (GLenum *) bp; bp += 4; + int * stringsLen = (int *) bp; bp += 4; + int * stringsTotSize = (int *) bp; bp += 4; + GLchar **strings; + strings = (GLchar **) driver_alloc(sizeof(GLchar *) * *stringsLen); + for(int i=0;i<*stringsLen;i++) { + strings[i] = (GLchar *) bp; bp += 1+strlen(bp);}; + bp += (8 - ((0 + *stringsTotSize) % 8)) % 8; + GLuint result = weglCreateShaderProgramv(*type,*stringsLen,(const GLchar **) strings); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(strings); +}; break; +case 5779: { // glBindProgramPipeline + GLuint *pipeline = (GLuint *) bp; bp += 4; + weglBindProgramPipeline(*pipeline); +}; break; +case 5780: { // glDeleteProgramPipelines + int * pipelinesLen = (int *) bp; bp += 4; + GLuint * pipelines = (GLuint *) bp; bp += (8-((*pipelinesLen*4+4)%8))%8; + weglDeleteProgramPipelines(*pipelinesLen,pipelines); +}; break; +case 5781: { // glGenProgramPipelines + GLsizei *n = (GLsizei *) bp; bp += 4; + GLuint *pipelines; + pipelines = (GLuint *) driver_alloc(sizeof(GLuint) * *n); + weglGenProgramPipelines(*n,pipelines); + int AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(7 + (*n)*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + for(int i=0; i < *n; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) pipelines[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = (*n)+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(rt); + driver_free(pipelines); +}; break; +case 5782: { // glIsProgramPipeline + GLuint *pipeline = (GLuint *) bp; bp += 4; + GLboolean result = weglIsProgramPipeline(*pipeline); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5783: { // glGetProgramPipelineiv + GLuint *pipeline = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLint params[1] = {0}; + weglGetProgramPipelineiv(*pipeline,*pname,params); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) *params; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5784: { // glProgramUniform1i + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLint *v0 = (GLint *) bp; bp += 4; + weglProgramUniform1i(*program,*location,*v0); +}; break; +case 5785: { // glProgramUniform1iv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int * valueLen = (int *) bp; bp += 4; + GLint * value = (GLint *) bp; bp += (8-((*valueLen*4+4)%8))%8; + weglProgramUniform1iv(*program,*location,*valueLen,value); +}; break; +case 5786: { // glProgramUniform1f + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLfloat *v0 = (GLfloat *) bp; bp += 4; + weglProgramUniform1f(*program,*location,*v0); +}; break; +case 5787: { // glProgramUniform1fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int * valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += (8-((*valueLen*4+4)%8))%8; + weglProgramUniform1fv(*program,*location,*valueLen,value); +}; break; +case 5788: { // glProgramUniform1d + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLdouble *v0 = (GLdouble *) bp; bp += 8; + weglProgramUniform1d(*program,*location,*v0); +}; break; +case 5789: { // glProgramUniform1dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int * valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += (8-((*valueLen*8+0)%8))%8; + weglProgramUniform1dv(*program,*location,*valueLen,value); +}; break; +case 5790: { // glProgramUniform1ui + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLuint *v0 = (GLuint *) bp; bp += 4; + weglProgramUniform1ui(*program,*location,*v0); +}; break; +case 5791: { // glProgramUniform1uiv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int * valueLen = (int *) bp; bp += 4; + GLuint * value = (GLuint *) bp; bp += (8-((*valueLen*4+4)%8))%8; + weglProgramUniform1uiv(*program,*location,*valueLen,value); +}; break; +case 5792: { // glProgramUniform2i + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLint *v0 = (GLint *) bp; bp += 4; + GLint *v1 = (GLint *) bp; bp += 4; + weglProgramUniform2i(*program,*location,*v0,*v1); +}; break; +case 5793: { // glProgramUniform2iv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLint * value = (GLint *) bp; bp += *valueLen*8; + weglProgramUniform2iv(*program,*location,*valueLen,value); +}; break; +case 5794: { // glProgramUniform2f + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLfloat *v0 = (GLfloat *) bp; bp += 4; + GLfloat *v1 = (GLfloat *) bp; bp += 4; + weglProgramUniform2f(*program,*location,*v0,*v1); +}; break; +case 5795: { // glProgramUniform2fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*8; + weglProgramUniform2fv(*program,*location,*valueLen,value); +}; break; +case 5796: { // glProgramUniform2d + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLdouble *v0 = (GLdouble *) bp; bp += 8; + GLdouble *v1 = (GLdouble *) bp; bp += 8; + weglProgramUniform2d(*program,*location,*v0,*v1); +}; break; +case 5797: { // glProgramUniform2dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*16; + weglProgramUniform2dv(*program,*location,*valueLen,value); +}; break; +case 5798: { // glProgramUniform2ui + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLuint *v0 = (GLuint *) bp; bp += 4; + GLuint *v1 = (GLuint *) bp; bp += 4; + weglProgramUniform2ui(*program,*location,*v0,*v1); +}; break; +case 5799: { // glProgramUniform2uiv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLuint * value = (GLuint *) bp; bp += *valueLen*8; + weglProgramUniform2uiv(*program,*location,*valueLen,value); +}; break; +case 5800: { // glProgramUniform3i + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLint *v0 = (GLint *) bp; bp += 4; + GLint *v1 = (GLint *) bp; bp += 4; + GLint *v2 = (GLint *) bp; bp += 4; + weglProgramUniform3i(*program,*location,*v0,*v1,*v2); +}; break; +case 5801: { // glProgramUniform3iv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLint * value = (GLint *) bp; bp += *valueLen*12; + weglProgramUniform3iv(*program,*location,*valueLen,value); +}; break; +case 5802: { // glProgramUniform3f + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLfloat *v0 = (GLfloat *) bp; bp += 4; + GLfloat *v1 = (GLfloat *) bp; bp += 4; + GLfloat *v2 = (GLfloat *) bp; bp += 4; + weglProgramUniform3f(*program,*location,*v0,*v1,*v2); +}; break; +case 5803: { // glProgramUniform3fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*12; + weglProgramUniform3fv(*program,*location,*valueLen,value); +}; break; +case 5804: { // glProgramUniform3d + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLdouble *v0 = (GLdouble *) bp; bp += 8; + GLdouble *v1 = (GLdouble *) bp; bp += 8; + GLdouble *v2 = (GLdouble *) bp; bp += 8; + weglProgramUniform3d(*program,*location,*v0,*v1,*v2); +}; break; +case 5805: { // glProgramUniform3dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*24; + weglProgramUniform3dv(*program,*location,*valueLen,value); +}; break; +case 5806: { // glProgramUniform3ui + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLuint *v0 = (GLuint *) bp; bp += 4; + GLuint *v1 = (GLuint *) bp; bp += 4; + GLuint *v2 = (GLuint *) bp; bp += 4; + weglProgramUniform3ui(*program,*location,*v0,*v1,*v2); +}; break; +case 5807: { // glProgramUniform3uiv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLuint * value = (GLuint *) bp; bp += *valueLen*12; + weglProgramUniform3uiv(*program,*location,*valueLen,value); +}; break; +case 5808: { // glProgramUniform4i + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLint *v0 = (GLint *) bp; bp += 4; + GLint *v1 = (GLint *) bp; bp += 4; + GLint *v2 = (GLint *) bp; bp += 4; + GLint *v3 = (GLint *) bp; bp += 4; + weglProgramUniform4i(*program,*location,*v0,*v1,*v2,*v3); +}; break; +case 5809: { // glProgramUniform4iv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLint * value = (GLint *) bp; bp += *valueLen*16; + weglProgramUniform4iv(*program,*location,*valueLen,value); +}; break; +case 5810: { // glProgramUniform4f + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLfloat *v0 = (GLfloat *) bp; bp += 4; + GLfloat *v1 = (GLfloat *) bp; bp += 4; + GLfloat *v2 = (GLfloat *) bp; bp += 4; + GLfloat *v3 = (GLfloat *) bp; bp += 4; + weglProgramUniform4f(*program,*location,*v0,*v1,*v2,*v3); +}; break; +case 5811: { // glProgramUniform4fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*16; + weglProgramUniform4fv(*program,*location,*valueLen,value); +}; break; +case 5812: { // glProgramUniform4d + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLdouble *v0 = (GLdouble *) bp; bp += 8; + GLdouble *v1 = (GLdouble *) bp; bp += 8; + GLdouble *v2 = (GLdouble *) bp; bp += 8; + GLdouble *v3 = (GLdouble *) bp; bp += 8; + weglProgramUniform4d(*program,*location,*v0,*v1,*v2,*v3); +}; break; +case 5813: { // glProgramUniform4dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*32; + weglProgramUniform4dv(*program,*location,*valueLen,value); +}; break; +case 5814: { // glProgramUniform4ui + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLuint *v0 = (GLuint *) bp; bp += 4; + GLuint *v1 = (GLuint *) bp; bp += 4; + GLuint *v2 = (GLuint *) bp; bp += 4; + GLuint *v3 = (GLuint *) bp; bp += 4; + weglProgramUniform4ui(*program,*location,*v0,*v1,*v2,*v3); +}; break; +case 5815: { // glProgramUniform4uiv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + int *valueLen = (int *) bp; bp += 4; + GLuint * value = (GLuint *) bp; bp += *valueLen*16; + weglProgramUniform4uiv(*program,*location,*valueLen,value); +}; break; +case 5816: { // glProgramUniformMatrix2fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*16; + weglProgramUniformMatrix2fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5817: { // glProgramUniformMatrix3fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*36; + weglProgramUniformMatrix3fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5818: { // glProgramUniformMatrix4fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*64; + weglProgramUniformMatrix4fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5819: { // glProgramUniformMatrix2dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*32; + weglProgramUniformMatrix2dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5820: { // glProgramUniformMatrix3dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*72; + weglProgramUniformMatrix3dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5821: { // glProgramUniformMatrix4dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*128; + weglProgramUniformMatrix4dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5822: { // glProgramUniformMatrix2x3fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*24; + weglProgramUniformMatrix2x3fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5823: { // glProgramUniformMatrix3x2fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*24; + weglProgramUniformMatrix3x2fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5824: { // glProgramUniformMatrix2x4fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*32; + weglProgramUniformMatrix2x4fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5825: { // glProgramUniformMatrix4x2fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*32; + weglProgramUniformMatrix4x2fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5826: { // glProgramUniformMatrix3x4fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*48; + weglProgramUniformMatrix3x4fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5827: { // glProgramUniformMatrix4x3fv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 3; + int *valueLen = (int *) bp; bp += 4; + GLfloat * value = (GLfloat *) bp; bp += *valueLen*48; + weglProgramUniformMatrix4x3fv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5828: { // glProgramUniformMatrix2x3dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*48; + weglProgramUniformMatrix2x3dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5829: { // glProgramUniformMatrix3x2dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*48; + weglProgramUniformMatrix3x2dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5830: { // glProgramUniformMatrix2x4dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*64; + weglProgramUniformMatrix2x4dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5831: { // glProgramUniformMatrix4x2dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*64; + weglProgramUniformMatrix4x2dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5832: { // glProgramUniformMatrix3x4dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*96; + weglProgramUniformMatrix3x4dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5833: { // glProgramUniformMatrix4x3dv + GLuint *program = (GLuint *) bp; bp += 4; + GLint *location = (GLint *) bp; bp += 4; + GLboolean *transpose = (GLboolean *) bp; bp += 1; + bp += 7; + int *valueLen = (int *) bp; bp += 8; + GLdouble * value = (GLdouble *) bp; bp += *valueLen*96; + weglProgramUniformMatrix4x3dv(*program,*location,*valueLen,*transpose,value); +}; break; +case 5834: { // glValidateProgramPipeline + GLuint *pipeline = (GLuint *) bp; bp += 4; + weglValidateProgramPipeline(*pipeline); +}; break; +case 5835: { // glGetProgramPipelineInfoLog + GLuint *pipeline = (GLuint *) bp; bp += 4; + GLsizei *bufSize = (GLsizei *) bp; bp += 4; + GLsizei length[1] = {0}; + GLchar *infoLog; + infoLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufSize); + weglGetProgramPipelineInfoLog(*pipeline,*bufSize,length,infoLog); + int AP = 0; ErlDrvTermData rt[7]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) infoLog; rt[AP++] = *length; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(infoLog); +}; break; +case 5836: { // glVertexAttribL1dv + GLuint *index = (GLuint *) bp; bp += 4; + bp += 4; + GLdouble *v = (GLdouble *) bp; bp += 8; + weglVertexAttribL1dv(*index,v); +}; break; +case 5837: { // glVertexAttribL2dv + GLuint *index = (GLuint *) bp; bp += 4; + bp += 4; + GLdouble *v = (GLdouble *) bp; bp += 8; + weglVertexAttribL2dv(*index,v); +}; break; +case 5838: { // glVertexAttribL3dv + GLuint *index = (GLuint *) bp; bp += 4; + bp += 4; + GLdouble *v = (GLdouble *) bp; bp += 8; + weglVertexAttribL3dv(*index,v); +}; break; +case 5839: { // glVertexAttribL4dv + GLuint *index = (GLuint *) bp; bp += 4; + bp += 4; + GLdouble *v = (GLdouble *) bp; bp += 8; + weglVertexAttribL4dv(*index,v); +}; break; +case 5840: { // glVertexAttribLPointer + GLuint *index = (GLuint *) bp; bp += 4; + GLint *size = (GLint *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLsizei *stride = (GLsizei *) bp; bp += 4; + GLvoid *pointer = (GLvoid *) * (int *) bp; bp += 4; + weglVertexAttribLPointer(*index,*size,*type,*stride,pointer); +}; break; +case 5841: { // glVertexAttribLPointer + GLuint *index = (GLuint *) bp; bp += 4; + GLint *size = (GLint *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLsizei *stride = (GLsizei *) bp; bp += 4; + GLvoid *pointer = (GLvoid *) bins[0]; + weglVertexAttribLPointer(*index,*size,*type,*stride,pointer); +}; break; +case 5842: { // glGetVertexAttribLdv + GLuint *index = (GLuint *) bp; bp += 4; + GLenum *pname = (GLenum *) bp; bp += 4; + GLdouble params[4] = {0.0,0.0,0.0,0.0}; + weglGetVertexAttribLdv(*index,*pname,params); + int AP = 0; ErlDrvTermData rt[14]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble *paramsTmp = params; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) paramsTmp++; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 4; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5843: { // glViewportArrayv + GLuint *first = (GLuint *) bp; bp += 4; + int *vLen = (int *) bp; bp += 4; + GLfloat * v = (GLfloat *) bp; bp += *vLen*16; + weglViewportArrayv(*first,*vLen,v); +}; break; +case 5844: { // glViewportIndexedf + GLuint *index = (GLuint *) bp; bp += 4; + GLfloat *x = (GLfloat *) bp; bp += 4; + GLfloat *y = (GLfloat *) bp; bp += 4; + GLfloat *w = (GLfloat *) bp; bp += 4; + GLfloat *h = (GLfloat *) bp; bp += 4; + weglViewportIndexedf(*index,*x,*y,*w,*h); +}; break; +case 5845: { // glViewportIndexedfv + GLuint *index = (GLuint *) bp; bp += 4; + GLfloat * v = (GLfloat *) bp; bp += 16; + weglViewportIndexedfv(*index,v); +}; break; +case 5846: { // glScissorArrayv + GLuint *first = (GLuint *) bp; bp += 4; + int *vLen = (int *) bp; bp += 4; + GLint * v = (GLint *) bp; bp += *vLen*16; + weglScissorArrayv(*first,*vLen,v); +}; break; +case 5847: { // glScissorIndexed + GLuint *index = (GLuint *) bp; bp += 4; + GLint *left = (GLint *) bp; bp += 4; + GLint *bottom = (GLint *) bp; bp += 4; + GLsizei *width = (GLsizei *) bp; bp += 4; + GLsizei *height = (GLsizei *) bp; bp += 4; + weglScissorIndexed(*index,*left,*bottom,*width,*height); +}; break; +case 5848: { // glScissorIndexedv + GLuint *index = (GLuint *) bp; bp += 4; + GLint * v = (GLint *) bp; bp += 16; + weglScissorIndexedv(*index,v); +}; break; +case 5849: { // glDepthRangeArrayv + GLuint *first = (GLuint *) bp; bp += 4; + bp += 4; + int *vLen = (int *) bp; bp += 8; + GLclampd * v = (GLclampd *) bp; bp += *vLen*16; + weglDepthRangeArrayv(*first,*vLen,v); +}; break; +case 5850: { // glDepthRangeIndexed + GLuint *index = (GLuint *) bp; bp += 4; + bp += 4; + GLclampd *n = (GLclampd *) bp; bp += 8; + GLclampd *f = (GLclampd *) bp; bp += 8; + weglDepthRangeIndexed(*index,*n,*f); +}; break; +case 5851: { // glGetFloati_v + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLfloat data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + weglGetFloati_v(*target,*index,data); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble dataConv[16], *dataTmp = dataConv; + for(int i=0; i < 16; i++) dataConv[i] = (GLdouble) data[i]; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5852: { // glGetDoublei_v + GLenum *target = (GLenum *) bp; bp += 4; + GLuint *index = (GLuint *) bp; bp += 4; + GLdouble data[16] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; + weglGetDoublei_v(*target,*index,data); + int AP = 0; ErlDrvTermData rt[39]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + GLdouble *dataTmp = data; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_FLOAT; rt[AP++] = (ErlDrvTermData) dataTmp++; + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = 16+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5853: { // glDebugMessageControlARB + GLenum *source = (GLenum *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLenum *severity = (GLenum *) bp; bp += 4; + int * idsLen = (int *) bp; bp += 4; + GLuint * ids = (GLuint *) bp; bp += (8-((*idsLen*4+0)%8))%8; + GLboolean *enabled = (GLboolean *) bp; bp += 1; + weglDebugMessageControlARB(*source,*type,*severity,*idsLen,ids,*enabled); +}; break; +case 5854: { // glDebugMessageInsertARB + GLenum *source = (GLenum *) bp; bp += 4; + GLenum *type = (GLenum *) bp; bp += 4; + GLuint *id = (GLuint *) bp; bp += 4; + GLenum *severity = (GLenum *) bp; bp += 4; + GLchar *buf = (GLchar *) bp; + int bufLen[1] = {strlen((char *)buf)}; bp += bufLen[0]+1+((8-((1+bufLen[0]+0)%8))%8); + weglDebugMessageInsertARB(*source,*type,*id,*severity,*bufLen,buf); +}; break; +case 5855: { // glGetDebugMessageLogARB + GLuint *count = (GLuint *) bp; bp += 4; + GLsizei *bufsize = (GLsizei *) bp; bp += 4; + GLenum *sources; + sources = (GLenum *) driver_alloc(sizeof(GLenum) * *count); + GLenum *types; + types = (GLenum *) driver_alloc(sizeof(GLenum) * *count); + GLuint *ids; + ids = (GLuint *) driver_alloc(sizeof(GLuint) * *count); + GLenum *severities; + severities = (GLenum *) driver_alloc(sizeof(GLenum) * *count); + GLsizei *lengths; + lengths = (GLsizei *) driver_alloc(sizeof(GLsizei) * *count); + GLchar *messageLog; + messageLog = (GLchar *) driver_alloc(sizeof(GLchar) * *bufsize); + GLuint result = weglGetDebugMessageLogARB(*count,*bufsize,sources,types,ids,severities,lengths,messageLog); + int AP = 0; ErlDrvTermData *rt; + rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData)*(23 + result*3 + result*2 + result*2 + result*2 + result*2)); + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + for(int i=0; i < (int) result; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) sources[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1; + for(int i=0; i < (int) result; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) types[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1; + for(int i=0; i < (int) result; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) ids[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1; + for(int i=0; i < (int) result; i++) { + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) severities[i];} + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1; + for(int i=0; i < (int) result; i++) { + rt[AP++] = ERL_DRV_STRING; rt[AP++] = (ErlDrvTermData) messageLog; rt[AP++] = lengths[i]-1; + messageLog += lengths[i]; } + rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = ((int) result)+1; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 6; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); + driver_free(rt); + driver_free(messageLog); + driver_free(lengths); + driver_free(severities); + driver_free(ids); + driver_free(types); + driver_free(sources); +}; break; +case 5856: { // glGetGraphicsResetStatusARB + GLenum result = weglGetGraphicsResetStatusARB(); + int AP = 0; ErlDrvTermData rt[6]; + rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); + rt[AP++] = ERL_DRV_INT; rt[AP++] = (ErlDrvSInt) result; + rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; + driver_send_term(port,caller,rt,AP); +}; break; +case 5857: { // glResizeBuffersMESA weglResizeBuffersMESA(); }; break; -case 5677: { // glWindowPos4dvMESA +case 5858: { // glWindowPos4dvMESA GLdouble *v = (GLdouble *) bp; bp += 8; weglWindowPos4dvMESA(v); }; break; -case 5678: { // glWindowPos4fvMESA +case 5859: { // glWindowPos4fvMESA GLfloat *v = (GLfloat *) bp; bp += 4; weglWindowPos4fvMESA(v); }; break; -case 5679: { // glWindowPos4ivMESA +case 5860: { // glWindowPos4ivMESA GLint *v = (GLint *) bp; bp += 4; weglWindowPos4ivMESA(v); }; break; -case 5680: { // glWindowPos4svMESA +case 5861: { // glWindowPos4svMESA GLshort *v = (GLshort *) bp; bp += 2; weglWindowPos4svMESA(v); }; break; -case 5681: { // glDepthBoundsEXT +case 5862: { // glDepthBoundsEXT GLclampd *zmin = (GLclampd *) bp; bp += 8; GLclampd *zmax = (GLclampd *) bp; bp += 8; weglDepthBoundsEXT(*zmin,*zmax); }; break; -case 5682: { // glStencilClearTagEXT +case 5863: { // glStencilClearTagEXT GLsizei *stencilTagBits = (GLsizei *) bp; bp += 4; GLuint *stencilClearTag = (GLuint *) bp; bp += 4; weglStencilClearTagEXT(*stencilTagBits,*stencilClearTag); }; break; +}} catch (char *err_msg) { +int AP = 0; ErlDrvTermData rt[12]; +rt[AP++] = ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_error_"); +rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) op; +rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) err_msg); +// rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *) gl_fns[op-GLE_GL_FUNC_START].name); +// rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; +rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; +driver_send_term(port,caller,rt,AP); }} /* The End */ diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp index 8c056bbb91..479d7679a4 100644 --- a/lib/wx/c_src/gen/wxe_funcs.cpp +++ b/lib/wx/c_src/gen/wxe_funcs.cpp @@ -23,6 +23,7 @@ #include "../wxe_impl.h" #include "../wxe_events.h" #include "../wxe_return.h" +#include "../wxe_gl.h" #include "wxe_macros.h" #include "wxe_derived_dest.h" @@ -43,6 +44,15 @@ void WxeApp::wxe_dispatch(wxeCommand& Ecmd) rt.addAtom("ok"); break; } + case WXE_BIN_INCR: + driver_binary_inc_refc(Ecmd.bin[0]->bin); + break; + case WXE_BIN_DECR: + driver_binary_dec_refc(Ecmd.bin[0]->bin); + break; + case WXE_INIT_OPENGL: + wxe_initOpenGL(rt, bp); + break; case 98: { // wxeEvtListener::wxeEvtListener wxeEvtListener *Result = new wxeEvtListener(Ecmd.port); rt.addRef(getRef((void *)Result,memenv), "wxeEvtListener"); diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h index 13a17e356f..5c5b8614ed 100644 --- a/lib/wx/c_src/wxe_driver.h +++ b/lib/wx/c_src/wxe_driver.h @@ -83,8 +83,9 @@ extern char * erl_wx_privdir; #define WXE_CB_START 8 #define WXE_DEBUG_DRIVER 9 #define WXE_DEBUG_PING 10 -#define WXE_BIN_INCR 5001 -#define WXE_BIN_DECR 5002 +#define WXE_BIN_INCR 11 +#define WXE_BIN_DECR 12 +#define WXE_INIT_OPENGL 13 #define OPENGL_START 5000 diff --git a/lib/wx/c_src/wxe_gl.cpp b/lib/wx/c_src/wxe_gl.cpp index 63dd68fa5e..e947a1bc6e 100644 --- a/lib/wx/c_src/wxe_gl.cpp +++ b/lib/wx/c_src/wxe_gl.cpp @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-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 @@ -19,303 +19,142 @@ #include <stdio.h> #include <string.h> +#ifndef _WIN32 +#include <dlfcn.h> +#else +#include <windows.h> +#endif #include "wxe_impl.h" - -#include "wxe_gl.h" - -#define WX_DEF_EXTS -#include "gen/gl_fdefs.h" -#include "gen/gl_finit.h" -#include "gen/glu_finit.h" +#include "wxe_return.h" /* **************************************************************************** * Opengl context management * * ****************************************************************************/ -int gl_initiated = FALSE; +int erl_gl_initiated = FALSE; ErlDrvTermData gl_active = 0; wxeGLC glc; -void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas) -{ - if(gl_initiated == FALSE) { - initOpenGL(); - init_tess(); - gl_initiated = TRUE; - } - gl_active = caller; - glc[caller] = canvas; -} - -void deleteActiveGL(wxGLCanvas *canvas) -{ - gl_active = 0; - wxeGLC::iterator it; - for(it = glc.begin(); it != glc.end(); ++it) { - if(it->second == canvas) { - it->second = (wxGLCanvas *) 0; - } - } -} - -/* **************************************************************************** - * OPENGL INITIALIZATION - *****************************************************************************/ +typedef void (*WXE_GL_DISPATCH) (int, char *, ErlDrvPort, ErlDrvTermData, char **, int *); +WXE_GL_DISPATCH wxe_gl_dispatch; #ifdef _WIN32 +#define RTLD_LAZY 0 +typedef HMODULE DL_LIB_P; void * dlsym(HMODULE Lib, const char *func) { void * funcp; - if((funcp = (void *) GetProcAddress(Lib, func))) + if((funcp = (void *) GetProcAddress(Lib, func))) return funcp; - else + else return (void *) wglGetProcAddress(func); } -#endif -int initOpenGL() -{ -#ifdef _MACOSX - char * DLName = "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib"; - void * LIBhandle = dlopen(DLName, RTLD_LAZY); -#elif defined(_WIN32) - WCHAR * DLName = wxT("opengl32.dll"); - HMODULE LIBhandle = LoadLibrary(DLName); -#else - char * DLName = (char *) "libGL.so"; - void * LIBhandle = dlopen(DLName, RTLD_LAZY); -#endif - // fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName); - void * func = NULL; - int i; +HMODULE dlopen(const char *path, int unused) { + WCHAR * DLL; + int len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0); + DLL = (WCHAR *) malloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, path, -1, DLL, len); + HMODULE lib = LoadLibrary(DLL); + free(DLL); + return lib; +} - if(LIBhandle) { - for(i=0; gl_fns[i].name != NULL; i++) { - if((func = dlsym(LIBhandle, gl_fns[i].name))) { - * (void **) (gl_fns[i].func) = func; - // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].name); - } else { - if(gl_fns[i].alt != NULL) { - if((func = dlsym(LIBhandle, gl_fns[i].alt))) { - * (void **) (gl_fns[i].func) = func; - // fprintf(stderr, "GL LOADED %s \r\n", gl_fns[i].alt); - } else { - * (void **) (gl_fns[i].func) = (void *) &gl_error; - // fprintf(stderr, "GL Skipped %s and %s \r\n", gl_fns[i].name, gl_fns[i].alt); - }; - } else { - * (void **) (gl_fns[i].func) = (void *) &gl_error; - // fprintf(stderr, "GL Skipped %s \r\n", gl_fns[i].name); - } - } - } -#ifdef _WIN32 - FreeLibrary(LIBhandle); -#else - dlclose(LIBhandle); -#endif - // fprintf(stderr, "OPENGL library is loaded\r\n"); - } else { - wxString msg; - msg.Printf(wxT("Could NOT load OpenGL library: ")); -#ifdef _WIN32 - msg += DLName; +void dlclose(HMODULE Lib) { + FreeLibrary(Lib); +} #else - msg += wxString::FromAscii((char *)DLName); +typedef void * DL_LIB_P; #endif - send_msg("error", &msg); - }; -#ifdef _MACOSX - DLName = "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib"; - LIBhandle = dlopen(DLName, RTLD_LAZY); -#elif defined(_WIN32) - DLName = wxT("glu32.dll"); - LIBhandle = LoadLibrary(DLName); +void wxe_initOpenGL(wxeReturn rt, char *bp) { + DL_LIB_P LIBhandle; + int (*init_opengl)(void *); +#ifdef _WIN32 + void * erlCallbacks = &WinDynDriverCallbacks; #else - DLName = (char *) "libGLU.so"; - LIBhandle = dlopen(DLName, RTLD_LAZY); + void * erlCallbacks = NULL; #endif - // fprintf(stderr, "Loading GL: %s\r\n", (const char*)DLName); - func = NULL; - - if(LIBhandle) { - for(i=0; glu_fns[i].name != NULL; i++) { - if((func = dlsym(LIBhandle, glu_fns[i].name))) { - * (void **) (glu_fns[i].func) = func; + + if(erl_gl_initiated == FALSE) { + if((LIBhandle = dlopen(bp, RTLD_LAZY))) { + *(void **) (&init_opengl) = dlsym(LIBhandle, "egl_init_opengl"); + wxe_gl_dispatch = (WXE_GL_DISPATCH) dlsym(LIBhandle, "egl_dispatch"); + if(init_opengl && wxe_gl_dispatch) { + (*init_opengl)(erlCallbacks); + rt.addAtom((char *) "ok"); + rt.add(wxString::FromAscii("initiated")); + rt.addTupleCount(2); + erl_gl_initiated = TRUE; } else { - if(glu_fns[i].alt != NULL) { - if((func = dlsym(LIBhandle, glu_fns[i].alt))) { - * (void **) (glu_fns[i].func) = func; - } else { - * (void **) (glu_fns[i].func) = (void *) &gl_error; - // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].alt); - }; - } else { - * (void **) (glu_fns[i].func) = (void *) &gl_error; - // fprintf(stderr, "GLU Skipped %s\r\n", glu_fns[i].name); - } + wxString msg; + msg.Printf(wxT("In library: ")); + msg += wxString::FromAscii(bp); + msg += wxT(" functions: "); + if(!init_opengl) + msg += wxT("egl_init_opengl "); + if(!wxe_gl_dispatch) + msg += wxT("egl_dispatch "); + rt.addAtom((char *) "error"); + rt.add(msg); + rt.addTupleCount(2); } + } else { + wxString msg; + msg.Printf(wxT("Could not load dll: ")); + msg += wxString::FromAscii(bp); + rt.addAtom((char *) "error"); + rt.add(msg); + rt.addTupleCount(2); } -#ifdef _WIN32 - FreeLibrary(LIBhandle); -#else - dlclose(LIBhandle); -#endif - // fprintf(stderr, "GLU library is loaded\r\n"); } else { - wxString msg; - msg.Printf(wxT("Could NOT load OpenGL GLU library: ")); -#ifdef _WIN32 - msg += DLName; -#else - msg += wxString::FromAscii((char *)DLName); -#endif - send_msg("error", &msg); - }; - return 0; -} - -void gl_error() { - int AP = 0; ErlDrvTermData rt[8]; - rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *)"_wxe_error_"); - rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) gl_error_op; - rt[AP++] = ERL_DRV_ATOM; rt[AP++] = driver_mk_atom((char *)"undef"); - rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 3; - driver_send_term(WXE_DRV_PORT,gl_active,rt,AP); -} - -/* ******************************************************************************* - * GLU Tesselation special - * ******************************************************************************/ - -static GLUtesselator* tess; -static GLdouble* tess_coords; -static GLdouble* tess_alloc_vertex; -static int* tess_vertices; - -void CALLBACK -wxe_ogla_vertex(GLdouble* coords) -{ - /* fprintf(stderr, "%d\r\n", (int) (coords - tess_coords) / 3); */ - - *tess_vertices++ = (int) (coords - tess_coords) / 3; -} - -void CALLBACK -wxe_ogla_edge_flag(GLboolean flag) -{ + rt.addAtom((char *) "ok"); + rt.add(wxString::FromAscii("already initilized")); + rt.addTupleCount(2); + } + rt.send(); } -void CALLBACK -wxe_ogla_error(GLenum errorCode) +void setActiveGL(ErlDrvTermData caller, wxGLCanvas *canvas) { - const GLubyte *err; - err = gluErrorString(errorCode); - wxString msg; - msg.Printf(wxT("Tesselation error: %d: "), (int)errorCode); - msg += wxString::FromAscii((char *) err); - send_msg("error", &msg); + gl_active = caller; + glc[caller] = canvas; } -void CALLBACK -wxe_ogla_combine(GLdouble coords[3], - void* vertex_data[4], - GLfloat w[4], - void **dataOut) +void deleteActiveGL(wxGLCanvas *canvas) { - GLdouble* vertex = tess_alloc_vertex; - - tess_alloc_vertex += 3; - -#if 0 - fprintf(stderr, "combine: "); - int i; - for (i = 0; i < 4; i++) { - if (w[i] > 0.0) { - fprintf(stderr, "%d(%g) ", (int) vertex_data[i], w[i]); + gl_active = 0; + wxeGLC::iterator it; + for(it = glc.begin(); it != glc.end(); ++it) { + if(it->second == canvas) { + it->second = (wxGLCanvas *) 0; } } - fprintf(stderr, "\r\n"); - fprintf(stderr, "%g %g %g\r\n", vertex[0], vertex[1], vertex[2]); -#endif - - vertex[0] = coords[0]; - vertex[1] = coords[1]; - vertex[2] = coords[2]; - *dataOut = vertex; -} - -void init_tess() -{ - tess = gluNewTess(); - - gluTessCallback(tess, GLU_TESS_VERTEX, (GLUfuncptr) wxe_ogla_vertex); - gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (GLUfuncptr) wxe_ogla_edge_flag); - gluTessCallback(tess, GLU_TESS_COMBINE, (GLUfuncptr) wxe_ogla_combine); - gluTessCallback(tess, GLU_TESS_ERROR, (GLUfuncptr) wxe_ogla_error); - } -void exit_tess() -{ - gluDeleteTess(tess); -} - -int wxe_tess_impl(char* buff, ErlDrvTermData caller) -{ - ErlDrvBinary* bin; - int i; - int num_vertices = * (int *) buff; buff += 8; // Align - GLdouble *n = (double *) buff; buff += 8*3; - - GLdouble* new_vertices; - bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble)); - new_vertices = tess_coords = (double *) bin->orig_bytes; - memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble)); - tess_alloc_vertex = tess_coords + num_vertices*3; - -#if 0 - fprintf(stderr, "n=%d\r\n", num_vertices); -#endif - int *vertices; - vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices); - - tess_vertices = vertices; - - gluTessNormal(tess, n[0], n[1], n[2]); - gluTessBeginPolygon(tess, 0); - gluTessBeginContour(tess); - for (i = 0; i < num_vertices; i++) { - gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i); - } - gluTessEndContour(tess); - gluTessEndPolygon(tess); - - int n_pos = (tess_vertices - vertices); - - int AP = 0; ErlDrvTermData *rt; - rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2)); - rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_wxe_result_"); - - for(i=0; i < n_pos; i++) { - rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i]; +void gl_dispatch(int op, char *bp,ErlDrvTermData caller,WXEBinRef *bins[]){ + if(caller != gl_active) { + wxGLCanvas * current = glc[caller]; + if(current) { gl_active = caller; current->SetCurrent();} + else { + ErlDrvTermData rt[] = // Error msg + {ERL_DRV_ATOM, driver_mk_atom((char *) "_egl_error_"), + ERL_DRV_INT, op, + ERL_DRV_ATOM, driver_mk_atom((char *) "no_gl_context"), + ERL_DRV_TUPLE,3}; + driver_send_term(WXE_DRV_PORT,caller,rt,8); + return ; + } }; - rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1; - - rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; - rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0; - - rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} - rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple - - driver_send_term(WXE_DRV_PORT,caller,rt,AP); -// fprintf(stderr, "List %d %d %d \r\n", -// n_pos, -// (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), -// num_vertices*6*sizeof(GLdouble)); - driver_free_binary(bin); - driver_free(vertices); - driver_free(rt); - return 0; + char * bs[3]; + int bs_sz[3]; + for(int i=0; i<3; i++) { + if(bins[i]) { + bs[i] = bins[i]->base; + bs_sz[i] = bins[i]->size; + } + else + bs[i] = NULL; + } + wxe_gl_dispatch(op, bp, WXE_DRV_PORT, caller, bs, bs_sz); } diff --git a/lib/wx/c_src/wxe_gl.h b/lib/wx/c_src/wxe_gl.h index 3a47b3c1bd..1b556ff4ec 100644 --- a/lib/wx/c_src/wxe_gl.h +++ b/lib/wx/c_src/wxe_gl.h @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2008-2009. All Rights Reserved. + * Copyright Ericsson AB 2008-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 @@ -17,119 +17,6 @@ * %CopyrightEnd% */ +#include "egl_impl.h" -#ifndef _WIN32 -# include <dlfcn.h> -#endif - -#ifndef __WXMAC__ -# include <GL/gl.h> -# include <GL/glu.h> /* Header File For The OpenGL Library */ -#else -# include <OpenGL/glu.h> /* Header File For The OpenGL Library */ -#endif - -#ifndef CALLBACK -# define CALLBACK -#endif - -#ifdef _WIN32 -# ifndef _GLUfuncptr -// Visual studio CPP ++ compiler -# define _GLUfuncptr void (_stdcall *)() -# endif -#endif - -#ifdef _GLUfuncptr -# define GLUfuncptr _GLUfuncptr -#elif defined(TESS_CB_TIGER_STYLE) -# define GLUfuncptr GLvoid (*)(...) -#else -# define GLUfuncptr GLvoid (*)() -#endif - -#ifdef WIN32 -#include <windows.h> -#include <gl/gl.h> -#elif defined(HAVE_GL_GL_H) -#include <GL/gl.h> -#elif defined(HAVE_OPENGL_GL_H) -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif - -int initOpenGL(); -void gl_error(); -extern int gl_error_op; -extern ErlDrvTermData gl_active; - -/* Some new GL types (eliminates the need for glext.h) */ - -#ifndef HAVE_GLINTPTR -#ifndef HAVE_GLINTPTRARB -# include <stddef.h> -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; -#endif /* HAVE_GLINTPTRARB */ -typedef GLintptrARB GLintptr; -typedef GLsizeiptrARB GLsizeiptr; -#endif /* HAVE_GLINTPTR */ - -#ifndef HAVE_GLCHAR -# ifndef HAVE_GLCHARARB -/* GL types for handling shader object handles and characters */ -typedef char GLcharARB; /* native character */ -typedef unsigned int GLhandleARB; /* shader object handle */ -#endif /* HAVE_GLCHARARB */ -typedef GLcharARB GLchar; -#endif - -#ifndef HAVE_GLHALFARB -/* GL types for "half" precision (s10e5) float data in host memory */ -typedef unsigned short GLhalfARB; -#endif - -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GLX_OML_sync_control extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include <inttypes.h> -#elif defined(__sun__) -#include <inttypes.h> -#if defined(__STDC__) -#if defined(__arch64__) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) -#include <inttypes.h> -#elif defined(__SCO__) || defined(__USLC__) -#include <stdint.h> -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(WIN32) && defined(_MSC_VER) -typedef long int int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#elif defined(WIN32) && defined(__GNUC__) -#include <stdint.h> -#else -#include <inttypes.h> /* Fallback option */ -#endif - -#ifndef HAVE_GLINT64EXT -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif - -void init_tess(); -void exit_tess(); -int wxe_tess_impl(char* buff, ErlDrvTermData caller); +void wxe_initOpenGL(wxeReturn, char*); diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp index 6d2926ce4e..79d1a29519 100644 --- a/lib/wx/c_src/wxe_impl.cpp +++ b/lib/wx/c_src/wxe_impl.cpp @@ -68,7 +68,6 @@ ErlDrvTermData wxe_batch_caller = 0; ErlDrvTermData init_caller = 0; // extern opengl -extern int gl_initiated; void gl_dispatch(int op, char *bp, ErlDrvTermData caller, WXEBinRef *bins[]); @@ -265,7 +264,6 @@ bool WxeApp::OnInit() init_nonconsts(global_me, init_caller); erl_drv_mutex_lock(wxe_status_m); wxe_status = WXE_INITIATED; - gl_initiated = FALSE; erl_drv_cond_signal(wxe_status_c); erl_drv_mutex_unlock(wxe_status_m); return TRUE; diff --git a/lib/wx/c_src/wxe_return.cpp b/lib/wx/c_src/wxe_return.cpp index 2c4f7541e7..9fd627829e 100644 --- a/lib/wx/c_src/wxe_return.cpp +++ b/lib/wx/c_src/wxe_return.cpp @@ -64,11 +64,14 @@ int wxeReturn::send() { int res = driver_send_term(port, caller, rtData, rtLength); driver_free(rtData); +#ifdef DEBUG if(res == -1) { wxString msg; msg.Printf(wxT("Failed to send return or event msg")); send_msg("internal_error", &msg); } +#endif + reset(); return res; } diff --git a/lib/wx/configure.in b/lib/wx/configure.in index 855c0c975e..f7128db23a 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -162,16 +162,20 @@ esac case $host_os in darwin*) CFLAGS="-no-cpp-precomp $CFLAGS" - LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC -framework OpenGL $LDFLAGS" + LDFLAGS="-bundle -flat_namespace -undefined warning -fPIC $LDFLAGS" + GL_LIBS="-framework OpenGL" ;; win32) LDFLAGS="-dll $LDFLAGS" + GL_LIBS="-lglu32 -lOpengl32" ;; mingw32) LDFLAGS="-shared -fPIC $LDFLAGS" + GL_LIBS="-lglu32 -lOpengl32" ;; *) LDFLAGS="-shared -fPIC $LDFLAGS" + GL_LIBS="-lGL -lGLU" ;; esac @@ -194,6 +198,42 @@ case $host_os in ;; esac +dnl +dnl Opengl tests +dnl + +if test X"$host_os" != X"win32" ; then + AC_CHECK_HEADERS([GL/gl.h], [], + [AC_CHECK_HEADERS([OpenGL/gl.h])]) + if test X"$ac_cv_header_GL_gl_h" != Xyes && + test X"$ac_cv_header_OpenGL_gl_h" != Xyes + then + saved_CPPFLAGS="$CPPFLAGS" + AC_MSG_NOTICE(Checking for OpenGL headers in /usr/X11R6) + CPPFLAGS="-isystem /usr/X11R6/include $CPPFLAGS" + $as_unset ac_cv_header_GL_gl_h + AC_CHECK_HEADERS([GL/gl.h]) + if test X"$ac_cv_header_GL_gl_h" != Xyes ; then + AC_MSG_NOTICE(Checking for OpenGL headers in /usr/local) + CPPFLAGS="-isystem /usr/local/include $saved_CPPFLAGS" + $as_unset ac_cv_header_GL_gl_h + AC_CHECK_HEADERS([GL/gl.h]) + if test X"$ac_cv_header_GL_gl_h" != Xyes ; then + AC_MSG_WARN([No OpenGL headers found, wx will NOT be usable]) + CPPFLAGS="$saved_CPPFLAGS" + else + GL_LIBS="-L/usr/local/lib $GL_LIBS" + fi + else + GL_LIBS="-L/usr/X11R6/lib $GL_LIBS" + fi + fi +else + AC_CHECK_HEADERS([gl/gl.h],[],[],[#include <windows.h>]) +fi + +AC_SUBST(GL_LIBS) + CXXFLAGS="$CFLAGS $CPPFLAGS" CFLAGS="$CFLAGS $CPPFLAGS $C_ONLY_FLAGS" @@ -386,17 +426,6 @@ if test "$WXERL_CAN_BUILD_DRIVER" != "false"; then AC_SUBST(WX_HAVE_STATIC_LIBS) AC_SUBST(RC_FILE_TYPE) -dnl -dnl Opengl tests -dnl - -if test X"$host_os" != X"win32" ; then - AC_CHECK_HEADERS([GL/gl.h]) - AC_CHECK_HEADERS([OpenGL/gl.h]) -else - AC_CHECK_HEADERS([gl/gl.h],[],[],[#include <windows.h>]) -fi - AC_MSG_CHECKING(if wxwidgets have opengl support) AC_LANG_PUSH(C++) saved_CXXFLAGS=$CXXFLAGS diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl index 2fa0d72a59..52f2635af9 100644 --- a/lib/wx/include/gl.hrl +++ b/lib/wx/include/gl.hrl @@ -782,7 +782,7 @@ -define(GL_TEXTURE_COMPARE_MODE, 16#884C). -define(GL_TEXTURE_COMPARE_FUNC, 16#884D). -define(GL_COMPARE_R_TO_TEXTURE, 16#884E). --define(GL_GLEXT_VERSION, 52). +-define(GL_GLEXT_VERSION, 65). -define(GL_CONSTANT_COLOR, 16#8001). -define(GL_ONE_MINUS_CONSTANT_COLOR, 16#8002). -define(GL_CONSTANT_ALPHA, 16#8003). @@ -1021,6 +1021,8 @@ -define(GL_CLIP_DISTANCE3, 16#3003). -define(GL_CLIP_DISTANCE4, 16#3004). -define(GL_CLIP_DISTANCE5, 16#3005). +-define(GL_CLIP_DISTANCE6, 16#3006). +-define(GL_CLIP_DISTANCE7, 16#3007). -define(GL_MAX_CLIP_DISTANCES, 16#D32). -define(GL_MAJOR_VERSION, 16#821B). -define(GL_MINOR_VERSION, 16#821C). @@ -1111,6 +1113,9 @@ -define(GL_QUERY_NO_WAIT, 16#8E14). -define(GL_QUERY_BY_REGION_WAIT, 16#8E15). -define(GL_QUERY_BY_REGION_NO_WAIT, 16#8E16). +-define(GL_BUFFER_ACCESS_FLAGS, 16#911F). +-define(GL_BUFFER_MAP_LENGTH, 16#9120). +-define(GL_BUFFER_MAP_OFFSET, 16#9121). -define(GL_CLAMP_VERTEX_COLOR, 16#891A). -define(GL_CLAMP_FRAGMENT_COLOR, 16#891B). -define(GL_ALPHA_INTEGER, 16#8D97). @@ -1145,6 +1150,40 @@ -define(GL_SIGNED_NORMALIZED, 16#8F9C). -define(GL_PRIMITIVE_RESTART, 16#8F9D). -define(GL_PRIMITIVE_RESTART_INDEX, 16#8F9E). +-define(GL_CONTEXT_CORE_PROFILE_BIT, 16#1). +-define(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT, 16#2). +-define(GL_LINES_ADJACENCY, 16#A). +-define(GL_LINE_STRIP_ADJACENCY, 16#B). +-define(GL_TRIANGLES_ADJACENCY, 16#C). +-define(GL_TRIANGLE_STRIP_ADJACENCY, 16#D). +-define(GL_PROGRAM_POINT_SIZE, 16#8642). +-define(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, 16#8C29). +-define(GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 16#8DA7). +-define(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS, 16#8DA8). +-define(GL_GEOMETRY_SHADER, 16#8DD9). +-define(GL_GEOMETRY_VERTICES_OUT, 16#8916). +-define(GL_GEOMETRY_INPUT_TYPE, 16#8917). +-define(GL_GEOMETRY_OUTPUT_TYPE, 16#8918). +-define(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS, 16#8DDF). +-define(GL_MAX_GEOMETRY_OUTPUT_VERTICES, 16#8DE0). +-define(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, 16#8DE1). +-define(GL_MAX_VERTEX_OUTPUT_COMPONENTS, 16#9122). +-define(GL_MAX_GEOMETRY_INPUT_COMPONENTS, 16#9123). +-define(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, 16#9124). +-define(GL_MAX_FRAGMENT_INPUT_COMPONENTS, 16#9125). +-define(GL_CONTEXT_PROFILE_MASK, 16#9126). +-define(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 16#88FE). +-define(GL_SAMPLE_SHADING, 16#8C36). +-define(GL_MIN_SAMPLE_SHADING_VALUE, 16#8C37). +-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, 16#8E5E). +-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, 16#8E5F). +-define(GL_TEXTURE_CUBE_MAP_ARRAY, 16#9009). +-define(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, 16#900A). +-define(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 16#900B). +-define(GL_SAMPLER_CUBE_MAP_ARRAY, 16#900C). +-define(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, 16#900D). +-define(GL_INT_SAMPLER_CUBE_MAP_ARRAY, 16#900E). +-define(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, 16#900F). -define(GL_TEXTURE0_ARB, 16#84C0). -define(GL_TEXTURE1_ARB, 16#84C1). -define(GL_TEXTURE2_ARB, 16#84C2). @@ -1712,6 +1751,211 @@ -define(GL_INVALID_INDEX, 16#FFFFFFFF). -define(GL_COPY_READ_BUFFER, 16#8F36). -define(GL_COPY_WRITE_BUFFER, 16#8F37). +-define(GL_DEPTH_CLAMP, 16#864F). +-define(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION, 16#8E4C). +-define(GL_FIRST_VERTEX_CONVENTION, 16#8E4D). +-define(GL_LAST_VERTEX_CONVENTION, 16#8E4E). +-define(GL_PROVOKING_VERTEX, 16#8E4F). +-define(GL_TEXTURE_CUBE_MAP_SEAMLESS, 16#884F). +-define(GL_MAX_SERVER_WAIT_TIMEOUT, 16#9111). +-define(GL_OBJECT_TYPE, 16#9112). +-define(GL_SYNC_CONDITION, 16#9113). +-define(GL_SYNC_STATUS, 16#9114). +-define(GL_SYNC_FLAGS, 16#9115). +-define(GL_SYNC_FENCE, 16#9116). +-define(GL_SYNC_GPU_COMMANDS_COMPLETE, 16#9117). +-define(GL_UNSIGNALED, 16#9118). +-define(GL_SIGNALED, 16#9119). +-define(GL_ALREADY_SIGNALED, 16#911A). +-define(GL_TIMEOUT_EXPIRED, 16#911B). +-define(GL_CONDITION_SATISFIED, 16#911C). +-define(GL_WAIT_FAILED, 16#911D). +-define(GL_SYNC_FLUSH_COMMANDS_BIT, 16#1). +-define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFF). +-define(GL_SAMPLE_POSITION, 16#8E50). +-define(GL_SAMPLE_MASK, 16#8E51). +-define(GL_SAMPLE_MASK_VALUE, 16#8E52). +-define(GL_MAX_SAMPLE_MASK_WORDS, 16#8E59). +-define(GL_TEXTURE_2D_MULTISAMPLE, 16#9100). +-define(GL_PROXY_TEXTURE_2D_MULTISAMPLE, 16#9101). +-define(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 16#9102). +-define(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY, 16#9103). +-define(GL_TEXTURE_BINDING_2D_MULTISAMPLE, 16#9104). +-define(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, 16#9105). +-define(GL_TEXTURE_SAMPLES, 16#9106). +-define(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, 16#9107). +-define(GL_SAMPLER_2D_MULTISAMPLE, 16#9108). +-define(GL_INT_SAMPLER_2D_MULTISAMPLE, 16#9109). +-define(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, 16#910A). +-define(GL_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910B). +-define(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910C). +-define(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, 16#910D). +-define(GL_MAX_COLOR_TEXTURE_SAMPLES, 16#910E). +-define(GL_MAX_DEPTH_TEXTURE_SAMPLES, 16#910F). +-define(GL_MAX_INTEGER_SAMPLES, 16#9110). +-define(GL_SAMPLE_SHADING_ARB, 16#8C36). +-define(GL_MIN_SAMPLE_SHADING_VALUE_ARB, 16#8C37). +-define(GL_TEXTURE_CUBE_MAP_ARRAY_ARB, 16#9009). +-define(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB, 16#900A). +-define(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB, 16#900B). +-define(GL_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900C). +-define(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB, 16#900D). +-define(GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900E). +-define(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB, 16#900F). +-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB, 16#8E5E). +-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB, 16#8E5F). +-define(GL_SHADER_INCLUDE_ARB, 16#8DAE). +-define(GL_NAMED_STRING_LENGTH_ARB, 16#8DE9). +-define(GL_NAMED_STRING_TYPE_ARB, 16#8DEA). +-define(GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, 16#8E8C). +-define(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB, 16#8E8D). +-define(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB, 16#8E8E). +-define(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB, 16#8E8F). +-define(GL_SRC1_COLOR, 16#88F9). +-define(GL_ONE_MINUS_SRC1_COLOR, 16#88FA). +-define(GL_ONE_MINUS_SRC1_ALPHA, 16#88FB). +-define(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, 16#88FC). +-define(GL_ANY_SAMPLES_PASSED, 16#8C2F). +-define(GL_SAMPLER_BINDING, 16#8919). +-define(GL_RGB10_A2UI, 16#906F). +-define(GL_TEXTURE_SWIZZLE_R, 16#8E42). +-define(GL_TEXTURE_SWIZZLE_G, 16#8E43). +-define(GL_TEXTURE_SWIZZLE_B, 16#8E44). +-define(GL_TEXTURE_SWIZZLE_A, 16#8E45). +-define(GL_TEXTURE_SWIZZLE_RGBA, 16#8E46). +-define(GL_TIME_ELAPSED, 16#88BF). +-define(GL_TIMESTAMP, 16#8E28). +-define(GL_INT_2_10_10_10_REV, 16#8D9F). +-define(GL_DRAW_INDIRECT_BUFFER, 16#8F3F). +-define(GL_DRAW_INDIRECT_BUFFER_BINDING, 16#8F43). +-define(GL_GEOMETRY_SHADER_INVOCATIONS, 16#887F). +-define(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, 16#8E5A). +-define(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET, 16#8E5B). +-define(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET, 16#8E5C). +-define(GL_FRAGMENT_INTERPOLATION_OFFSET_BITS, 16#8E5D). +-define(GL_DOUBLE_VEC2, 16#8FFC). +-define(GL_DOUBLE_VEC3, 16#8FFD). +-define(GL_DOUBLE_VEC4, 16#8FFE). +-define(GL_DOUBLE_MAT2, 16#8F46). +-define(GL_DOUBLE_MAT3, 16#8F47). +-define(GL_DOUBLE_MAT4, 16#8F48). +-define(GL_DOUBLE_MAT2x3, 16#8F49). +-define(GL_DOUBLE_MAT2x4, 16#8F4A). +-define(GL_DOUBLE_MAT3x2, 16#8F4B). +-define(GL_DOUBLE_MAT3x4, 16#8F4C). +-define(GL_DOUBLE_MAT4x2, 16#8F4D). +-define(GL_DOUBLE_MAT4x3, 16#8F4E). +-define(GL_ACTIVE_SUBROUTINES, 16#8DE5). +-define(GL_ACTIVE_SUBROUTINE_UNIFORMS, 16#8DE6). +-define(GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, 16#8E47). +-define(GL_ACTIVE_SUBROUTINE_MAX_LENGTH, 16#8E48). +-define(GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH, 16#8E49). +-define(GL_MAX_SUBROUTINES, 16#8DE7). +-define(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, 16#8DE8). +-define(GL_NUM_COMPATIBLE_SUBROUTINES, 16#8E4A). +-define(GL_COMPATIBLE_SUBROUTINES, 16#8E4B). +-define(GL_PATCHES, 16#E). +-define(GL_PATCH_VERTICES, 16#8E72). +-define(GL_PATCH_DEFAULT_INNER_LEVEL, 16#8E73). +-define(GL_PATCH_DEFAULT_OUTER_LEVEL, 16#8E74). +-define(GL_TESS_CONTROL_OUTPUT_VERTICES, 16#8E75). +-define(GL_TESS_GEN_MODE, 16#8E76). +-define(GL_TESS_GEN_SPACING, 16#8E77). +-define(GL_TESS_GEN_VERTEX_ORDER, 16#8E78). +-define(GL_TESS_GEN_POINT_MODE, 16#8E79). +-define(GL_ISOLINES, 16#8E7A). +-define(GL_FRACTIONAL_ODD, 16#8E7B). +-define(GL_FRACTIONAL_EVEN, 16#8E7C). +-define(GL_MAX_PATCH_VERTICES, 16#8E7D). +-define(GL_MAX_TESS_GEN_LEVEL, 16#8E7E). +-define(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, 16#8E7F). +-define(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, 16#8E80). +-define(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, 16#8E81). +-define(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, 16#8E82). +-define(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, 16#8E83). +-define(GL_MAX_TESS_PATCH_COMPONENTS, 16#8E84). +-define(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, 16#8E85). +-define(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, 16#8E86). +-define(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, 16#8E89). +-define(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, 16#8E8A). +-define(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, 16#886C). +-define(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, 16#886D). +-define(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, 16#8E1E). +-define(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, 16#8E1F). +-define(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER, 16#84F0). +-define(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER, 16#84F1). +-define(GL_TESS_EVALUATION_SHADER, 16#8E87). +-define(GL_TESS_CONTROL_SHADER, 16#8E88). +-define(GL_TRANSFORM_FEEDBACK, 16#8E22). +-define(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, 16#8E23). +-define(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, 16#8E24). +-define(GL_TRANSFORM_FEEDBACK_BINDING, 16#8E25). +-define(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, 16#8E70). +-define(GL_MAX_VERTEX_STREAMS, 16#8E71). +-define(GL_FIXED, 16#140C). +-define(GL_IMPLEMENTATION_COLOR_READ_TYPE, 16#8B9A). +-define(GL_IMPLEMENTATION_COLOR_READ_FORMAT, 16#8B9B). +-define(GL_LOW_FLOAT, 16#8DF0). +-define(GL_MEDIUM_FLOAT, 16#8DF1). +-define(GL_HIGH_FLOAT, 16#8DF2). +-define(GL_LOW_INT, 16#8DF3). +-define(GL_MEDIUM_INT, 16#8DF4). +-define(GL_HIGH_INT, 16#8DF5). +-define(GL_SHADER_COMPILER, 16#8DFA). +-define(GL_NUM_SHADER_BINARY_FORMATS, 16#8DF9). +-define(GL_MAX_VERTEX_UNIFORM_VECTORS, 16#8DFB). +-define(GL_MAX_VARYING_VECTORS, 16#8DFC). +-define(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 16#8DFD). +-define(GL_PROGRAM_BINARY_RETRIEVABLE_HINT, 16#8257). +-define(GL_PROGRAM_BINARY_LENGTH, 16#8741). +-define(GL_NUM_PROGRAM_BINARY_FORMATS, 16#87FE). +-define(GL_PROGRAM_BINARY_FORMATS, 16#87FF). +-define(GL_VERTEX_SHADER_BIT, 16#1). +-define(GL_FRAGMENT_SHADER_BIT, 16#2). +-define(GL_GEOMETRY_SHADER_BIT, 16#4). +-define(GL_TESS_CONTROL_SHADER_BIT, 16#8). +-define(GL_TESS_EVALUATION_SHADER_BIT, 16#10). +-define(GL_ALL_SHADER_BITS, 16#FFFFFFFF). +-define(GL_PROGRAM_SEPARABLE, 16#8258). +-define(GL_ACTIVE_PROGRAM, 16#8259). +-define(GL_PROGRAM_PIPELINE_BINDING, 16#825A). +-define(GL_MAX_VIEWPORTS, 16#825B). +-define(GL_VIEWPORT_SUBPIXEL_BITS, 16#825C). +-define(GL_VIEWPORT_BOUNDS_RANGE, 16#825D). +-define(GL_LAYER_PROVOKING_VERTEX, 16#825E). +-define(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, 16#825F). +-define(GL_UNDEFINED_VERTEX, 16#8260). +-define(GL_SYNC_CL_EVENT_ARB, 16#8240). +-define(GL_SYNC_CL_EVENT_COMPLETE_ARB, 16#8241). +-define(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB, 16#8242). +-define(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB, 16#8243). +-define(GL_DEBUG_CALLBACK_FUNCTION_ARB, 16#8244). +-define(GL_DEBUG_CALLBACK_USER_PARAM_ARB, 16#8245). +-define(GL_DEBUG_SOURCE_API_ARB, 16#8246). +-define(GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, 16#8247). +-define(GL_DEBUG_SOURCE_SHADER_COMPILER_ARB, 16#8248). +-define(GL_DEBUG_SOURCE_THIRD_PARTY_ARB, 16#8249). +-define(GL_DEBUG_SOURCE_APPLICATION_ARB, 16#824A). +-define(GL_DEBUG_SOURCE_OTHER_ARB, 16#824B). +-define(GL_DEBUG_TYPE_ERROR_ARB, 16#824C). +-define(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, 16#824D). +-define(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, 16#824E). +-define(GL_DEBUG_TYPE_PORTABILITY_ARB, 16#824F). +-define(GL_DEBUG_TYPE_PERFORMANCE_ARB, 16#8250). +-define(GL_DEBUG_TYPE_OTHER_ARB, 16#8251). +-define(GL_MAX_DEBUG_MESSAGE_LENGTH_ARB, 16#9143). +-define(GL_MAX_DEBUG_LOGGED_MESSAGES_ARB, 16#9144). +-define(GL_DEBUG_LOGGED_MESSAGES_ARB, 16#9145). +-define(GL_DEBUG_SEVERITY_HIGH_ARB, 16#9146). +-define(GL_DEBUG_SEVERITY_MEDIUM_ARB, 16#9147). +-define(GL_DEBUG_SEVERITY_LOW_ARB, 16#9148). +-define(GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB, 16#4). +-define(GL_LOSE_CONTEXT_ON_RESET_ARB, 16#8252). +-define(GL_GUILTY_CONTEXT_RESET_ARB, 16#8253). +-define(GL_INNOCENT_CONTEXT_RESET_ARB, 16#8254). +-define(GL_UNKNOWN_CONTEXT_RESET_ARB, 16#8255). +-define(GL_RESET_NOTIFICATION_STRATEGY_ARB, 16#8256). +-define(GL_NO_RESET_NOTIFICATION_ARB, 16#8261). -define(GL_CONSTANT_COLOR_EXT, 16#8001). -define(GL_ONE_MINUS_CONSTANT_COLOR_EXT, 16#8002). -define(GL_CONSTANT_ALPHA_EXT, 16#8003). @@ -2921,9 +3165,9 @@ -define(GL_ACTIVE_STENCIL_FACE_EXT, 16#8911). -define(GL_TEXT_FRAGMENT_SHADER_ATI, 16#8200). -define(GL_UNPACK_CLIENT_STORAGE_APPLE, 16#85B2). --define(GL_ELEMENT_ARRAY_APPLE, 16#8768). --define(GL_ELEMENT_ARRAY_TYPE_APPLE, 16#8769). --define(GL_ELEMENT_ARRAY_POINTER_APPLE, 16#876A). +-define(GL_ELEMENT_ARRAY_APPLE, 16#8A0C). +-define(GL_ELEMENT_ARRAY_TYPE_APPLE, 16#8A0D). +-define(GL_ELEMENT_ARRAY_POINTER_APPLE, 16#8A0E). -define(GL_DRAW_PIXELS_APPLE, 16#8A0A). -define(GL_FENCE_APPLE, 16#8A0B). -define(GL_VERTEX_ARRAY_BINDING_APPLE, 16#85B5). @@ -2931,6 +3175,7 @@ -define(GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE, 16#851E). -define(GL_VERTEX_ARRAY_STORAGE_HINT_APPLE, 16#851F). -define(GL_VERTEX_ARRAY_RANGE_POINTER_APPLE, 16#8521). +-define(GL_STORAGE_CLIENT_APPLE, 16#85B4). -define(GL_STORAGE_CACHED_APPLE, 16#85BE). -define(GL_STORAGE_SHARED_APPLE, 16#85BF). -define(GL_YCBCR_422_APPLE, 16#85B9). @@ -3244,6 +3489,12 @@ -define(GL_SEPARATE_ATTRIBS_NV, 16#8C8D). -define(GL_TRANSFORM_FEEDBACK_BUFFER_NV, 16#8C8E). -define(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV, 16#8C8F). +-define(GL_LAYER_NV, 16#8DAA). +-define(GL_NEXT_BUFFER_NV, -2). +-define(GL_SKIP_COMPONENTS4_NV, -3). +-define(GL_SKIP_COMPONENTS3_NV, -4). +-define(GL_SKIP_COMPONENTS2_NV, -5). +-define(GL_SKIP_COMPONENTS1_NV, -6). -define(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT, 16#8DE2). -define(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT, 16#8DE3). -define(GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT, 16#8DE4). @@ -3335,11 +3586,11 @@ -define(GL_SAMPLE_MASK_VALUE_NV, 16#8E52). -define(GL_TEXTURE_BINDING_RENDERBUFFER_NV, 16#8E53). -define(GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV, 16#8E54). --define(GL_MAX_SAMPLE_MASK_WORDS_NV, 16#8E59). -define(GL_TEXTURE_RENDERBUFFER_NV, 16#8E55). -define(GL_SAMPLER_RENDERBUFFER_NV, 16#8E56). -define(GL_INT_SAMPLER_RENDERBUFFER_NV, 16#8E57). -define(GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV, 16#8E58). +-define(GL_MAX_SAMPLE_MASK_WORDS_NV, 16#8E59). -define(GL_TRANSFORM_FEEDBACK_NV, 16#8E22). -define(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV, 16#8E23). -define(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV, 16#8E24). @@ -3365,6 +3616,247 @@ -define(GL_FIRST_VERTEX_CONVENTION_EXT, 16#8E4D). -define(GL_LAST_VERTEX_CONVENTION_EXT, 16#8E4E). -define(GL_PROVOKING_VERTEX_EXT, 16#8E4F). +-define(GL_ALPHA_SNORM, 16#9010). +-define(GL_LUMINANCE_SNORM, 16#9011). +-define(GL_LUMINANCE_ALPHA_SNORM, 16#9012). +-define(GL_INTENSITY_SNORM, 16#9013). +-define(GL_ALPHA8_SNORM, 16#9014). +-define(GL_LUMINANCE8_SNORM, 16#9015). +-define(GL_LUMINANCE8_ALPHA8_SNORM, 16#9016). +-define(GL_INTENSITY8_SNORM, 16#9017). +-define(GL_ALPHA16_SNORM, 16#9018). +-define(GL_LUMINANCE16_SNORM, 16#9019). +-define(GL_LUMINANCE16_ALPHA16_SNORM, 16#901A). +-define(GL_INTENSITY16_SNORM, 16#901B). +-define(GL_TEXTURE_RANGE_LENGTH_APPLE, 16#85B7). +-define(GL_TEXTURE_RANGE_POINTER_APPLE, 16#85B8). +-define(GL_TEXTURE_STORAGE_HINT_APPLE, 16#85BC). +-define(GL_STORAGE_PRIVATE_APPLE, 16#85BD). +-define(GL_HALF_APPLE, 16#140B). +-define(GL_RGBA_FLOAT32_APPLE, 16#8814). +-define(GL_RGB_FLOAT32_APPLE, 16#8815). +-define(GL_ALPHA_FLOAT32_APPLE, 16#8816). +-define(GL_INTENSITY_FLOAT32_APPLE, 16#8817). +-define(GL_LUMINANCE_FLOAT32_APPLE, 16#8818). +-define(GL_LUMINANCE_ALPHA_FLOAT32_APPLE, 16#8819). +-define(GL_RGBA_FLOAT16_APPLE, 16#881A). +-define(GL_RGB_FLOAT16_APPLE, 16#881B). +-define(GL_ALPHA_FLOAT16_APPLE, 16#881C). +-define(GL_INTENSITY_FLOAT16_APPLE, 16#881D). +-define(GL_LUMINANCE_FLOAT16_APPLE, 16#881E). +-define(GL_LUMINANCE_ALPHA_FLOAT16_APPLE, 16#881F). +-define(GL_COLOR_FLOAT_APPLE, 16#8A0F). +-define(GL_VERTEX_ATTRIB_MAP1_APPLE, 16#8A00). +-define(GL_VERTEX_ATTRIB_MAP2_APPLE, 16#8A01). +-define(GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE, 16#8A02). +-define(GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE, 16#8A03). +-define(GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE, 16#8A04). +-define(GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE, 16#8A05). +-define(GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE, 16#8A06). +-define(GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE, 16#8A07). +-define(GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE, 16#8A08). +-define(GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE, 16#8A09). +-define(GL_AUX_DEPTH_STENCIL_APPLE, 16#8A14). +-define(GL_BUFFER_OBJECT_APPLE, 16#85B3). +-define(GL_RELEASED_APPLE, 16#8A19). +-define(GL_VOLATILE_APPLE, 16#8A1A). +-define(GL_RETAINED_APPLE, 16#8A1B). +-define(GL_UNDEFINED_APPLE, 16#8A1C). +-define(GL_PURGEABLE_APPLE, 16#8A1D). +-define(GL_PACK_ROW_BYTES_APPLE, 16#8A15). +-define(GL_UNPACK_ROW_BYTES_APPLE, 16#8A16). +-define(GL_RGB_422_APPLE, 16#8A1F). +-define(GL_VIDEO_BUFFER_NV, 16#9020). +-define(GL_VIDEO_BUFFER_BINDING_NV, 16#9021). +-define(GL_FIELD_UPPER_NV, 16#9022). +-define(GL_FIELD_LOWER_NV, 16#9023). +-define(GL_NUM_VIDEO_CAPTURE_STREAMS_NV, 16#9024). +-define(GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV, 16#9025). +-define(GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV, 16#9026). +-define(GL_LAST_VIDEO_CAPTURE_STATUS_NV, 16#9027). +-define(GL_VIDEO_BUFFER_PITCH_NV, 16#9028). +-define(GL_VIDEO_COLOR_CONVERSION_MATRIX_NV, 16#9029). +-define(GL_VIDEO_COLOR_CONVERSION_MAX_NV, 16#902A). +-define(GL_VIDEO_COLOR_CONVERSION_MIN_NV, 16#902B). +-define(GL_VIDEO_COLOR_CONVERSION_OFFSET_NV, 16#902C). +-define(GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV, 16#902D). +-define(GL_PARTIAL_SUCCESS_NV, 16#902E). +-define(GL_SUCCESS_NV, 16#902F). +-define(GL_FAILURE_NV, 16#9030). +-define(GL_YCBYCR8_422_NV, 16#9031). +-define(GL_YCBAYCR8A_4224_NV, 16#9032). +-define(GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV, 16#9033). +-define(GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV, 16#9034). +-define(GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV, 16#9035). +-define(GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV, 16#9036). +-define(GL_Z4Y12Z4CB12Z4CR12_444_NV, 16#9037). +-define(GL_VIDEO_CAPTURE_FRAME_WIDTH_NV, 16#9038). +-define(GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV, 16#9039). +-define(GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV, 16#903A). +-define(GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV, 16#903B). +-define(GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV, 16#903C). +-define(GL_ACTIVE_PROGRAM_EXT, 16#8B8D). +-define(GL_BUFFER_GPU_ADDRESS_NV, 16#8F1D). +-define(GL_GPU_ADDRESS_NV, 16#8F34). +-define(GL_MAX_SHADER_BUFFER_ADDRESS_NV, 16#8F35). +-define(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV, 16#8F1E). +-define(GL_ELEMENT_ARRAY_UNIFIED_NV, 16#8F1F). +-define(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 16#8F20). +-define(GL_VERTEX_ARRAY_ADDRESS_NV, 16#8F21). +-define(GL_NORMAL_ARRAY_ADDRESS_NV, 16#8F22). +-define(GL_COLOR_ARRAY_ADDRESS_NV, 16#8F23). +-define(GL_INDEX_ARRAY_ADDRESS_NV, 16#8F24). +-define(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV, 16#8F25). +-define(GL_EDGE_FLAG_ARRAY_ADDRESS_NV, 16#8F26). +-define(GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV, 16#8F27). +-define(GL_FOG_COORD_ARRAY_ADDRESS_NV, 16#8F28). +-define(GL_ELEMENT_ARRAY_ADDRESS_NV, 16#8F29). +-define(GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV, 16#8F2A). +-define(GL_VERTEX_ARRAY_LENGTH_NV, 16#8F2B). +-define(GL_NORMAL_ARRAY_LENGTH_NV, 16#8F2C). +-define(GL_COLOR_ARRAY_LENGTH_NV, 16#8F2D). +-define(GL_INDEX_ARRAY_LENGTH_NV, 16#8F2E). +-define(GL_TEXTURE_COORD_ARRAY_LENGTH_NV, 16#8F2F). +-define(GL_EDGE_FLAG_ARRAY_LENGTH_NV, 16#8F30). +-define(GL_SECONDARY_COLOR_ARRAY_LENGTH_NV, 16#8F31). +-define(GL_FOG_COORD_ARRAY_LENGTH_NV, 16#8F32). +-define(GL_ELEMENT_ARRAY_LENGTH_NV, 16#8F33). +-define(GL_DRAW_INDIRECT_UNIFIED_NV, 16#8F40). +-define(GL_DRAW_INDIRECT_ADDRESS_NV, 16#8F41). +-define(GL_DRAW_INDIRECT_LENGTH_NV, 16#8F42). +-define(GL_MAX_IMAGE_UNITS_EXT, 16#8F38). +-define(GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT, 16#8F39). +-define(GL_IMAGE_BINDING_NAME_EXT, 16#8F3A). +-define(GL_IMAGE_BINDING_LEVEL_EXT, 16#8F3B). +-define(GL_IMAGE_BINDING_LAYERED_EXT, 16#8F3C). +-define(GL_IMAGE_BINDING_LAYER_EXT, 16#8F3D). +-define(GL_IMAGE_BINDING_ACCESS_EXT, 16#8F3E). +-define(GL_IMAGE_1D_EXT, 16#904C). +-define(GL_IMAGE_2D_EXT, 16#904D). +-define(GL_IMAGE_3D_EXT, 16#904E). +-define(GL_IMAGE_2D_RECT_EXT, 16#904F). +-define(GL_IMAGE_CUBE_EXT, 16#9050). +-define(GL_IMAGE_BUFFER_EXT, 16#9051). +-define(GL_IMAGE_1D_ARRAY_EXT, 16#9052). +-define(GL_IMAGE_2D_ARRAY_EXT, 16#9053). +-define(GL_IMAGE_CUBE_MAP_ARRAY_EXT, 16#9054). +-define(GL_IMAGE_2D_MULTISAMPLE_EXT, 16#9055). +-define(GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#9056). +-define(GL_INT_IMAGE_1D_EXT, 16#9057). +-define(GL_INT_IMAGE_2D_EXT, 16#9058). +-define(GL_INT_IMAGE_3D_EXT, 16#9059). +-define(GL_INT_IMAGE_2D_RECT_EXT, 16#905A). +-define(GL_INT_IMAGE_CUBE_EXT, 16#905B). +-define(GL_INT_IMAGE_BUFFER_EXT, 16#905C). +-define(GL_INT_IMAGE_1D_ARRAY_EXT, 16#905D). +-define(GL_INT_IMAGE_2D_ARRAY_EXT, 16#905E). +-define(GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT, 16#905F). +-define(GL_INT_IMAGE_2D_MULTISAMPLE_EXT, 16#9060). +-define(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#9061). +-define(GL_UNSIGNED_INT_IMAGE_1D_EXT, 16#9062). +-define(GL_UNSIGNED_INT_IMAGE_2D_EXT, 16#9063). +-define(GL_UNSIGNED_INT_IMAGE_3D_EXT, 16#9064). +-define(GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT, 16#9065). +-define(GL_UNSIGNED_INT_IMAGE_CUBE_EXT, 16#9066). +-define(GL_UNSIGNED_INT_IMAGE_BUFFER_EXT, 16#9067). +-define(GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT, 16#9068). +-define(GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT, 16#9069). +-define(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT, 16#906A). +-define(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT, 16#906B). +-define(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT, 16#906C). +-define(GL_MAX_IMAGE_SAMPLES_EXT, 16#906D). +-define(GL_IMAGE_BINDING_FORMAT_EXT, 16#906E). +-define(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT, 16#1). +-define(GL_ELEMENT_ARRAY_BARRIER_BIT_EXT, 16#2). +-define(GL_UNIFORM_BARRIER_BIT_EXT, 16#4). +-define(GL_TEXTURE_FETCH_BARRIER_BIT_EXT, 16#8). +-define(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT, 16#20). +-define(GL_COMMAND_BARRIER_BIT_EXT, 16#40). +-define(GL_PIXEL_BUFFER_BARRIER_BIT_EXT, 16#80). +-define(GL_TEXTURE_UPDATE_BARRIER_BIT_EXT, 16#100). +-define(GL_BUFFER_UPDATE_BARRIER_BIT_EXT, 16#200). +-define(GL_FRAMEBUFFER_BARRIER_BIT_EXT, 16#400). +-define(GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT, 16#800). +-define(GL_ATOMIC_COUNTER_BARRIER_BIT_EXT, 16#1000). +-define(GL_ALL_BARRIER_BITS_EXT, 16#FFFFFFFF). +-define(GL_DOUBLE_VEC2_EXT, 16#8FFC). +-define(GL_DOUBLE_VEC3_EXT, 16#8FFD). +-define(GL_DOUBLE_VEC4_EXT, 16#8FFE). +-define(GL_DOUBLE_MAT2_EXT, 16#8F46). +-define(GL_DOUBLE_MAT3_EXT, 16#8F47). +-define(GL_DOUBLE_MAT4_EXT, 16#8F48). +-define(GL_DOUBLE_MAT2x3_EXT, 16#8F49). +-define(GL_DOUBLE_MAT2x4_EXT, 16#8F4A). +-define(GL_DOUBLE_MAT3x2_EXT, 16#8F4B). +-define(GL_DOUBLE_MAT3x4_EXT, 16#8F4C). +-define(GL_DOUBLE_MAT4x2_EXT, 16#8F4D). +-define(GL_DOUBLE_MAT4x3_EXT, 16#8F4E). +-define(GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV, 16#8E5A). +-define(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV, 16#8E5B). +-define(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV, 16#8E5C). +-define(GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV, 16#8E5D). +-define(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV, 16#8E5E). +-define(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV, 16#8E5F). +-define(GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV, 16#8F44). +-define(GL_MAX_PROGRAM_SUBROUTINE_NUM_NV, 16#8F45). +-define(GL_INT64_NV, 16#140E). +-define(GL_UNSIGNED_INT64_NV, 16#140F). +-define(GL_INT8_NV, 16#8FE0). +-define(GL_INT8_VEC2_NV, 16#8FE1). +-define(GL_INT8_VEC3_NV, 16#8FE2). +-define(GL_INT8_VEC4_NV, 16#8FE3). +-define(GL_INT16_NV, 16#8FE4). +-define(GL_INT16_VEC2_NV, 16#8FE5). +-define(GL_INT16_VEC3_NV, 16#8FE6). +-define(GL_INT16_VEC4_NV, 16#8FE7). +-define(GL_INT64_VEC2_NV, 16#8FE9). +-define(GL_INT64_VEC3_NV, 16#8FEA). +-define(GL_INT64_VEC4_NV, 16#8FEB). +-define(GL_UNSIGNED_INT8_NV, 16#8FEC). +-define(GL_UNSIGNED_INT8_VEC2_NV, 16#8FED). +-define(GL_UNSIGNED_INT8_VEC3_NV, 16#8FEE). +-define(GL_UNSIGNED_INT8_VEC4_NV, 16#8FEF). +-define(GL_UNSIGNED_INT16_NV, 16#8FF0). +-define(GL_UNSIGNED_INT16_VEC2_NV, 16#8FF1). +-define(GL_UNSIGNED_INT16_VEC3_NV, 16#8FF2). +-define(GL_UNSIGNED_INT16_VEC4_NV, 16#8FF3). +-define(GL_UNSIGNED_INT64_VEC2_NV, 16#8FF5). +-define(GL_UNSIGNED_INT64_VEC3_NV, 16#8FF6). +-define(GL_UNSIGNED_INT64_VEC4_NV, 16#8FF7). +-define(GL_FLOAT16_NV, 16#8FF8). +-define(GL_FLOAT16_VEC2_NV, 16#8FF9). +-define(GL_FLOAT16_VEC3_NV, 16#8FFA). +-define(GL_FLOAT16_VEC4_NV, 16#8FFB). +-define(GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV, 16#10). +-define(GL_MAX_PROGRAM_PATCH_ATTRIBS_NV, 16#86D8). +-define(GL_TESS_CONTROL_PROGRAM_NV, 16#891E). +-define(GL_TESS_EVALUATION_PROGRAM_NV, 16#891F). +-define(GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV, 16#8C74). +-define(GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV, 16#8C75). +-define(GL_COVERAGE_SAMPLES_NV, 16#80A9). +-define(GL_COLOR_SAMPLES_NV, 16#8E20). +-define(GL_DATA_BUFFER_AMD, 16#9151). +-define(GL_PERFORMANCE_MONITOR_AMD, 16#9152). +-define(GL_QUERY_OBJECT_AMD, 16#9153). +-define(GL_VERTEX_ARRAY_OBJECT_AMD, 16#9154). +-define(GL_SAMPLER_OBJECT_AMD, 16#9155). +-define(GL_MAX_DEBUG_LOGGED_MESSAGES_AMD, 16#9144). +-define(GL_DEBUG_LOGGED_MESSAGES_AMD, 16#9145). +-define(GL_DEBUG_SEVERITY_HIGH_AMD, 16#9146). +-define(GL_DEBUG_SEVERITY_MEDIUM_AMD, 16#9147). +-define(GL_DEBUG_SEVERITY_LOW_AMD, 16#9148). +-define(GL_DEBUG_CATEGORY_API_ERROR_AMD, 16#9149). +-define(GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD, 16#914A). +-define(GL_DEBUG_CATEGORY_DEPRECATION_AMD, 16#914B). +-define(GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD, 16#914C). +-define(GL_DEBUG_CATEGORY_PERFORMANCE_AMD, 16#914D). +-define(GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD, 16#914E). +-define(GL_DEBUG_CATEGORY_APPLICATION_AMD, 16#914F). +-define(GL_DEBUG_CATEGORY_OTHER_AMD, 16#9150). +-define(GL_SURFACE_STATE_NV, 16#86EB). +-define(GL_SURFACE_REGISTERED_NV, 16#86FD). +-define(GL_SURFACE_MAPPED_NV, 16#8700). +-define(GL_WRITE_DISCARD_NV, 16#88BE). -define(GL_VERSION_1_2, 1). -define(GL_VERSION_1_2_DEPRECATED, 1). -define(GL_VERSION_1_3, 1). @@ -3375,8 +3867,11 @@ -define(GL_VERSION_2_0, 1). -define(GL_VERSION_2_1, 1). -define(GL_VERSION_3_0, 1). --define(GL_VERSION_3_0_DEPRECATED, 1). -define(GL_VERSION_3_1, 1). +-define(GL_VERSION_3_2, 1). +-define(GL_VERSION_3_3, 1). +-define(GL_VERSION_4_0, 1). +-define(GL_VERSION_4_1, 1). -define(GL_ARB_multitexture, 1). -define(GL_ARB_transpose_matrix, 1). -define(GL_ARB_multisample, 1). @@ -3428,6 +3923,46 @@ -define(GL_ARB_compatibility, 1). -define(GL_ARB_copy_buffer, 1). -define(GL_ARB_shader_texture_lod, 1). +-define(GL_ARB_depth_clamp, 1). +-define(GL_ARB_draw_elements_base_vertex, 1). +-define(GL_ARB_fragment_coord_conventions, 1). +-define(GL_ARB_provoking_vertex, 1). +-define(GL_ARB_seamless_cube_map, 1). +-define(GL_ARB_sync, 1). +-define(GL_ARB_texture_multisample, 1). +-define(GL_ARB_vertex_array_bgra, 1). +-define(GL_ARB_draw_buffers_blend, 1). +-define(GL_ARB_sample_shading, 1). +-define(GL_ARB_texture_cube_map_array, 1). +-define(GL_ARB_texture_gather, 1). +-define(GL_ARB_texture_query_lod, 1). +-define(GL_ARB_shading_language_include, 1). +-define(GL_ARB_texture_compression_bptc, 1). +-define(GL_ARB_blend_func_extended, 1). +-define(GL_ARB_explicit_attrib_location, 1). +-define(GL_ARB_occlusion_query2, 1). +-define(GL_ARB_sampler_objects, 1). +-define(GL_ARB_texture_rgb10_a2ui, 1). +-define(GL_ARB_texture_swizzle, 1). +-define(GL_ARB_timer_query, 1). +-define(GL_ARB_vertex_type_2_10_10_10_rev, 1). +-define(GL_ARB_draw_indirect, 1). +-define(GL_ARB_gpu_shader5, 1). +-define(GL_ARB_gpu_shader_fp64, 1). +-define(GL_ARB_shader_subroutine, 1). +-define(GL_ARB_tessellation_shader, 1). +-define(GL_ARB_texture_buffer_object_rgb32, 1). +-define(GL_ARB_transform_feedback2, 1). +-define(GL_ARB_transform_feedback3, 1). +-define(GL_ARB_ES2_compatibility, 1). +-define(GL_ARB_get_program_binary, 1). +-define(GL_ARB_separate_shader_objects, 1). +-define(GL_ARB_vertex_attrib_64bit, 1). +-define(GL_ARB_viewport_array, 1). +-define(GL_ARB_cl_event, 1). +-define(GL_ARB_debug_output, 1). +-define(GL_ARB_robustness, 1). +-define(GL_ARB_shader_stencil_export, 1). -define(GL_EXT_abgr, 1). -define(GL_EXT_blend_color, 1). -define(GL_EXT_polygon_offset, 1). @@ -3684,3 +4219,34 @@ -define(GL_AMD_texture_texture4, 1). -define(GL_AMD_vertex_shader_tesselator, 1). -define(GL_EXT_provoking_vertex, 1). +-define(GL_EXT_texture_snorm, 1). +-define(GL_AMD_draw_buffers_blend, 1). +-define(GL_APPLE_texture_range, 1). +-define(GL_APPLE_float_pixels, 1). +-define(GL_APPLE_vertex_program_evaluators, 1). +-define(GL_APPLE_aux_depth_stencil, 1). +-define(GL_APPLE_object_purgeable, 1). +-define(GL_APPLE_row_bytes, 1). +-define(GL_APPLE_rgb_422, 1). +-define(GL_NV_video_capture, 1). +-define(GL_NV_copy_image, 1). +-define(GL_EXT_separate_shader_objects, 1). +-define(GL_NV_parameter_buffer_object2, 1). +-define(GL_NV_shader_buffer_load, 1). +-define(GL_NV_vertex_buffer_unified_memory, 1). +-define(GL_NV_texture_barrier, 1). +-define(GL_AMD_shader_stencil_export, 1). +-define(GL_AMD_seamless_cubemap_per_texture, 1). +-define(GL_AMD_conservative_depth, 1). +-define(GL_EXT_shader_image_load_store, 1). +-define(GL_EXT_vertex_attrib_64bit, 1). +-define(GL_NV_gpu_program5, 1). +-define(GL_NV_gpu_shader5, 1). +-define(GL_NV_shader_buffer_store, 1). +-define(GL_NV_tessellation_program5, 1). +-define(GL_NV_vertex_attrib_integer_64bit, 1). +-define(GL_NV_multisample_coverage, 1). +-define(GL_AMD_name_gen_delete, 1). +-define(GL_AMD_debug_output, 1). +-define(GL_NV_vdpau_interop, 1). +-define(GL_AMD_transform_feedback3_lines_triangles, 1). diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile index a9fd468959..3cc668375f 100644 --- a/lib/wx/src/Makefile +++ b/lib/wx/src/Makefile @@ -47,7 +47,6 @@ GEN_FILES = $(wildcard gen/wx*.erl) \ GEN_MODS = $(GEN_FILES:gen/%.erl= %,\n ) GEN_HRL = \ - $(EGEN)/gl_debug.hrl \ $(EGEN)/wxe_debug.hrl \ $(EGEN)/wxe_funcs.hrl diff --git a/lib/wx/src/gen/gl.erl b/lib/wx/src/gen/gl.erl index 62d0ff6aed..0ebf51d28a 100644 --- a/lib/wx/src/gen/gl.erl +++ b/lib/wx/src/gen/gl.erl @@ -25,14 +25,13 @@ %% %% Booleans are represented by integers 0 and 1. -%% @type wx_mem(). see wx.erl on memory allocation functions +%% @type mem(). memory block %% @type enum(). An integer defined in gl.hrl %% @type offset(). An integer which is an offset in an array %% @type clamp(). A float clamped between 0.0 - 1.0 -module(gl). -compile(inline). --include("wxe.hrl"). -define(GLenum,32/native-unsigned). -define(GLboolean,8/native-unsigned). -define(GLbitfield,32/native-unsigned). @@ -51,6 +50,13 @@ -define(GLintptr,64/native-unsigned). -define(GLUquadric,64/native-unsigned). -define(GLhandleARB,64/native-unsigned). +-define(GLsync,64/native-unsigned). +-define(GLuint64,64/native-unsigned). +-define(GLint64,64/native-signed). +-type clamp() :: float(). +-type offset() :: non_neg_integer(). +-type enum() :: non_neg_integer(). +-type mem() :: binary() | tuple(). -export([accum/2,alphaFunc/2,areTexturesResident/1,arrayElement/1,'begin'/1, bindTexture/2,bitmap/7,blendFunc/2,callList/1,callLists/1,clear/1,clearAccum/4, @@ -173,3862 +179,5840 @@ enablei/2,disablei/2,isEnabledi/2,beginTransformFeedback/1,endTransformFeedback/0, bindBufferRange/5,bindBufferBase/3,transformFeedbackVaryings/3,getTransformFeedbackVarying/3, clampColor/2,beginConditionalRender/2,endConditionalRender/0,vertexAttribIPointer/5, - getVertexAttribIiv/2,getVertexAttribIuiv/2,getUniformuiv/2,bindFragDataLocation/3, + getVertexAttribIiv/2,getVertexAttribIuiv/2,vertexAttribI1i/2,vertexAttribI2i/3, + vertexAttribI3i/4,vertexAttribI4i/5,vertexAttribI1ui/2,vertexAttribI2ui/3, + vertexAttribI3ui/4,vertexAttribI4ui/5,vertexAttribI1iv/2,vertexAttribI2iv/2, + vertexAttribI3iv/2,vertexAttribI4iv/2,vertexAttribI1uiv/2,vertexAttribI2uiv/2, + vertexAttribI3uiv/2,vertexAttribI4uiv/2,vertexAttribI4bv/2,vertexAttribI4sv/2, + vertexAttribI4ubv/2,vertexAttribI4usv/2,getUniformuiv/2,bindFragDataLocation/3, getFragDataLocation/2,uniform1ui/2,uniform2ui/3,uniform3ui/4,uniform4ui/5, uniform1uiv/2,uniform2uiv/2,uniform3uiv/2,uniform4uiv/2,texParameterIiv/3, texParameterIuiv/3,getTexParameterIiv/2,getTexParameterIuiv/2,clearBufferiv/3, - clearBufferuiv/3,clearBufferfv/3,clearBufferfi/4,getStringi/2,vertexAttribI1i/2, - vertexAttribI2i/3,vertexAttribI3i/4,vertexAttribI4i/5,vertexAttribI1ui/2, - vertexAttribI2ui/3,vertexAttribI3ui/4,vertexAttribI4ui/5,vertexAttribI1iv/2, - vertexAttribI2iv/2,vertexAttribI3iv/2,vertexAttribI4iv/2,vertexAttribI1uiv/2, - vertexAttribI2uiv/2,vertexAttribI3uiv/2,vertexAttribI4uiv/2,vertexAttribI4bv/2, - vertexAttribI4sv/2,vertexAttribI4ubv/2,vertexAttribI4usv/2,drawArraysInstanced/4, - drawElementsInstanced/5,texBuffer/3,primitiveRestartIndex/1,loadTransposeMatrixfARB/1, - loadTransposeMatrixdARB/1,multTransposeMatrixfARB/1,multTransposeMatrixdARB/1, - weightbvARB/1,weightsvARB/1,weightivARB/1,weightfvARB/1,weightdvARB/1, - weightubvARB/1,weightusvARB/1,weightuivARB/1,vertexBlendARB/1,currentPaletteMatrixARB/1, + clearBufferuiv/3,clearBufferfv/3,clearBufferfi/4,getStringi/2,drawArraysInstanced/4, + drawElementsInstanced/5,texBuffer/3,primitiveRestartIndex/1,getInteger64i_v/2, + getBufferParameteri64v/2,framebufferTexture/4,vertexAttribDivisor/2, + minSampleShading/1,blendEquationi/2,blendEquationSeparatei/3,blendFunci/3, + blendFuncSeparatei/5,loadTransposeMatrixfARB/1,loadTransposeMatrixdARB/1, + multTransposeMatrixfARB/1,multTransposeMatrixdARB/1,weightbvARB/1, + weightsvARB/1,weightivARB/1,weightfvARB/1,weightdvARB/1,weightubvARB/1, + weightusvARB/1,weightuivARB/1,vertexBlendARB/1,currentPaletteMatrixARB/1, matrixIndexubvARB/1,matrixIndexusvARB/1,matrixIndexuivARB/1,programStringARB/3, bindProgramARB/2,deleteProgramsARB/1,genProgramsARB/1,programEnvParameter4dARB/6, programEnvParameter4dvARB/3,programEnvParameter4fARB/6,programEnvParameter4fvARB/3, programLocalParameter4dARB/6,programLocalParameter4dvARB/3,programLocalParameter4fARB/6, programLocalParameter4fvARB/3,getProgramEnvParameterdvARB/2,getProgramEnvParameterfvARB/2, getProgramLocalParameterdvARB/2,getProgramLocalParameterfvARB/2, - getProgramStringARB/3,deleteObjectARB/1,getHandleARB/1,detachObjectARB/2, - createShaderObjectARB/1,shaderSourceARB/2,compileShaderARB/1,createProgramObjectARB/0, - attachObjectARB/2,linkProgramARB/1,useProgramObjectARB/1,validateProgramARB/1, - getObjectParameterfvARB/2,getObjectParameterivARB/2,getInfoLogARB/2, - getAttachedObjectsARB/2,getUniformLocationARB/2,getActiveUniformARB/3, - getUniformfvARB/2,getUniformivARB/2,getShaderSourceARB/2,bindAttribLocationARB/3, - getActiveAttribARB/3,getAttribLocationARB/2,isRenderbuffer/1,bindRenderbuffer/2, - deleteRenderbuffers/1,genRenderbuffers/1,renderbufferStorage/4,getRenderbufferParameteriv/2, + getProgramStringARB/3,getBufferParameterivARB/2,deleteObjectARB/1, + getHandleARB/1,detachObjectARB/2,createShaderObjectARB/1,shaderSourceARB/2, + compileShaderARB/1,createProgramObjectARB/0,attachObjectARB/2,linkProgramARB/1, + useProgramObjectARB/1,validateProgramARB/1,getObjectParameterfvARB/2, + getObjectParameterivARB/2,getInfoLogARB/2,getAttachedObjectsARB/2, + getUniformLocationARB/2,getActiveUniformARB/3,getUniformfvARB/2, + getUniformivARB/2,getShaderSourceARB/2,bindAttribLocationARB/3,getActiveAttribARB/3, + getAttribLocationARB/2,isRenderbuffer/1,bindRenderbuffer/2,deleteRenderbuffers/1, + genRenderbuffers/1,renderbufferStorage/4,getRenderbufferParameteriv/2, isFramebuffer/1,bindFramebuffer/2,deleteFramebuffers/1,genFramebuffers/1, checkFramebufferStatus/1,framebufferTexture1D/5,framebufferTexture2D/5, framebufferTexture3D/6,framebufferRenderbuffer/4,getFramebufferAttachmentParameteriv/3, generateMipmap/1,blitFramebuffer/10,renderbufferStorageMultisample/5, - framebufferTextureLayer/5,programParameteriARB/3,framebufferTextureARB/4, - framebufferTextureFaceARB/5,vertexAttribDivisorARB/2,flushMappedBufferRange/3, + framebufferTextureLayer/5,framebufferTextureFaceARB/5,flushMappedBufferRange/3, bindVertexArray/1,deleteVertexArrays/1,genVertexArrays/1,isVertexArray/1, getUniformIndices/2,getActiveUniformsiv/3,getActiveUniformName/3, getUniformBlockIndex/2,getActiveUniformBlockiv/4,getActiveUniformBlockName/3, - uniformBlockBinding/3,copyBufferSubData/5,resizeBuffersMESA/0,windowPos4dMESA/4, + uniformBlockBinding/3,copyBufferSubData/5,drawElementsBaseVertex/5, + drawRangeElementsBaseVertex/7,drawElementsInstancedBaseVertex/6, + provokingVertex/1,fenceSync/2,isSync/1,deleteSync/1,clientWaitSync/3, + waitSync/3,getInteger64v/1,getSynciv/3,texImage2DMultisample/6,texImage3DMultisample/7, + getMultisamplefv/2,sampleMaski/2,namedStringARB/3,deleteNamedStringARB/1, + compileShaderIncludeARB/2,isNamedStringARB/1,getNamedStringARB/2, + getNamedStringivARB/2,bindFragDataLocationIndexed/4,getFragDataIndex/2, + genSamplers/1,deleteSamplers/1,isSampler/1,bindSampler/2,samplerParameteri/3, + samplerParameteriv/3,samplerParameterf/3,samplerParameterfv/3,samplerParameterIiv/3, + samplerParameterIuiv/3,getSamplerParameteriv/2,getSamplerParameterIiv/2, + getSamplerParameterfv/2,getSamplerParameterIuiv/2,queryCounter/2, + getQueryObjecti64v/2,getQueryObjectui64v/2,drawArraysIndirect/2, + drawElementsIndirect/3,uniform1d/2,uniform2d/3,uniform3d/4,uniform4d/5, + uniform1dv/2,uniform2dv/2,uniform3dv/2,uniform4dv/2,uniformMatrix2dv/3, + uniformMatrix3dv/3,uniformMatrix4dv/3,uniformMatrix2x3dv/3,uniformMatrix2x4dv/3, + uniformMatrix3x2dv/3,uniformMatrix3x4dv/3,uniformMatrix4x2dv/3,uniformMatrix4x3dv/3, + getUniformdv/2,getSubroutineUniformLocation/3,getSubroutineIndex/3, + getActiveSubroutineUniformName/4,getActiveSubroutineName/4,uniformSubroutinesuiv/2, + getUniformSubroutineuiv/2,getProgramStageiv/3,patchParameteri/2, + patchParameterfv/2,bindTransformFeedback/2,deleteTransformFeedbacks/1, + genTransformFeedbacks/1,isTransformFeedback/1,pauseTransformFeedback/0, + resumeTransformFeedback/0,drawTransformFeedback/2,drawTransformFeedbackStream/3, + beginQueryIndexed/3,endQueryIndexed/2,getQueryIndexediv/3,releaseShaderCompiler/0, + shaderBinary/3,getShaderPrecisionFormat/2,depthRangef/2,clearDepthf/1, + getProgramBinary/2,programBinary/3,programParameteri/3,useProgramStages/3, + activeShaderProgram/2,createShaderProgramv/2,bindProgramPipeline/1, + deleteProgramPipelines/1,genProgramPipelines/1,isProgramPipeline/1, + getProgramPipelineiv/2,programUniform1i/3,programUniform1iv/3,programUniform1f/3, + programUniform1fv/3,programUniform1d/3,programUniform1dv/3,programUniform1ui/3, + programUniform1uiv/3,programUniform2i/4,programUniform2iv/3,programUniform2f/4, + programUniform2fv/3,programUniform2d/4,programUniform2dv/3,programUniform2ui/4, + programUniform2uiv/3,programUniform3i/5,programUniform3iv/3,programUniform3f/5, + programUniform3fv/3,programUniform3d/5,programUniform3dv/3,programUniform3ui/5, + programUniform3uiv/3,programUniform4i/6,programUniform4iv/3,programUniform4f/6, + programUniform4fv/3,programUniform4d/6,programUniform4dv/3,programUniform4ui/6, + programUniform4uiv/3,programUniformMatrix2fv/4,programUniformMatrix3fv/4, + programUniformMatrix4fv/4,programUniformMatrix2dv/4,programUniformMatrix3dv/4, + programUniformMatrix4dv/4,programUniformMatrix2x3fv/4,programUniformMatrix3x2fv/4, + programUniformMatrix2x4fv/4,programUniformMatrix4x2fv/4,programUniformMatrix3x4fv/4, + programUniformMatrix4x3fv/4,programUniformMatrix2x3dv/4,programUniformMatrix3x2dv/4, + programUniformMatrix2x4dv/4,programUniformMatrix4x2dv/4,programUniformMatrix3x4dv/4, + programUniformMatrix4x3dv/4,validateProgramPipeline/1,getProgramPipelineInfoLog/2, + vertexAttribL1d/2,vertexAttribL2d/3,vertexAttribL3d/4,vertexAttribL4d/5, + vertexAttribL1dv/2,vertexAttribL2dv/2,vertexAttribL3dv/2,vertexAttribL4dv/2, + vertexAttribLPointer/5,getVertexAttribLdv/2,viewportArrayv/2,viewportIndexedf/5, + viewportIndexedfv/2,scissorArrayv/2,scissorIndexed/5,scissorIndexedv/2, + depthRangeArrayv/2,depthRangeIndexed/3,getFloati_v/2,getDoublei_v/2, + debugMessageControlARB/5,debugMessageInsertARB/5,getDebugMessageLogARB/2, + getGraphicsResetStatusARB/0,resizeBuffersMESA/0,windowPos4dMESA/4, windowPos4dvMESA/1,windowPos4fMESA/4,windowPos4fvMESA/1,windowPos4iMESA/4, windowPos4ivMESA/1,windowPos4sMESA/4,windowPos4svMESA/1,depthBoundsEXT/2, stencilClearTagEXT/2]). +-export([call/2, cast/2, send_bin/1]). +%% @hidden +call(Op, Args) -> + Port = get(opengl_port), + _ = erlang:port_control(Port,Op,Args), + rec(). + +%% @hidden +cast(Op, Args) -> + Port = get(opengl_port), + _ = erlang:port_control(Port,Op,Args), + ok. + +%% @hidden +rec() -> + receive + {'_egl_result_', Res} -> Res; + {'_egl_error_', Op, Res} -> error({error,Res,Op}) + end. + +%% @hidden +send_bin(Bin) when is_binary(Bin) -> + Port = get(opengl_port), + erlang:port_command(Port,Bin); +send_bin(Tuple) when is_tuple(Tuple) -> + Port = get(opengl_port), + case element(2, Tuple) of + Bin when is_binary(Bin) -> + erlang:port_command(Port,Bin) + end. + %% API %% @spec (Op::enum(),Value::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAccum.xml">external</a> documentation. +-spec accum(enum(),float()) -> ok. accum(Op,Value) -> - wxe_util:cast(5037, <<Op:?GLenum,Value:?GLfloat>>). + cast(5037, <<Op:?GLenum,Value:?GLfloat>>). %% @spec (Func::enum(),Ref::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAlphaFunc.xml">external</a> documentation. +-spec alphaFunc(enum(),clamp()) -> ok. alphaFunc(Func,Ref) -> - wxe_util:cast(5038, <<Func:?GLenum,Ref:?GLclampf>>). + cast(5038, <<Func:?GLenum,Ref:?GLclampf>>). %% @spec (Textures::[integer()]) -> {0|1,Residences::[0|1]} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAreTexturesResident.xml">external</a> documentation. +-spec areTexturesResident([integer()]) -> {0|1,[0|1]}. areTexturesResident(Textures) -> - wxe_util:call(5039, <<(length(Textures)):?GLuint, + call(5039, <<(length(Textures)):?GLuint, (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>). %% @spec (I::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glArrayElement.xml">external</a> documentation. +-spec arrayElement(integer()) -> ok. arrayElement(I) -> - wxe_util:cast(5040, <<I:?GLint>>). + cast(5040, <<I:?GLint>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml">external</a> documentation. +-spec 'begin'(enum()) -> ok. 'begin'(Mode) -> - wxe_util:cast(5041, <<Mode:?GLenum>>). + cast(5041, <<Mode:?GLenum>>). %% @spec (Target::enum(),Texture::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTexture.xml">external</a> documentation. +-spec bindTexture(enum(),integer()) -> ok. bindTexture(Target,Texture) -> - wxe_util:cast(5042, <<Target:?GLenum,Texture:?GLuint>>). + cast(5042, <<Target:?GLenum,Texture:?GLuint>>). -%% @spec (Width::integer(),Height::integer(),Xorig::float(),Yorig::float(),Xmove::float(),Ymove::float(),Bitmap::offset()|binary()) -> ok +%% @spec (Width::integer(),Height::integer(),Xorig::float(),Yorig::float(),Xmove::float(),Ymove::float(),Bitmap::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBitmap.xml">external</a> documentation. +-spec bitmap(integer(),integer(),float(),float(),float(),float(),offset()|mem()) -> ok. bitmap(Width,Height,Xorig,Yorig,Xmove,Ymove,Bitmap) when is_integer(Bitmap) -> - wxe_util:cast(5043, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat,Bitmap:?GLuint>>); + cast(5043, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat,Bitmap:?GLuint>>); bitmap(Width,Height,Xorig,Yorig,Xmove,Ymove,Bitmap) -> - wxe_util:send_bin(Bitmap), - wxe_util:cast(5044, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat>>). + send_bin(Bitmap), + cast(5044, <<Width:?GLsizei,Height:?GLsizei,Xorig:?GLfloat,Yorig:?GLfloat,Xmove:?GLfloat,Ymove:?GLfloat>>). %% @spec (Sfactor::enum(),Dfactor::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml">external</a> documentation. +-spec blendFunc(enum(),enum()) -> ok. blendFunc(Sfactor,Dfactor) -> - wxe_util:cast(5045, <<Sfactor:?GLenum,Dfactor:?GLenum>>). + cast(5045, <<Sfactor:?GLenum,Dfactor:?GLenum>>). %% @spec (List::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallList.xml">external</a> documentation. +-spec callList(integer()) -> ok. callList(List) -> - wxe_util:cast(5046, <<List:?GLuint>>). + cast(5046, <<List:?GLuint>>). %% @spec (Lists::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCallLists.xml">external</a> documentation. +-spec callLists([integer()]) -> ok. callLists(Lists) -> - wxe_util:cast(5047, <<(length(Lists)):?GLuint, + cast(5047, <<(length(Lists)):?GLuint, (<< <<C:?GLuint>> || C <- Lists>>)/binary,0:(((1+length(Lists)) rem 2)*32)>>). %% @spec (Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClear.xml">external</a> documentation. +-spec clear(integer()) -> ok. clear(Mask) -> - wxe_util:cast(5048, <<Mask:?GLbitfield>>). + cast(5048, <<Mask:?GLbitfield>>). %% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearAccum.xml">external</a> documentation. +-spec clearAccum(float(),float(),float(),float()) -> ok. clearAccum(Red,Green,Blue,Alpha) -> - wxe_util:cast(5049, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>). + cast(5049, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>). %% @spec (Red::clamp(),Green::clamp(),Blue::clamp(),Alpha::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearColor.xml">external</a> documentation. +-spec clearColor(clamp(),clamp(),clamp(),clamp()) -> ok. clearColor(Red,Green,Blue,Alpha) -> - wxe_util:cast(5050, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>). + cast(5050, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>). %% @spec (Depth::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepth.xml">external</a> documentation. +-spec clearDepth(clamp()) -> ok. clearDepth(Depth) -> - wxe_util:cast(5051, <<Depth:?GLclampd>>). + cast(5051, <<Depth:?GLclampd>>). %% @spec (C::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearIndex.xml">external</a> documentation. +-spec clearIndex(float()) -> ok. clearIndex(C) -> - wxe_util:cast(5052, <<C:?GLfloat>>). + cast(5052, <<C:?GLfloat>>). %% @spec (S::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearStencil.xml">external</a> documentation. +-spec clearStencil(integer()) -> ok. clearStencil(S) -> - wxe_util:cast(5053, <<S:?GLint>>). + cast(5053, <<S:?GLint>>). -%% @spec (Plane::enum(),Equation::{float()}) -> ok +%% @spec (Plane::enum(),Equation::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClipPlane.xml">external</a> documentation. +-spec clipPlane(enum(),{float(),float(),float(),float()}) -> ok. clipPlane(Plane,{E1,E2,E3,E4}) -> - wxe_util:cast(5054, <<Plane:?GLenum,0:32,E1:?GLdouble,E2:?GLdouble,E3:?GLdouble,E4:?GLdouble>>). + cast(5054, <<Plane:?GLenum,0:32,E1:?GLdouble,E2:?GLdouble,E3:?GLdouble,E4:?GLdouble>>). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3b(integer(),integer(),integer()) -> ok. color3b(Red,Green,Blue) -> - wxe_util:cast(5055, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>). + cast(5055, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3b(Red,Green,Blue) +-spec color3bv({integer(),integer(),integer()}) -> ok. color3bv({Red,Green,Blue}) -> color3b(Red,Green,Blue). %% @spec (Red::float(),Green::float(),Blue::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3d(float(),float(),float()) -> ok. color3d(Red,Green,Blue) -> - wxe_util:cast(5056, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>). + cast(5056, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3d(Red,Green,Blue) +-spec color3dv({float(),float(),float()}) -> ok. color3dv({Red,Green,Blue}) -> color3d(Red,Green,Blue). %% @spec (Red::float(),Green::float(),Blue::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3f(float(),float(),float()) -> ok. color3f(Red,Green,Blue) -> - wxe_util:cast(5057, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>). + cast(5057, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3f(Red,Green,Blue) +-spec color3fv({float(),float(),float()}) -> ok. color3fv({Red,Green,Blue}) -> color3f(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3i(integer(),integer(),integer()) -> ok. color3i(Red,Green,Blue) -> - wxe_util:cast(5058, <<Red:?GLint,Green:?GLint,Blue:?GLint>>). + cast(5058, <<Red:?GLint,Green:?GLint,Blue:?GLint>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3i(Red,Green,Blue) +-spec color3iv({integer(),integer(),integer()}) -> ok. color3iv({Red,Green,Blue}) -> color3i(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3s(integer(),integer(),integer()) -> ok. color3s(Red,Green,Blue) -> - wxe_util:cast(5059, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>). + cast(5059, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3s(Red,Green,Blue) +-spec color3sv({integer(),integer(),integer()}) -> ok. color3sv({Red,Green,Blue}) -> color3s(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3ub(integer(),integer(),integer()) -> ok. color3ub(Red,Green,Blue) -> - wxe_util:cast(5060, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>). + cast(5060, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3ub(Red,Green,Blue) +-spec color3ubv({integer(),integer(),integer()}) -> ok. color3ubv({Red,Green,Blue}) -> color3ub(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3ui(integer(),integer(),integer()) -> ok. color3ui(Red,Green,Blue) -> - wxe_util:cast(5061, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>). + cast(5061, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3ui(Red,Green,Blue) +-spec color3uiv({integer(),integer(),integer()}) -> ok. color3uiv({Red,Green,Blue}) -> color3ui(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color3us(integer(),integer(),integer()) -> ok. color3us(Red,Green,Blue) -> - wxe_util:cast(5062, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>). + cast(5062, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv color3us(Red,Green,Blue) +-spec color3usv({integer(),integer(),integer()}) -> ok. color3usv({Red,Green,Blue}) -> color3us(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4b(integer(),integer(),integer(),integer()) -> ok. color4b(Red,Green,Blue,Alpha) -> - wxe_util:cast(5063, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte,Alpha:?GLbyte>>). + cast(5063, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte,Alpha:?GLbyte>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4b(Red,Green,Blue,Alpha) +-spec color4bv({integer(),integer(),integer(),integer()}) -> ok. color4bv({Red,Green,Blue,Alpha}) -> color4b(Red,Green,Blue,Alpha). %% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4d(float(),float(),float(),float()) -> ok. color4d(Red,Green,Blue,Alpha) -> - wxe_util:cast(5064, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble,Alpha:?GLdouble>>). + cast(5064, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble,Alpha:?GLdouble>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4d(Red,Green,Blue,Alpha) +-spec color4dv({float(),float(),float(),float()}) -> ok. color4dv({Red,Green,Blue,Alpha}) -> color4d(Red,Green,Blue,Alpha). %% @spec (Red::float(),Green::float(),Blue::float(),Alpha::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4f(float(),float(),float(),float()) -> ok. color4f(Red,Green,Blue,Alpha) -> - wxe_util:cast(5065, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>). + cast(5065, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat,Alpha:?GLfloat>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4f(Red,Green,Blue,Alpha) +-spec color4fv({float(),float(),float(),float()}) -> ok. color4fv({Red,Green,Blue,Alpha}) -> color4f(Red,Green,Blue,Alpha). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4i(integer(),integer(),integer(),integer()) -> ok. color4i(Red,Green,Blue,Alpha) -> - wxe_util:cast(5066, <<Red:?GLint,Green:?GLint,Blue:?GLint,Alpha:?GLint>>). + cast(5066, <<Red:?GLint,Green:?GLint,Blue:?GLint,Alpha:?GLint>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4i(Red,Green,Blue,Alpha) +-spec color4iv({integer(),integer(),integer(),integer()}) -> ok. color4iv({Red,Green,Blue,Alpha}) -> color4i(Red,Green,Blue,Alpha). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4s(integer(),integer(),integer(),integer()) -> ok. color4s(Red,Green,Blue,Alpha) -> - wxe_util:cast(5067, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort,Alpha:?GLshort>>). + cast(5067, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort,Alpha:?GLshort>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4s(Red,Green,Blue,Alpha) +-spec color4sv({integer(),integer(),integer(),integer()}) -> ok. color4sv({Red,Green,Blue,Alpha}) -> color4s(Red,Green,Blue,Alpha). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4ub(integer(),integer(),integer(),integer()) -> ok. color4ub(Red,Green,Blue,Alpha) -> - wxe_util:cast(5068, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte,Alpha:?GLubyte>>). + cast(5068, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte,Alpha:?GLubyte>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4ub(Red,Green,Blue,Alpha) +-spec color4ubv({integer(),integer(),integer(),integer()}) -> ok. color4ubv({Red,Green,Blue,Alpha}) -> color4ub(Red,Green,Blue,Alpha). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4ui(integer(),integer(),integer(),integer()) -> ok. color4ui(Red,Green,Blue,Alpha) -> - wxe_util:cast(5069, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint,Alpha:?GLuint>>). + cast(5069, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint,Alpha:?GLuint>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4ui(Red,Green,Blue,Alpha) +-spec color4uiv({integer(),integer(),integer(),integer()}) -> ok. color4uiv({Red,Green,Blue,Alpha}) -> color4ui(Red,Green,Blue,Alpha). %% @spec (Red::integer(),Green::integer(),Blue::integer(),Alpha::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColor.xml">external</a> documentation. +-spec color4us(integer(),integer(),integer(),integer()) -> ok. color4us(Red,Green,Blue,Alpha) -> - wxe_util:cast(5070, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort,Alpha:?GLushort>>). + cast(5070, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort,Alpha:?GLushort>>). %% @spec ({Red,Green,Blue,Alpha}) -> ok %% @equiv color4us(Red,Green,Blue,Alpha) +-spec color4usv({integer(),integer(),integer(),integer()}) -> ok. color4usv({Red,Green,Blue,Alpha}) -> color4us(Red,Green,Blue,Alpha). %% @spec (Red::0|1,Green::0|1,Blue::0|1,Alpha::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml">external</a> documentation. +-spec colorMask(0|1,0|1,0|1,0|1) -> ok. colorMask(Red,Green,Blue,Alpha) -> - wxe_util:cast(5071, <<Red:?GLboolean,Green:?GLboolean,Blue:?GLboolean,Alpha:?GLboolean>>). + cast(5071, <<Red:?GLboolean,Green:?GLboolean,Blue:?GLboolean,Alpha:?GLboolean>>). %% @spec (Face::enum(),Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaterial.xml">external</a> documentation. +-spec colorMaterial(enum(),enum()) -> ok. colorMaterial(Face,Mode) -> - wxe_util:cast(5072, <<Face:?GLenum,Mode:?GLenum>>). + cast(5072, <<Face:?GLenum,Mode:?GLenum>>). -%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorPointer.xml">external</a> documentation. +-spec colorPointer(integer(),enum(),integer(),offset()|mem()) -> ok. colorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5073, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5073, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); colorPointer(Size,Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5074, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5074, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). %% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Type::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyPixels.xml">external</a> documentation. +-spec copyPixels(integer(),integer(),integer(),integer(),enum()) -> ok. copyPixels(X,Y,Width,Height,Type) -> - wxe_util:cast(5075, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Type:?GLenum>>). + cast(5075, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Type:?GLenum>>). %% @spec (Target::enum(),Level::integer(),InternalFormat::enum(),X::integer(),Y::integer(),Width::integer(),Border::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexImage1D.xml">external</a> documentation. +-spec copyTexImage1D(enum(),integer(),enum(),integer(),integer(),integer(),integer()) -> ok. copyTexImage1D(Target,Level,InternalFormat,X,Y,Width,Border) -> - wxe_util:cast(5076, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Border:?GLint>>). + cast(5076, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Border:?GLint>>). %% @spec (Target::enum(),Level::integer(),InternalFormat::enum(),X::integer(),Y::integer(),Width::integer(),Height::integer(),Border::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexImage2D.xml">external</a> documentation. +-spec copyTexImage2D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),integer()) -> ok. copyTexImage2D(Target,Level,InternalFormat,X,Y,Width,Height,Border) -> - wxe_util:cast(5077, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint>>). + cast(5077, <<Target:?GLenum,Level:?GLint,InternalFormat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint>>). %% @spec (Target::enum(),Level::integer(),Xoffset::integer(),X::integer(),Y::integer(),Width::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage1D.xml">external</a> documentation. +-spec copyTexSubImage1D(enum(),integer(),integer(),integer(),integer(),integer()) -> ok. copyTexSubImage1D(Target,Level,Xoffset,X,Y,Width) -> - wxe_util:cast(5078, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei>>). + cast(5078, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei>>). %% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage2D.xml">external</a> documentation. +-spec copyTexSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer()) -> ok. copyTexSubImage2D(Target,Level,Xoffset,Yoffset,X,Y,Width,Height) -> - wxe_util:cast(5079, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). + cast(5079, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml">external</a> documentation. +-spec cullFace(enum()) -> ok. cullFace(Mode) -> - wxe_util:cast(5080, <<Mode:?GLenum>>). + cast(5080, <<Mode:?GLenum>>). %% @spec (List::integer(),Range::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteLists.xml">external</a> documentation. +-spec deleteLists(integer(),integer()) -> ok. deleteLists(List,Range) -> - wxe_util:cast(5081, <<List:?GLuint,Range:?GLsizei>>). + cast(5081, <<List:?GLuint,Range:?GLsizei>>). %% @spec (Textures::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTextures.xml">external</a> documentation. +-spec deleteTextures([integer()]) -> ok. deleteTextures(Textures) -> - wxe_util:cast(5082, <<(length(Textures)):?GLuint, + cast(5082, <<(length(Textures)):?GLuint, (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32)>>). %% @spec (Func::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml">external</a> documentation. +-spec depthFunc(enum()) -> ok. depthFunc(Func) -> - wxe_util:cast(5083, <<Func:?GLenum>>). + cast(5083, <<Func:?GLenum>>). %% @spec (Flag::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml">external</a> documentation. +-spec depthMask(0|1) -> ok. depthMask(Flag) -> - wxe_util:cast(5084, <<Flag:?GLboolean>>). + cast(5084, <<Flag:?GLboolean>>). %% @spec (ZNear::clamp(),ZFar::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml">external</a> documentation. +-spec depthRange(clamp(),clamp()) -> ok. depthRange(ZNear,ZFar) -> - wxe_util:cast(5085, <<ZNear:?GLclampd,ZFar:?GLclampd>>). + cast(5085, <<ZNear:?GLclampd,ZFar:?GLclampd>>). %% @spec (Cap::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisable.xml">external</a> documentation. +-spec disable(enum()) -> ok. disable(Cap) -> - wxe_util:cast(5086, <<Cap:?GLenum>>). + cast(5086, <<Cap:?GLenum>>). %% @spec (Array::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisableClientState.xml">external</a> documentation. +-spec disableClientState(enum()) -> ok. disableClientState(Array) -> - wxe_util:cast(5087, <<Array:?GLenum>>). + cast(5087, <<Array:?GLenum>>). %% @spec (Mode::enum(),First::integer(),Count::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml">external</a> documentation. +-spec drawArrays(enum(),integer(),integer()) -> ok. drawArrays(Mode,First,Count) -> - wxe_util:cast(5088, <<Mode:?GLenum,First:?GLint,Count:?GLsizei>>). + cast(5088, <<Mode:?GLenum,First:?GLint,Count:?GLsizei>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffer.xml">external</a> documentation. +-spec drawBuffer(enum()) -> ok. drawBuffer(Mode) -> - wxe_util:cast(5089, <<Mode:?GLenum>>). + cast(5089, <<Mode:?GLenum>>). -%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|binary()) -> ok +%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml">external</a> documentation. +-spec drawElements(enum(),integer(),enum(),offset()|mem()) -> ok. drawElements(Mode,Count,Type,Indices) when is_integer(Indices) -> - wxe_util:cast(5090, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>); + cast(5090, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>); drawElements(Mode,Count,Type,Indices) -> - wxe_util:send_bin(Indices), - wxe_util:cast(5091, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum>>). + send_bin(Indices), + cast(5091, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum>>). -%% @spec (Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawPixels.xml">external</a> documentation. +-spec drawPixels(integer(),integer(),enum(),enum(),offset()|mem()) -> ok. drawPixels(Width,Height,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5092, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5092, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); drawPixels(Width,Height,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5093, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5093, <<Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Flag::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEdgeFlag.xml">external</a> documentation. +-spec edgeFlag(0|1) -> ok. edgeFlag(Flag) -> - wxe_util:cast(5094, <<Flag:?GLboolean>>). + cast(5094, <<Flag:?GLboolean>>). -%% @spec (Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEdgeFlagPointer.xml">external</a> documentation. +-spec edgeFlagPointer(integer(),offset()|mem()) -> ok. edgeFlagPointer(Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5095, <<Stride:?GLsizei,Pointer:?GLuint>>); + cast(5095, <<Stride:?GLsizei,Pointer:?GLuint>>); edgeFlagPointer(Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5096, <<Stride:?GLsizei>>). + send_bin(Pointer), + cast(5096, <<Stride:?GLsizei>>). %% @spec ({Flag}) -> ok %% @equiv edgeFlag(Flag) +-spec edgeFlagv({0|1}) -> ok. edgeFlagv({Flag}) -> edgeFlag(Flag). %% @spec (Cap::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml">external</a> documentation. +-spec enable(enum()) -> ok. enable(Cap) -> - wxe_util:cast(5097, <<Cap:?GLenum>>). + cast(5097, <<Cap:?GLenum>>). %% @spec (Array::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableClientState.xml">external</a> documentation. +-spec enableClientState(enum()) -> ok. enableClientState(Array) -> - wxe_util:cast(5098, <<Array:?GLenum>>). + cast(5098, <<Array:?GLenum>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnd.xml">external</a> documentation. +-spec 'end'() -> ok. 'end'() -> - wxe_util:cast(5099, <<>>). + cast(5099, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndList.xml">external</a> documentation. +-spec endList() -> ok. endList() -> - wxe_util:cast(5100, <<>>). + cast(5100, <<>>). %% @spec (U::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation. +-spec evalCoord1d(float()) -> ok. evalCoord1d(U) -> - wxe_util:cast(5101, <<U:?GLdouble>>). + cast(5101, <<U:?GLdouble>>). %% @spec ({U}) -> ok %% @equiv evalCoord1d(U) +-spec evalCoord1dv({float()}) -> ok. evalCoord1dv({U}) -> evalCoord1d(U). %% @spec (U::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation. +-spec evalCoord1f(float()) -> ok. evalCoord1f(U) -> - wxe_util:cast(5102, <<U:?GLfloat>>). + cast(5102, <<U:?GLfloat>>). %% @spec ({U}) -> ok %% @equiv evalCoord1f(U) +-spec evalCoord1fv({float()}) -> ok. evalCoord1fv({U}) -> evalCoord1f(U). %% @spec (U::float(),V::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation. +-spec evalCoord2d(float(),float()) -> ok. evalCoord2d(U,V) -> - wxe_util:cast(5103, <<U:?GLdouble,V:?GLdouble>>). + cast(5103, <<U:?GLdouble,V:?GLdouble>>). %% @spec ({U,V}) -> ok %% @equiv evalCoord2d(U,V) +-spec evalCoord2dv({float(),float()}) -> ok. evalCoord2dv({U,V}) -> evalCoord2d(U,V). %% @spec (U::float(),V::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalCoord.xml">external</a> documentation. +-spec evalCoord2f(float(),float()) -> ok. evalCoord2f(U,V) -> - wxe_util:cast(5104, <<U:?GLfloat,V:?GLfloat>>). + cast(5104, <<U:?GLfloat,V:?GLfloat>>). %% @spec ({U,V}) -> ok %% @equiv evalCoord2f(U,V) +-spec evalCoord2fv({float(),float()}) -> ok. evalCoord2fv({U,V}) -> evalCoord2f(U,V). %% @spec (Mode::enum(),I1::integer(),I2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalMesh.xml">external</a> documentation. +-spec evalMesh1(enum(),integer(),integer()) -> ok. evalMesh1(Mode,I1,I2) -> - wxe_util:cast(5105, <<Mode:?GLenum,I1:?GLint,I2:?GLint>>). + cast(5105, <<Mode:?GLenum,I1:?GLint,I2:?GLint>>). %% @spec (Mode::enum(),I1::integer(),I2::integer(),J1::integer(),J2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalMesh.xml">external</a> documentation. +-spec evalMesh2(enum(),integer(),integer(),integer(),integer()) -> ok. evalMesh2(Mode,I1,I2,J1,J2) -> - wxe_util:cast(5106, <<Mode:?GLenum,I1:?GLint,I2:?GLint,J1:?GLint,J2:?GLint>>). + cast(5106, <<Mode:?GLenum,I1:?GLint,I2:?GLint,J1:?GLint,J2:?GLint>>). %% @spec (I::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalPoint.xml">external</a> documentation. +-spec evalPoint1(integer()) -> ok. evalPoint1(I) -> - wxe_util:cast(5107, <<I:?GLint>>). + cast(5107, <<I:?GLint>>). %% @spec (I::integer(),J::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEvalPoint.xml">external</a> documentation. +-spec evalPoint2(integer(),integer()) -> ok. evalPoint2(I,J) -> - wxe_util:cast(5108, <<I:?GLint,J:?GLint>>). + cast(5108, <<I:?GLint,J:?GLint>>). -%% @spec (Size::integer(),Type::enum(),Buffer::wx:wx_mem()) -> ok +%% @spec (Size::integer(),Type::enum(),Buffer::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFeedbackBuffer.xml">external</a> documentation. +-spec feedbackBuffer(integer(),enum(),mem()) -> ok. feedbackBuffer(Size,Type,Buffer) -> - wxe_util:send_bin(Buffer#wx_mem.bin), - wxe_util:call(5109, <<Size:?GLsizei,Type:?GLenum>>). + send_bin(Buffer), + call(5109, <<Size:?GLsizei,Type:?GLenum>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFinish.xml">external</a> documentation. +-spec finish() -> ok. finish() -> - wxe_util:cast(5110, <<>>). + cast(5110, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlush.xml">external</a> documentation. +-spec flush() -> ok. flush() -> - wxe_util:cast(5111, <<>>). + cast(5111, <<>>). %% @spec (Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation. +-spec fogf(enum(),float()) -> ok. fogf(Pname,Param) -> - wxe_util:cast(5112, <<Pname:?GLenum,Param:?GLfloat>>). + cast(5112, <<Pname:?GLenum,Param:?GLfloat>>). %% @spec (Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation. +-spec fogfv(enum(),{float()}) -> ok. fogfv(Pname,Params) -> - wxe_util:cast(5113, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5113, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation. +-spec fogi(enum(),integer()) -> ok. fogi(Pname,Param) -> - wxe_util:cast(5114, <<Pname:?GLenum,Param:?GLint>>). + cast(5114, <<Pname:?GLenum,Param:?GLint>>). %% @spec (Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFog.xml">external</a> documentation. +-spec fogiv(enum(),{integer()}) -> ok. fogiv(Pname,Params) -> - wxe_util:cast(5115, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5115, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml">external</a> documentation. +-spec frontFace(enum()) -> ok. frontFace(Mode) -> - wxe_util:cast(5116, <<Mode:?GLenum>>). + cast(5116, <<Mode:?GLenum>>). %% @spec (Left::float(),Right::float(),Bottom::float(),Top::float(),ZNear::float(),ZFar::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml">external</a> documentation. +-spec frustum(float(),float(),float(),float(),float(),float()) -> ok. frustum(Left,Right,Bottom,Top,ZNear,ZFar) -> - wxe_util:cast(5117, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). + cast(5117, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). %% @spec (Range::integer()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenLists.xml">external</a> documentation. +-spec genLists(integer()) -> integer(). genLists(Range) -> - wxe_util:call(5118, <<Range:?GLsizei>>). + call(5118, <<Range:?GLsizei>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml">external</a> documentation. +-spec genTextures(integer()) -> [integer()]. genTextures(N) -> - wxe_util:call(5119, <<N:?GLsizei>>). + call(5119, <<N:?GLsizei>>). %% @spec (Pname::enum()) -> [0|1] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBooleanv.xml">external</a> documentation. +-spec getBooleanv(enum()) -> [0|1]. getBooleanv(Pname) -> - wxe_util:call(5120, <<Pname:?GLenum>>). + call(5120, <<Pname:?GLenum>>). -%% @spec (Plane::enum()) -> {float()} +%% @spec (Plane::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetClipPlane.xml">external</a> documentation. +-spec getClipPlane(enum()) -> {float(),float(),float(),float()}. getClipPlane(Plane) -> - wxe_util:call(5121, <<Plane:?GLenum>>). + call(5121, <<Plane:?GLenum>>). %% @spec (Pname::enum()) -> [float()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDoublev.xml">external</a> documentation. +-spec getDoublev(enum()) -> [float()]. getDoublev(Pname) -> - wxe_util:call(5122, <<Pname:?GLenum>>). + call(5122, <<Pname:?GLenum>>). %% @spec () -> enum() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetError.xml">external</a> documentation. +-spec getError() -> enum(). getError() -> - wxe_util:call(5123, <<>>). + call(5123, <<>>). %% @spec (Pname::enum()) -> [float()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFloatv.xml">external</a> documentation. +-spec getFloatv(enum()) -> [float()]. getFloatv(Pname) -> - wxe_util:call(5124, <<Pname:?GLenum>>). + call(5124, <<Pname:?GLenum>>). %% @spec (Pname::enum()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetIntegerv.xml">external</a> documentation. +-spec getIntegerv(enum()) -> [integer()]. getIntegerv(Pname) -> - wxe_util:call(5125, <<Pname:?GLenum>>). + call(5125, <<Pname:?GLenum>>). -%% @spec (Light::enum(),Pname::enum()) -> {float()} +%% @spec (Light::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetLight.xml">external</a> documentation. +-spec getLightfv(enum(),enum()) -> {float(),float(),float(),float()}. getLightfv(Light,Pname) -> - wxe_util:call(5126, <<Light:?GLenum,Pname:?GLenum>>). + call(5126, <<Light:?GLenum,Pname:?GLenum>>). -%% @spec (Light::enum(),Pname::enum()) -> {integer()} +%% @spec (Light::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetLight.xml">external</a> documentation. +-spec getLightiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getLightiv(Light,Pname) -> - wxe_util:call(5127, <<Light:?GLenum,Pname:?GLenum>>). + call(5127, <<Light:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation. +-spec getMapdv(enum(),enum(),mem()) -> ok. getMapdv(Target,Query,V) -> - wxe_util:send_bin(V#wx_mem.bin), - wxe_util:call(5128, <<Target:?GLenum,Query:?GLenum>>). + send_bin(V), + call(5128, <<Target:?GLenum,Query:?GLenum>>). -%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation. +-spec getMapfv(enum(),enum(),mem()) -> ok. getMapfv(Target,Query,V) -> - wxe_util:send_bin(V#wx_mem.bin), - wxe_util:call(5129, <<Target:?GLenum,Query:?GLenum>>). + send_bin(V), + call(5129, <<Target:?GLenum,Query:?GLenum>>). -%% @spec (Target::enum(),Query::enum(),V::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Query::enum(),V::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMap.xml">external</a> documentation. +-spec getMapiv(enum(),enum(),mem()) -> ok. getMapiv(Target,Query,V) -> - wxe_util:send_bin(V#wx_mem.bin), - wxe_util:call(5130, <<Target:?GLenum,Query:?GLenum>>). + send_bin(V), + call(5130, <<Target:?GLenum,Query:?GLenum>>). -%% @spec (Face::enum(),Pname::enum()) -> {float()} +%% @spec (Face::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMaterial.xml">external</a> documentation. +-spec getMaterialfv(enum(),enum()) -> {float(),float(),float(),float()}. getMaterialfv(Face,Pname) -> - wxe_util:call(5131, <<Face:?GLenum,Pname:?GLenum>>). + call(5131, <<Face:?GLenum,Pname:?GLenum>>). -%% @spec (Face::enum(),Pname::enum()) -> {integer()} +%% @spec (Face::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMaterial.xml">external</a> documentation. +-spec getMaterialiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getMaterialiv(Face,Pname) -> - wxe_util:call(5132, <<Face:?GLenum,Pname:?GLenum>>). + call(5132, <<Face:?GLenum,Pname:?GLenum>>). -%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok +%% @spec (Map::enum(),Values::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation. +-spec getPixelMapfv(enum(),mem()) -> ok. getPixelMapfv(Map,Values) -> - wxe_util:send_bin(Values#wx_mem.bin), - wxe_util:call(5133, <<Map:?GLenum>>). + send_bin(Values), + call(5133, <<Map:?GLenum>>). -%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok +%% @spec (Map::enum(),Values::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation. +-spec getPixelMapuiv(enum(),mem()) -> ok. getPixelMapuiv(Map,Values) -> - wxe_util:send_bin(Values#wx_mem.bin), - wxe_util:call(5134, <<Map:?GLenum>>). + send_bin(Values), + call(5134, <<Map:?GLenum>>). -%% @spec (Map::enum(),Values::wx:wx_mem()) -> ok +%% @spec (Map::enum(),Values::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPixelMap.xml">external</a> documentation. +-spec getPixelMapusv(enum(),mem()) -> ok. getPixelMapusv(Map,Values) -> - wxe_util:send_bin(Values#wx_mem.bin), - wxe_util:call(5135, <<Map:?GLenum>>). + send_bin(Values), + call(5135, <<Map:?GLenum>>). %% @spec () -> binary() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetPolygonStipple.xml">external</a> documentation. +-spec getPolygonStipple() -> binary(). getPolygonStipple() -> - wxe_util:call(5136, <<>>). + call(5136, <<>>). %% @spec (Name::enum()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetString.xml">external</a> documentation. +-spec getString(enum()) -> string(). getString(Name) -> - wxe_util:call(5137, <<Name:?GLenum>>). + call(5137, <<Name:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {float()} +%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml">external</a> documentation. +-spec getTexEnvfv(enum(),enum()) -> {float(),float(),float(),float()}. getTexEnvfv(Target,Pname) -> - wxe_util:call(5138, <<Target:?GLenum,Pname:?GLenum>>). + call(5138, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexEnv.xml">external</a> documentation. +-spec getTexEnviv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getTexEnviv(Target,Pname) -> - wxe_util:call(5139, <<Target:?GLenum,Pname:?GLenum>>). + call(5139, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Coord::enum(),Pname::enum()) -> {float()} +%% @spec (Coord::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation. +-spec getTexGendv(enum(),enum()) -> {float(),float(),float(),float()}. getTexGendv(Coord,Pname) -> - wxe_util:call(5140, <<Coord:?GLenum,Pname:?GLenum>>). + call(5140, <<Coord:?GLenum,Pname:?GLenum>>). -%% @spec (Coord::enum(),Pname::enum()) -> {float()} +%% @spec (Coord::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation. +-spec getTexGenfv(enum(),enum()) -> {float(),float(),float(),float()}. getTexGenfv(Coord,Pname) -> - wxe_util:call(5141, <<Coord:?GLenum,Pname:?GLenum>>). + call(5141, <<Coord:?GLenum,Pname:?GLenum>>). -%% @spec (Coord::enum(),Pname::enum()) -> {integer()} +%% @spec (Coord::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexGen.xml">external</a> documentation. +-spec getTexGeniv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getTexGeniv(Coord,Pname) -> - wxe_util:call(5142, <<Coord:?GLenum,Pname:?GLenum>>). + call(5142, <<Coord:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Level::integer(),Format::enum(),Type::enum(),Pixels::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Level::integer(),Format::enum(),Type::enum(),Pixels::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml">external</a> documentation. +-spec getTexImage(enum(),integer(),enum(),enum(),mem()) -> ok. getTexImage(Target,Level,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels#wx_mem.bin), - wxe_util:call(5143, <<Target:?GLenum,Level:?GLint,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + call(5143, <<Target:?GLenum,Level:?GLint,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Level::integer(),Pname::enum()) -> {float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexLevelParameter.xml">external</a> documentation. +-spec getTexLevelParameterfv(enum(),integer(),enum()) -> {float()}. getTexLevelParameterfv(Target,Level,Pname) -> - wxe_util:call(5144, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>). + call(5144, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>). %% @spec (Target::enum(),Level::integer(),Pname::enum()) -> {integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexLevelParameter.xml">external</a> documentation. +-spec getTexLevelParameteriv(enum(),integer(),enum()) -> {integer()}. getTexLevelParameteriv(Target,Level,Pname) -> - wxe_util:call(5145, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>). + call(5145, <<Target:?GLenum,Level:?GLint,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {float()} +%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameter.xml">external</a> documentation. +-spec getTexParameterfv(enum(),enum()) -> {float(),float(),float(),float()}. getTexParameterfv(Target,Pname) -> - wxe_util:call(5146, <<Target:?GLenum,Pname:?GLenum>>). + call(5146, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameter.xml">external</a> documentation. +-spec getTexParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getTexParameteriv(Target,Pname) -> - wxe_util:call(5147, <<Target:?GLenum,Pname:?GLenum>>). + call(5147, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Target::enum(),Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glHint.xml">external</a> documentation. +-spec hint(enum(),enum()) -> ok. hint(Target,Mode) -> - wxe_util:cast(5148, <<Target:?GLenum,Mode:?GLenum>>). + cast(5148, <<Target:?GLenum,Mode:?GLenum>>). %% @spec (Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndexMask.xml">external</a> documentation. +-spec indexMask(integer()) -> ok. indexMask(Mask) -> - wxe_util:cast(5149, <<Mask:?GLuint>>). + cast(5149, <<Mask:?GLuint>>). -%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndexPointer.xml">external</a> documentation. +-spec indexPointer(enum(),integer(),offset()|mem()) -> ok. indexPointer(Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5150, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5150, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); indexPointer(Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5151, <<Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5151, <<Type:?GLenum,Stride:?GLsizei>>). %% @spec (C::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation. +-spec indexd(float()) -> ok. indexd(C) -> - wxe_util:cast(5152, <<C:?GLdouble>>). + cast(5152, <<C:?GLdouble>>). %% @spec ({C}) -> ok %% @equiv indexd(C) +-spec indexdv({float()}) -> ok. indexdv({C}) -> indexd(C). %% @spec (C::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation. +-spec indexf(float()) -> ok. indexf(C) -> - wxe_util:cast(5153, <<C:?GLfloat>>). + cast(5153, <<C:?GLfloat>>). %% @spec ({C}) -> ok %% @equiv indexf(C) +-spec indexfv({float()}) -> ok. indexfv({C}) -> indexf(C). %% @spec (C::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation. +-spec indexi(integer()) -> ok. indexi(C) -> - wxe_util:cast(5154, <<C:?GLint>>). + cast(5154, <<C:?GLint>>). %% @spec ({C}) -> ok %% @equiv indexi(C) +-spec indexiv({integer()}) -> ok. indexiv({C}) -> indexi(C). %% @spec (C::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation. +-spec indexs(integer()) -> ok. indexs(C) -> - wxe_util:cast(5155, <<C:?GLshort>>). + cast(5155, <<C:?GLshort>>). %% @spec ({C}) -> ok %% @equiv indexs(C) +-spec indexsv({integer()}) -> ok. indexsv({C}) -> indexs(C). %% @spec (C::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIndex.xml">external</a> documentation. +-spec indexub(integer()) -> ok. indexub(C) -> - wxe_util:cast(5156, <<C:?GLubyte>>). + cast(5156, <<C:?GLubyte>>). %% @spec ({C}) -> ok %% @equiv indexub(C) +-spec indexubv({integer()}) -> ok. indexubv({C}) -> indexub(C). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glInitNames.xml">external</a> documentation. +-spec initNames() -> ok. initNames() -> - wxe_util:cast(5157, <<>>). + cast(5157, <<>>). -%% @spec (Format::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Format::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml">external</a> documentation. +-spec interleavedArrays(enum(),integer(),offset()|mem()) -> ok. interleavedArrays(Format,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5158, <<Format:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5158, <<Format:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); interleavedArrays(Format,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5159, <<Format:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5159, <<Format:?GLenum,Stride:?GLsizei>>). %% @spec (Cap::enum()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabled.xml">external</a> documentation. +-spec isEnabled(enum()) -> 0|1. isEnabled(Cap) -> - wxe_util:call(5160, <<Cap:?GLenum>>). + call(5160, <<Cap:?GLenum>>). %% @spec (List::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsList.xml">external</a> documentation. +-spec isList(integer()) -> 0|1. isList(List) -> - wxe_util:call(5161, <<List:?GLuint>>). + call(5161, <<List:?GLuint>>). %% @spec (Texture::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTexture.xml">external</a> documentation. +-spec isTexture(integer()) -> 0|1. isTexture(Texture) -> - wxe_util:call(5162, <<Texture:?GLuint>>). + call(5162, <<Texture:?GLuint>>). %% @spec (Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation. +-spec lightModelf(enum(),float()) -> ok. lightModelf(Pname,Param) -> - wxe_util:cast(5163, <<Pname:?GLenum,Param:?GLfloat>>). + cast(5163, <<Pname:?GLenum,Param:?GLfloat>>). %% @spec (Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation. +-spec lightModelfv(enum(),{float()}) -> ok. lightModelfv(Pname,Params) -> - wxe_util:cast(5164, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5164, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation. +-spec lightModeli(enum(),integer()) -> ok. lightModeli(Pname,Param) -> - wxe_util:cast(5165, <<Pname:?GLenum,Param:?GLint>>). + cast(5165, <<Pname:?GLenum,Param:?GLint>>). %% @spec (Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLightModel.xml">external</a> documentation. +-spec lightModeliv(enum(),{integer()}) -> ok. lightModeliv(Pname,Params) -> - wxe_util:cast(5166, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5166, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Light::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation. +-spec lightf(enum(),enum(),float()) -> ok. lightf(Light,Pname,Param) -> - wxe_util:cast(5167, <<Light:?GLenum,Pname:?GLenum,Param:?GLfloat>>). + cast(5167, <<Light:?GLenum,Pname:?GLenum,Param:?GLfloat>>). %% @spec (Light::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation. +-spec lightfv(enum(),enum(),{float()}) -> ok. lightfv(Light,Pname,Params) -> - wxe_util:cast(5168, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5168, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Light::enum(),Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation. +-spec lighti(enum(),enum(),integer()) -> ok. lighti(Light,Pname,Param) -> - wxe_util:cast(5169, <<Light:?GLenum,Pname:?GLenum,Param:?GLint>>). + cast(5169, <<Light:?GLenum,Pname:?GLenum,Param:?GLint>>). %% @spec (Light::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLight.xml">external</a> documentation. +-spec lightiv(enum(),enum(),{integer()}) -> ok. lightiv(Light,Pname,Params) -> - wxe_util:cast(5170, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5170, <<Light:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Factor::integer(),Pattern::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLineStipple.xml">external</a> documentation. +-spec lineStipple(integer(),integer()) -> ok. lineStipple(Factor,Pattern) -> - wxe_util:cast(5171, <<Factor:?GLint,Pattern:?GLushort>>). + cast(5171, <<Factor:?GLint,Pattern:?GLushort>>). %% @spec (Width::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLineWidth.xml">external</a> documentation. +-spec lineWidth(float()) -> ok. lineWidth(Width) -> - wxe_util:cast(5172, <<Width:?GLfloat>>). + cast(5172, <<Width:?GLfloat>>). %% @spec (Base::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glListBase.xml">external</a> documentation. +-spec listBase(integer()) -> ok. listBase(Base) -> - wxe_util:cast(5173, <<Base:?GLuint>>). + cast(5173, <<Base:?GLuint>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadIdentity.xml">external</a> documentation. +-spec loadIdentity() -> ok. loadIdentity() -> - wxe_util:cast(5174, <<>>). + cast(5174, <<>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml">external</a> documentation. +-spec loadMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); loadMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5175, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadMatrix.xml">external</a> documentation. +-spec loadMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); loadMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5176, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). %% @spec (Name::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadName.xml">external</a> documentation. +-spec loadName(integer()) -> ok. loadName(Name) -> - wxe_util:cast(5177, <<Name:?GLuint>>). + cast(5177, <<Name:?GLuint>>). %% @spec (Opcode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml">external</a> documentation. +-spec logicOp(enum()) -> ok. logicOp(Opcode) -> - wxe_util:cast(5178, <<Opcode:?GLenum>>). + cast(5178, <<Opcode:?GLenum>>). %% @spec (Target::enum(),U1::float(),U2::float(),Stride::integer(),Order::integer(),Points::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation. +-spec map1d(enum(),float(),float(),integer(),integer(),binary()) -> ok. map1d(Target,U1,U2,Stride,Order,Points) -> - wxe_util:send_bin(Points), - wxe_util:cast(5179, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Stride:?GLint,Order:?GLint>>). + send_bin(Points), + cast(5179, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Stride:?GLint,Order:?GLint>>). %% @spec (Target::enum(),U1::float(),U2::float(),Stride::integer(),Order::integer(),Points::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation. +-spec map1f(enum(),float(),float(),integer(),integer(),binary()) -> ok. map1f(Target,U1,U2,Stride,Order,Points) -> - wxe_util:send_bin(Points), - wxe_util:cast(5180, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Stride:?GLint,Order:?GLint>>). + send_bin(Points), + cast(5180, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Stride:?GLint,Order:?GLint>>). %% @spec (Target::enum(),U1::float(),U2::float(),Ustride::integer(),Uorder::integer(),V1::float(),V2::float(),Vstride::integer(),Vorder::integer(),Points::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation. +-spec map2d(enum(),float(),float(),integer(),integer(),float(),float(),integer(),integer(),binary()) -> ok. map2d(Target,U1,U2,Ustride,Uorder,V1,V2,Vstride,Vorder,Points) -> - wxe_util:send_bin(Points), - wxe_util:cast(5181, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Ustride:?GLint,Uorder:?GLint,V1:?GLdouble,V2:?GLdouble,Vstride:?GLint,Vorder:?GLint>>). + send_bin(Points), + cast(5181, <<Target:?GLenum,0:32,U1:?GLdouble,U2:?GLdouble,Ustride:?GLint,Uorder:?GLint,V1:?GLdouble,V2:?GLdouble,Vstride:?GLint,Vorder:?GLint>>). %% @spec (Target::enum(),U1::float(),U2::float(),Ustride::integer(),Uorder::integer(),V1::float(),V2::float(),Vstride::integer(),Vorder::integer(),Points::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMap.xml">external</a> documentation. +-spec map2f(enum(),float(),float(),integer(),integer(),float(),float(),integer(),integer(),binary()) -> ok. map2f(Target,U1,U2,Ustride,Uorder,V1,V2,Vstride,Vorder,Points) -> - wxe_util:send_bin(Points), - wxe_util:cast(5182, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Ustride:?GLint,Uorder:?GLint,V1:?GLfloat,V2:?GLfloat,Vstride:?GLint,Vorder:?GLint>>). + send_bin(Points), + cast(5182, <<Target:?GLenum,U1:?GLfloat,U2:?GLfloat,Ustride:?GLint,Uorder:?GLint,V1:?GLfloat,V2:?GLfloat,Vstride:?GLint,Vorder:?GLint>>). %% @spec (Un::integer(),U1::float(),U2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation. +-spec mapGrid1d(integer(),float(),float()) -> ok. mapGrid1d(Un,U1,U2) -> - wxe_util:cast(5183, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble>>). + cast(5183, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble>>). %% @spec (Un::integer(),U1::float(),U2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation. +-spec mapGrid1f(integer(),float(),float()) -> ok. mapGrid1f(Un,U1,U2) -> - wxe_util:cast(5184, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat>>). + cast(5184, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat>>). %% @spec (Un::integer(),U1::float(),U2::float(),Vn::integer(),V1::float(),V2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation. +-spec mapGrid2d(integer(),float(),float(),integer(),float(),float()) -> ok. mapGrid2d(Un,U1,U2,Vn,V1,V2) -> - wxe_util:cast(5185, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble,Vn:?GLint,0:32,V1:?GLdouble,V2:?GLdouble>>). + cast(5185, <<Un:?GLint,0:32,U1:?GLdouble,U2:?GLdouble,Vn:?GLint,0:32,V1:?GLdouble,V2:?GLdouble>>). %% @spec (Un::integer(),U1::float(),U2::float(),Vn::integer(),V1::float(),V2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMapGrid.xml">external</a> documentation. +-spec mapGrid2f(integer(),float(),float(),integer(),float(),float()) -> ok. mapGrid2f(Un,U1,U2,Vn,V1,V2) -> - wxe_util:cast(5186, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat,Vn:?GLint,V1:?GLfloat,V2:?GLfloat>>). + cast(5186, <<Un:?GLint,U1:?GLfloat,U2:?GLfloat,Vn:?GLint,V1:?GLfloat,V2:?GLfloat>>). %% @spec (Face::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation. +-spec materialf(enum(),enum(),float()) -> ok. materialf(Face,Pname,Param) -> - wxe_util:cast(5187, <<Face:?GLenum,Pname:?GLenum,Param:?GLfloat>>). + cast(5187, <<Face:?GLenum,Pname:?GLenum,Param:?GLfloat>>). %% @spec (Face::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation. +-spec materialfv(enum(),enum(),{float()}) -> ok. materialfv(Face,Pname,Params) -> - wxe_util:cast(5188, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5188, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Face::enum(),Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation. +-spec materiali(enum(),enum(),integer()) -> ok. materiali(Face,Pname,Param) -> - wxe_util:cast(5189, <<Face:?GLenum,Pname:?GLenum,Param:?GLint>>). + cast(5189, <<Face:?GLenum,Pname:?GLenum,Param:?GLint>>). %% @spec (Face::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMaterial.xml">external</a> documentation. +-spec materialiv(enum(),enum(),{integer()}) -> ok. materialiv(Face,Pname,Params) -> - wxe_util:cast(5190, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5190, <<Face:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixMode.xml">external</a> documentation. +-spec matrixMode(enum()) -> ok. matrixMode(Mode) -> - wxe_util:cast(5191, <<Mode:?GLenum>>). + cast(5191, <<Mode:?GLenum>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultMatrix.xml">external</a> documentation. +-spec multMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); multMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5192, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultMatrix.xml">external</a> documentation. +-spec multMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); multMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5193, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). %% @spec (List::integer(),Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNewList.xml">external</a> documentation. +-spec newList(integer(),enum()) -> ok. newList(List,Mode) -> - wxe_util:cast(5194, <<List:?GLuint,Mode:?GLenum>>). + cast(5194, <<List:?GLuint,Mode:?GLenum>>). %% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation. +-spec normal3b(integer(),integer(),integer()) -> ok. normal3b(Nx,Ny,Nz) -> - wxe_util:cast(5195, <<Nx:?GLbyte,Ny:?GLbyte,Nz:?GLbyte>>). + cast(5195, <<Nx:?GLbyte,Ny:?GLbyte,Nz:?GLbyte>>). %% @spec ({Nx,Ny,Nz}) -> ok %% @equiv normal3b(Nx,Ny,Nz) +-spec normal3bv({integer(),integer(),integer()}) -> ok. normal3bv({Nx,Ny,Nz}) -> normal3b(Nx,Ny,Nz). %% @spec (Nx::float(),Ny::float(),Nz::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation. +-spec normal3d(float(),float(),float()) -> ok. normal3d(Nx,Ny,Nz) -> - wxe_util:cast(5196, <<Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble>>). + cast(5196, <<Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble>>). %% @spec ({Nx,Ny,Nz}) -> ok %% @equiv normal3d(Nx,Ny,Nz) +-spec normal3dv({float(),float(),float()}) -> ok. normal3dv({Nx,Ny,Nz}) -> normal3d(Nx,Ny,Nz). %% @spec (Nx::float(),Ny::float(),Nz::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation. +-spec normal3f(float(),float(),float()) -> ok. normal3f(Nx,Ny,Nz) -> - wxe_util:cast(5197, <<Nx:?GLfloat,Ny:?GLfloat,Nz:?GLfloat>>). + cast(5197, <<Nx:?GLfloat,Ny:?GLfloat,Nz:?GLfloat>>). %% @spec ({Nx,Ny,Nz}) -> ok %% @equiv normal3f(Nx,Ny,Nz) +-spec normal3fv({float(),float(),float()}) -> ok. normal3fv({Nx,Ny,Nz}) -> normal3f(Nx,Ny,Nz). %% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation. +-spec normal3i(integer(),integer(),integer()) -> ok. normal3i(Nx,Ny,Nz) -> - wxe_util:cast(5198, <<Nx:?GLint,Ny:?GLint,Nz:?GLint>>). + cast(5198, <<Nx:?GLint,Ny:?GLint,Nz:?GLint>>). %% @spec ({Nx,Ny,Nz}) -> ok %% @equiv normal3i(Nx,Ny,Nz) +-spec normal3iv({integer(),integer(),integer()}) -> ok. normal3iv({Nx,Ny,Nz}) -> normal3i(Nx,Ny,Nz). %% @spec (Nx::integer(),Ny::integer(),Nz::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormal.xml">external</a> documentation. +-spec normal3s(integer(),integer(),integer()) -> ok. normal3s(Nx,Ny,Nz) -> - wxe_util:cast(5199, <<Nx:?GLshort,Ny:?GLshort,Nz:?GLshort>>). + cast(5199, <<Nx:?GLshort,Ny:?GLshort,Nz:?GLshort>>). %% @spec ({Nx,Ny,Nz}) -> ok %% @equiv normal3s(Nx,Ny,Nz) +-spec normal3sv({integer(),integer(),integer()}) -> ok. normal3sv({Nx,Ny,Nz}) -> normal3s(Nx,Ny,Nz). -%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNormalPointer.xml">external</a> documentation. +-spec normalPointer(enum(),integer(),offset()|mem()) -> ok. normalPointer(Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5200, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5200, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); normalPointer(Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5201, <<Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5201, <<Type:?GLenum,Stride:?GLsizei>>). %% @spec (Left::float(),Right::float(),Bottom::float(),Top::float(),ZNear::float(),ZFar::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml">external</a> documentation. +-spec ortho(float(),float(),float(),float(),float(),float()) -> ok. ortho(Left,Right,Bottom,Top,ZNear,ZFar) -> - wxe_util:cast(5202, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). + cast(5202, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). %% @spec (Token::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPassThrough.xml">external</a> documentation. +-spec passThrough(float()) -> ok. passThrough(Token) -> - wxe_util:cast(5203, <<Token:?GLfloat>>). + cast(5203, <<Token:?GLfloat>>). %% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation. +-spec pixelMapfv(enum(),integer(),binary()) -> ok. pixelMapfv(Map,Mapsize,Values) -> - wxe_util:send_bin(Values), - wxe_util:cast(5204, <<Map:?GLenum,Mapsize:?GLsizei>>). + send_bin(Values), + cast(5204, <<Map:?GLenum,Mapsize:?GLsizei>>). %% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation. +-spec pixelMapuiv(enum(),integer(),binary()) -> ok. pixelMapuiv(Map,Mapsize,Values) -> - wxe_util:send_bin(Values), - wxe_util:cast(5205, <<Map:?GLenum,Mapsize:?GLsizei>>). + send_bin(Values), + cast(5205, <<Map:?GLenum,Mapsize:?GLsizei>>). %% @spec (Map::enum(),Mapsize::integer(),Values::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelMap.xml">external</a> documentation. +-spec pixelMapusv(enum(),integer(),binary()) -> ok. pixelMapusv(Map,Mapsize,Values) -> - wxe_util:send_bin(Values), - wxe_util:cast(5206, <<Map:?GLenum,Mapsize:?GLsizei>>). + send_bin(Values), + cast(5206, <<Map:?GLenum,Mapsize:?GLsizei>>). %% @spec (Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml">external</a> documentation. +-spec pixelStoref(enum(),float()) -> ok. pixelStoref(Pname,Param) -> - wxe_util:cast(5207, <<Pname:?GLenum,Param:?GLfloat>>). + cast(5207, <<Pname:?GLenum,Param:?GLfloat>>). %% @spec (Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelStore.xml">external</a> documentation. +-spec pixelStorei(enum(),integer()) -> ok. pixelStorei(Pname,Param) -> - wxe_util:cast(5208, <<Pname:?GLenum,Param:?GLint>>). + cast(5208, <<Pname:?GLenum,Param:?GLint>>). %% @spec (Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml">external</a> documentation. +-spec pixelTransferf(enum(),float()) -> ok. pixelTransferf(Pname,Param) -> - wxe_util:cast(5209, <<Pname:?GLenum,Param:?GLfloat>>). + cast(5209, <<Pname:?GLenum,Param:?GLfloat>>). %% @spec (Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelTransfer.xml">external</a> documentation. +-spec pixelTransferi(enum(),integer()) -> ok. pixelTransferi(Pname,Param) -> - wxe_util:cast(5210, <<Pname:?GLenum,Param:?GLint>>). + cast(5210, <<Pname:?GLenum,Param:?GLint>>). %% @spec (Xfactor::float(),Yfactor::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPixelZoom.xml">external</a> documentation. +-spec pixelZoom(float(),float()) -> ok. pixelZoom(Xfactor,Yfactor) -> - wxe_util:cast(5211, <<Xfactor:?GLfloat,Yfactor:?GLfloat>>). + cast(5211, <<Xfactor:?GLfloat,Yfactor:?GLfloat>>). %% @spec (Size::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointSize.xml">external</a> documentation. +-spec pointSize(float()) -> ok. pointSize(Size) -> - wxe_util:cast(5212, <<Size:?GLfloat>>). + cast(5212, <<Size:?GLfloat>>). %% @spec (Face::enum(),Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonMode.xml">external</a> documentation. +-spec polygonMode(enum(),enum()) -> ok. polygonMode(Face,Mode) -> - wxe_util:cast(5213, <<Face:?GLenum,Mode:?GLenum>>). + cast(5213, <<Face:?GLenum,Mode:?GLenum>>). %% @spec (Factor::float(),Units::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml">external</a> documentation. +-spec polygonOffset(float(),float()) -> ok. polygonOffset(Factor,Units) -> - wxe_util:cast(5214, <<Factor:?GLfloat,Units:?GLfloat>>). + cast(5214, <<Factor:?GLfloat,Units:?GLfloat>>). %% @spec (Mask::binary()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPolygonStipple.xml">external</a> documentation. +-spec polygonStipple(binary()) -> ok. polygonStipple(Mask) -> - wxe_util:send_bin(Mask), - wxe_util:cast(5215, <<>>). + send_bin(Mask), + cast(5215, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopAttrib.xml">external</a> documentation. +-spec popAttrib() -> ok. popAttrib() -> - wxe_util:cast(5216, <<>>). + cast(5216, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopClientAttrib.xml">external</a> documentation. +-spec popClientAttrib() -> ok. popClientAttrib() -> - wxe_util:cast(5217, <<>>). + cast(5217, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopMatrix.xml">external</a> documentation. +-spec popMatrix() -> ok. popMatrix() -> - wxe_util:cast(5218, <<>>). + cast(5218, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPopName.xml">external</a> documentation. +-spec popName() -> ok. popName() -> - wxe_util:cast(5219, <<>>). + cast(5219, <<>>). %% @spec (Textures::[integer()],Priorities::[clamp()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrioritizeTextures.xml">external</a> documentation. +-spec prioritizeTextures([integer()],[clamp()]) -> ok. prioritizeTextures(Textures,Priorities) -> - wxe_util:cast(5220, <<(length(Textures)):?GLuint, + cast(5220, <<(length(Textures)):?GLuint, (<< <<C:?GLuint>> || C <- Textures>>)/binary,0:(((1+length(Textures)) rem 2)*32),(length(Priorities)):?GLuint, (<< <<C:?GLclampf>> || C <- Priorities>>)/binary,0:(((1+length(Priorities)) rem 2)*32)>>). %% @spec (Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushAttrib.xml">external</a> documentation. +-spec pushAttrib(integer()) -> ok. pushAttrib(Mask) -> - wxe_util:cast(5221, <<Mask:?GLbitfield>>). + cast(5221, <<Mask:?GLbitfield>>). %% @spec (Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushClientAttrib.xml">external</a> documentation. +-spec pushClientAttrib(integer()) -> ok. pushClientAttrib(Mask) -> - wxe_util:cast(5222, <<Mask:?GLbitfield>>). + cast(5222, <<Mask:?GLbitfield>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushMatrix.xml">external</a> documentation. +-spec pushMatrix() -> ok. pushMatrix() -> - wxe_util:cast(5223, <<>>). + cast(5223, <<>>). %% @spec (Name::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPushName.xml">external</a> documentation. +-spec pushName(integer()) -> ok. pushName(Name) -> - wxe_util:cast(5224, <<Name:?GLuint>>). + cast(5224, <<Name:?GLuint>>). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos2d(float(),float()) -> ok. rasterPos2d(X,Y) -> - wxe_util:cast(5225, <<X:?GLdouble,Y:?GLdouble>>). + cast(5225, <<X:?GLdouble,Y:?GLdouble>>). %% @spec ({X,Y}) -> ok %% @equiv rasterPos2d(X,Y) +-spec rasterPos2dv({float(),float()}) -> ok. rasterPos2dv({X,Y}) -> rasterPos2d(X,Y). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos2f(float(),float()) -> ok. rasterPos2f(X,Y) -> - wxe_util:cast(5226, <<X:?GLfloat,Y:?GLfloat>>). + cast(5226, <<X:?GLfloat,Y:?GLfloat>>). %% @spec ({X,Y}) -> ok %% @equiv rasterPos2f(X,Y) +-spec rasterPos2fv({float(),float()}) -> ok. rasterPos2fv({X,Y}) -> rasterPos2f(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos2i(integer(),integer()) -> ok. rasterPos2i(X,Y) -> - wxe_util:cast(5227, <<X:?GLint,Y:?GLint>>). + cast(5227, <<X:?GLint,Y:?GLint>>). %% @spec ({X,Y}) -> ok %% @equiv rasterPos2i(X,Y) +-spec rasterPos2iv({integer(),integer()}) -> ok. rasterPos2iv({X,Y}) -> rasterPos2i(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos2s(integer(),integer()) -> ok. rasterPos2s(X,Y) -> - wxe_util:cast(5228, <<X:?GLshort,Y:?GLshort>>). + cast(5228, <<X:?GLshort,Y:?GLshort>>). %% @spec ({X,Y}) -> ok %% @equiv rasterPos2s(X,Y) +-spec rasterPos2sv({integer(),integer()}) -> ok. rasterPos2sv({X,Y}) -> rasterPos2s(X,Y). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos3d(float(),float(),float()) -> ok. rasterPos3d(X,Y,Z) -> - wxe_util:cast(5229, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5229, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec ({X,Y,Z}) -> ok %% @equiv rasterPos3d(X,Y,Z) +-spec rasterPos3dv({float(),float(),float()}) -> ok. rasterPos3dv({X,Y,Z}) -> rasterPos3d(X,Y,Z). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos3f(float(),float(),float()) -> ok. rasterPos3f(X,Y,Z) -> - wxe_util:cast(5230, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5230, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec ({X,Y,Z}) -> ok %% @equiv rasterPos3f(X,Y,Z) +-spec rasterPos3fv({float(),float(),float()}) -> ok. rasterPos3fv({X,Y,Z}) -> rasterPos3f(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos3i(integer(),integer(),integer()) -> ok. rasterPos3i(X,Y,Z) -> - wxe_util:cast(5231, <<X:?GLint,Y:?GLint,Z:?GLint>>). + cast(5231, <<X:?GLint,Y:?GLint,Z:?GLint>>). %% @spec ({X,Y,Z}) -> ok %% @equiv rasterPos3i(X,Y,Z) +-spec rasterPos3iv({integer(),integer(),integer()}) -> ok. rasterPos3iv({X,Y,Z}) -> rasterPos3i(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos3s(integer(),integer(),integer()) -> ok. rasterPos3s(X,Y,Z) -> - wxe_util:cast(5232, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). + cast(5232, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). %% @spec ({X,Y,Z}) -> ok %% @equiv rasterPos3s(X,Y,Z) +-spec rasterPos3sv({integer(),integer(),integer()}) -> ok. rasterPos3sv({X,Y,Z}) -> rasterPos3s(X,Y,Z). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos4d(float(),float(),float(),float()) -> ok. rasterPos4d(X,Y,Z,W) -> - wxe_util:cast(5233, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5233, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv rasterPos4d(X,Y,Z,W) +-spec rasterPos4dv({float(),float(),float(),float()}) -> ok. rasterPos4dv({X,Y,Z,W}) -> rasterPos4d(X,Y,Z,W). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos4f(float(),float(),float(),float()) -> ok. rasterPos4f(X,Y,Z,W) -> - wxe_util:cast(5234, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5234, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv rasterPos4f(X,Y,Z,W) +-spec rasterPos4fv({float(),float(),float(),float()}) -> ok. rasterPos4fv({X,Y,Z,W}) -> rasterPos4f(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos4i(integer(),integer(),integer(),integer()) -> ok. rasterPos4i(X,Y,Z,W) -> - wxe_util:cast(5235, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). + cast(5235, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv rasterPos4i(X,Y,Z,W) +-spec rasterPos4iv({integer(),integer(),integer(),integer()}) -> ok. rasterPos4iv({X,Y,Z,W}) -> rasterPos4i(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRasterPos.xml">external</a> documentation. +-spec rasterPos4s(integer(),integer(),integer(),integer()) -> ok. rasterPos4s(X,Y,Z,W) -> - wxe_util:cast(5236, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). + cast(5236, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv rasterPos4s(X,Y,Z,W) +-spec rasterPos4sv({integer(),integer(),integer(),integer()}) -> ok. rasterPos4sv({X,Y,Z,W}) -> rasterPos4s(X,Y,Z,W). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReadBuffer.xml">external</a> documentation. +-spec readBuffer(enum()) -> ok. readBuffer(Mode) -> - wxe_util:cast(5237, <<Mode:?GLenum>>). + cast(5237, <<Mode:?GLenum>>). -%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::wx:wx_mem()) -> ok +%% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml">external</a> documentation. +-spec readPixels(integer(),integer(),integer(),integer(),enum(),enum(),mem()) -> ok. readPixels(X,Y,Width,Height,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels#wx_mem.bin), - wxe_util:call(5238, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + call(5238, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (X1::float(),Y1::float(),X2::float(),Y2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectd(float(),float(),float(),float()) -> ok. rectd(X1,Y1,X2,Y2) -> - wxe_util:cast(5239, <<X1:?GLdouble,Y1:?GLdouble,X2:?GLdouble,Y2:?GLdouble>>). + cast(5239, <<X1:?GLdouble,Y1:?GLdouble,X2:?GLdouble,Y2:?GLdouble>>). -%% @spec (V1::{float()},V2::{float()}) -> ok +%% @spec (V1::{float(),float()},V2::{float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectdv({float(),float()},{float(),float()}) -> ok. rectdv({V1,V2},{V1,V2}) -> - wxe_util:cast(5240, <<V1:?GLdouble,V2:?GLdouble,V1:?GLdouble,V2:?GLdouble>>). + cast(5240, <<V1:?GLdouble,V2:?GLdouble,V1:?GLdouble,V2:?GLdouble>>). %% @spec (X1::float(),Y1::float(),X2::float(),Y2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectf(float(),float(),float(),float()) -> ok. rectf(X1,Y1,X2,Y2) -> - wxe_util:cast(5241, <<X1:?GLfloat,Y1:?GLfloat,X2:?GLfloat,Y2:?GLfloat>>). + cast(5241, <<X1:?GLfloat,Y1:?GLfloat,X2:?GLfloat,Y2:?GLfloat>>). -%% @spec (V1::{float()},V2::{float()}) -> ok +%% @spec (V1::{float(),float()},V2::{float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectfv({float(),float()},{float(),float()}) -> ok. rectfv({V1,V2},{V1,V2}) -> - wxe_util:cast(5242, <<V1:?GLfloat,V2:?GLfloat,V1:?GLfloat,V2:?GLfloat>>). + cast(5242, <<V1:?GLfloat,V2:?GLfloat,V1:?GLfloat,V2:?GLfloat>>). %% @spec (X1::integer(),Y1::integer(),X2::integer(),Y2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec recti(integer(),integer(),integer(),integer()) -> ok. recti(X1,Y1,X2,Y2) -> - wxe_util:cast(5243, <<X1:?GLint,Y1:?GLint,X2:?GLint,Y2:?GLint>>). + cast(5243, <<X1:?GLint,Y1:?GLint,X2:?GLint,Y2:?GLint>>). -%% @spec (V1::{integer()},V2::{integer()}) -> ok +%% @spec (V1::{integer(),integer()},V2::{integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectiv({integer(),integer()},{integer(),integer()}) -> ok. rectiv({V1,V2},{V1,V2}) -> - wxe_util:cast(5244, <<V1:?GLint,V2:?GLint,V1:?GLint,V2:?GLint>>). + cast(5244, <<V1:?GLint,V2:?GLint,V1:?GLint,V2:?GLint>>). %% @spec (X1::integer(),Y1::integer(),X2::integer(),Y2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rects(integer(),integer(),integer(),integer()) -> ok. rects(X1,Y1,X2,Y2) -> - wxe_util:cast(5245, <<X1:?GLshort,Y1:?GLshort,X2:?GLshort,Y2:?GLshort>>). + cast(5245, <<X1:?GLshort,Y1:?GLshort,X2:?GLshort,Y2:?GLshort>>). -%% @spec (V1::{integer()},V2::{integer()}) -> ok +%% @spec (V1::{integer(),integer()},V2::{integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRect.xml">external</a> documentation. +-spec rectsv({integer(),integer()},{integer(),integer()}) -> ok. rectsv({V1,V2},{V1,V2}) -> - wxe_util:cast(5246, <<V1:?GLshort,V2:?GLshort,V1:?GLshort,V2:?GLshort>>). + cast(5246, <<V1:?GLshort,V2:?GLshort,V1:?GLshort,V2:?GLshort>>). %% @spec (Mode::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderMode.xml">external</a> documentation. +-spec renderMode(enum()) -> integer(). renderMode(Mode) -> - wxe_util:call(5247, <<Mode:?GLenum>>). + call(5247, <<Mode:?GLenum>>). %% @spec (Angle::float(),X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml">external</a> documentation. +-spec rotated(float(),float(),float(),float()) -> ok. rotated(Angle,X,Y,Z) -> - wxe_util:cast(5248, <<Angle:?GLdouble,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5248, <<Angle:?GLdouble,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec (Angle::float(),X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRotate.xml">external</a> documentation. +-spec rotatef(float(),float(),float(),float()) -> ok. rotatef(Angle,X,Y,Z) -> - wxe_util:cast(5249, <<Angle:?GLfloat,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5249, <<Angle:?GLfloat,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScale.xml">external</a> documentation. +-spec scaled(float(),float(),float()) -> ok. scaled(X,Y,Z) -> - wxe_util:cast(5250, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5250, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScale.xml">external</a> documentation. +-spec scalef(float(),float(),float()) -> ok. scalef(X,Y,Z) -> - wxe_util:cast(5251, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5251, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml">external</a> documentation. +-spec scissor(integer(),integer(),integer(),integer()) -> ok. scissor(X,Y,Width,Height) -> - wxe_util:cast(5252, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). + cast(5252, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). -%% @spec (Size::integer(),Buffer::wx:wx_mem()) -> ok +%% @spec (Size::integer(),Buffer::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSelectBuffer.xml">external</a> documentation. +-spec selectBuffer(integer(),mem()) -> ok. selectBuffer(Size,Buffer) -> - wxe_util:send_bin(Buffer#wx_mem.bin), - wxe_util:call(5253, <<Size:?GLsizei>>). + send_bin(Buffer), + call(5253, <<Size:?GLsizei>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShadeModel.xml">external</a> documentation. +-spec shadeModel(enum()) -> ok. shadeModel(Mode) -> - wxe_util:cast(5254, <<Mode:?GLenum>>). + cast(5254, <<Mode:?GLenum>>). %% @spec (Func::enum(),Ref::integer(),Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFunc.xml">external</a> documentation. +-spec stencilFunc(enum(),integer(),integer()) -> ok. stencilFunc(Func,Ref,Mask) -> - wxe_util:cast(5255, <<Func:?GLenum,Ref:?GLint,Mask:?GLuint>>). + cast(5255, <<Func:?GLenum,Ref:?GLint,Mask:?GLuint>>). %% @spec (Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMask.xml">external</a> documentation. +-spec stencilMask(integer()) -> ok. stencilMask(Mask) -> - wxe_util:cast(5256, <<Mask:?GLuint>>). + cast(5256, <<Mask:?GLuint>>). %% @spec (Fail::enum(),Zfail::enum(),Zpass::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOp.xml">external</a> documentation. +-spec stencilOp(enum(),enum(),enum()) -> ok. stencilOp(Fail,Zfail,Zpass) -> - wxe_util:cast(5257, <<Fail:?GLenum,Zfail:?GLenum,Zpass:?GLenum>>). + cast(5257, <<Fail:?GLenum,Zfail:?GLenum,Zpass:?GLenum>>). %% @spec (S::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord1d(float()) -> ok. texCoord1d(S) -> - wxe_util:cast(5258, <<S:?GLdouble>>). + cast(5258, <<S:?GLdouble>>). %% @spec ({S}) -> ok %% @equiv texCoord1d(S) +-spec texCoord1dv({float()}) -> ok. texCoord1dv({S}) -> texCoord1d(S). %% @spec (S::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord1f(float()) -> ok. texCoord1f(S) -> - wxe_util:cast(5259, <<S:?GLfloat>>). + cast(5259, <<S:?GLfloat>>). %% @spec ({S}) -> ok %% @equiv texCoord1f(S) +-spec texCoord1fv({float()}) -> ok. texCoord1fv({S}) -> texCoord1f(S). %% @spec (S::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord1i(integer()) -> ok. texCoord1i(S) -> - wxe_util:cast(5260, <<S:?GLint>>). + cast(5260, <<S:?GLint>>). %% @spec ({S}) -> ok %% @equiv texCoord1i(S) +-spec texCoord1iv({integer()}) -> ok. texCoord1iv({S}) -> texCoord1i(S). %% @spec (S::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord1s(integer()) -> ok. texCoord1s(S) -> - wxe_util:cast(5261, <<S:?GLshort>>). + cast(5261, <<S:?GLshort>>). %% @spec ({S}) -> ok %% @equiv texCoord1s(S) +-spec texCoord1sv({integer()}) -> ok. texCoord1sv({S}) -> texCoord1s(S). %% @spec (S::float(),T::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord2d(float(),float()) -> ok. texCoord2d(S,T) -> - wxe_util:cast(5262, <<S:?GLdouble,T:?GLdouble>>). + cast(5262, <<S:?GLdouble,T:?GLdouble>>). %% @spec ({S,T}) -> ok %% @equiv texCoord2d(S,T) +-spec texCoord2dv({float(),float()}) -> ok. texCoord2dv({S,T}) -> texCoord2d(S,T). %% @spec (S::float(),T::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord2f(float(),float()) -> ok. texCoord2f(S,T) -> - wxe_util:cast(5263, <<S:?GLfloat,T:?GLfloat>>). + cast(5263, <<S:?GLfloat,T:?GLfloat>>). %% @spec ({S,T}) -> ok %% @equiv texCoord2f(S,T) +-spec texCoord2fv({float(),float()}) -> ok. texCoord2fv({S,T}) -> texCoord2f(S,T). %% @spec (S::integer(),T::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord2i(integer(),integer()) -> ok. texCoord2i(S,T) -> - wxe_util:cast(5264, <<S:?GLint,T:?GLint>>). + cast(5264, <<S:?GLint,T:?GLint>>). %% @spec ({S,T}) -> ok %% @equiv texCoord2i(S,T) +-spec texCoord2iv({integer(),integer()}) -> ok. texCoord2iv({S,T}) -> texCoord2i(S,T). %% @spec (S::integer(),T::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord2s(integer(),integer()) -> ok. texCoord2s(S,T) -> - wxe_util:cast(5265, <<S:?GLshort,T:?GLshort>>). + cast(5265, <<S:?GLshort,T:?GLshort>>). %% @spec ({S,T}) -> ok %% @equiv texCoord2s(S,T) +-spec texCoord2sv({integer(),integer()}) -> ok. texCoord2sv({S,T}) -> texCoord2s(S,T). %% @spec (S::float(),T::float(),R::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord3d(float(),float(),float()) -> ok. texCoord3d(S,T,R) -> - wxe_util:cast(5266, <<S:?GLdouble,T:?GLdouble,R:?GLdouble>>). + cast(5266, <<S:?GLdouble,T:?GLdouble,R:?GLdouble>>). %% @spec ({S,T,R}) -> ok %% @equiv texCoord3d(S,T,R) +-spec texCoord3dv({float(),float(),float()}) -> ok. texCoord3dv({S,T,R}) -> texCoord3d(S,T,R). %% @spec (S::float(),T::float(),R::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord3f(float(),float(),float()) -> ok. texCoord3f(S,T,R) -> - wxe_util:cast(5267, <<S:?GLfloat,T:?GLfloat,R:?GLfloat>>). + cast(5267, <<S:?GLfloat,T:?GLfloat,R:?GLfloat>>). %% @spec ({S,T,R}) -> ok %% @equiv texCoord3f(S,T,R) +-spec texCoord3fv({float(),float(),float()}) -> ok. texCoord3fv({S,T,R}) -> texCoord3f(S,T,R). %% @spec (S::integer(),T::integer(),R::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord3i(integer(),integer(),integer()) -> ok. texCoord3i(S,T,R) -> - wxe_util:cast(5268, <<S:?GLint,T:?GLint,R:?GLint>>). + cast(5268, <<S:?GLint,T:?GLint,R:?GLint>>). %% @spec ({S,T,R}) -> ok %% @equiv texCoord3i(S,T,R) +-spec texCoord3iv({integer(),integer(),integer()}) -> ok. texCoord3iv({S,T,R}) -> texCoord3i(S,T,R). %% @spec (S::integer(),T::integer(),R::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord3s(integer(),integer(),integer()) -> ok. texCoord3s(S,T,R) -> - wxe_util:cast(5269, <<S:?GLshort,T:?GLshort,R:?GLshort>>). + cast(5269, <<S:?GLshort,T:?GLshort,R:?GLshort>>). %% @spec ({S,T,R}) -> ok %% @equiv texCoord3s(S,T,R) +-spec texCoord3sv({integer(),integer(),integer()}) -> ok. texCoord3sv({S,T,R}) -> texCoord3s(S,T,R). %% @spec (S::float(),T::float(),R::float(),Q::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord4d(float(),float(),float(),float()) -> ok. texCoord4d(S,T,R,Q) -> - wxe_util:cast(5270, <<S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>). + cast(5270, <<S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>). %% @spec ({S,T,R,Q}) -> ok %% @equiv texCoord4d(S,T,R,Q) +-spec texCoord4dv({float(),float(),float(),float()}) -> ok. texCoord4dv({S,T,R,Q}) -> texCoord4d(S,T,R,Q). %% @spec (S::float(),T::float(),R::float(),Q::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord4f(float(),float(),float(),float()) -> ok. texCoord4f(S,T,R,Q) -> - wxe_util:cast(5271, <<S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>). + cast(5271, <<S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>). %% @spec ({S,T,R,Q}) -> ok %% @equiv texCoord4f(S,T,R,Q) +-spec texCoord4fv({float(),float(),float(),float()}) -> ok. texCoord4fv({S,T,R,Q}) -> texCoord4f(S,T,R,Q). %% @spec (S::integer(),T::integer(),R::integer(),Q::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord4i(integer(),integer(),integer(),integer()) -> ok. texCoord4i(S,T,R,Q) -> - wxe_util:cast(5272, <<S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>). + cast(5272, <<S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>). %% @spec ({S,T,R,Q}) -> ok %% @equiv texCoord4i(S,T,R,Q) +-spec texCoord4iv({integer(),integer(),integer(),integer()}) -> ok. texCoord4iv({S,T,R,Q}) -> texCoord4i(S,T,R,Q). %% @spec (S::integer(),T::integer(),R::integer(),Q::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoord.xml">external</a> documentation. +-spec texCoord4s(integer(),integer(),integer(),integer()) -> ok. texCoord4s(S,T,R,Q) -> - wxe_util:cast(5273, <<S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>). + cast(5273, <<S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>). %% @spec ({S,T,R,Q}) -> ok %% @equiv texCoord4s(S,T,R,Q) +-spec texCoord4sv({integer(),integer(),integer(),integer()}) -> ok. texCoord4sv({S,T,R,Q}) -> texCoord4s(S,T,R,Q). -%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexCoordPointer.xml">external</a> documentation. +-spec texCoordPointer(integer(),enum(),integer(),offset()|mem()) -> ok. texCoordPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5274, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5274, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); texCoordPointer(Size,Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5275, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5275, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). %% @spec (Target::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnvf.xml">external</a> documentation. +-spec texEnvf(enum(),enum(),float()) -> ok. texEnvf(Target,Pname,Param) -> - wxe_util:cast(5276, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>). + cast(5276, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>). %% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation. +-spec texEnvfv(enum(),enum(),{float()}) -> ok. texEnvfv(Target,Pname,Params) -> - wxe_util:cast(5277, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5277, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Target::enum(),Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnvi.xml">external</a> documentation. +-spec texEnvi(enum(),enum(),integer()) -> ok. texEnvi(Target,Pname,Param) -> - wxe_util:cast(5278, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>). + cast(5278, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>). %% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexEnv.xml">external</a> documentation. +-spec texEnviv(enum(),enum(),{integer()}) -> ok. texEnviv(Target,Pname,Params) -> - wxe_util:cast(5279, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5279, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Coord::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGend(enum(),enum(),float()) -> ok. texGend(Coord,Pname,Param) -> - wxe_util:cast(5280, <<Coord:?GLenum,Pname:?GLenum,Param:?GLdouble>>). + cast(5280, <<Coord:?GLenum,Pname:?GLenum,Param:?GLdouble>>). %% @spec (Coord::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGendv(enum(),enum(),{float()}) -> ok. texGendv(Coord,Pname,Params) -> - wxe_util:cast(5281, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32, + cast(5281, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint,0:32, (<< <<C:?GLdouble>> ||C <- tuple_to_list(Params)>>)/binary>>). %% @spec (Coord::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGenf(enum(),enum(),float()) -> ok. texGenf(Coord,Pname,Param) -> - wxe_util:cast(5282, <<Coord:?GLenum,Pname:?GLenum,Param:?GLfloat>>). + cast(5282, <<Coord:?GLenum,Pname:?GLenum,Param:?GLfloat>>). %% @spec (Coord::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGenfv(enum(),enum(),{float()}) -> ok. texGenfv(Coord,Pname,Params) -> - wxe_util:cast(5283, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5283, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Coord::enum(),Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGeni(enum(),enum(),integer()) -> ok. texGeni(Coord,Pname,Param) -> - wxe_util:cast(5284, <<Coord:?GLenum,Pname:?GLenum,Param:?GLint>>). + cast(5284, <<Coord:?GLenum,Pname:?GLenum,Param:?GLint>>). %% @spec (Coord::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexGen.xml">external</a> documentation. +-spec texGeniv(enum(),enum(),{integer()}) -> ok. texGeniv(Coord,Pname,Params) -> - wxe_util:cast(5285, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5285, <<Coord:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage1D.xml">external</a> documentation. +-spec texImage1D(enum(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texImage1D(Target,Level,Internalformat,Width,Border,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5286, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5286, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texImage1D(Target,Level,Internalformat,Width,Border,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5287, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5287, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml">external</a> documentation. +-spec texImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texImage2D(Target,Level,Internalformat,Width,Height,Border,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5288, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5288, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texImage2D(Target,Level,Internalformat,Width,Height,Border,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5289, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5289, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation. +-spec texParameterf(enum(),enum(),float()) -> ok. texParameterf(Target,Pname,Param) -> - wxe_util:cast(5290, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>). + cast(5290, <<Target:?GLenum,Pname:?GLenum,Param:?GLfloat>>). %% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation. +-spec texParameterfv(enum(),enum(),{float()}) -> ok. texParameterfv(Target,Pname,Params) -> - wxe_util:cast(5291, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5291, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Target::enum(),Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation. +-spec texParameteri(enum(),enum(),integer()) -> ok. texParameteri(Target,Pname,Param) -> - wxe_util:cast(5292, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>). + cast(5292, <<Target:?GLenum,Pname:?GLenum,Param:?GLint>>). %% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameter.xml">external</a> documentation. +-spec texParameteriv(enum(),enum(),{integer()}) -> ok. texParameteriv(Target,Pname,Params) -> - wxe_util:cast(5293, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5293, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage1D.xml">external</a> documentation. +-spec texSubImage1D(enum(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texSubImage1D(Target,Level,Xoffset,Width,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5294, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5294, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texSubImage1D(Target,Level,Xoffset,Width,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5295, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5295, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml">external</a> documentation. +-spec texSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5296, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5296, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5297, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5297, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml">external</a> documentation. +-spec translated(float(),float(),float()) -> ok. translated(X,Y,Z) -> - wxe_util:cast(5298, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5298, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTranslate.xml">external</a> documentation. +-spec translatef(float(),float(),float()) -> ok. translatef(X,Y,Z) -> - wxe_util:cast(5299, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5299, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex2d(float(),float()) -> ok. vertex2d(X,Y) -> - wxe_util:cast(5300, <<X:?GLdouble,Y:?GLdouble>>). + cast(5300, <<X:?GLdouble,Y:?GLdouble>>). %% @spec ({X,Y}) -> ok %% @equiv vertex2d(X,Y) +-spec vertex2dv({float(),float()}) -> ok. vertex2dv({X,Y}) -> vertex2d(X,Y). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex2f(float(),float()) -> ok. vertex2f(X,Y) -> - wxe_util:cast(5301, <<X:?GLfloat,Y:?GLfloat>>). + cast(5301, <<X:?GLfloat,Y:?GLfloat>>). %% @spec ({X,Y}) -> ok %% @equiv vertex2f(X,Y) +-spec vertex2fv({float(),float()}) -> ok. vertex2fv({X,Y}) -> vertex2f(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex2i(integer(),integer()) -> ok. vertex2i(X,Y) -> - wxe_util:cast(5302, <<X:?GLint,Y:?GLint>>). + cast(5302, <<X:?GLint,Y:?GLint>>). %% @spec ({X,Y}) -> ok %% @equiv vertex2i(X,Y) +-spec vertex2iv({integer(),integer()}) -> ok. vertex2iv({X,Y}) -> vertex2i(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex2s(integer(),integer()) -> ok. vertex2s(X,Y) -> - wxe_util:cast(5303, <<X:?GLshort,Y:?GLshort>>). + cast(5303, <<X:?GLshort,Y:?GLshort>>). %% @spec ({X,Y}) -> ok %% @equiv vertex2s(X,Y) +-spec vertex2sv({integer(),integer()}) -> ok. vertex2sv({X,Y}) -> vertex2s(X,Y). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex3d(float(),float(),float()) -> ok. vertex3d(X,Y,Z) -> - wxe_util:cast(5304, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5304, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec ({X,Y,Z}) -> ok %% @equiv vertex3d(X,Y,Z) +-spec vertex3dv({float(),float(),float()}) -> ok. vertex3dv({X,Y,Z}) -> vertex3d(X,Y,Z). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex3f(float(),float(),float()) -> ok. vertex3f(X,Y,Z) -> - wxe_util:cast(5305, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5305, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec ({X,Y,Z}) -> ok %% @equiv vertex3f(X,Y,Z) +-spec vertex3fv({float(),float(),float()}) -> ok. vertex3fv({X,Y,Z}) -> vertex3f(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex3i(integer(),integer(),integer()) -> ok. vertex3i(X,Y,Z) -> - wxe_util:cast(5306, <<X:?GLint,Y:?GLint,Z:?GLint>>). + cast(5306, <<X:?GLint,Y:?GLint,Z:?GLint>>). %% @spec ({X,Y,Z}) -> ok %% @equiv vertex3i(X,Y,Z) +-spec vertex3iv({integer(),integer(),integer()}) -> ok. vertex3iv({X,Y,Z}) -> vertex3i(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex3s(integer(),integer(),integer()) -> ok. vertex3s(X,Y,Z) -> - wxe_util:cast(5307, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). + cast(5307, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). %% @spec ({X,Y,Z}) -> ok %% @equiv vertex3s(X,Y,Z) +-spec vertex3sv({integer(),integer(),integer()}) -> ok. vertex3sv({X,Y,Z}) -> vertex3s(X,Y,Z). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex4d(float(),float(),float(),float()) -> ok. vertex4d(X,Y,Z,W) -> - wxe_util:cast(5308, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5308, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv vertex4d(X,Y,Z,W) +-spec vertex4dv({float(),float(),float(),float()}) -> ok. vertex4dv({X,Y,Z,W}) -> vertex4d(X,Y,Z,W). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex4f(float(),float(),float(),float()) -> ok. vertex4f(X,Y,Z,W) -> - wxe_util:cast(5309, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5309, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv vertex4f(X,Y,Z,W) +-spec vertex4fv({float(),float(),float(),float()}) -> ok. vertex4fv({X,Y,Z,W}) -> vertex4f(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex4i(integer(),integer(),integer(),integer()) -> ok. vertex4i(X,Y,Z,W) -> - wxe_util:cast(5310, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). + cast(5310, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv vertex4i(X,Y,Z,W) +-spec vertex4iv({integer(),integer(),integer(),integer()}) -> ok. vertex4iv({X,Y,Z,W}) -> vertex4i(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml">external</a> documentation. +-spec vertex4s(integer(),integer(),integer(),integer()) -> ok. vertex4s(X,Y,Z,W) -> - wxe_util:cast(5311, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). + cast(5311, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv vertex4s(X,Y,Z,W) +-spec vertex4sv({integer(),integer(),integer(),integer()}) -> ok. vertex4sv({X,Y,Z,W}) -> vertex4s(X,Y,Z,W). -%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml">external</a> documentation. +-spec vertexPointer(integer(),enum(),integer(),offset()|mem()) -> ok. vertexPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5312, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5312, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); vertexPointer(Size,Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5313, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5313, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). %% @spec (X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewport.xml">external</a> documentation. +-spec viewport(integer(),integer(),integer(),integer()) -> ok. viewport(X,Y,Width,Height) -> - wxe_util:cast(5314, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). + cast(5314, <<X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). %% @spec (Red::clamp(),Green::clamp(),Blue::clamp(),Alpha::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendColor.xml">external</a> documentation. +-spec blendColor(clamp(),clamp(),clamp(),clamp()) -> ok. blendColor(Red,Green,Blue,Alpha) -> - wxe_util:cast(5315, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>). + cast(5315, <<Red:?GLclampf,Green:?GLclampf,Blue:?GLclampf,Alpha:?GLclampf>>). %% @spec (Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml">external</a> documentation. +-spec blendEquation(enum()) -> ok. blendEquation(Mode) -> - wxe_util:cast(5316, <<Mode:?GLenum>>). + cast(5316, <<Mode:?GLenum>>). -%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|binary()) -> ok +%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElements.xml">external</a> documentation. +-spec drawRangeElements(enum(),integer(),integer(),integer(),enum(),offset()|mem()) -> ok. drawRangeElements(Mode,Start,End,Count,Type,Indices) when is_integer(Indices) -> - wxe_util:cast(5317, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>); + cast(5317, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint>>); drawRangeElements(Mode,Start,End,Count,Type,Indices) -> - wxe_util:send_bin(Indices), - wxe_util:cast(5318, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum>>). + send_bin(Indices), + cast(5318, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml">external</a> documentation. +-spec texImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5319, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5319, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5320, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5320, <<Target:?GLenum,Level:?GLint,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Pixels::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Pixels::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage3D.xml">external</a> documentation. +-spec texSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. texSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,Type,Pixels) when is_integer(Pixels) -> - wxe_util:cast(5321, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); + cast(5321, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Pixels:?GLuint>>); texSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,Type,Pixels) -> - wxe_util:send_bin(Pixels), - wxe_util:cast(5322, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Pixels), + cast(5322, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyTexSubImage3D.xml">external</a> documentation. +-spec copyTexSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()) -> ok. copyTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,X,Y,Width,Height) -> - wxe_util:cast(5323, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). + cast(5323, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). -%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Table::offset()|binary()) -> ok +%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Table::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTable.xml">external</a> documentation. +-spec colorTable(enum(),enum(),integer(),enum(),enum(),offset()|mem()) -> ok. colorTable(Target,Internalformat,Width,Format,Type,Table) when is_integer(Table) -> - wxe_util:cast(5324, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Table:?GLuint>>); + cast(5324, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Table:?GLuint>>); colorTable(Target,Internalformat,Width,Format,Type,Table) -> - wxe_util:send_bin(Table), - wxe_util:cast(5325, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Table), + cast(5325, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok +%% @spec (Target::enum(),Pname::enum(),Params::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTableParameter.xml">external</a> documentation. +-spec colorTableParameterfv(enum(),enum(),{float(),float(),float(),float()}) -> ok. colorTableParameterfv(Target,Pname,{P1,P2,P3,P4}) -> - wxe_util:cast(5326, <<Target:?GLenum,Pname:?GLenum,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). + cast(5326, <<Target:?GLenum,Pname:?GLenum,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). -%% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok +%% @spec (Target::enum(),Pname::enum(),Params::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorTableParameter.xml">external</a> documentation. +-spec colorTableParameteriv(enum(),enum(),{integer(),integer(),integer(),integer()}) -> ok. colorTableParameteriv(Target,Pname,{P1,P2,P3,P4}) -> - wxe_util:cast(5327, <<Target:?GLenum,Pname:?GLenum,P1:?GLint,P2:?GLint,P3:?GLint,P4:?GLint>>). + cast(5327, <<Target:?GLenum,Pname:?GLenum,P1:?GLint,P2:?GLint,P3:?GLint,P4:?GLint>>). %% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyColorTable.xml">external</a> documentation. +-spec copyColorTable(enum(),enum(),integer(),integer(),integer()) -> ok. copyColorTable(Target,Internalformat,X,Y,Width) -> - wxe_util:cast(5328, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>). + cast(5328, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>). -%% @spec (Target::enum(),Format::enum(),Type::enum(),Table::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Format::enum(),Type::enum(),Table::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTable.xml">external</a> documentation. +-spec getColorTable(enum(),enum(),enum(),mem()) -> ok. getColorTable(Target,Format,Type,Table) -> - wxe_util:send_bin(Table#wx_mem.bin), - wxe_util:call(5329, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>). + send_bin(Table), + call(5329, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {float()} +%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTableParameter.xml">external</a> documentation. +-spec getColorTableParameterfv(enum(),enum()) -> {float(),float(),float(),float()}. getColorTableParameterfv(Target,Pname) -> - wxe_util:call(5330, <<Target:?GLenum,Pname:?GLenum>>). + call(5330, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetColorTableParameter.xml">external</a> documentation. +-spec getColorTableParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getColorTableParameteriv(Target,Pname) -> - wxe_util:call(5331, <<Target:?GLenum,Pname:?GLenum>>). + call(5331, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Start::integer(),Count::integer(),Format::enum(),Type::enum(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Start::integer(),Count::integer(),Format::enum(),Type::enum(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorSubTable.xml">external</a> documentation. +-spec colorSubTable(enum(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. colorSubTable(Target,Start,Count,Format,Type,Data) when is_integer(Data) -> - wxe_util:cast(5332, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum,Data:?GLuint>>); + cast(5332, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum,Data:?GLuint>>); colorSubTable(Target,Start,Count,Format,Type,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5333, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Data), + cast(5333, <<Target:?GLenum,Start:?GLsizei,Count:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Start::integer(),X::integer(),Y::integer(),Width::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyColorSubTable.xml">external</a> documentation. +-spec copyColorSubTable(enum(),integer(),integer(),integer(),integer()) -> ok. copyColorSubTable(Target,Start,X,Y,Width) -> - wxe_util:cast(5334, <<Target:?GLenum,Start:?GLsizei,X:?GLint,Y:?GLint,Width:?GLsizei>>). + cast(5334, <<Target:?GLenum,Start:?GLsizei,X:?GLint,Y:?GLint,Width:?GLsizei>>). -%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Image::offset()|binary()) -> ok +%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Format::enum(),Type::enum(),Image::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionFilter1D.xml">external</a> documentation. +-spec convolutionFilter1D(enum(),enum(),integer(),enum(),enum(),offset()|mem()) -> ok. convolutionFilter1D(Target,Internalformat,Width,Format,Type,Image) when is_integer(Image) -> - wxe_util:cast(5335, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>); + cast(5335, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>); convolutionFilter1D(Target,Internalformat,Width,Format,Type,Image) -> - wxe_util:send_bin(Image), - wxe_util:cast(5336, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Image), + cast(5336, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Image::offset()|binary()) -> ok +%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Image::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionFilter2D.xml">external</a> documentation. +-spec convolutionFilter2D(enum(),enum(),integer(),integer(),enum(),enum(),offset()|mem()) -> ok. convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) when is_integer(Image) -> - wxe_util:cast(5337, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>); + cast(5337, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Image:?GLuint>>); convolutionFilter2D(Target,Internalformat,Width,Height,Format,Type,Image) -> - wxe_util:send_bin(Image), - wxe_util:cast(5338, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Image), + cast(5338, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation. +-spec convolutionParameterf(enum(),enum(),{float()}) -> ok. convolutionParameterf(Target,Pname,Params) -> - wxe_util:cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5339, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Target,Pname,{Params}) -> ok %% @equiv convolutionParameterf(Target,Pname,Params) +-spec convolutionParameterfv(enum(),enum(),{{float()}}) -> ok. convolutionParameterfv(Target,Pname,{Params}) -> convolutionParameterf(Target,Pname,Params). %% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glConvolutionParameter.xml">external</a> documentation. +-spec convolutionParameteri(enum(),enum(),{integer()}) -> ok. convolutionParameteri(Target,Pname,Params) -> - wxe_util:cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5340, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Target,Pname,{Params}) -> ok %% @equiv convolutionParameteri(Target,Pname,Params) +-spec convolutionParameteriv(enum(),enum(),{{integer()}}) -> ok. convolutionParameteriv(Target,Pname,{Params}) -> convolutionParameteri(Target,Pname,Params). %% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyConvolutionFilter1D.xml">external</a> documentation. +-spec copyConvolutionFilter1D(enum(),enum(),integer(),integer(),integer()) -> ok. copyConvolutionFilter1D(Target,Internalformat,X,Y,Width) -> - wxe_util:cast(5341, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>). + cast(5341, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei>>). %% @spec (Target::enum(),Internalformat::enum(),X::integer(),Y::integer(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyConvolutionFilter2D.xml">external</a> documentation. +-spec copyConvolutionFilter2D(enum(),enum(),integer(),integer(),integer(),integer()) -> ok. copyConvolutionFilter2D(Target,Internalformat,X,Y,Width,Height) -> - wxe_util:cast(5342, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). + cast(5342, <<Target:?GLenum,Internalformat:?GLenum,X:?GLint,Y:?GLint,Width:?GLsizei,Height:?GLsizei>>). -%% @spec (Target::enum(),Format::enum(),Type::enum(),Image::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Format::enum(),Type::enum(),Image::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionFilter.xml">external</a> documentation. +-spec getConvolutionFilter(enum(),enum(),enum(),mem()) -> ok. getConvolutionFilter(Target,Format,Type,Image) -> - wxe_util:send_bin(Image#wx_mem.bin), - wxe_util:call(5343, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>). + send_bin(Image), + call(5343, <<Target:?GLenum,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {float()} +%% @spec (Target::enum(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionParameter.xml">external</a> documentation. +-spec getConvolutionParameterfv(enum(),enum()) -> {float(),float(),float(),float()}. getConvolutionParameterfv(Target,Pname) -> - wxe_util:call(5344, <<Target:?GLenum,Pname:?GLenum>>). + call(5344, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetConvolutionParameter.xml">external</a> documentation. +-spec getConvolutionParameteriv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getConvolutionParameteriv(Target,Pname) -> - wxe_util:call(5345, <<Target:?GLenum,Pname:?GLenum>>). + call(5345, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Row::offset()|binary(),Column::offset()|binary()) -> ok +%% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Row::offset()|mem(),Column::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSeparableFilter2D.xml">external</a> documentation. +-spec separableFilter2D(enum(),enum(),integer(),integer(),enum(),enum(),offset()|mem(),offset()|mem()) -> ok. separableFilter2D(Target,Internalformat,Width,Height,Format,Type,Row,Column) when is_integer(Row), is_integer(Column) -> - wxe_util:cast(5346, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Row:?GLuint,Column:?GLuint>>); + cast(5346, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Row:?GLuint,Column:?GLuint>>); separableFilter2D(Target,Internalformat,Width,Height,Format,Type,Row,Column) -> - wxe_util:send_bin(Row), - wxe_util:send_bin(Column), - wxe_util:cast(5347, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Row), + send_bin(Column), + cast(5347, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). -%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogram.xml">external</a> documentation. +-spec getHistogram(enum(),0|1,enum(),enum(),mem()) -> ok. getHistogram(Target,Reset,Format,Type,Values) -> - wxe_util:send_bin(Values#wx_mem.bin), - wxe_util:call(5348, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>). + send_bin(Values), + call(5348, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Pname::enum()) -> {float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogramParameter.xml">external</a> documentation. +-spec getHistogramParameterfv(enum(),enum()) -> {float()}. getHistogramParameterfv(Target,Pname) -> - wxe_util:call(5349, <<Target:?GLenum,Pname:?GLenum>>). + call(5349, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Target::enum(),Pname::enum()) -> {integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHistogramParameter.xml">external</a> documentation. +-spec getHistogramParameteriv(enum(),enum()) -> {integer()}. getHistogramParameteriv(Target,Pname) -> - wxe_util:call(5350, <<Target:?GLenum,Pname:?GLenum>>). + call(5350, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Reset::0|1,Format::enum(),Type::enum(),Values::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmax.xml">external</a> documentation. +-spec getMinmax(enum(),0|1,enum(),enum(),mem()) -> ok. getMinmax(Target,Reset,Format,Type,Values) -> - wxe_util:send_bin(Values#wx_mem.bin), - wxe_util:call(5351, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>). + send_bin(Values), + call(5351, <<Target:?GLenum,Reset:?GLboolean,0:24,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),Pname::enum()) -> {float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmaxParameter.xml">external</a> documentation. +-spec getMinmaxParameterfv(enum(),enum()) -> {float()}. getMinmaxParameterfv(Target,Pname) -> - wxe_util:call(5352, <<Target:?GLenum,Pname:?GLenum>>). + call(5352, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Target::enum(),Pname::enum()) -> {integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMinmaxParameter.xml">external</a> documentation. +-spec getMinmaxParameteriv(enum(),enum()) -> {integer()}. getMinmaxParameteriv(Target,Pname) -> - wxe_util:call(5353, <<Target:?GLenum,Pname:?GLenum>>). + call(5353, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Target::enum(),Width::integer(),Internalformat::enum(),Sink::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glHistogram.xml">external</a> documentation. +-spec histogram(enum(),integer(),enum(),0|1) -> ok. histogram(Target,Width,Internalformat,Sink) -> - wxe_util:cast(5354, <<Target:?GLenum,Width:?GLsizei,Internalformat:?GLenum,Sink:?GLboolean>>). + cast(5354, <<Target:?GLenum,Width:?GLsizei,Internalformat:?GLenum,Sink:?GLboolean>>). %% @spec (Target::enum(),Internalformat::enum(),Sink::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinmax.xml">external</a> documentation. +-spec minmax(enum(),enum(),0|1) -> ok. minmax(Target,Internalformat,Sink) -> - wxe_util:cast(5355, <<Target:?GLenum,Internalformat:?GLenum,Sink:?GLboolean>>). + cast(5355, <<Target:?GLenum,Internalformat:?GLenum,Sink:?GLboolean>>). %% @spec (Target::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResetHistogram.xml">external</a> documentation. +-spec resetHistogram(enum()) -> ok. resetHistogram(Target) -> - wxe_util:cast(5356, <<Target:?GLenum>>). + cast(5356, <<Target:?GLenum>>). %% @spec (Target::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResetMinmax.xml">external</a> documentation. +-spec resetMinmax(enum()) -> ok. resetMinmax(Target) -> - wxe_util:cast(5357, <<Target:?GLenum>>). + cast(5357, <<Target:?GLenum>>). %% @spec (Texture::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveTexture.xml">external</a> documentation. +-spec activeTexture(enum()) -> ok. activeTexture(Texture) -> - wxe_util:cast(5358, <<Texture:?GLenum>>). + cast(5358, <<Texture:?GLenum>>). %% @spec (Value::clamp(),Invert::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleCoverage.xml">external</a> documentation. +-spec sampleCoverage(clamp(),0|1) -> ok. sampleCoverage(Value,Invert) -> - wxe_util:cast(5359, <<Value:?GLclampf,Invert:?GLboolean>>). + cast(5359, <<Value:?GLclampf,Invert:?GLboolean>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Depth::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage3D.xml">external</a> documentation. +-spec compressedTexImage3D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),integer(),offset()|mem()) -> ok. compressedTexImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5360, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5360, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexImage3D(Target,Level,Internalformat,Width,Height,Depth,Border,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5361, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5361, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Height::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage2D.xml">external</a> documentation. +-spec compressedTexImage2D(enum(),integer(),enum(),integer(),integer(),integer(),integer(),offset()|mem()) -> ok. compressedTexImage2D(Target,Level,Internalformat,Width,Height,Border,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5362, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5362, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexImage2D(Target,Level,Internalformat,Width,Height,Border,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5363, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5363, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Border::integer(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Internalformat::enum(),Width::integer(),Border::integer(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage1D.xml">external</a> documentation. +-spec compressedTexImage1D(enum(),integer(),enum(),integer(),integer(),integer(),offset()|mem()) -> ok. compressedTexImage1D(Target,Level,Internalformat,Width,Border,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5364, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5364, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexImage1D(Target,Level,Internalformat,Width,Border,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5365, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5365, <<Target:?GLenum,Level:?GLint,Internalformat:?GLenum,Width:?GLsizei,Border:?GLint,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Zoffset::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage3D.xml">external</a> documentation. +-spec compressedTexSubImage3D(enum(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok. compressedTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5366, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5366, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexSubImage3D(Target,Level,Xoffset,Yoffset,Zoffset,Width,Height,Depth,Format,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5367, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5367, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Zoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Yoffset::integer(),Width::integer(),Height::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage2D.xml">external</a> documentation. +-spec compressedTexSubImage2D(enum(),integer(),integer(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok. compressedTexSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5368, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5368, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexSubImage2D(Target,Level,Xoffset,Yoffset,Width,Height,Format,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5369, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5369, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Yoffset:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),ImageSize::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Level::integer(),Xoffset::integer(),Width::integer(),Format::enum(),ImageSize::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexSubImage1D.xml">external</a> documentation. +-spec compressedTexSubImage1D(enum(),integer(),integer(),integer(),enum(),integer(),offset()|mem()) -> ok. compressedTexSubImage1D(Target,Level,Xoffset,Width,Format,ImageSize,Data) when is_integer(Data) -> - wxe_util:cast(5370, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); + cast(5370, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei,Data:?GLuint>>); compressedTexSubImage1D(Target,Level,Xoffset,Width,Format,ImageSize,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5371, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). + send_bin(Data), + cast(5371, <<Target:?GLenum,Level:?GLint,Xoffset:?GLint,Width:?GLsizei,Format:?GLenum,ImageSize:?GLsizei>>). -%% @spec (Target::enum(),Level::integer(),Img::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Level::integer(),Img::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml">external</a> documentation. +-spec getCompressedTexImage(enum(),integer(),mem()) -> ok. getCompressedTexImage(Target,Level,Img) -> - wxe_util:send_bin(Img#wx_mem.bin), - wxe_util:call(5372, <<Target:?GLenum,Level:?GLint>>). + send_bin(Img), + call(5372, <<Target:?GLenum,Level:?GLint>>). %% @spec (Texture::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientActiveTexture.xml">external</a> documentation. +-spec clientActiveTexture(enum()) -> ok. clientActiveTexture(Texture) -> - wxe_util:cast(5373, <<Texture:?GLenum>>). + cast(5373, <<Texture:?GLenum>>). %% @spec (Target::enum(),S::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord1d(enum(),float()) -> ok. multiTexCoord1d(Target,S) -> - wxe_util:cast(5374, <<Target:?GLenum,0:32,S:?GLdouble>>). + cast(5374, <<Target:?GLenum,0:32,S:?GLdouble>>). %% @spec (Target,{S}) -> ok %% @equiv multiTexCoord1d(Target,S) +-spec multiTexCoord1dv(enum(),{float()}) -> ok. multiTexCoord1dv(Target,{S}) -> multiTexCoord1d(Target,S). %% @spec (Target::enum(),S::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord1f(enum(),float()) -> ok. multiTexCoord1f(Target,S) -> - wxe_util:cast(5375, <<Target:?GLenum,S:?GLfloat>>). + cast(5375, <<Target:?GLenum,S:?GLfloat>>). %% @spec (Target,{S}) -> ok %% @equiv multiTexCoord1f(Target,S) +-spec multiTexCoord1fv(enum(),{float()}) -> ok. multiTexCoord1fv(Target,{S}) -> multiTexCoord1f(Target,S). %% @spec (Target::enum(),S::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord1i(enum(),integer()) -> ok. multiTexCoord1i(Target,S) -> - wxe_util:cast(5376, <<Target:?GLenum,S:?GLint>>). + cast(5376, <<Target:?GLenum,S:?GLint>>). %% @spec (Target,{S}) -> ok %% @equiv multiTexCoord1i(Target,S) +-spec multiTexCoord1iv(enum(),{integer()}) -> ok. multiTexCoord1iv(Target,{S}) -> multiTexCoord1i(Target,S). %% @spec (Target::enum(),S::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord1s(enum(),integer()) -> ok. multiTexCoord1s(Target,S) -> - wxe_util:cast(5377, <<Target:?GLenum,S:?GLshort>>). + cast(5377, <<Target:?GLenum,S:?GLshort>>). %% @spec (Target,{S}) -> ok %% @equiv multiTexCoord1s(Target,S) +-spec multiTexCoord1sv(enum(),{integer()}) -> ok. multiTexCoord1sv(Target,{S}) -> multiTexCoord1s(Target,S). %% @spec (Target::enum(),S::float(),T::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord2d(enum(),float(),float()) -> ok. multiTexCoord2d(Target,S,T) -> - wxe_util:cast(5378, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble>>). + cast(5378, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble>>). %% @spec (Target,{S,T}) -> ok %% @equiv multiTexCoord2d(Target,S,T) +-spec multiTexCoord2dv(enum(),{float(),float()}) -> ok. multiTexCoord2dv(Target,{S,T}) -> multiTexCoord2d(Target,S,T). %% @spec (Target::enum(),S::float(),T::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord2f(enum(),float(),float()) -> ok. multiTexCoord2f(Target,S,T) -> - wxe_util:cast(5379, <<Target:?GLenum,S:?GLfloat,T:?GLfloat>>). + cast(5379, <<Target:?GLenum,S:?GLfloat,T:?GLfloat>>). %% @spec (Target,{S,T}) -> ok %% @equiv multiTexCoord2f(Target,S,T) +-spec multiTexCoord2fv(enum(),{float(),float()}) -> ok. multiTexCoord2fv(Target,{S,T}) -> multiTexCoord2f(Target,S,T). %% @spec (Target::enum(),S::integer(),T::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord2i(enum(),integer(),integer()) -> ok. multiTexCoord2i(Target,S,T) -> - wxe_util:cast(5380, <<Target:?GLenum,S:?GLint,T:?GLint>>). + cast(5380, <<Target:?GLenum,S:?GLint,T:?GLint>>). %% @spec (Target,{S,T}) -> ok %% @equiv multiTexCoord2i(Target,S,T) +-spec multiTexCoord2iv(enum(),{integer(),integer()}) -> ok. multiTexCoord2iv(Target,{S,T}) -> multiTexCoord2i(Target,S,T). %% @spec (Target::enum(),S::integer(),T::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord2s(enum(),integer(),integer()) -> ok. multiTexCoord2s(Target,S,T) -> - wxe_util:cast(5381, <<Target:?GLenum,S:?GLshort,T:?GLshort>>). + cast(5381, <<Target:?GLenum,S:?GLshort,T:?GLshort>>). %% @spec (Target,{S,T}) -> ok %% @equiv multiTexCoord2s(Target,S,T) +-spec multiTexCoord2sv(enum(),{integer(),integer()}) -> ok. multiTexCoord2sv(Target,{S,T}) -> multiTexCoord2s(Target,S,T). %% @spec (Target::enum(),S::float(),T::float(),R::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord3d(enum(),float(),float(),float()) -> ok. multiTexCoord3d(Target,S,T,R) -> - wxe_util:cast(5382, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble>>). + cast(5382, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble>>). %% @spec (Target,{S,T,R}) -> ok %% @equiv multiTexCoord3d(Target,S,T,R) +-spec multiTexCoord3dv(enum(),{float(),float(),float()}) -> ok. multiTexCoord3dv(Target,{S,T,R}) -> multiTexCoord3d(Target,S,T,R). %% @spec (Target::enum(),S::float(),T::float(),R::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord3f(enum(),float(),float(),float()) -> ok. multiTexCoord3f(Target,S,T,R) -> - wxe_util:cast(5383, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat>>). + cast(5383, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat>>). %% @spec (Target,{S,T,R}) -> ok %% @equiv multiTexCoord3f(Target,S,T,R) +-spec multiTexCoord3fv(enum(),{float(),float(),float()}) -> ok. multiTexCoord3fv(Target,{S,T,R}) -> multiTexCoord3f(Target,S,T,R). %% @spec (Target::enum(),S::integer(),T::integer(),R::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord3i(enum(),integer(),integer(),integer()) -> ok. multiTexCoord3i(Target,S,T,R) -> - wxe_util:cast(5384, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint>>). + cast(5384, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint>>). %% @spec (Target,{S,T,R}) -> ok %% @equiv multiTexCoord3i(Target,S,T,R) +-spec multiTexCoord3iv(enum(),{integer(),integer(),integer()}) -> ok. multiTexCoord3iv(Target,{S,T,R}) -> multiTexCoord3i(Target,S,T,R). %% @spec (Target::enum(),S::integer(),T::integer(),R::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord3s(enum(),integer(),integer(),integer()) -> ok. multiTexCoord3s(Target,S,T,R) -> - wxe_util:cast(5385, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort>>). + cast(5385, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort>>). %% @spec (Target,{S,T,R}) -> ok %% @equiv multiTexCoord3s(Target,S,T,R) +-spec multiTexCoord3sv(enum(),{integer(),integer(),integer()}) -> ok. multiTexCoord3sv(Target,{S,T,R}) -> multiTexCoord3s(Target,S,T,R). %% @spec (Target::enum(),S::float(),T::float(),R::float(),Q::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord4d(enum(),float(),float(),float(),float()) -> ok. multiTexCoord4d(Target,S,T,R,Q) -> - wxe_util:cast(5386, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>). + cast(5386, <<Target:?GLenum,0:32,S:?GLdouble,T:?GLdouble,R:?GLdouble,Q:?GLdouble>>). %% @spec (Target,{S,T,R,Q}) -> ok %% @equiv multiTexCoord4d(Target,S,T,R,Q) +-spec multiTexCoord4dv(enum(),{float(),float(),float(),float()}) -> ok. multiTexCoord4dv(Target,{S,T,R,Q}) -> multiTexCoord4d(Target,S,T,R,Q). %% @spec (Target::enum(),S::float(),T::float(),R::float(),Q::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord4f(enum(),float(),float(),float(),float()) -> ok. multiTexCoord4f(Target,S,T,R,Q) -> - wxe_util:cast(5387, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>). + cast(5387, <<Target:?GLenum,S:?GLfloat,T:?GLfloat,R:?GLfloat,Q:?GLfloat>>). %% @spec (Target,{S,T,R,Q}) -> ok %% @equiv multiTexCoord4f(Target,S,T,R,Q) +-spec multiTexCoord4fv(enum(),{float(),float(),float(),float()}) -> ok. multiTexCoord4fv(Target,{S,T,R,Q}) -> multiTexCoord4f(Target,S,T,R,Q). %% @spec (Target::enum(),S::integer(),T::integer(),R::integer(),Q::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord4i(enum(),integer(),integer(),integer(),integer()) -> ok. multiTexCoord4i(Target,S,T,R,Q) -> - wxe_util:cast(5388, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>). + cast(5388, <<Target:?GLenum,S:?GLint,T:?GLint,R:?GLint,Q:?GLint>>). %% @spec (Target,{S,T,R,Q}) -> ok %% @equiv multiTexCoord4i(Target,S,T,R,Q) +-spec multiTexCoord4iv(enum(),{integer(),integer(),integer(),integer()}) -> ok. multiTexCoord4iv(Target,{S,T,R,Q}) -> multiTexCoord4i(Target,S,T,R,Q). %% @spec (Target::enum(),S::integer(),T::integer(),R::integer(),Q::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiTexCoord.xml">external</a> documentation. +-spec multiTexCoord4s(enum(),integer(),integer(),integer(),integer()) -> ok. multiTexCoord4s(Target,S,T,R,Q) -> - wxe_util:cast(5389, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>). + cast(5389, <<Target:?GLenum,S:?GLshort,T:?GLshort,R:?GLshort,Q:?GLshort>>). %% @spec (Target,{S,T,R,Q}) -> ok %% @equiv multiTexCoord4s(Target,S,T,R,Q) +-spec multiTexCoord4sv(enum(),{integer(),integer(),integer(),integer()}) -> ok. multiTexCoord4sv(Target,{S,T,R,Q}) -> multiTexCoord4s(Target,S,T,R,Q). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrix.xml">external</a> documentation. +-spec loadTransposeMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); loadTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5390, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrix.xml">external</a> documentation. +-spec loadTransposeMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); loadTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5391, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrix.xml">external</a> documentation. +-spec multTransposeMatrixf({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); multTransposeMatrixf({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5392, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrix.xml">external</a> documentation. +-spec multTransposeMatrixd({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); multTransposeMatrixd({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5393, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). %% @spec (SfactorRGB::enum(),DfactorRGB::enum(),SfactorAlpha::enum(),DfactorAlpha::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml">external</a> documentation. +-spec blendFuncSeparate(enum(),enum(),enum(),enum()) -> ok. blendFuncSeparate(SfactorRGB,DfactorRGB,SfactorAlpha,DfactorAlpha) -> - wxe_util:cast(5394, <<SfactorRGB:?GLenum,DfactorRGB:?GLenum,SfactorAlpha:?GLenum,DfactorAlpha:?GLenum>>). + cast(5394, <<SfactorRGB:?GLenum,DfactorRGB:?GLenum,SfactorAlpha:?GLenum,DfactorAlpha:?GLenum>>). %% @spec (Mode::enum(),First::[integer()],Count::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultiDrawArrays.xml">external</a> documentation. +-spec multiDrawArrays(enum(),[integer()],[integer()]) -> ok. multiDrawArrays(Mode,First,Count) -> - wxe_util:cast(5395, <<Mode:?GLenum,(length(First)):?GLuint, + cast(5395, <<Mode:?GLenum,(length(First)):?GLuint, (<< <<C:?GLint>> || C <- First>>)/binary,0:(((length(First)) rem 2)*32),(length(Count)):?GLuint, (<< <<C:?GLsizei>> || C <- Count>>)/binary,0:(((1+length(Count)) rem 2)*32)>>). %% @spec (Pname::enum(),Param::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation. +-spec pointParameterf(enum(),float()) -> ok. pointParameterf(Pname,Param) -> - wxe_util:cast(5396, <<Pname:?GLenum,Param:?GLfloat>>). + cast(5396, <<Pname:?GLenum,Param:?GLfloat>>). %% @spec (Pname::enum(),Params::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation. +-spec pointParameterfv(enum(),{float()}) -> ok. pointParameterfv(Pname,Params) -> - wxe_util:cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5397, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Pname::enum(),Param::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation. +-spec pointParameteri(enum(),integer()) -> ok. pointParameteri(Pname,Param) -> - wxe_util:cast(5398, <<Pname:?GLenum,Param:?GLint>>). + cast(5398, <<Pname:?GLenum,Param:?GLint>>). %% @spec (Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPointParameter.xml">external</a> documentation. +-spec pointParameteriv(enum(),{integer()}) -> ok. pointParameteriv(Pname,Params) -> - wxe_util:cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint, + cast(5399, <<Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((0+size(Params)) rem 2)*32)>>). %% @spec (Coord::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation. +-spec fogCoordf(float()) -> ok. fogCoordf(Coord) -> - wxe_util:cast(5400, <<Coord:?GLfloat>>). + cast(5400, <<Coord:?GLfloat>>). %% @spec ({Coord}) -> ok %% @equiv fogCoordf(Coord) +-spec fogCoordfv({float()}) -> ok. fogCoordfv({Coord}) -> fogCoordf(Coord). %% @spec (Coord::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoord.xml">external</a> documentation. +-spec fogCoordd(float()) -> ok. fogCoordd(Coord) -> - wxe_util:cast(5401, <<Coord:?GLdouble>>). + cast(5401, <<Coord:?GLdouble>>). %% @spec ({Coord}) -> ok %% @equiv fogCoordd(Coord) +-spec fogCoorddv({float()}) -> ok. fogCoorddv({Coord}) -> fogCoordd(Coord). -%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFogCoordPointer.xml">external</a> documentation. +-spec fogCoordPointer(enum(),integer(),offset()|mem()) -> ok. fogCoordPointer(Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5402, <<Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); fogCoordPointer(Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5403, <<Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5403, <<Type:?GLenum,Stride:?GLsizei>>). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3b(integer(),integer(),integer()) -> ok. secondaryColor3b(Red,Green,Blue) -> - wxe_util:cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>). + cast(5404, <<Red:?GLbyte,Green:?GLbyte,Blue:?GLbyte>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3b(Red,Green,Blue) +-spec secondaryColor3bv({integer(),integer(),integer()}) -> ok. secondaryColor3bv({Red,Green,Blue}) -> secondaryColor3b(Red,Green,Blue). %% @spec (Red::float(),Green::float(),Blue::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3d(float(),float(),float()) -> ok. secondaryColor3d(Red,Green,Blue) -> - wxe_util:cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>). + cast(5405, <<Red:?GLdouble,Green:?GLdouble,Blue:?GLdouble>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3d(Red,Green,Blue) +-spec secondaryColor3dv({float(),float(),float()}) -> ok. secondaryColor3dv({Red,Green,Blue}) -> secondaryColor3d(Red,Green,Blue). %% @spec (Red::float(),Green::float(),Blue::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3f(float(),float(),float()) -> ok. secondaryColor3f(Red,Green,Blue) -> - wxe_util:cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>). + cast(5406, <<Red:?GLfloat,Green:?GLfloat,Blue:?GLfloat>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3f(Red,Green,Blue) +-spec secondaryColor3fv({float(),float(),float()}) -> ok. secondaryColor3fv({Red,Green,Blue}) -> secondaryColor3f(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3i(integer(),integer(),integer()) -> ok. secondaryColor3i(Red,Green,Blue) -> - wxe_util:cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>). + cast(5407, <<Red:?GLint,Green:?GLint,Blue:?GLint>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3i(Red,Green,Blue) +-spec secondaryColor3iv({integer(),integer(),integer()}) -> ok. secondaryColor3iv({Red,Green,Blue}) -> secondaryColor3i(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3s(integer(),integer(),integer()) -> ok. secondaryColor3s(Red,Green,Blue) -> - wxe_util:cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>). + cast(5408, <<Red:?GLshort,Green:?GLshort,Blue:?GLshort>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3s(Red,Green,Blue) +-spec secondaryColor3sv({integer(),integer(),integer()}) -> ok. secondaryColor3sv({Red,Green,Blue}) -> secondaryColor3s(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3ub(integer(),integer(),integer()) -> ok. secondaryColor3ub(Red,Green,Blue) -> - wxe_util:cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>). + cast(5409, <<Red:?GLubyte,Green:?GLubyte,Blue:?GLubyte>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3ub(Red,Green,Blue) +-spec secondaryColor3ubv({integer(),integer(),integer()}) -> ok. secondaryColor3ubv({Red,Green,Blue}) -> secondaryColor3ub(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3ui(integer(),integer(),integer()) -> ok. secondaryColor3ui(Red,Green,Blue) -> - wxe_util:cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>). + cast(5410, <<Red:?GLuint,Green:?GLuint,Blue:?GLuint>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3ui(Red,Green,Blue) +-spec secondaryColor3uiv({integer(),integer(),integer()}) -> ok. secondaryColor3uiv({Red,Green,Blue}) -> secondaryColor3ui(Red,Green,Blue). %% @spec (Red::integer(),Green::integer(),Blue::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColor.xml">external</a> documentation. +-spec secondaryColor3us(integer(),integer(),integer()) -> ok. secondaryColor3us(Red,Green,Blue) -> - wxe_util:cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>). + cast(5411, <<Red:?GLushort,Green:?GLushort,Blue:?GLushort>>). %% @spec ({Red,Green,Blue}) -> ok %% @equiv secondaryColor3us(Red,Green,Blue) +-spec secondaryColor3usv({integer(),integer(),integer()}) -> ok. secondaryColor3usv({Red,Green,Blue}) -> secondaryColor3us(Red,Green,Blue). -%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSecondaryColorPointer.xml">external</a> documentation. +-spec secondaryColorPointer(integer(),enum(),integer(),offset()|mem()) -> ok. secondaryColorPointer(Size,Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5412, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); secondaryColorPointer(Size,Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5413, <<Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos2d(float(),float()) -> ok. windowPos2d(X,Y) -> - wxe_util:cast(5414, <<X:?GLdouble,Y:?GLdouble>>). + cast(5414, <<X:?GLdouble,Y:?GLdouble>>). %% @spec ({X,Y}) -> ok %% @equiv windowPos2d(X,Y) +-spec windowPos2dv({float(),float()}) -> ok. windowPos2dv({X,Y}) -> windowPos2d(X,Y). %% @spec (X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos2f(float(),float()) -> ok. windowPos2f(X,Y) -> - wxe_util:cast(5415, <<X:?GLfloat,Y:?GLfloat>>). + cast(5415, <<X:?GLfloat,Y:?GLfloat>>). %% @spec ({X,Y}) -> ok %% @equiv windowPos2f(X,Y) +-spec windowPos2fv({float(),float()}) -> ok. windowPos2fv({X,Y}) -> windowPos2f(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos2i(integer(),integer()) -> ok. windowPos2i(X,Y) -> - wxe_util:cast(5416, <<X:?GLint,Y:?GLint>>). + cast(5416, <<X:?GLint,Y:?GLint>>). %% @spec ({X,Y}) -> ok %% @equiv windowPos2i(X,Y) +-spec windowPos2iv({integer(),integer()}) -> ok. windowPos2iv({X,Y}) -> windowPos2i(X,Y). %% @spec (X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos2s(integer(),integer()) -> ok. windowPos2s(X,Y) -> - wxe_util:cast(5417, <<X:?GLshort,Y:?GLshort>>). + cast(5417, <<X:?GLshort,Y:?GLshort>>). %% @spec ({X,Y}) -> ok %% @equiv windowPos2s(X,Y) +-spec windowPos2sv({integer(),integer()}) -> ok. windowPos2sv({X,Y}) -> windowPos2s(X,Y). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos3d(float(),float(),float()) -> ok. windowPos3d(X,Y,Z) -> - wxe_util:cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5418, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec ({X,Y,Z}) -> ok %% @equiv windowPos3d(X,Y,Z) +-spec windowPos3dv({float(),float(),float()}) -> ok. windowPos3dv({X,Y,Z}) -> windowPos3d(X,Y,Z). %% @spec (X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos3f(float(),float(),float()) -> ok. windowPos3f(X,Y,Z) -> - wxe_util:cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5419, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec ({X,Y,Z}) -> ok %% @equiv windowPos3f(X,Y,Z) +-spec windowPos3fv({float(),float(),float()}) -> ok. windowPos3fv({X,Y,Z}) -> windowPos3f(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos3i(integer(),integer(),integer()) -> ok. windowPos3i(X,Y,Z) -> - wxe_util:cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>). + cast(5420, <<X:?GLint,Y:?GLint,Z:?GLint>>). %% @spec ({X,Y,Z}) -> ok %% @equiv windowPos3i(X,Y,Z) +-spec windowPos3iv({integer(),integer(),integer()}) -> ok. windowPos3iv({X,Y,Z}) -> windowPos3i(X,Y,Z). %% @spec (X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos.xml">external</a> documentation. +-spec windowPos3s(integer(),integer(),integer()) -> ok. windowPos3s(X,Y,Z) -> - wxe_util:cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). + cast(5421, <<X:?GLshort,Y:?GLshort,Z:?GLshort>>). %% @spec ({X,Y,Z}) -> ok %% @equiv windowPos3s(X,Y,Z) +-spec windowPos3sv({integer(),integer(),integer()}) -> ok. windowPos3sv({X,Y,Z}) -> windowPos3s(X,Y,Z). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenQueries.xml">external</a> documentation. +-spec genQueries(integer()) -> [integer()]. genQueries(N) -> - wxe_util:call(5422, <<N:?GLsizei>>). + call(5422, <<N:?GLsizei>>). %% @spec (Ids::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteQueries.xml">external</a> documentation. +-spec deleteQueries([integer()]) -> ok. deleteQueries(Ids) -> - wxe_util:cast(5423, <<(length(Ids)):?GLuint, + cast(5423, <<(length(Ids)):?GLuint, (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>). %% @spec (Id::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsQuery.xml">external</a> documentation. +-spec isQuery(integer()) -> 0|1. isQuery(Id) -> - wxe_util:call(5424, <<Id:?GLuint>>). + call(5424, <<Id:?GLuint>>). %% @spec (Target::enum(),Id::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQuery.xml">external</a> documentation. +-spec beginQuery(enum(),integer()) -> ok. beginQuery(Target,Id) -> - wxe_util:cast(5425, <<Target:?GLenum,Id:?GLuint>>). + cast(5425, <<Target:?GLenum,Id:?GLuint>>). %% @spec (Target::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndQuery.xml">external</a> documentation. +-spec endQuery(enum()) -> ok. endQuery(Target) -> - wxe_util:cast(5426, <<Target:?GLenum>>). + cast(5426, <<Target:?GLenum>>). %% @spec (Target::enum(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQuery.xml">external</a> documentation. +-spec getQueryiv(enum(),enum()) -> integer(). getQueryiv(Target,Pname) -> - wxe_util:call(5427, <<Target:?GLenum,Pname:?GLenum>>). + call(5427, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Id::integer(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation. +-spec getQueryObjectiv(integer(),enum()) -> integer(). getQueryObjectiv(Id,Pname) -> - wxe_util:call(5428, <<Id:?GLuint,Pname:?GLenum>>). + call(5428, <<Id:?GLuint,Pname:?GLenum>>). %% @spec (Id::integer(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObject.xml">external</a> documentation. +-spec getQueryObjectuiv(integer(),enum()) -> integer(). getQueryObjectuiv(Id,Pname) -> - wxe_util:call(5429, <<Id:?GLuint,Pname:?GLenum>>). + call(5429, <<Id:?GLuint,Pname:?GLenum>>). %% @spec (Target::enum(),Buffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBuffer.xml">external</a> documentation. +-spec bindBuffer(enum(),integer()) -> ok. bindBuffer(Target,Buffer) -> - wxe_util:cast(5430, <<Target:?GLenum,Buffer:?GLuint>>). + cast(5430, <<Target:?GLenum,Buffer:?GLuint>>). %% @spec (Buffers::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteBuffers.xml">external</a> documentation. +-spec deleteBuffers([integer()]) -> ok. deleteBuffers(Buffers) -> - wxe_util:cast(5431, <<(length(Buffers)):?GLuint, + cast(5431, <<(length(Buffers)):?GLuint, (<< <<C:?GLuint>> || C <- Buffers>>)/binary,0:(((1+length(Buffers)) rem 2)*32)>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenBuffers.xml">external</a> documentation. +-spec genBuffers(integer()) -> [integer()]. genBuffers(N) -> - wxe_util:call(5432, <<N:?GLsizei>>). + call(5432, <<N:?GLsizei>>). %% @spec (Buffer::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsBuffer.xml">external</a> documentation. +-spec isBuffer(integer()) -> 0|1. isBuffer(Buffer) -> - wxe_util:call(5433, <<Buffer:?GLuint>>). + call(5433, <<Buffer:?GLuint>>). -%% @spec (Target::enum(),Size::integer(),Data::offset()|binary(),Usage::enum()) -> ok +%% @spec (Target::enum(),Size::integer(),Data::offset()|mem(),Usage::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml">external</a> documentation. +-spec bufferData(enum(),integer(),offset()|mem(),enum()) -> ok. bufferData(Target,Size,Data,Usage) when is_integer(Data) -> - wxe_util:cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>); + cast(5434, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Data:?GLuint,Usage:?GLenum>>); bufferData(Target,Size,Data,Usage) -> - wxe_util:send_bin(Data), - wxe_util:cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>). + send_bin(Data), + cast(5435, <<Target:?GLenum,0:32,Size:?GLsizeiptr,Usage:?GLenum>>). -%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::offset()|binary()) -> ok +%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBufferSubData.xml">external</a> documentation. +-spec bufferSubData(enum(),integer(),integer(),offset()|mem()) -> ok. bufferSubData(Target,Offset,Size,Data) when is_integer(Data) -> - wxe_util:cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>); + cast(5436, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr,Data:?GLuint>>); bufferSubData(Target,Offset,Size,Data) -> - wxe_util:send_bin(Data), - wxe_util:cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). + send_bin(Data), + cast(5437, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). -%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Offset::integer(),Size::integer(),Data::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferSubData.xml">external</a> documentation. +-spec getBufferSubData(enum(),integer(),integer(),mem()) -> ok. getBufferSubData(Target,Offset,Size,Data) -> - wxe_util:send_bin(Data#wx_mem.bin), - wxe_util:call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). + send_bin(Data), + call(5438, <<Target:?GLenum,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). %% @spec (Target::enum(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteriv.xml">external</a> documentation. +-spec getBufferParameteriv(enum(),enum()) -> integer(). getBufferParameteriv(Target,Pname) -> - wxe_util:call(5439, <<Target:?GLenum,Pname:?GLenum>>). + call(5439, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (ModeRGB::enum(),ModeAlpha::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation. +-spec blendEquationSeparate(enum(),enum()) -> ok. blendEquationSeparate(ModeRGB,ModeAlpha) -> - wxe_util:cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>). + cast(5440, <<ModeRGB:?GLenum,ModeAlpha:?GLenum>>). %% @spec (Bufs::[enum()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffers.xml">external</a> documentation. +-spec drawBuffers([enum()]) -> ok. drawBuffers(Bufs) -> - wxe_util:cast(5441, <<(length(Bufs)):?GLuint, + cast(5441, <<(length(Bufs)):?GLuint, (<< <<C:?GLenum>> || C <- Bufs>>)/binary,0:(((1+length(Bufs)) rem 2)*32)>>). %% @spec (Face::enum(),Sfail::enum(),Dpfail::enum(),Dppass::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilOpSeparate.xml">external</a> documentation. +-spec stencilOpSeparate(enum(),enum(),enum(),enum()) -> ok. stencilOpSeparate(Face,Sfail,Dpfail,Dppass) -> - wxe_util:cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>). + cast(5442, <<Face:?GLenum,Sfail:?GLenum,Dpfail:?GLenum,Dppass:?GLenum>>). -%% @spec (Frontfunc::enum(),Backfunc::enum(),Ref::integer(),Mask::integer()) -> ok +%% @spec (Face::enum(),Func::enum(),Ref::integer(),Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilFuncSeparate.xml">external</a> documentation. -stencilFuncSeparate(Frontfunc,Backfunc,Ref,Mask) -> - wxe_util:cast(5443, <<Frontfunc:?GLenum,Backfunc:?GLenum,Ref:?GLint,Mask:?GLuint>>). +-spec stencilFuncSeparate(enum(),enum(),integer(),integer()) -> ok. +stencilFuncSeparate(Face,Func,Ref,Mask) -> + cast(5443, <<Face:?GLenum,Func:?GLenum,Ref:?GLint,Mask:?GLuint>>). %% @spec (Face::enum(),Mask::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilMaskSeparate.xml">external</a> documentation. +-spec stencilMaskSeparate(enum(),integer()) -> ok. stencilMaskSeparate(Face,Mask) -> - wxe_util:cast(5444, <<Face:?GLenum,Mask:?GLuint>>). + cast(5444, <<Face:?GLenum,Mask:?GLuint>>). %% @spec (Program::integer(),Shader::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachShader.xml">external</a> documentation. +-spec attachShader(integer(),integer()) -> ok. attachShader(Program,Shader) -> - wxe_util:cast(5445, <<Program:?GLuint,Shader:?GLuint>>). + cast(5445, <<Program:?GLuint,Shader:?GLuint>>). %% @spec (Program::integer(),Index::integer(),Name::string()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocation.xml">external</a> documentation. +-spec bindAttribLocation(integer(),integer(),string()) -> ok. bindAttribLocation(Program,Index,Name) -> - wxe_util:cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + cast(5446, <<Program:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). %% @spec (Shader::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShader.xml">external</a> documentation. +-spec compileShader(integer()) -> ok. compileShader(Shader) -> - wxe_util:cast(5447, <<Shader:?GLuint>>). + cast(5447, <<Shader:?GLuint>>). %% @spec () -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgram.xml">external</a> documentation. +-spec createProgram() -> integer(). createProgram() -> - wxe_util:call(5448, <<>>). + call(5448, <<>>). %% @spec (Type::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShader.xml">external</a> documentation. +-spec createShader(enum()) -> integer(). createShader(Type) -> - wxe_util:call(5449, <<Type:?GLenum>>). + call(5449, <<Type:?GLenum>>). %% @spec (Program::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgram.xml">external</a> documentation. +-spec deleteProgram(integer()) -> ok. deleteProgram(Program) -> - wxe_util:cast(5450, <<Program:?GLuint>>). + cast(5450, <<Program:?GLuint>>). %% @spec (Shader::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteShader.xml">external</a> documentation. +-spec deleteShader(integer()) -> ok. deleteShader(Shader) -> - wxe_util:cast(5451, <<Shader:?GLuint>>). + cast(5451, <<Shader:?GLuint>>). %% @spec (Program::integer(),Shader::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachShader.xml">external</a> documentation. +-spec detachShader(integer(),integer()) -> ok. detachShader(Program,Shader) -> - wxe_util:cast(5452, <<Program:?GLuint,Shader:?GLuint>>). + cast(5452, <<Program:?GLuint,Shader:?GLuint>>). %% @spec (Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisableVertexAttribArray.xml">external</a> documentation. +-spec disableVertexAttribArray(integer()) -> ok. disableVertexAttribArray(Index) -> - wxe_util:cast(5453, <<Index:?GLuint>>). + cast(5453, <<Index:?GLuint>>). %% @spec (Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml">external</a> documentation. +-spec enableVertexAttribArray(integer()) -> ok. enableVertexAttribArray(Index) -> - wxe_util:cast(5454, <<Index:?GLuint>>). + cast(5454, <<Index:?GLuint>>). %% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttrib.xml">external</a> documentation. +-spec getActiveAttrib(integer(),integer(),integer()) -> {integer(),enum(),string()}. getActiveAttrib(Program,Index,BufSize) -> - wxe_util:call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). + call(5455, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). %% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniform.xml">external</a> documentation. +-spec getActiveUniform(integer(),integer(),integer()) -> {integer(),enum(),string()}. getActiveUniform(Program,Index,BufSize) -> - wxe_util:call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). + call(5456, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). %% @spec (Program::integer(),MaxCount::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedShaders.xml">external</a> documentation. +-spec getAttachedShaders(integer(),integer()) -> [integer()]. getAttachedShaders(Program,MaxCount) -> - wxe_util:call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>). + call(5457, <<Program:?GLuint,MaxCount:?GLsizei>>). %% @spec (Program::integer(),Name::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml">external</a> documentation. +-spec getAttribLocation(integer(),string()) -> integer(). getAttribLocation(Program,Name) -> - wxe_util:call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + call(5458, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). %% @spec (Program::integer(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgram.xml">external</a> documentation. +-spec getProgramiv(integer(),enum()) -> integer(). getProgramiv(Program,Pname) -> - wxe_util:call(5459, <<Program:?GLuint,Pname:?GLenum>>). + call(5459, <<Program:?GLuint,Pname:?GLenum>>). %% @spec (Program::integer(),BufSize::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramInfoLog.xml">external</a> documentation. +-spec getProgramInfoLog(integer(),integer()) -> string(). getProgramInfoLog(Program,BufSize) -> - wxe_util:call(5460, <<Program:?GLuint,BufSize:?GLsizei>>). + call(5460, <<Program:?GLuint,BufSize:?GLsizei>>). %% @spec (Shader::integer(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShader.xml">external</a> documentation. +-spec getShaderiv(integer(),enum()) -> integer(). getShaderiv(Shader,Pname) -> - wxe_util:call(5461, <<Shader:?GLuint,Pname:?GLenum>>). + call(5461, <<Shader:?GLuint,Pname:?GLenum>>). %% @spec (Shader::integer(),BufSize::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderInfoLog.xml">external</a> documentation. +-spec getShaderInfoLog(integer(),integer()) -> string(). getShaderInfoLog(Shader,BufSize) -> - wxe_util:call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>). + call(5462, <<Shader:?GLuint,BufSize:?GLsizei>>). %% @spec (Shader::integer(),BufSize::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSource.xml">external</a> documentation. +-spec getShaderSource(integer(),integer()) -> string(). getShaderSource(Shader,BufSize) -> - wxe_util:call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>). + call(5463, <<Shader:?GLuint,BufSize:?GLsizei>>). %% @spec (Program::integer(),Name::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml">external</a> documentation. +-spec getUniformLocation(integer(),string()) -> integer(). getUniformLocation(Program,Name) -> - wxe_util:call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + call(5464, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). -%% @spec (Program::integer(),Location::integer()) -> {float()} +%% @spec (Program::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation. +-spec getUniformfv(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}. getUniformfv(Program,Location) -> - wxe_util:call(5465, <<Program:?GLuint,Location:?GLint>>). + call(5465, <<Program:?GLuint,Location:?GLint>>). -%% @spec (Program::integer(),Location::integer()) -> {integer()} +%% @spec (Program::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation. +-spec getUniformiv(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}. getUniformiv(Program,Location) -> - wxe_util:call(5466, <<Program:?GLuint,Location:?GLint>>). + call(5466, <<Program:?GLuint,Location:?GLint>>). -%% @spec (Index::integer(),Pname::enum()) -> {float()} +%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation. +-spec getVertexAttribdv(integer(),enum()) -> {float(),float(),float(),float()}. getVertexAttribdv(Index,Pname) -> - wxe_util:call(5467, <<Index:?GLuint,Pname:?GLenum>>). + call(5467, <<Index:?GLuint,Pname:?GLenum>>). -%% @spec (Index::integer(),Pname::enum()) -> {float()} +%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation. +-spec getVertexAttribfv(integer(),enum()) -> {float(),float(),float(),float()}. getVertexAttribfv(Index,Pname) -> - wxe_util:call(5468, <<Index:?GLuint,Pname:?GLenum>>). + call(5468, <<Index:?GLuint,Pname:?GLenum>>). -%% @spec (Index::integer(),Pname::enum()) -> {integer()} +%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttrib.xml">external</a> documentation. +-spec getVertexAttribiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}. getVertexAttribiv(Index,Pname) -> - wxe_util:call(5469, <<Index:?GLuint,Pname:?GLenum>>). + call(5469, <<Index:?GLuint,Pname:?GLenum>>). %% @spec (Program::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgram.xml">external</a> documentation. +-spec isProgram(integer()) -> 0|1. isProgram(Program) -> - wxe_util:call(5470, <<Program:?GLuint>>). + call(5470, <<Program:?GLuint>>). %% @spec (Shader::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsShader.xml">external</a> documentation. +-spec isShader(integer()) -> 0|1. isShader(Shader) -> - wxe_util:call(5471, <<Shader:?GLuint>>). + call(5471, <<Shader:?GLuint>>). %% @spec (Program::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgram.xml">external</a> documentation. +-spec linkProgram(integer()) -> ok. linkProgram(Program) -> - wxe_util:cast(5472, <<Program:?GLuint>>). + cast(5472, <<Program:?GLuint>>). %% @spec (Shader::integer(),String::[string()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSource.xml">external</a> documentation. +-spec shaderSource(integer(),[string()]) -> ok. shaderSource(Shader,String) -> StringTemp = list_to_binary([[Str|[0]] || Str <- String ]), - wxe_util:cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>). + cast(5473, <<Shader:?GLuint,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+0) rem 8)) rem 8)>>). %% @spec (Program::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgram.xml">external</a> documentation. +-spec useProgram(integer()) -> ok. useProgram(Program) -> - wxe_util:cast(5474, <<Program:?GLuint>>). + cast(5474, <<Program:?GLuint>>). %% @spec (Location::integer(),V0::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1f(integer(),float()) -> ok. uniform1f(Location,V0) -> - wxe_util:cast(5475, <<Location:?GLint,V0:?GLfloat>>). + cast(5475, <<Location:?GLint,V0:?GLfloat>>). %% @spec (Location::integer(),V0::float(),V1::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2f(integer(),float(),float()) -> ok. uniform2f(Location,V0,V1) -> - wxe_util:cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>). + cast(5476, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat>>). %% @spec (Location::integer(),V0::float(),V1::float(),V2::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3f(integer(),float(),float(),float()) -> ok. uniform3f(Location,V0,V1,V2) -> - wxe_util:cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>). + cast(5477, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>). %% @spec (Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4f(integer(),float(),float(),float(),float()) -> ok. uniform4f(Location,V0,V1,V2,V3) -> - wxe_util:cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>). + cast(5478, <<Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>). %% @spec (Location::integer(),V0::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1i(integer(),integer()) -> ok. uniform1i(Location,V0) -> - wxe_util:cast(5479, <<Location:?GLint,V0:?GLint>>). + cast(5479, <<Location:?GLint,V0:?GLint>>). %% @spec (Location::integer(),V0::integer(),V1::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2i(integer(),integer(),integer()) -> ok. uniform2i(Location,V0,V1) -> - wxe_util:cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>). + cast(5480, <<Location:?GLint,V0:?GLint,V1:?GLint>>). %% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3i(integer(),integer(),integer(),integer()) -> ok. uniform3i(Location,V0,V1,V2) -> - wxe_util:cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>). + cast(5481, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>). %% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4i(integer(),integer(),integer(),integer(),integer()) -> ok. uniform4i(Location,V0,V1,V2,V3) -> - wxe_util:cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>). + cast(5482, <<Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>). %% @spec (Location::integer(),Value::[float()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1fv(integer(),[float()]) -> ok. uniform1fv(Location,Value) -> - wxe_util:cast(5483, <<Location:?GLint,(length(Value)):?GLuint, + cast(5483, <<Location:?GLint,(length(Value)):?GLuint, (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>). -%% @spec (Location::integer(),Value::[{float()}]) -> ok +%% @spec (Location::integer(),Value::[{float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2fv(integer(),[{float(),float()}]) -> ok. uniform2fv(Location,Value) -> - wxe_util:cast(5484, <<Location:?GLint,(length(Value)):?GLuint, + cast(5484, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{float()}]) -> ok +%% @spec (Location::integer(),Value::[{float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3fv(integer(),[{float(),float(),float()}]) -> ok. uniform3fv(Location,Value) -> - wxe_util:cast(5485, <<Location:?GLint,(length(Value)):?GLuint, + cast(5485, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{float()}]) -> ok +%% @spec (Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4fv(integer(),[{float(),float(),float(),float()}]) -> ok. uniform4fv(Location,Value) -> - wxe_util:cast(5486, <<Location:?GLint,(length(Value)):?GLuint, + cast(5486, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>). %% @spec (Location::integer(),Value::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1iv(integer(),[integer()]) -> ok. uniform1iv(Location,Value) -> - wxe_util:cast(5487, <<Location:?GLint,(length(Value)):?GLuint, + cast(5487, <<Location:?GLint,(length(Value)):?GLuint, (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2iv(integer(),[{integer(),integer()}]) -> ok. uniform2iv(Location,Value) -> - wxe_util:cast(5488, <<Location:?GLint,(length(Value)):?GLuint, + cast(5488, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3iv(integer(),[{integer(),integer(),integer()}]) -> ok. uniform3iv(Location,Value) -> - wxe_util:cast(5489, <<Location:?GLint,(length(Value)):?GLuint, + cast(5489, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4iv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok. uniform4iv(Location,Value) -> - wxe_util:cast(5490, <<Location:?GLint,(length(Value)):?GLuint, + cast(5490, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix2fv(integer(),0|1,[{float(),float(),float(),float()}]) -> ok. uniformMatrix2fv(Location,Transpose,Value) -> - wxe_util:cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5491, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix3fv(Location,Transpose,Value) -> - wxe_util:cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5492, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix4fv(Location,Transpose,Value) -> - wxe_util:cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5493, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>). %% @spec (Program::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgram.xml">external</a> documentation. +-spec validateProgram(integer()) -> ok. validateProgram(Program) -> - wxe_util:cast(5494, <<Program:?GLuint>>). + cast(5494, <<Program:?GLuint>>). %% @spec (Index::integer(),X::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib1d(integer(),float()) -> ok. vertexAttrib1d(Index,X) -> - wxe_util:cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>). + cast(5495, <<Index:?GLuint,0:32,X:?GLdouble>>). %% @spec (Index,{X}) -> ok %% @equiv vertexAttrib1d(Index,X) +-spec vertexAttrib1dv(integer(),{float()}) -> ok. vertexAttrib1dv(Index,{X}) -> vertexAttrib1d(Index,X). %% @spec (Index::integer(),X::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib1f(integer(),float()) -> ok. vertexAttrib1f(Index,X) -> - wxe_util:cast(5496, <<Index:?GLuint,X:?GLfloat>>). + cast(5496, <<Index:?GLuint,X:?GLfloat>>). %% @spec (Index,{X}) -> ok %% @equiv vertexAttrib1f(Index,X) +-spec vertexAttrib1fv(integer(),{float()}) -> ok. vertexAttrib1fv(Index,{X}) -> vertexAttrib1f(Index,X). %% @spec (Index::integer(),X::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib1s(integer(),integer()) -> ok. vertexAttrib1s(Index,X) -> - wxe_util:cast(5497, <<Index:?GLuint,X:?GLshort>>). + cast(5497, <<Index:?GLuint,X:?GLshort>>). %% @spec (Index,{X}) -> ok %% @equiv vertexAttrib1s(Index,X) +-spec vertexAttrib1sv(integer(),{integer()}) -> ok. vertexAttrib1sv(Index,{X}) -> vertexAttrib1s(Index,X). %% @spec (Index::integer(),X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib2d(integer(),float(),float()) -> ok. vertexAttrib2d(Index,X,Y) -> - wxe_util:cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>). + cast(5498, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>). %% @spec (Index,{X,Y}) -> ok %% @equiv vertexAttrib2d(Index,X,Y) +-spec vertexAttrib2dv(integer(),{float(),float()}) -> ok. vertexAttrib2dv(Index,{X,Y}) -> vertexAttrib2d(Index,X,Y). %% @spec (Index::integer(),X::float(),Y::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib2f(integer(),float(),float()) -> ok. vertexAttrib2f(Index,X,Y) -> - wxe_util:cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>). + cast(5499, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat>>). %% @spec (Index,{X,Y}) -> ok %% @equiv vertexAttrib2f(Index,X,Y) +-spec vertexAttrib2fv(integer(),{float(),float()}) -> ok. vertexAttrib2fv(Index,{X,Y}) -> vertexAttrib2f(Index,X,Y). %% @spec (Index::integer(),X::integer(),Y::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib2s(integer(),integer(),integer()) -> ok. vertexAttrib2s(Index,X,Y) -> - wxe_util:cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>). + cast(5500, <<Index:?GLuint,X:?GLshort,Y:?GLshort>>). %% @spec (Index,{X,Y}) -> ok %% @equiv vertexAttrib2s(Index,X,Y) +-spec vertexAttrib2sv(integer(),{integer(),integer()}) -> ok. vertexAttrib2sv(Index,{X,Y}) -> vertexAttrib2s(Index,X,Y). %% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib3d(integer(),float(),float(),float()) -> ok. vertexAttrib3d(Index,X,Y,Z) -> - wxe_util:cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + cast(5501, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). %% @spec (Index,{X,Y,Z}) -> ok %% @equiv vertexAttrib3d(Index,X,Y,Z) +-spec vertexAttrib3dv(integer(),{float(),float(),float()}) -> ok. vertexAttrib3dv(Index,{X,Y,Z}) -> vertexAttrib3d(Index,X,Y,Z). %% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib3f(integer(),float(),float(),float()) -> ok. vertexAttrib3f(Index,X,Y,Z) -> - wxe_util:cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). + cast(5502, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat>>). %% @spec (Index,{X,Y,Z}) -> ok %% @equiv vertexAttrib3f(Index,X,Y,Z) +-spec vertexAttrib3fv(integer(),{float(),float(),float()}) -> ok. vertexAttrib3fv(Index,{X,Y,Z}) -> vertexAttrib3f(Index,X,Y,Z). %% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib3s(integer(),integer(),integer(),integer()) -> ok. vertexAttrib3s(Index,X,Y,Z) -> - wxe_util:cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>). + cast(5503, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort>>). %% @spec (Index,{X,Y,Z}) -> ok %% @equiv vertexAttrib3s(Index,X,Y,Z) +-spec vertexAttrib3sv(integer(),{integer(),integer(),integer()}) -> ok. vertexAttrib3sv(Index,{X,Y,Z}) -> vertexAttrib3s(Index,X,Y,Z). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Nbv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Nbv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). + cast(5504, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Niv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Niv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + cast(5505, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Nsv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Nsv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>). + cast(5506, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>). %% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Nub(integer(),integer(),integer(),integer(),integer()) -> ok. vertexAttrib4Nub(Index,X,Y,Z,W) -> - wxe_util:cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>). + cast(5507, <<Index:?GLuint,X:?GLubyte,Y:?GLubyte,Z:?GLubyte,W:?GLubyte>>). %% @spec (Index,{X,Y,Z,W}) -> ok %% @equiv vertexAttrib4Nub(Index,X,Y,Z,W) +-spec vertexAttrib4Nubv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Nubv(Index,{X,Y,Z,W}) -> vertexAttrib4Nub(Index,X,Y,Z,W). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Nuiv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Nuiv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>). + cast(5508, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4Nusv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4Nusv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). + cast(5509, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4bv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4bv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). + cast(5510, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). %% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4d(integer(),float(),float(),float(),float()) -> ok. vertexAttrib4d(Index,X,Y,Z,W) -> - wxe_util:cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5511, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). %% @spec (Index,{X,Y,Z,W}) -> ok %% @equiv vertexAttrib4d(Index,X,Y,Z,W) +-spec vertexAttrib4dv(integer(),{float(),float(),float(),float()}) -> ok. vertexAttrib4dv(Index,{X,Y,Z,W}) -> vertexAttrib4d(Index,X,Y,Z,W). %% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4f(integer(),float(),float(),float(),float()) -> ok. vertexAttrib4f(Index,X,Y,Z,W) -> - wxe_util:cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5512, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). %% @spec (Index,{X,Y,Z,W}) -> ok %% @equiv vertexAttrib4f(Index,X,Y,Z,W) +-spec vertexAttrib4fv(integer(),{float(),float(),float(),float()}) -> ok. vertexAttrib4fv(Index,{X,Y,Z,W}) -> vertexAttrib4f(Index,X,Y,Z,W). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4iv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4iv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + cast(5513, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). %% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4s(integer(),integer(),integer(),integer(),integer()) -> ok. vertexAttrib4s(Index,X,Y,Z,W) -> - wxe_util:cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). + cast(5514, <<Index:?GLuint,X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). %% @spec (Index,{X,Y,Z,W}) -> ok %% @equiv vertexAttrib4s(Index,X,Y,Z,W) +-spec vertexAttrib4sv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4sv(Index,{X,Y,Z,W}) -> vertexAttrib4s(Index,X,Y,Z,W). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4ubv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4ubv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>). + cast(5515, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4uiv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4uiv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>). + cast(5516, <<Index:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>>). -%% @spec (Index::integer(),V::{integer()}) -> ok +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttrib.xml">external</a> documentation. +-spec vertexAttrib4usv(integer(),{integer(),integer(),integer(),integer()}) -> ok. vertexAttrib4usv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). + cast(5517, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). -%% @spec (Index::integer(),Size::integer(),Type::enum(),Normalized::0|1,Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Index::integer(),Size::integer(),Type::enum(),Normalized::0|1,Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribPointer.xml">external</a> documentation. +-spec vertexAttribPointer(integer(),integer(),enum(),0|1,integer(),offset()|mem()) -> ok. vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5518, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei,Pointer:?GLuint>>); vertexAttribPointer(Index,Size,Type,Normalized,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5519, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Normalized:?GLboolean,0:24,Stride:?GLsizei>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation. +-spec uniformMatrix2x3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix2x3fv(Location,Transpose,Value) -> - wxe_util:cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5520, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation. +-spec uniformMatrix3x2fv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix3x2fv(Location,Transpose,Value) -> - wxe_util:cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5521, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation. +-spec uniformMatrix2x4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix2x4fv(Location,Transpose,Value) -> - wxe_util:cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5522, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation. +-spec uniformMatrix4x2fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix4x2fv(Location,Transpose,Value) -> - wxe_util:cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5523, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation. +-spec uniformMatrix3x4fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix3x4fv(Location,Transpose,Value) -> - wxe_util:cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5524, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). -%% @spec (Location::integer(),Transpose::0|1,Value::[{float()}]) -> ok +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation. +-spec uniformMatrix4x3fv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. uniformMatrix4x3fv(Location,Transpose,Value) -> - wxe_util:cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + cast(5525, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). %% @spec (Index::integer(),R::0|1,G::0|1,B::0|1,A::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glColorMaski.xml">external</a> documentation. +-spec colorMaski(integer(),0|1,0|1,0|1,0|1) -> ok. colorMaski(Index,R,G,B,A) -> - wxe_util:cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>). + cast(5526, <<Index:?GLuint,R:?GLboolean,G:?GLboolean,B:?GLboolean,A:?GLboolean>>). %% @spec (Target::enum(),Index::integer()) -> [0|1] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBooleani_v.xml">external</a> documentation. +-spec getBooleani_v(enum(),integer()) -> [0|1]. getBooleani_v(Target,Index) -> - wxe_util:call(5527, <<Target:?GLenum,Index:?GLuint>>). + call(5527, <<Target:?GLenum,Index:?GLuint>>). %% @spec (Target::enum(),Index::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetIntegeri_v.xml">external</a> documentation. +-spec getIntegeri_v(enum(),integer()) -> [integer()]. getIntegeri_v(Target,Index) -> - wxe_util:call(5528, <<Target:?GLenum,Index:?GLuint>>). + call(5528, <<Target:?GLenum,Index:?GLuint>>). %% @spec (Target::enum(),Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml">external</a> documentation. +-spec enablei(enum(),integer()) -> ok. enablei(Target,Index) -> - wxe_util:cast(5529, <<Target:?GLenum,Index:?GLuint>>). + cast(5529, <<Target:?GLenum,Index:?GLuint>>). %% @spec (Target::enum(),Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDisable.xml">external</a> documentation. +-spec disablei(enum(),integer()) -> ok. disablei(Target,Index) -> - wxe_util:cast(5530, <<Target:?GLenum,Index:?GLuint>>). + cast(5530, <<Target:?GLenum,Index:?GLuint>>). %% @spec (Target::enum(),Index::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabledi.xml">external</a> documentation. +-spec isEnabledi(enum(),integer()) -> 0|1. isEnabledi(Target,Index) -> - wxe_util:call(5531, <<Target:?GLenum,Index:?GLuint>>). + call(5531, <<Target:?GLenum,Index:?GLuint>>). %% @spec (PrimitiveMode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginTransformFeedback.xml">external</a> documentation. +-spec beginTransformFeedback(enum()) -> ok. beginTransformFeedback(PrimitiveMode) -> - wxe_util:cast(5532, <<PrimitiveMode:?GLenum>>). + cast(5532, <<PrimitiveMode:?GLenum>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndTransformFeedback.xml">external</a> documentation. +-spec endTransformFeedback() -> ok. endTransformFeedback() -> - wxe_util:cast(5533, <<>>). + cast(5533, <<>>). %% @spec (Target::enum(),Index::integer(),Buffer::integer(),Offset::integer(),Size::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferRange.xml">external</a> documentation. +-spec bindBufferRange(enum(),integer(),integer(),integer(),integer()) -> ok. bindBufferRange(Target,Index,Buffer,Offset,Size) -> - wxe_util:cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). + cast(5534, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint,0:32,Offset:?GLintptr,Size:?GLsizeiptr>>). %% @spec (Target::enum(),Index::integer(),Buffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindBufferBase.xml">external</a> documentation. +-spec bindBufferBase(enum(),integer(),integer()) -> ok. bindBufferBase(Target,Index,Buffer) -> - wxe_util:cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>). + cast(5535, <<Target:?GLenum,Index:?GLuint,Buffer:?GLuint>>). %% @spec (Program::integer(),Varyings::[string()],BufferMode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTransformFeedbackVaryings.xml">external</a> documentation. +-spec transformFeedbackVaryings(integer(),[string()],enum()) -> ok. transformFeedbackVaryings(Program,Varyings,BufferMode) -> VaryingsTemp = list_to_binary([[Str|[0]] || Str <- Varyings ]), - wxe_util:cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>). + cast(5536, <<Program:?GLuint,(length(Varyings)):?GLuint,(size(VaryingsTemp)):?GLuint,(VaryingsTemp)/binary,0:((8-((size(VaryingsTemp)+0) rem 8)) rem 8),BufferMode:?GLenum>>). %% @spec (Program::integer(),Index::integer(),BufSize::integer()) -> {Size::integer(),Type::enum(),Name::string()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTransformFeedbackVarying.xml">external</a> documentation. +-spec getTransformFeedbackVarying(integer(),integer(),integer()) -> {integer(),enum(),string()}. getTransformFeedbackVarying(Program,Index,BufSize) -> - wxe_util:call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). + call(5537, <<Program:?GLuint,Index:?GLuint,BufSize:?GLsizei>>). %% @spec (Target::enum(),Clamp::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClampColor.xml">external</a> documentation. +-spec clampColor(enum(),enum()) -> ok. clampColor(Target,Clamp) -> - wxe_util:cast(5538, <<Target:?GLenum,Clamp:?GLenum>>). + cast(5538, <<Target:?GLenum,Clamp:?GLenum>>). %% @spec (Id::integer(),Mode::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginConditionalRender.xml">external</a> documentation. +-spec beginConditionalRender(integer(),enum()) -> ok. beginConditionalRender(Id,Mode) -> - wxe_util:cast(5539, <<Id:?GLuint,Mode:?GLenum>>). + cast(5539, <<Id:?GLuint,Mode:?GLenum>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndConditionalRender.xml">external</a> documentation. +-spec endConditionalRender() -> ok. endConditionalRender() -> - wxe_util:cast(5540, <<>>). + cast(5540, <<>>). -%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|binary()) -> ok +%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribIPointer.xml">external</a> documentation. +-spec vertexAttribIPointer(integer(),integer(),enum(),integer(),offset()|mem()) -> ok. vertexAttribIPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) -> - wxe_util:cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); + cast(5541, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); vertexAttribIPointer(Index,Size,Type,Stride,Pointer) -> - wxe_util:send_bin(Pointer), - wxe_util:cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + send_bin(Pointer), + cast(5542, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). -%% @spec (Index::integer(),Pname::enum()) -> {integer()} +%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation. +-spec getVertexAttribIiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}. getVertexAttribIiv(Index,Pname) -> - wxe_util:call(5543, <<Index:?GLuint,Pname:?GLenum>>). + call(5543, <<Index:?GLuint,Pname:?GLenum>>). -%% @spec (Index::integer(),Pname::enum()) -> {integer()} +%% @spec (Index::integer(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribI.xml">external</a> documentation. +-spec getVertexAttribIuiv(integer(),enum()) -> {integer(),integer(),integer(),integer()}. getVertexAttribIuiv(Index,Pname) -> - wxe_util:call(5544, <<Index:?GLuint,Pname:?GLenum>>). + call(5544, <<Index:?GLuint,Pname:?GLenum>>). + +%% @spec (Index::integer(),X::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI1i(integer(),integer()) -> ok. +vertexAttribI1i(Index,X) -> + cast(5545, <<Index:?GLuint,X:?GLint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI2i(integer(),integer(),integer()) -> ok. +vertexAttribI2i(Index,X,Y) -> + cast(5546, <<Index:?GLuint,X:?GLint,Y:?GLint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI3i(integer(),integer(),integer(),integer()) -> ok. +vertexAttribI3i(Index,X,Y,Z) -> + cast(5547, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4i(integer(),integer(),integer(),integer(),integer()) -> ok. +vertexAttribI4i(Index,X,Y,Z,W) -> + cast(5548, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). + +%% @spec (Index::integer(),X::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI1ui(integer(),integer()) -> ok. +vertexAttribI1ui(Index,X) -> + cast(5549, <<Index:?GLuint,X:?GLuint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI2ui(integer(),integer(),integer()) -> ok. +vertexAttribI2ui(Index,X,Y) -> + cast(5550, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI3ui(integer(),integer(),integer(),integer()) -> ok. +vertexAttribI3ui(Index,X,Y,Z) -> + cast(5551, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>). + +%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4ui(integer(),integer(),integer(),integer(),integer()) -> ok. +vertexAttribI4ui(Index,X,Y,Z,W) -> + cast(5552, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>). + +%% @spec (Index,{X}) -> ok +%% @equiv vertexAttribI1i(Index,X) +-spec vertexAttribI1iv(integer(),{integer()}) -> ok. +vertexAttribI1iv(Index,{X}) -> vertexAttribI1i(Index,X). + +%% @spec (Index,{X,Y}) -> ok +%% @equiv vertexAttribI2i(Index,X,Y) +-spec vertexAttribI2iv(integer(),{integer(),integer()}) -> ok. +vertexAttribI2iv(Index,{X,Y}) -> vertexAttribI2i(Index,X,Y). + +%% @spec (Index,{X,Y,Z}) -> ok +%% @equiv vertexAttribI3i(Index,X,Y,Z) +-spec vertexAttribI3iv(integer(),{integer(),integer(),integer()}) -> ok. +vertexAttribI3iv(Index,{X,Y,Z}) -> vertexAttribI3i(Index,X,Y,Z). + +%% @spec (Index,{X,Y,Z,W}) -> ok +%% @equiv vertexAttribI4i(Index,X,Y,Z,W) +-spec vertexAttribI4iv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4iv(Index,{X,Y,Z,W}) -> vertexAttribI4i(Index,X,Y,Z,W). + +%% @spec (Index,{X}) -> ok +%% @equiv vertexAttribI1ui(Index,X) +-spec vertexAttribI1uiv(integer(),{integer()}) -> ok. +vertexAttribI1uiv(Index,{X}) -> vertexAttribI1ui(Index,X). + +%% @spec (Index,{X,Y}) -> ok +%% @equiv vertexAttribI2ui(Index,X,Y) +-spec vertexAttribI2uiv(integer(),{integer(),integer()}) -> ok. +vertexAttribI2uiv(Index,{X,Y}) -> vertexAttribI2ui(Index,X,Y). + +%% @spec (Index,{X,Y,Z}) -> ok +%% @equiv vertexAttribI3ui(Index,X,Y,Z) +-spec vertexAttribI3uiv(integer(),{integer(),integer(),integer()}) -> ok. +vertexAttribI3uiv(Index,{X,Y,Z}) -> vertexAttribI3ui(Index,X,Y,Z). + +%% @spec (Index,{X,Y,Z,W}) -> ok +%% @equiv vertexAttribI4ui(Index,X,Y,Z,W) +-spec vertexAttribI4uiv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W). + +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4bv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4bv(Index,{V1,V2,V3,V4}) -> + cast(5553, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). + +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4sv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4sv(Index,{V1,V2,V3,V4}) -> + cast(5554, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>). + +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4ubv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4ubv(Index,{V1,V2,V3,V4}) -> + cast(5555, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>). + +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. +-spec vertexAttribI4usv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +vertexAttribI4usv(Index,{V1,V2,V3,V4}) -> + cast(5556, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). -%% @spec (Program::integer(),Location::integer()) -> {integer()} +%% @spec (Program::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation. +-spec getUniformuiv(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}. getUniformuiv(Program,Location) -> - wxe_util:call(5545, <<Program:?GLuint,Location:?GLint>>). + call(5557, <<Program:?GLuint,Location:?GLint>>). %% @spec (Program::integer(),Color::integer(),Name::string()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocation.xml">external</a> documentation. +-spec bindFragDataLocation(integer(),integer(),string()) -> ok. bindFragDataLocation(Program,Color,Name) -> - wxe_util:cast(5546, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + cast(5558, <<Program:?GLuint,Color:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). %% @spec (Program::integer(),Name::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataLocation.xml">external</a> documentation. +-spec getFragDataLocation(integer(),string()) -> integer(). getFragDataLocation(Program,Name) -> - wxe_util:call(5547, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + call(5559, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). %% @spec (Location::integer(),V0::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1ui(integer(),integer()) -> ok. uniform1ui(Location,V0) -> - wxe_util:cast(5548, <<Location:?GLint,V0:?GLuint>>). + cast(5560, <<Location:?GLint,V0:?GLuint>>). %% @spec (Location::integer(),V0::integer(),V1::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2ui(integer(),integer(),integer()) -> ok. uniform2ui(Location,V0,V1) -> - wxe_util:cast(5549, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>). + cast(5561, <<Location:?GLint,V0:?GLuint,V1:?GLuint>>). %% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3ui(integer(),integer(),integer(),integer()) -> ok. uniform3ui(Location,V0,V1,V2) -> - wxe_util:cast(5550, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>). + cast(5562, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>). %% @spec (Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4ui(integer(),integer(),integer(),integer(),integer()) -> ok. uniform4ui(Location,V0,V1,V2,V3) -> - wxe_util:cast(5551, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>). + cast(5563, <<Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>). %% @spec (Location::integer(),Value::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1uiv(integer(),[integer()]) -> ok. uniform1uiv(Location,Value) -> - wxe_util:cast(5552, <<Location:?GLint,(length(Value)):?GLuint, + cast(5564, <<Location:?GLint,(length(Value)):?GLuint, (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((length(Value)) rem 2)*32)>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2uiv(integer(),[{integer(),integer()}]) -> ok. uniform2uiv(Location,Value) -> - wxe_util:cast(5553, <<Location:?GLint,(length(Value)):?GLuint, + cast(5565, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3uiv(integer(),[{integer(),integer(),integer()}]) -> ok. uniform3uiv(Location,Value) -> - wxe_util:cast(5554, <<Location:?GLint,(length(Value)):?GLuint, + cast(5566, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>). -%% @spec (Location::integer(),Value::[{integer()}]) -> ok +%% @spec (Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4uiv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok. uniform4uiv(Location,Value) -> - wxe_util:cast(5555, <<Location:?GLint,(length(Value)):?GLuint, + cast(5567, <<Location:?GLint,(length(Value)):?GLuint, (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>). %% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation. +-spec texParameterIiv(enum(),enum(),{integer()}) -> ok. texParameterIiv(Target,Pname,Params) -> - wxe_util:cast(5556, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5568, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). %% @spec (Target::enum(),Pname::enum(),Params::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexParameterI.xml">external</a> documentation. +-spec texParameterIuiv(enum(),enum(),{integer()}) -> ok. texParameterIuiv(Target,Pname,Params) -> - wxe_util:cast(5557, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, + cast(5569, <<Target:?GLenum,Pname:?GLenum,(size(Params)):?GLuint, (<< <<C:?GLuint>> ||C <- tuple_to_list(Params)>>)/binary,0:(((1+size(Params)) rem 2)*32)>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation. +-spec getTexParameterIiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getTexParameterIiv(Target,Pname) -> - wxe_util:call(5558, <<Target:?GLenum,Pname:?GLenum>>). + call(5570, <<Target:?GLenum,Pname:?GLenum>>). -%% @spec (Target::enum(),Pname::enum()) -> {integer()} +%% @spec (Target::enum(),Pname::enum()) -> {integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetTexParameterI.xml">external</a> documentation. +-spec getTexParameterIuiv(enum(),enum()) -> {integer(),integer(),integer(),integer()}. getTexParameterIuiv(Target,Pname) -> - wxe_util:call(5559, <<Target:?GLenum,Pname:?GLenum>>). + call(5571, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation. +-spec clearBufferiv(enum(),integer(),{integer()}) -> ok. clearBufferiv(Buffer,Drawbuffer,Value) -> - wxe_util:cast(5560, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, + cast(5572, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, (<< <<C:?GLint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>). %% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation. +-spec clearBufferuiv(enum(),integer(),{integer()}) -> ok. clearBufferuiv(Buffer,Drawbuffer,Value) -> - wxe_util:cast(5561, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, + cast(5573, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, (<< <<C:?GLuint>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>). %% @spec (Buffer::enum(),Drawbuffer::integer(),Value::{float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBuffer.xml">external</a> documentation. +-spec clearBufferfv(enum(),integer(),{float()}) -> ok. clearBufferfv(Buffer,Drawbuffer,Value) -> - wxe_util:cast(5562, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, + cast(5574, <<Buffer:?GLenum,Drawbuffer:?GLint,(size(Value)):?GLuint, (<< <<C:?GLfloat>> ||C <- tuple_to_list(Value)>>)/binary,0:(((1+size(Value)) rem 2)*32)>>). %% @spec (Buffer::enum(),Drawbuffer::integer(),Depth::float(),Stencil::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearBufferfi.xml">external</a> documentation. +-spec clearBufferfi(enum(),integer(),float(),integer()) -> ok. clearBufferfi(Buffer,Drawbuffer,Depth,Stencil) -> - wxe_util:cast(5563, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>). + cast(5575, <<Buffer:?GLenum,Drawbuffer:?GLint,Depth:?GLfloat,Stencil:?GLint>>). %% @spec (Name::enum(),Index::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetString.xml">external</a> documentation. +-spec getStringi(enum(),integer()) -> string(). getStringi(Name,Index) -> - wxe_util:call(5564, <<Name:?GLenum,Index:?GLuint>>). - -%% @spec (Index::integer(),X::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI1i(Index,X) -> - wxe_util:cast(5565, <<Index:?GLuint,X:?GLint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI2i(Index,X,Y) -> - wxe_util:cast(5566, <<Index:?GLuint,X:?GLint,Y:?GLint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI3i(Index,X,Y,Z) -> - wxe_util:cast(5567, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4i(Index,X,Y,Z,W) -> - wxe_util:cast(5568, <<Index:?GLuint,X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). - -%% @spec (Index::integer(),X::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI1ui(Index,X) -> - wxe_util:cast(5569, <<Index:?GLuint,X:?GLuint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI2ui(Index,X,Y) -> - wxe_util:cast(5570, <<Index:?GLuint,X:?GLuint,Y:?GLuint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI3ui(Index,X,Y,Z) -> - wxe_util:cast(5571, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint>>). - -%% @spec (Index::integer(),X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4ui(Index,X,Y,Z,W) -> - wxe_util:cast(5572, <<Index:?GLuint,X:?GLuint,Y:?GLuint,Z:?GLuint,W:?GLuint>>). - -%% @spec (Index,{X}) -> ok -%% @equiv vertexAttribI1i(Index,X) -vertexAttribI1iv(Index,{X}) -> vertexAttribI1i(Index,X). - -%% @spec (Index,{X,Y}) -> ok -%% @equiv vertexAttribI2i(Index,X,Y) -vertexAttribI2iv(Index,{X,Y}) -> vertexAttribI2i(Index,X,Y). - -%% @spec (Index,{X,Y,Z}) -> ok -%% @equiv vertexAttribI3i(Index,X,Y,Z) -vertexAttribI3iv(Index,{X,Y,Z}) -> vertexAttribI3i(Index,X,Y,Z). - -%% @spec (Index,{X,Y,Z,W}) -> ok -%% @equiv vertexAttribI4i(Index,X,Y,Z,W) -vertexAttribI4iv(Index,{X,Y,Z,W}) -> vertexAttribI4i(Index,X,Y,Z,W). - -%% @spec (Index,{X}) -> ok -%% @equiv vertexAttribI1ui(Index,X) -vertexAttribI1uiv(Index,{X}) -> vertexAttribI1ui(Index,X). - -%% @spec (Index,{X,Y}) -> ok -%% @equiv vertexAttribI2ui(Index,X,Y) -vertexAttribI2uiv(Index,{X,Y}) -> vertexAttribI2ui(Index,X,Y). - -%% @spec (Index,{X,Y,Z}) -> ok -%% @equiv vertexAttribI3ui(Index,X,Y,Z) -vertexAttribI3uiv(Index,{X,Y,Z}) -> vertexAttribI3ui(Index,X,Y,Z). - -%% @spec (Index,{X,Y,Z,W}) -> ok -%% @equiv vertexAttribI4ui(Index,X,Y,Z,W) -vertexAttribI4uiv(Index,{X,Y,Z,W}) -> vertexAttribI4ui(Index,X,Y,Z,W). - -%% @spec (Index::integer(),V::{integer()}) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4bv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5573, <<Index:?GLuint,V1:?GLbyte,V2:?GLbyte,V3:?GLbyte,V4:?GLbyte>>). - -%% @spec (Index::integer(),V::{integer()}) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4sv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5574, <<Index:?GLuint,V1:?GLshort,V2:?GLshort,V3:?GLshort,V4:?GLshort>>). - -%% @spec (Index::integer(),V::{integer()}) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4ubv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5575, <<Index:?GLuint,V1:?GLubyte,V2:?GLubyte,V3:?GLubyte,V4:?GLubyte>>). - -%% @spec (Index::integer(),V::{integer()}) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribI.xml">external</a> documentation. -vertexAttribI4usv(Index,{V1,V2,V3,V4}) -> - wxe_util:cast(5576, <<Index:?GLuint,V1:?GLushort,V2:?GLushort,V3:?GLushort,V4:?GLushort>>). + call(5576, <<Name:?GLenum,Index:?GLuint>>). %% @spec (Mode::enum(),First::integer(),Count::integer(),Primcount::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysInstance.xml">external</a> documentation. +-spec drawArraysInstanced(enum(),integer(),integer(),integer()) -> ok. drawArraysInstanced(Mode,First,Count,Primcount) -> - wxe_util:cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>). + cast(5577, <<Mode:?GLenum,First:?GLint,Count:?GLsizei,Primcount:?GLsizei>>). -%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|binary(),Primcount::integer()) -> ok +%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Primcount::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstance.xml">external</a> documentation. +-spec drawElementsInstanced(enum(),integer(),enum(),offset()|mem(),integer()) -> ok. drawElementsInstanced(Mode,Count,Type,Indices,Primcount) when is_integer(Indices) -> - wxe_util:cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>); + cast(5578, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei>>); drawElementsInstanced(Mode,Count,Type,Indices,Primcount) -> - wxe_util:send_bin(Indices), - wxe_util:cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>). + send_bin(Indices), + cast(5579, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei>>). %% @spec (Target::enum(),Internalformat::enum(),Buffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexBuffer.xml">external</a> documentation. +-spec texBuffer(enum(),enum(),integer()) -> ok. texBuffer(Target,Internalformat,Buffer) -> - wxe_util:cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>). + cast(5580, <<Target:?GLenum,Internalformat:?GLenum,Buffer:?GLuint>>). %% @spec (Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPrimitiveRestartIndex.xml">external</a> documentation. +-spec primitiveRestartIndex(integer()) -> ok. primitiveRestartIndex(Index) -> - wxe_util:cast(5581, <<Index:?GLuint>>). + cast(5581, <<Index:?GLuint>>). + +%% @spec (Target::enum(),Index::integer()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInteger64i_v.xml">external</a> documentation. +-spec getInteger64i_v(enum(),integer()) -> [integer()]. +getInteger64i_v(Target,Index) -> + call(5582, <<Target:?GLenum,Index:?GLuint>>). + +%% @spec (Target::enum(),Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameteri64v.xml">external</a> documentation. +-spec getBufferParameteri64v(enum(),enum()) -> [integer()]. +getBufferParameteri64v(Target,Pname) -> + call(5583, <<Target:?GLenum,Pname:?GLenum>>). + +%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture.xml">external</a> documentation. +-spec framebufferTexture(enum(),enum(),integer(),integer()) -> ok. +framebufferTexture(Target,Attachment,Texture,Level) -> + cast(5584, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>). -%% @spec (M::{float()}) -> ok +%% @spec (Index::integer(),Divisor::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisor.xml">external</a> documentation. +-spec vertexAttribDivisor(integer(),integer()) -> ok. +vertexAttribDivisor(Index,Divisor) -> + cast(5585, <<Index:?GLuint,Divisor:?GLuint>>). + +%% @spec (Value::clamp()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMinSampleShading.xml">external</a> documentation. +-spec minSampleShading(clamp()) -> ok. +minSampleShading(Value) -> + cast(5586, <<Value:?GLclampf>>). + +%% @spec (Buf::integer(),Mode::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml">external</a> documentation. +-spec blendEquationi(integer(),enum()) -> ok. +blendEquationi(Buf,Mode) -> + cast(5587, <<Buf:?GLuint,Mode:?GLenum>>). + +%% @spec (Buf::integer(),ModeRGB::enum(),ModeAlpha::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml">external</a> documentation. +-spec blendEquationSeparatei(integer(),enum(),enum()) -> ok. +blendEquationSeparatei(Buf,ModeRGB,ModeAlpha) -> + cast(5588, <<Buf:?GLuint,ModeRGB:?GLenum,ModeAlpha:?GLenum>>). + +%% @spec (Buf::integer(),Src::enum(),Dst::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunci.xml">external</a> documentation. +-spec blendFunci(integer(),enum(),enum()) -> ok. +blendFunci(Buf,Src,Dst) -> + cast(5589, <<Buf:?GLuint,Src:?GLenum,Dst:?GLenum>>). + +%% @spec (Buf::integer(),SrcRGB::enum(),DstRGB::enum(),SrcAlpha::enum(),DstAlpha::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml">external</a> documentation. +-spec blendFuncSeparatei(integer(),enum(),enum(),enum(),enum()) -> ok. +blendFuncSeparatei(Buf,SrcRGB,DstRGB,SrcAlpha,DstAlpha) -> + cast(5590, <<Buf:?GLuint,SrcRGB:?GLenum,DstRGB:?GLenum,SrcAlpha:?GLenum,DstAlpha:?GLenum>>). + +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation. +-spec loadTransposeMatrixfARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5582, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); loadTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5582, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5591, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLoadTransposeMatrixARB.xml">external</a> documentation. +-spec loadTransposeMatrixdARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5583, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); loadTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5583, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5592, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation. +-spec multTransposeMatrixfARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5584, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); + cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,M13:?GLfloat,M14:?GLfloat,M15:?GLfloat,M16:?GLfloat>>); multTransposeMatrixfARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5584, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). + cast(5593, <<M1:?GLfloat,M2:?GLfloat,M3:?GLfloat,0:?GLfloat,M4:?GLfloat,M5:?GLfloat,M6:?GLfloat,0:?GLfloat,M7:?GLfloat,M8:?GLfloat,M9:?GLfloat,0:?GLfloat,M10:?GLfloat,M11:?GLfloat,M12:?GLfloat,1:?GLfloat>>). -%% @spec (M::{float()}) -> ok +%% @spec (M::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMultTransposeMatrixARB.xml">external</a> documentation. +-spec multTransposeMatrixdARB({float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}) -> ok. multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16}) -> - wxe_util:cast(5585, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); + cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble>>); multTransposeMatrixdARB({M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12}) -> - wxe_util:cast(5585, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). + cast(5594, <<M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightbvARB([integer()]) -> ok. weightbvARB(Weights) -> - wxe_util:cast(5586, <<(length(Weights)):?GLuint, + cast(5595, <<(length(Weights)):?GLuint, (<< <<C:?GLbyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightsvARB([integer()]) -> ok. weightsvARB(Weights) -> - wxe_util:cast(5587, <<(length(Weights)):?GLuint, + cast(5596, <<(length(Weights)):?GLuint, (<< <<C:?GLshort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightivARB([integer()]) -> ok. weightivARB(Weights) -> - wxe_util:cast(5588, <<(length(Weights)):?GLuint, + cast(5597, <<(length(Weights)):?GLuint, (<< <<C:?GLint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>). %% @spec (Weights::[float()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightfvARB([float()]) -> ok. weightfvARB(Weights) -> - wxe_util:cast(5589, <<(length(Weights)):?GLuint, + cast(5598, <<(length(Weights)):?GLuint, (<< <<C:?GLfloat>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>). %% @spec (Weights::[float()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightdvARB([float()]) -> ok. weightdvARB(Weights) -> - wxe_util:cast(5590, <<(length(Weights)):?GLuint,0:32, + cast(5599, <<(length(Weights)):?GLuint,0:32, (<< <<C:?GLdouble>> || C <- Weights>>)/binary>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightubvARB([integer()]) -> ok. weightubvARB(Weights) -> - wxe_util:cast(5591, <<(length(Weights)):?GLuint, + cast(5600, <<(length(Weights)):?GLuint, (<< <<C:?GLubyte>> || C <- Weights>>)/binary,0:((8-((length(Weights)+ 4) rem 8)) rem 8)>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightusvARB([integer()]) -> ok. weightusvARB(Weights) -> - wxe_util:cast(5592, <<(length(Weights)):?GLuint, + cast(5601, <<(length(Weights)):?GLuint, (<< <<C:?GLushort>> || C <- Weights>>)/binary,0:((8-((length(Weights)*2+ 4) rem 8)) rem 8)>>). %% @spec (Weights::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWeightARB.xml">external</a> documentation. +-spec weightuivARB([integer()]) -> ok. weightuivARB(Weights) -> - wxe_util:cast(5593, <<(length(Weights)):?GLuint, + cast(5602, <<(length(Weights)):?GLuint, (<< <<C:?GLuint>> || C <- Weights>>)/binary,0:(((1+length(Weights)) rem 2)*32)>>). %% @spec (Count::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexBlenARB.xml">external</a> documentation. +-spec vertexBlendARB(integer()) -> ok. vertexBlendARB(Count) -> - wxe_util:cast(5594, <<Count:?GLint>>). + cast(5603, <<Count:?GLint>>). %% @spec (Index::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCurrentPaletteMatrixARB.xml">external</a> documentation. +-spec currentPaletteMatrixARB(integer()) -> ok. currentPaletteMatrixARB(Index) -> - wxe_util:cast(5595, <<Index:?GLint>>). + cast(5604, <<Index:?GLint>>). %% @spec (Indices::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation. +-spec matrixIndexubvARB([integer()]) -> ok. matrixIndexubvARB(Indices) -> - wxe_util:cast(5596, <<(length(Indices)):?GLuint, + cast(5605, <<(length(Indices)):?GLuint, (<< <<C:?GLubyte>> || C <- Indices>>)/binary,0:((8-((length(Indices)+ 4) rem 8)) rem 8)>>). %% @spec (Indices::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation. +-spec matrixIndexusvARB([integer()]) -> ok. matrixIndexusvARB(Indices) -> - wxe_util:cast(5597, <<(length(Indices)):?GLuint, + cast(5606, <<(length(Indices)):?GLuint, (<< <<C:?GLushort>> || C <- Indices>>)/binary,0:((8-((length(Indices)*2+ 4) rem 8)) rem 8)>>). %% @spec (Indices::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glMatrixIndexARB.xml">external</a> documentation. +-spec matrixIndexuivARB([integer()]) -> ok. matrixIndexuivARB(Indices) -> - wxe_util:cast(5598, <<(length(Indices)):?GLuint, + cast(5607, <<(length(Indices)):?GLuint, (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((1+length(Indices)) rem 2)*32)>>). %% @spec (Target::enum(),Format::enum(),String::string()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramStringARB.xml">external</a> documentation. +-spec programStringARB(enum(),enum(),string()) -> ok. programStringARB(Target,Format,String) -> - wxe_util:cast(5599, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>). + cast(5608, <<Target:?GLenum,Format:?GLenum,(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>). %% @spec (Target::enum(),Program::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramARB.xml">external</a> documentation. +-spec bindProgramARB(enum(),integer()) -> ok. bindProgramARB(Target,Program) -> - wxe_util:cast(5600, <<Target:?GLenum,Program:?GLuint>>). + cast(5609, <<Target:?GLenum,Program:?GLuint>>). %% @spec (Programs::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramsARB.xml">external</a> documentation. +-spec deleteProgramsARB([integer()]) -> ok. deleteProgramsARB(Programs) -> - wxe_util:cast(5601, <<(length(Programs)):?GLuint, + cast(5610, <<(length(Programs)):?GLuint, (<< <<C:?GLuint>> || C <- Programs>>)/binary,0:(((1+length(Programs)) rem 2)*32)>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramsARB.xml">external</a> documentation. +-spec genProgramsARB(integer()) -> [integer()]. genProgramsARB(N) -> - wxe_util:call(5602, <<N:?GLsizei>>). + call(5611, <<N:?GLsizei>>). %% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation. +-spec programEnvParameter4dARB(enum(),integer(),float(),float(),float(),float()) -> ok. programEnvParameter4dARB(Target,Index,X,Y,Z,W) -> - wxe_util:cast(5603, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5612, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). -%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok +%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation. +-spec programEnvParameter4dvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok. programEnvParameter4dvARB(Target,Index,{P1,P2,P3,P4}) -> - wxe_util:cast(5604, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>). + cast(5613, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>). %% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation. +-spec programEnvParameter4fARB(enum(),integer(),float(),float(),float(),float()) -> ok. programEnvParameter4fARB(Target,Index,X,Y,Z,W) -> - wxe_util:cast(5605, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5614, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). -%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok +%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramEnvParameterARB.xml">external</a> documentation. +-spec programEnvParameter4fvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok. programEnvParameter4fvARB(Target,Index,{P1,P2,P3,P4}) -> - wxe_util:cast(5606, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). + cast(5615, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). %% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation. +-spec programLocalParameter4dARB(enum(),integer(),float(),float(),float(),float()) -> ok. programLocalParameter4dARB(Target,Index,X,Y,Z,W) -> - wxe_util:cast(5607, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5616, <<Target:?GLenum,Index:?GLuint,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). -%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok +%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation. +-spec programLocalParameter4dvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok. programLocalParameter4dvARB(Target,Index,{P1,P2,P3,P4}) -> - wxe_util:cast(5608, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>). + cast(5617, <<Target:?GLenum,Index:?GLuint,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble>>). %% @spec (Target::enum(),Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation. +-spec programLocalParameter4fARB(enum(),integer(),float(),float(),float(),float()) -> ok. programLocalParameter4fARB(Target,Index,X,Y,Z,W) -> - wxe_util:cast(5609, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5618, <<Target:?GLenum,Index:?GLuint,X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). -%% @spec (Target::enum(),Index::integer(),Params::{float()}) -> ok +%% @spec (Target::enum(),Index::integer(),Params::{float(),float(),float(),float()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramLocalParameterARB.xml">external</a> documentation. +-spec programLocalParameter4fvARB(enum(),integer(),{float(),float(),float(),float()}) -> ok. programLocalParameter4fvARB(Target,Index,{P1,P2,P3,P4}) -> - wxe_util:cast(5610, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). + cast(5619, <<Target:?GLenum,Index:?GLuint,P1:?GLfloat,P2:?GLfloat,P3:?GLfloat,P4:?GLfloat>>). -%% @spec (Target::enum(),Index::integer()) -> {float()} +%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation. +-spec getProgramEnvParameterdvARB(enum(),integer()) -> {float(),float(),float(),float()}. getProgramEnvParameterdvARB(Target,Index) -> - wxe_util:call(5611, <<Target:?GLenum,Index:?GLuint>>). + call(5620, <<Target:?GLenum,Index:?GLuint>>). -%% @spec (Target::enum(),Index::integer()) -> {float()} +%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramEnvParameterARB.xml">external</a> documentation. +-spec getProgramEnvParameterfvARB(enum(),integer()) -> {float(),float(),float(),float()}. getProgramEnvParameterfvARB(Target,Index) -> - wxe_util:call(5612, <<Target:?GLenum,Index:?GLuint>>). + call(5621, <<Target:?GLenum,Index:?GLuint>>). -%% @spec (Target::enum(),Index::integer()) -> {float()} +%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation. +-spec getProgramLocalParameterdvARB(enum(),integer()) -> {float(),float(),float(),float()}. getProgramLocalParameterdvARB(Target,Index) -> - wxe_util:call(5613, <<Target:?GLenum,Index:?GLuint>>). + call(5622, <<Target:?GLenum,Index:?GLuint>>). -%% @spec (Target::enum(),Index::integer()) -> {float()} +%% @spec (Target::enum(),Index::integer()) -> {float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramLocalParameterARB.xml">external</a> documentation. +-spec getProgramLocalParameterfvARB(enum(),integer()) -> {float(),float(),float(),float()}. getProgramLocalParameterfvARB(Target,Index) -> - wxe_util:call(5614, <<Target:?GLenum,Index:?GLuint>>). + call(5623, <<Target:?GLenum,Index:?GLuint>>). -%% @spec (Target::enum(),Pname::enum(),String::wx:wx_mem()) -> ok +%% @spec (Target::enum(),Pname::enum(),String::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStringARB.xml">external</a> documentation. +-spec getProgramStringARB(enum(),enum(),mem()) -> ok. getProgramStringARB(Target,Pname,String) -> - wxe_util:send_bin(String#wx_mem.bin), - wxe_util:call(5615, <<Target:?GLenum,Pname:?GLenum>>). + send_bin(String), + call(5624, <<Target:?GLenum,Pname:?GLenum>>). + +%% @spec (Target::enum(),Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetBufferParameterARB.xml">external</a> documentation. +-spec getBufferParameterivARB(enum(),enum()) -> [integer()]. +getBufferParameterivARB(Target,Pname) -> + call(5625, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Obj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteObjectARB.xml">external</a> documentation. +-spec deleteObjectARB(integer()) -> ok. deleteObjectARB(Obj) -> - wxe_util:cast(5616, <<Obj:?GLhandleARB>>). + cast(5626, <<Obj:?GLhandleARB>>). %% @spec (Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetHandleARB.xml">external</a> documentation. +-spec getHandleARB(enum()) -> integer(). getHandleARB(Pname) -> - wxe_util:call(5617, <<Pname:?GLenum>>). + call(5627, <<Pname:?GLenum>>). %% @spec (ContainerObj::integer(),AttachedObj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDetachObjectARB.xml">external</a> documentation. +-spec detachObjectARB(integer(),integer()) -> ok. detachObjectARB(ContainerObj,AttachedObj) -> - wxe_util:cast(5618, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>). + cast(5628, <<ContainerObj:?GLhandleARB,AttachedObj:?GLhandleARB>>). %% @spec (ShaderType::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderObjectARB.xml">external</a> documentation. +-spec createShaderObjectARB(enum()) -> integer(). createShaderObjectARB(ShaderType) -> - wxe_util:call(5619, <<ShaderType:?GLenum>>). + call(5629, <<ShaderType:?GLenum>>). %% @spec (ShaderObj::integer(),String::[string()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderSourceARB.xml">external</a> documentation. +-spec shaderSourceARB(integer(),[string()]) -> ok. shaderSourceARB(ShaderObj,String) -> StringTemp = list_to_binary([[Str|[0]] || Str <- String ]), - wxe_util:cast(5620, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>). + cast(5630, <<ShaderObj:?GLhandleARB,(length(String)):?GLuint,(size(StringTemp)):?GLuint,(StringTemp)/binary,0:((8-((size(StringTemp)+4) rem 8)) rem 8)>>). %% @spec (ShaderObj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderARB.xml">external</a> documentation. +-spec compileShaderARB(integer()) -> ok. compileShaderARB(ShaderObj) -> - wxe_util:cast(5621, <<ShaderObj:?GLhandleARB>>). + cast(5631, <<ShaderObj:?GLhandleARB>>). %% @spec () -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateProgramObjectARB.xml">external</a> documentation. +-spec createProgramObjectARB() -> integer(). createProgramObjectARB() -> - wxe_util:call(5622, <<>>). + call(5632, <<>>). %% @spec (ContainerObj::integer(),Obj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glAttachObjectARB.xml">external</a> documentation. +-spec attachObjectARB(integer(),integer()) -> ok. attachObjectARB(ContainerObj,Obj) -> - wxe_util:cast(5623, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>). + cast(5633, <<ContainerObj:?GLhandleARB,Obj:?GLhandleARB>>). %% @spec (ProgramObj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glLinkProgramARB.xml">external</a> documentation. +-spec linkProgramARB(integer()) -> ok. linkProgramARB(ProgramObj) -> - wxe_util:cast(5624, <<ProgramObj:?GLhandleARB>>). + cast(5634, <<ProgramObj:?GLhandleARB>>). %% @spec (ProgramObj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramObjectARB.xml">external</a> documentation. +-spec useProgramObjectARB(integer()) -> ok. useProgramObjectARB(ProgramObj) -> - wxe_util:cast(5625, <<ProgramObj:?GLhandleARB>>). + cast(5635, <<ProgramObj:?GLhandleARB>>). %% @spec (ProgramObj::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramARB.xml">external</a> documentation. +-spec validateProgramARB(integer()) -> ok. validateProgramARB(ProgramObj) -> - wxe_util:cast(5626, <<ProgramObj:?GLhandleARB>>). + cast(5636, <<ProgramObj:?GLhandleARB>>). %% @spec (Obj::integer(),Pname::enum()) -> float() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation. +-spec getObjectParameterfvARB(integer(),enum()) -> float(). getObjectParameterfvARB(Obj,Pname) -> - wxe_util:call(5627, <<Obj:?GLhandleARB,Pname:?GLenum>>). + call(5637, <<Obj:?GLhandleARB,Pname:?GLenum>>). %% @spec (Obj::integer(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetObjectParameterARB.xml">external</a> documentation. +-spec getObjectParameterivARB(integer(),enum()) -> integer(). getObjectParameterivARB(Obj,Pname) -> - wxe_util:call(5628, <<Obj:?GLhandleARB,Pname:?GLenum>>). + call(5638, <<Obj:?GLhandleARB,Pname:?GLenum>>). %% @spec (Obj::integer(),MaxLength::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInfoLogARB.xml">external</a> documentation. +-spec getInfoLogARB(integer(),integer()) -> string(). getInfoLogARB(Obj,MaxLength) -> - wxe_util:call(5629, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>). + call(5639, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>). %% @spec (ContainerObj::integer(),MaxCount::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttachedObjectsARB.xml">external</a> documentation. +-spec getAttachedObjectsARB(integer(),integer()) -> [integer()]. getAttachedObjectsARB(ContainerObj,MaxCount) -> - wxe_util:call(5630, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>). + call(5640, <<ContainerObj:?GLhandleARB,MaxCount:?GLsizei>>). %% @spec (ProgramObj::integer(),Name::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocationARB.xml">external</a> documentation. +-spec getUniformLocationARB(integer(),string()) -> integer(). getUniformLocationARB(ProgramObj,Name) -> - wxe_util:call(5631, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + call(5641, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). %% @spec (ProgramObj::integer(),Index::integer(),MaxLength::integer()) -> {Size::integer(),Type::enum(),Name::string()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformARB.xml">external</a> documentation. +-spec getActiveUniformARB(integer(),integer(),integer()) -> {integer(),enum(),string()}. getActiveUniformARB(ProgramObj,Index,MaxLength) -> - wxe_util:call(5632, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>). + call(5642, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>). -%% @spec (ProgramObj::integer(),Location::integer()) -> {float()} +%% @spec (ProgramObj::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation. +-spec getUniformfvARB(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}. getUniformfvARB(ProgramObj,Location) -> - wxe_util:call(5633, <<ProgramObj:?GLhandleARB,Location:?GLint>>). + call(5643, <<ProgramObj:?GLhandleARB,Location:?GLint>>). -%% @spec (ProgramObj::integer(),Location::integer()) -> {integer()} +%% @spec (ProgramObj::integer(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformARB.xml">external</a> documentation. +-spec getUniformivARB(integer(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}. getUniformivARB(ProgramObj,Location) -> - wxe_util:call(5634, <<ProgramObj:?GLhandleARB,Location:?GLint>>). + call(5644, <<ProgramObj:?GLhandleARB,Location:?GLint>>). %% @spec (Obj::integer(),MaxLength::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderSourceARB.xml">external</a> documentation. +-spec getShaderSourceARB(integer(),integer()) -> string(). getShaderSourceARB(Obj,MaxLength) -> - wxe_util:call(5635, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>). + call(5645, <<Obj:?GLhandleARB,MaxLength:?GLsizei>>). %% @spec (ProgramObj::integer(),Index::integer(),Name::string()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindAttribLocationARB.xml">external</a> documentation. +-spec bindAttribLocationARB(integer(),integer(),string()) -> ok. bindAttribLocationARB(ProgramObj,Index,Name) -> - wxe_util:cast(5636, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + cast(5646, <<ProgramObj:?GLhandleARB,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). %% @spec (ProgramObj::integer(),Index::integer(),MaxLength::integer()) -> {Size::integer(),Type::enum(),Name::string()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveAttribARB.xml">external</a> documentation. +-spec getActiveAttribARB(integer(),integer(),integer()) -> {integer(),enum(),string()}. getActiveAttribARB(ProgramObj,Index,MaxLength) -> - wxe_util:call(5637, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>). + call(5647, <<ProgramObj:?GLhandleARB,Index:?GLuint,MaxLength:?GLsizei>>). %% @spec (ProgramObj::integer(),Name::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocationARB.xml">external</a> documentation. +-spec getAttribLocationARB(integer(),string()) -> integer(). getAttribLocationARB(ProgramObj,Name) -> - wxe_util:call(5638, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + call(5648, <<ProgramObj:?GLhandleARB,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). %% @spec (Renderbuffer::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsRenderbuffer.xml">external</a> documentation. +-spec isRenderbuffer(integer()) -> 0|1. isRenderbuffer(Renderbuffer) -> - wxe_util:call(5639, <<Renderbuffer:?GLuint>>). + call(5649, <<Renderbuffer:?GLuint>>). %% @spec (Target::enum(),Renderbuffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindRenderbuffer.xml">external</a> documentation. +-spec bindRenderbuffer(enum(),integer()) -> ok. bindRenderbuffer(Target,Renderbuffer) -> - wxe_util:cast(5640, <<Target:?GLenum,Renderbuffer:?GLuint>>). + cast(5650, <<Target:?GLenum,Renderbuffer:?GLuint>>). %% @spec (Renderbuffers::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteRenderbuffers.xml">external</a> documentation. +-spec deleteRenderbuffers([integer()]) -> ok. deleteRenderbuffers(Renderbuffers) -> - wxe_util:cast(5641, <<(length(Renderbuffers)):?GLuint, + cast(5651, <<(length(Renderbuffers)):?GLuint, (<< <<C:?GLuint>> || C <- Renderbuffers>>)/binary,0:(((1+length(Renderbuffers)) rem 2)*32)>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenRenderbuffers.xml">external</a> documentation. +-spec genRenderbuffers(integer()) -> [integer()]. genRenderbuffers(N) -> - wxe_util:call(5642, <<N:?GLsizei>>). + call(5652, <<N:?GLsizei>>). %% @spec (Target::enum(),Internalformat::enum(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorage.xml">external</a> documentation. +-spec renderbufferStorage(enum(),enum(),integer(),integer()) -> ok. renderbufferStorage(Target,Internalformat,Width,Height) -> - wxe_util:cast(5643, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>). + cast(5653, <<Target:?GLenum,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>). %% @spec (Target::enum(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetRenderbufferParameter.xml">external</a> documentation. +-spec getRenderbufferParameteriv(enum(),enum()) -> integer(). getRenderbufferParameteriv(Target,Pname) -> - wxe_util:call(5644, <<Target:?GLenum,Pname:?GLenum>>). + call(5654, <<Target:?GLenum,Pname:?GLenum>>). %% @spec (Framebuffer::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsFramebuffer.xml">external</a> documentation. +-spec isFramebuffer(integer()) -> 0|1. isFramebuffer(Framebuffer) -> - wxe_util:call(5645, <<Framebuffer:?GLuint>>). + call(5655, <<Framebuffer:?GLuint>>). %% @spec (Target::enum(),Framebuffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFramebuffer.xml">external</a> documentation. +-spec bindFramebuffer(enum(),integer()) -> ok. bindFramebuffer(Target,Framebuffer) -> - wxe_util:cast(5646, <<Target:?GLenum,Framebuffer:?GLuint>>). + cast(5656, <<Target:?GLenum,Framebuffer:?GLuint>>). %% @spec (Framebuffers::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteFramebuffers.xml">external</a> documentation. +-spec deleteFramebuffers([integer()]) -> ok. deleteFramebuffers(Framebuffers) -> - wxe_util:cast(5647, <<(length(Framebuffers)):?GLuint, + cast(5657, <<(length(Framebuffers)):?GLuint, (<< <<C:?GLuint>> || C <- Framebuffers>>)/binary,0:(((1+length(Framebuffers)) rem 2)*32)>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenFramebuffers.xml">external</a> documentation. +-spec genFramebuffers(integer()) -> [integer()]. genFramebuffers(N) -> - wxe_util:call(5648, <<N:?GLsizei>>). + call(5658, <<N:?GLsizei>>). %% @spec (Target::enum()) -> enum() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCheckFramebufferStatus.xml">external</a> documentation. +-spec checkFramebufferStatus(enum()) -> enum(). checkFramebufferStatus(Target) -> - wxe_util:call(5649, <<Target:?GLenum>>). + call(5659, <<Target:?GLenum>>). %% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture1D.xml">external</a> documentation. +-spec framebufferTexture1D(enum(),enum(),enum(),integer(),integer()) -> ok. framebufferTexture1D(Target,Attachment,Textarget,Texture,Level) -> - wxe_util:cast(5650, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>). + cast(5660, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>). %% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture2D.xml">external</a> documentation. +-spec framebufferTexture2D(enum(),enum(),enum(),integer(),integer()) -> ok. framebufferTexture2D(Target,Attachment,Textarget,Texture,Level) -> - wxe_util:cast(5651, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>). + cast(5661, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint>>). %% @spec (Target::enum(),Attachment::enum(),Textarget::enum(),Texture::integer(),Level::integer(),Zoffset::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTexture3D.xml">external</a> documentation. +-spec framebufferTexture3D(enum(),enum(),enum(),integer(),integer(),integer()) -> ok. framebufferTexture3D(Target,Attachment,Textarget,Texture,Level,Zoffset) -> - wxe_util:cast(5652, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>). + cast(5662, <<Target:?GLenum,Attachment:?GLenum,Textarget:?GLenum,Texture:?GLuint,Level:?GLint,Zoffset:?GLint>>). %% @spec (Target::enum(),Attachment::enum(),Renderbuffertarget::enum(),Renderbuffer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferRenderbuffer.xml">external</a> documentation. +-spec framebufferRenderbuffer(enum(),enum(),enum(),integer()) -> ok. framebufferRenderbuffer(Target,Attachment,Renderbuffertarget,Renderbuffer) -> - wxe_util:cast(5653, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>). + cast(5663, <<Target:?GLenum,Attachment:?GLenum,Renderbuffertarget:?GLenum,Renderbuffer:?GLuint>>). %% @spec (Target::enum(),Attachment::enum(),Pname::enum()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFramebufferAttachmentParameter.xml">external</a> documentation. +-spec getFramebufferAttachmentParameteriv(enum(),enum(),enum()) -> integer(). getFramebufferAttachmentParameteriv(Target,Attachment,Pname) -> - wxe_util:call(5654, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>). + call(5664, <<Target:?GLenum,Attachment:?GLenum,Pname:?GLenum>>). %% @spec (Target::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenerateMipmap.xml">external</a> documentation. +-spec generateMipmap(enum()) -> ok. generateMipmap(Target) -> - wxe_util:cast(5655, <<Target:?GLenum>>). + cast(5665, <<Target:?GLenum>>). %% @spec (SrcX0::integer(),SrcY0::integer(),SrcX1::integer(),SrcY1::integer(),DstX0::integer(),DstY0::integer(),DstX1::integer(),DstY1::integer(),Mask::integer(),Filter::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBlitFramebuffer.xml">external</a> documentation. +-spec blitFramebuffer(integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),enum()) -> ok. blitFramebuffer(SrcX0,SrcY0,SrcX1,SrcY1,DstX0,DstY0,DstX1,DstY1,Mask,Filter) -> - wxe_util:cast(5656, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>). + cast(5666, <<SrcX0:?GLint,SrcY0:?GLint,SrcX1:?GLint,SrcY1:?GLint,DstX0:?GLint,DstY0:?GLint,DstX1:?GLint,DstY1:?GLint,Mask:?GLbitfield,Filter:?GLenum>>). %% @spec (Target::enum(),Samples::integer(),Internalformat::enum(),Width::integer(),Height::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glRenderbufferStorageMultisample.xml">external</a> documentation. +-spec renderbufferStorageMultisample(enum(),integer(),enum(),integer(),integer()) -> ok. renderbufferStorageMultisample(Target,Samples,Internalformat,Width,Height) -> - wxe_util:cast(5657, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>). + cast(5667, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLenum,Width:?GLsizei,Height:?GLsizei>>). %% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer(),Layer::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureLayer.xml">external</a> documentation. +-spec framebufferTextureLayer(enum(),enum(),integer(),integer(),integer()) -> ok. framebufferTextureLayer(Target,Attachment,Texture,Level,Layer) -> - wxe_util:cast(5658, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>). - -%% @spec (Program::integer(),Pname::enum(),Value::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameterARB.xml">external</a> documentation. -programParameteriARB(Program,Pname,Value) -> - wxe_util:cast(5659, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>). - -%% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureARB.xml">external</a> documentation. -framebufferTextureARB(Target,Attachment,Texture,Level) -> - wxe_util:cast(5660, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint>>). + cast(5668, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Layer:?GLint>>). %% @spec (Target::enum(),Attachment::enum(),Texture::integer(),Level::integer(),Face::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFramebufferTextureFaceARB.xml">external</a> documentation. +-spec framebufferTextureFaceARB(enum(),enum(),integer(),integer(),enum()) -> ok. framebufferTextureFaceARB(Target,Attachment,Texture,Level,Face) -> - wxe_util:cast(5661, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>). - -%% @spec (Index::integer(),Divisor::integer()) -> ok -%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribDivisorARB.xml">external</a> documentation. -vertexAttribDivisorARB(Index,Divisor) -> - wxe_util:cast(5662, <<Index:?GLuint,Divisor:?GLuint>>). + cast(5669, <<Target:?GLenum,Attachment:?GLenum,Texture:?GLuint,Level:?GLint,Face:?GLenum>>). %% @spec (Target::enum(),Offset::integer(),Length::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFlushMappedBufferRange.xml">external</a> documentation. +-spec flushMappedBufferRange(enum(),integer(),integer()) -> ok. flushMappedBufferRange(Target,Offset,Length) -> - wxe_util:cast(5663, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>). + cast(5670, <<Target:?GLenum,0:32,Offset:?GLintptr,Length:?GLsizeiptr>>). %% @spec (Array::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindVertexArray.xml">external</a> documentation. +-spec bindVertexArray(integer()) -> ok. bindVertexArray(Array) -> - wxe_util:cast(5664, <<Array:?GLuint>>). + cast(5671, <<Array:?GLuint>>). %% @spec (Arrays::[integer()]) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteVertexArrays.xml">external</a> documentation. +-spec deleteVertexArrays([integer()]) -> ok. deleteVertexArrays(Arrays) -> - wxe_util:cast(5665, <<(length(Arrays)):?GLuint, + cast(5672, <<(length(Arrays)):?GLuint, (<< <<C:?GLuint>> || C <- Arrays>>)/binary,0:(((1+length(Arrays)) rem 2)*32)>>). %% @spec (N::integer()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenVertexArrays.xml">external</a> documentation. +-spec genVertexArrays(integer()) -> [integer()]. genVertexArrays(N) -> - wxe_util:call(5666, <<N:?GLsizei>>). + call(5673, <<N:?GLsizei>>). %% @spec (Array::integer()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsVertexArray.xml">external</a> documentation. +-spec isVertexArray(integer()) -> 0|1. isVertexArray(Array) -> - wxe_util:call(5667, <<Array:?GLuint>>). + call(5674, <<Array:?GLuint>>). %% @spec (Program::integer(),UniformNames::[string()]) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformIndices.xml">external</a> documentation. +-spec getUniformIndices(integer(),[string()]) -> [integer()]. getUniformIndices(Program,UniformNames) -> UniformNamesTemp = list_to_binary([[Str|[0]] || Str <- UniformNames ]), - wxe_util:call(5668, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>). + call(5675, <<Program:?GLuint,(length(UniformNames)):?GLuint,(size(UniformNamesTemp)):?GLuint,(UniformNamesTemp)/binary,0:((8-((size(UniformNamesTemp)+0) rem 8)) rem 8)>>). %% @spec (Program::integer(),UniformIndices::[integer()],Pname::enum()) -> [integer()] %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniforms.xml">external</a> documentation. +-spec getActiveUniformsiv(integer(),[integer()],enum()) -> [integer()]. getActiveUniformsiv(Program,UniformIndices,Pname) -> - wxe_util:call(5669, <<Program:?GLuint,(length(UniformIndices)):?GLuint, + call(5676, <<Program:?GLuint,(length(UniformIndices)):?GLuint, (<< <<C:?GLuint>> || C <- UniformIndices>>)/binary,0:(((length(UniformIndices)) rem 2)*32),Pname:?GLenum>>). %% @spec (Program::integer(),UniformIndex::integer(),BufSize::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformName.xml">external</a> documentation. +-spec getActiveUniformName(integer(),integer(),integer()) -> string(). getActiveUniformName(Program,UniformIndex,BufSize) -> - wxe_util:call(5670, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>). + call(5677, <<Program:?GLuint,UniformIndex:?GLuint,BufSize:?GLsizei>>). %% @spec (Program::integer(),UniformBlockName::string()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformBlockIndex.xml">external</a> documentation. +-spec getUniformBlockIndex(integer(),string()) -> integer(). getUniformBlockIndex(Program,UniformBlockName) -> - wxe_util:call(5671, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>). + call(5678, <<Program:?GLuint,(list_to_binary([UniformBlockName|[0]]))/binary,0:((8-((length(UniformBlockName)+ 5) rem 8)) rem 8)>>). -%% @spec (Program::integer(),UniformBlockIndex::integer(),Pname::enum(),Params::wx:wx_mem()) -> ok +%% @spec (Program::integer(),UniformBlockIndex::integer(),Pname::enum(),Params::mem()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlock.xml">external</a> documentation. +-spec getActiveUniformBlockiv(integer(),integer(),enum(),mem()) -> ok. getActiveUniformBlockiv(Program,UniformBlockIndex,Pname,Params) -> - wxe_util:send_bin(Params#wx_mem.bin), - wxe_util:call(5672, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>). + send_bin(Params), + call(5679, <<Program:?GLuint,UniformBlockIndex:?GLuint,Pname:?GLenum>>). %% @spec (Program::integer(),UniformBlockIndex::integer(),BufSize::integer()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveUniformBlockName.xml">external</a> documentation. +-spec getActiveUniformBlockName(integer(),integer(),integer()) -> string(). getActiveUniformBlockName(Program,UniformBlockIndex,BufSize) -> - wxe_util:call(5673, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>). + call(5680, <<Program:?GLuint,UniformBlockIndex:?GLuint,BufSize:?GLsizei>>). %% @spec (Program::integer(),UniformBlockIndex::integer(),UniformBlockBinding::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformBlockBinding.xml">external</a> documentation. +-spec uniformBlockBinding(integer(),integer(),integer()) -> ok. uniformBlockBinding(Program,UniformBlockIndex,UniformBlockBinding) -> - wxe_util:cast(5674, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>). + cast(5681, <<Program:?GLuint,UniformBlockIndex:?GLuint,UniformBlockBinding:?GLuint>>). %% @spec (ReadTarget::enum(),WriteTarget::enum(),ReadOffset::integer(),WriteOffset::integer(),Size::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCopyBufferSubData.xml">external</a> documentation. +-spec copyBufferSubData(enum(),enum(),integer(),integer(),integer()) -> ok. copyBufferSubData(ReadTarget,WriteTarget,ReadOffset,WriteOffset,Size) -> - wxe_util:cast(5675, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>). + cast(5682, <<ReadTarget:?GLenum,WriteTarget:?GLenum,ReadOffset:?GLintptr,WriteOffset:?GLintptr,Size:?GLsizeiptr>>). + +%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Basevertex::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsBaseVertex.xml">external</a> documentation. +-spec drawElementsBaseVertex(enum(),integer(),enum(),offset()|mem(),integer()) -> ok. +drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) when is_integer(Indices) -> + cast(5683, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>); +drawElementsBaseVertex(Mode,Count,Type,Indices,Basevertex) -> + send_bin(Indices), + cast(5684, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>). + +%% @spec (Mode::enum(),Start::integer(),End::integer(),Count::integer(),Type::enum(),Indices::offset()|mem(),Basevertex::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawRangeElementsBaseVertex.xml">external</a> documentation. +-spec drawRangeElementsBaseVertex(enum(),integer(),integer(),integer(),enum(),offset()|mem(),integer()) -> ok. +drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) when is_integer(Indices) -> + cast(5685, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Basevertex:?GLint>>); +drawRangeElementsBaseVertex(Mode,Start,End,Count,Type,Indices,Basevertex) -> + send_bin(Indices), + cast(5686, <<Mode:?GLenum,Start:?GLuint,End:?GLuint,Count:?GLsizei,Type:?GLenum,Basevertex:?GLint>>). + +%% @spec (Mode::enum(),Count::integer(),Type::enum(),Indices::offset()|mem(),Primcount::integer(),Basevertex::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsInstancedBaseVertex.xml">external</a> documentation. +-spec drawElementsInstancedBaseVertex(enum(),integer(),enum(),offset()|mem(),integer(),integer()) -> ok. +drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) when is_integer(Indices) -> + cast(5687, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Indices:?GLuint,Primcount:?GLsizei,Basevertex:?GLint>>); +drawElementsInstancedBaseVertex(Mode,Count,Type,Indices,Primcount,Basevertex) -> + send_bin(Indices), + cast(5688, <<Mode:?GLenum,Count:?GLsizei,Type:?GLenum,Primcount:?GLsizei,Basevertex:?GLint>>). + +%% @spec (Mode::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProvokingVertex.xml">external</a> documentation. +-spec provokingVertex(enum()) -> ok. +provokingVertex(Mode) -> + cast(5689, <<Mode:?GLenum>>). + +%% @spec (Condition::enum(),Flags::integer()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glFenceSync.xml">external</a> documentation. +-spec fenceSync(enum(),integer()) -> integer(). +fenceSync(Condition,Flags) -> + call(5690, <<Condition:?GLenum,Flags:?GLbitfield>>). + +%% @spec (Sync::integer()) -> 0|1 +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSync.xml">external</a> documentation. +-spec isSync(integer()) -> 0|1. +isSync(Sync) -> + call(5691, <<Sync:?GLsync>>). + +%% @spec (Sync::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSync.xml">external</a> documentation. +-spec deleteSync(integer()) -> ok. +deleteSync(Sync) -> + cast(5692, <<Sync:?GLsync>>). + +%% @spec (Sync::integer(),Flags::integer(),Timeout::integer()) -> enum() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClientWaitSync.xml">external</a> documentation. +-spec clientWaitSync(integer(),integer(),integer()) -> enum(). +clientWaitSync(Sync,Flags,Timeout) -> + call(5693, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>). + +%% @spec (Sync::integer(),Flags::integer(),Timeout::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWaitSync.xml">external</a> documentation. +-spec waitSync(integer(),integer(),integer()) -> ok. +waitSync(Sync,Flags,Timeout) -> + cast(5694, <<Sync:?GLsync,Flags:?GLbitfield,0:32,Timeout:?GLuint64>>). + +%% @spec (Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetInteger64v.xml">external</a> documentation. +-spec getInteger64v(enum()) -> [integer()]. +getInteger64v(Pname) -> + call(5695, <<Pname:?GLenum>>). + +%% @spec (Sync::integer(),Pname::enum(),BufSize::integer()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSync.xml">external</a> documentation. +-spec getSynciv(integer(),enum(),integer()) -> [integer()]. +getSynciv(Sync,Pname,BufSize) -> + call(5696, <<Sync:?GLsync,Pname:?GLenum,BufSize:?GLsizei>>). + +%% @spec (Target::enum(),Samples::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Fixedsamplelocations::0|1) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2DMultisample.xml">external</a> documentation. +-spec texImage2DMultisample(enum(),integer(),integer(),integer(),integer(),0|1) -> ok. +texImage2DMultisample(Target,Samples,Internalformat,Width,Height,Fixedsamplelocations) -> + cast(5697, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Fixedsamplelocations:?GLboolean>>). + +%% @spec (Target::enum(),Samples::integer(),Internalformat::integer(),Width::integer(),Height::integer(),Depth::integer(),Fixedsamplelocations::0|1) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3DMultisample.xml">external</a> documentation. +-spec texImage3DMultisample(enum(),integer(),integer(),integer(),integer(),integer(),0|1) -> ok. +texImage3DMultisample(Target,Samples,Internalformat,Width,Height,Depth,Fixedsamplelocations) -> + cast(5698, <<Target:?GLenum,Samples:?GLsizei,Internalformat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Fixedsamplelocations:?GLboolean>>). + +%% @spec (Pname::enum(),Index::integer()) -> {float(),float()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetMultisample.xml">external</a> documentation. +-spec getMultisamplefv(enum(),integer()) -> {float(),float()}. +getMultisamplefv(Pname,Index) -> + call(5699, <<Pname:?GLenum,Index:?GLuint>>). + +%% @spec (Index::integer(),Mask::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSampleMaski.xml">external</a> documentation. +-spec sampleMaski(integer(),integer()) -> ok. +sampleMaski(Index,Mask) -> + cast(5700, <<Index:?GLuint,Mask:?GLbitfield>>). + +%% @spec (Type::enum(),Name::string(),String::string()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glNamedStringARB.xml">external</a> documentation. +-spec namedStringARB(enum(),string(),string()) -> ok. +namedStringARB(Type,Name,String) -> + cast(5701, <<Type:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8),(list_to_binary([String|[0]]))/binary,0:((8-((length(String)+ 1) rem 8)) rem 8)>>). + +%% @spec (Name::string()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteNamedStringARB.xml">external</a> documentation. +-spec deleteNamedStringARB(string()) -> ok. +deleteNamedStringARB(Name) -> + cast(5702, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + +%% @spec (Shader::integer(),Path::[string()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCompileShaderIncludeARB.xml">external</a> documentation. +-spec compileShaderIncludeARB(integer(),[string()]) -> ok. +compileShaderIncludeARB(Shader,Path) -> + PathTemp = list_to_binary([[Str|[0]] || Str <- Path ]), + cast(5703, <<Shader:?GLuint,(length(Path)):?GLuint,(size(PathTemp)):?GLuint,(PathTemp)/binary,0:((8-((size(PathTemp)+0) rem 8)) rem 8)>>). + +%% @spec (Name::string()) -> 0|1 +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsNamedStringARB.xml">external</a> documentation. +-spec isNamedStringARB(string()) -> 0|1. +isNamedStringARB(Name) -> + call(5704, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + +%% @spec (Name::string(),BufSize::integer()) -> string() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation. +-spec getNamedStringARB(string(),integer()) -> string(). +getNamedStringARB(Name,BufSize) -> + call(5705, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),BufSize:?GLsizei>>). + +%% @spec (Name::string(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetNamedStringARB.xml">external</a> documentation. +-spec getNamedStringivARB(string(),enum()) -> integer(). +getNamedStringivARB(Name,Pname) -> + call(5706, <<(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8),Pname:?GLenum>>). + +%% @spec (Program::integer(),ColorNumber::integer(),Index::integer(),Name::string()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindFragDataLocationIndexe.xml">external</a> documentation. +-spec bindFragDataLocationIndexed(integer(),integer(),integer(),string()) -> ok. +bindFragDataLocationIndexed(Program,ColorNumber,Index,Name) -> + cast(5707, <<Program:?GLuint,ColorNumber:?GLuint,Index:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + +%% @spec (Program::integer(),Name::string()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFragDataIndex.xml">external</a> documentation. +-spec getFragDataIndex(integer(),string()) -> integer(). +getFragDataIndex(Program,Name) -> + call(5708, <<Program:?GLuint,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 5) rem 8)) rem 8)>>). + +%% @spec (Count::integer()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenSamplers.xml">external</a> documentation. +-spec genSamplers(integer()) -> [integer()]. +genSamplers(Count) -> + call(5709, <<Count:?GLsizei>>). + +%% @spec (Samplers::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteSamplers.xml">external</a> documentation. +-spec deleteSamplers([integer()]) -> ok. +deleteSamplers(Samplers) -> + cast(5710, <<(length(Samplers)):?GLuint, + (<< <<C:?GLuint>> || C <- Samplers>>)/binary,0:(((1+length(Samplers)) rem 2)*32)>>). + +%% @spec (Sampler::integer()) -> 0|1 +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsSampler.xml">external</a> documentation. +-spec isSampler(integer()) -> 0|1. +isSampler(Sampler) -> + call(5711, <<Sampler:?GLuint>>). + +%% @spec (Unit::integer(),Sampler::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindSampler.xml">external</a> documentation. +-spec bindSampler(integer(),integer()) -> ok. +bindSampler(Unit,Sampler) -> + cast(5712, <<Unit:?GLuint,Sampler:?GLuint>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation. +-spec samplerParameteri(integer(),enum(),integer()) -> ok. +samplerParameteri(Sampler,Pname,Param) -> + cast(5713, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLint>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation. +-spec samplerParameteriv(integer(),enum(),[integer()]) -> ok. +samplerParameteriv(Sampler,Pname,Param) -> + cast(5714, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint, + (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation. +-spec samplerParameterf(integer(),enum(),float()) -> ok. +samplerParameterf(Sampler,Pname,Param) -> + cast(5715, <<Sampler:?GLuint,Pname:?GLenum,Param:?GLfloat>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::[float()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameter.xml">external</a> documentation. +-spec samplerParameterfv(integer(),enum(),[float()]) -> ok. +samplerParameterfv(Sampler,Pname,Param) -> + cast(5716, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint, + (<< <<C:?GLfloat>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation. +-spec samplerParameterIiv(integer(),enum(),[integer()]) -> ok. +samplerParameterIiv(Sampler,Pname,Param) -> + cast(5717, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint, + (<< <<C:?GLint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>). + +%% @spec (Sampler::integer(),Pname::enum(),Param::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glSamplerParameterI.xml">external</a> documentation. +-spec samplerParameterIuiv(integer(),enum(),[integer()]) -> ok. +samplerParameterIuiv(Sampler,Pname,Param) -> + cast(5718, <<Sampler:?GLuint,Pname:?GLenum,(length(Param)):?GLuint, + (<< <<C:?GLuint>> || C <- Param>>)/binary,0:(((1+length(Param)) rem 2)*32)>>). + +%% @spec (Sampler::integer(),Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation. +-spec getSamplerParameteriv(integer(),enum()) -> [integer()]. +getSamplerParameteriv(Sampler,Pname) -> + call(5719, <<Sampler:?GLuint,Pname:?GLenum>>). + +%% @spec (Sampler::integer(),Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation. +-spec getSamplerParameterIiv(integer(),enum()) -> [integer()]. +getSamplerParameterIiv(Sampler,Pname) -> + call(5720, <<Sampler:?GLuint,Pname:?GLenum>>). + +%% @spec (Sampler::integer(),Pname::enum()) -> [float()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameter.xml">external</a> documentation. +-spec getSamplerParameterfv(integer(),enum()) -> [float()]. +getSamplerParameterfv(Sampler,Pname) -> + call(5721, <<Sampler:?GLuint,Pname:?GLenum>>). + +%% @spec (Sampler::integer(),Pname::enum()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSamplerParameterI.xml">external</a> documentation. +-spec getSamplerParameterIuiv(integer(),enum()) -> [integer()]. +getSamplerParameterIuiv(Sampler,Pname) -> + call(5722, <<Sampler:?GLuint,Pname:?GLenum>>). + +%% @spec (Id::integer(),Target::enum()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glQueryCounter.xml">external</a> documentation. +-spec queryCounter(integer(),enum()) -> ok. +queryCounter(Id,Target) -> + cast(5723, <<Id:?GLuint,Target:?GLenum>>). + +%% @spec (Id::integer(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjecti64v.xml">external</a> documentation. +-spec getQueryObjecti64v(integer(),enum()) -> integer(). +getQueryObjecti64v(Id,Pname) -> + call(5724, <<Id:?GLuint,Pname:?GLenum>>). + +%% @spec (Id::integer(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryObjectui64v.xml">external</a> documentation. +-spec getQueryObjectui64v(integer(),enum()) -> integer(). +getQueryObjectui64v(Id,Pname) -> + call(5725, <<Id:?GLuint,Pname:?GLenum>>). + +%% @spec (Mode::enum(),Indirect::offset()|mem()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawArraysIndirect.xml">external</a> documentation. +-spec drawArraysIndirect(enum(),offset()|mem()) -> ok. +drawArraysIndirect(Mode,Indirect) when is_integer(Indirect) -> + cast(5726, <<Mode:?GLenum,Indirect:?GLuint>>); +drawArraysIndirect(Mode,Indirect) -> + send_bin(Indirect), + cast(5727, <<Mode:?GLenum>>). + +%% @spec (Mode::enum(),Type::enum(),Indirect::offset()|mem()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawElementsIndirect.xml">external</a> documentation. +-spec drawElementsIndirect(enum(),enum(),offset()|mem()) -> ok. +drawElementsIndirect(Mode,Type,Indirect) when is_integer(Indirect) -> + cast(5728, <<Mode:?GLenum,Type:?GLenum,Indirect:?GLuint>>); +drawElementsIndirect(Mode,Type,Indirect) -> + send_bin(Indirect), + cast(5729, <<Mode:?GLenum,Type:?GLenum>>). + +%% @spec (Location::integer(),X::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1d(integer(),float()) -> ok. +uniform1d(Location,X) -> + cast(5730, <<Location:?GLint,0:32,X:?GLdouble>>). + +%% @spec (Location::integer(),X::float(),Y::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2d(integer(),float(),float()) -> ok. +uniform2d(Location,X,Y) -> + cast(5731, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble>>). + +%% @spec (Location::integer(),X::float(),Y::float(),Z::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3d(integer(),float(),float(),float()) -> ok. +uniform3d(Location,X,Y,Z) -> + cast(5732, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + +%% @spec (Location::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4d(integer(),float(),float(),float(),float()) -> ok. +uniform4d(Location,X,Y,Z,W) -> + cast(5733, <<Location:?GLint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + +%% @spec (Location::integer(),Value::[float()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform1dv(integer(),[float()]) -> ok. +uniform1dv(Location,Value) -> + cast(5734, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32, + (<< <<C:?GLdouble>> || C <- Value>>)/binary>>). + +%% @spec (Location::integer(),Value::[{float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform2dv(integer(),[{float(),float()}]) -> ok. +uniform2dv(Location,Value) -> + cast(5735, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Value::[{float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform3dv(integer(),[{float(),float(),float()}]) -> ok. +uniform3dv(Location,Value) -> + cast(5736, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml">external</a> documentation. +-spec uniform4dv(integer(),[{float(),float(),float(),float()}]) -> ok. +uniform4dv(Location,Value) -> + cast(5737, <<Location:?GLint,0:32,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix2dv(integer(),0|1,[{float(),float(),float(),float()}]) -> ok. +uniformMatrix2dv(Location,Transpose,Value) -> + cast(5738, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix3dv(Location,Transpose,Value) -> + cast(5739, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix.xml">external</a> documentation. +-spec uniformMatrix4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix4dv(Location,Transpose,Value) -> + cast(5740, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation. +-spec uniformMatrix2x3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix2x3dv(Location,Transpose,Value) -> + cast(5741, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix2x.xml">external</a> documentation. +-spec uniformMatrix2x4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix2x4dv(Location,Transpose,Value) -> + cast(5742, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation. +-spec uniformMatrix3x2dv(integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix3x2dv(Location,Transpose,Value) -> + cast(5743, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix3x.xml">external</a> documentation. +-spec uniformMatrix3x4dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix3x4dv(Location,Transpose,Value) -> + cast(5744, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation. +-spec uniformMatrix4x2dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix4x2dv(Location,Transpose,Value) -> + cast(5745, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformMatrix4x.xml">external</a> documentation. +-spec uniformMatrix4x3dv(integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +uniformMatrix4x3dv(Location,Transpose,Value) -> + cast(5746, <<Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml">external</a> documentation. +-spec getUniformdv(integer(),integer()) -> {float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}. +getUniformdv(Program,Location) -> + call(5747, <<Program:?GLuint,Location:?GLint>>). + +%% @spec (Program::integer(),Shadertype::enum(),Name::string()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineUniformLocation.xml">external</a> documentation. +-spec getSubroutineUniformLocation(integer(),enum(),string()) -> integer(). +getSubroutineUniformLocation(Program,Shadertype,Name) -> + call(5748, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + +%% @spec (Program::integer(),Shadertype::enum(),Name::string()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetSubroutineIndex.xml">external</a> documentation. +-spec getSubroutineIndex(integer(),enum(),string()) -> integer(). +getSubroutineIndex(Program,Shadertype,Name) -> + call(5749, <<Program:?GLuint,Shadertype:?GLenum,(list_to_binary([Name|[0]]))/binary,0:((8-((length(Name)+ 1) rem 8)) rem 8)>>). + +%% @spec (Program::integer(),Shadertype::enum(),Index::integer(),Bufsize::integer()) -> string() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineUniformName.xml">external</a> documentation. +-spec getActiveSubroutineUniformName(integer(),enum(),integer(),integer()) -> string(). +getActiveSubroutineUniformName(Program,Shadertype,Index,Bufsize) -> + call(5750, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>). + +%% @spec (Program::integer(),Shadertype::enum(),Index::integer(),Bufsize::integer()) -> string() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetActiveSubroutineName.xml">external</a> documentation. +-spec getActiveSubroutineName(integer(),enum(),integer(),integer()) -> string(). +getActiveSubroutineName(Program,Shadertype,Index,Bufsize) -> + call(5751, <<Program:?GLuint,Shadertype:?GLenum,Index:?GLuint,Bufsize:?GLsizei>>). + +%% @spec (Shadertype::enum(),Indices::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUniformSubroutines.xml">external</a> documentation. +-spec uniformSubroutinesuiv(enum(),[integer()]) -> ok. +uniformSubroutinesuiv(Shadertype,Indices) -> + cast(5752, <<Shadertype:?GLenum,(length(Indices)):?GLuint, + (<< <<C:?GLuint>> || C <- Indices>>)/binary,0:(((length(Indices)) rem 2)*32)>>). + +%% @spec (Shadertype::enum(),Location::integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformSubroutine.xml">external</a> documentation. +-spec getUniformSubroutineuiv(enum(),integer()) -> {integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer(),integer()}. +getUniformSubroutineuiv(Shadertype,Location) -> + call(5753, <<Shadertype:?GLenum,Location:?GLint>>). + +%% @spec (Program::integer(),Shadertype::enum(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramStage.xml">external</a> documentation. +-spec getProgramStageiv(integer(),enum(),enum()) -> integer(). +getProgramStageiv(Program,Shadertype,Pname) -> + call(5754, <<Program:?GLuint,Shadertype:?GLenum,Pname:?GLenum>>). + +%% @spec (Pname::enum(),Value::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation. +-spec patchParameteri(enum(),integer()) -> ok. +patchParameteri(Pname,Value) -> + cast(5755, <<Pname:?GLenum,Value:?GLint>>). + +%% @spec (Pname::enum(),Values::[float()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPatchParameter.xml">external</a> documentation. +-spec patchParameterfv(enum(),[float()]) -> ok. +patchParameterfv(Pname,Values) -> + cast(5756, <<Pname:?GLenum,(length(Values)):?GLuint, + (<< <<C:?GLfloat>> || C <- Values>>)/binary,0:(((length(Values)) rem 2)*32)>>). + +%% @spec (Target::enum(),Id::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTransformFeedback.xml">external</a> documentation. +-spec bindTransformFeedback(enum(),integer()) -> ok. +bindTransformFeedback(Target,Id) -> + cast(5757, <<Target:?GLenum,Id:?GLuint>>). + +%% @spec (Ids::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteTransformFeedbacks.xml">external</a> documentation. +-spec deleteTransformFeedbacks([integer()]) -> ok. +deleteTransformFeedbacks(Ids) -> + cast(5758, <<(length(Ids)):?GLuint, + (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((1+length(Ids)) rem 2)*32)>>). + +%% @spec (N::integer()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenTransformFeedbacks.xml">external</a> documentation. +-spec genTransformFeedbacks(integer()) -> [integer()]. +genTransformFeedbacks(N) -> + call(5759, <<N:?GLsizei>>). + +%% @spec (Id::integer()) -> 0|1 +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsTransformFeedback.xml">external</a> documentation. +-spec isTransformFeedback(integer()) -> 0|1. +isTransformFeedback(Id) -> + call(5760, <<Id:?GLuint>>). + +%% @spec () -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glPauseTransformFeedback.xml">external</a> documentation. +-spec pauseTransformFeedback() -> ok. +pauseTransformFeedback() -> + cast(5761, <<>>). + +%% @spec () -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResumeTransformFeedback.xml">external</a> documentation. +-spec resumeTransformFeedback() -> ok. +resumeTransformFeedback() -> + cast(5762, <<>>). + +%% @spec (Mode::enum(),Id::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedback.xml">external</a> documentation. +-spec drawTransformFeedback(enum(),integer()) -> ok. +drawTransformFeedback(Mode,Id) -> + cast(5763, <<Mode:?GLenum,Id:?GLuint>>). + +%% @spec (Mode::enum(),Id::integer(),Stream::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDrawTransformFeedbackStream.xml">external</a> documentation. +-spec drawTransformFeedbackStream(enum(),integer(),integer()) -> ok. +drawTransformFeedbackStream(Mode,Id,Stream) -> + cast(5764, <<Mode:?GLenum,Id:?GLuint,Stream:?GLuint>>). + +%% @spec (Target::enum(),Index::integer(),Id::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBeginQueryIndexe.xml">external</a> documentation. +-spec beginQueryIndexed(enum(),integer(),integer()) -> ok. +beginQueryIndexed(Target,Index,Id) -> + cast(5765, <<Target:?GLenum,Index:?GLuint,Id:?GLuint>>). + +%% @spec (Target::enum(),Index::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glEndQueryIndexe.xml">external</a> documentation. +-spec endQueryIndexed(enum(),integer()) -> ok. +endQueryIndexed(Target,Index) -> + cast(5766, <<Target:?GLenum,Index:?GLuint>>). + +%% @spec (Target::enum(),Index::integer(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetQueryIndexed.xml">external</a> documentation. +-spec getQueryIndexediv(enum(),integer(),enum()) -> integer(). +getQueryIndexediv(Target,Index,Pname) -> + call(5767, <<Target:?GLenum,Index:?GLuint,Pname:?GLenum>>). + +%% @spec () -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glReleaseShaderCompiler.xml">external</a> documentation. +-spec releaseShaderCompiler() -> ok. +releaseShaderCompiler() -> + cast(5768, <<>>). + +%% @spec (Shaders::[integer()],Binaryformat::enum(),Binary::binary()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glShaderBinary.xml">external</a> documentation. +-spec shaderBinary([integer()],enum(),binary()) -> ok. +shaderBinary(Shaders,Binaryformat,Binary) -> + send_bin(Binary), + cast(5769, <<(length(Shaders)):?GLuint, + (<< <<C:?GLuint>> || C <- Shaders>>)/binary,0:(((1+length(Shaders)) rem 2)*32),Binaryformat:?GLenum>>). + +%% @spec (Shadertype::enum(),Precisiontype::enum()) -> {Range::{integer(),integer()},Precision::integer()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetShaderPrecisionFormat.xml">external</a> documentation. +-spec getShaderPrecisionFormat(enum(),enum()) -> {{integer(),integer()},integer()}. +getShaderPrecisionFormat(Shadertype,Precisiontype) -> + call(5770, <<Shadertype:?GLenum,Precisiontype:?GLenum>>). + +%% @spec (N::clamp(),F::clamp()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRange.xml">external</a> documentation. +-spec depthRangef(clamp(),clamp()) -> ok. +depthRangef(N,F) -> + cast(5771, <<N:?GLclampf,F:?GLclampf>>). + +%% @spec (D::clamp()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glClearDepthf.xml">external</a> documentation. +-spec clearDepthf(clamp()) -> ok. +clearDepthf(D) -> + cast(5772, <<D:?GLclampf>>). + +%% @spec (Program::integer(),BufSize::integer()) -> {BinaryFormat::enum(),Binary::binary()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramBinary.xml">external</a> documentation. +-spec getProgramBinary(integer(),integer()) -> {enum(),binary()}. +getProgramBinary(Program,BufSize) -> + call(5773, <<Program:?GLuint,BufSize:?GLsizei>>). + +%% @spec (Program::integer(),BinaryFormat::enum(),Binary::binary()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramBinary.xml">external</a> documentation. +-spec programBinary(integer(),enum(),binary()) -> ok. +programBinary(Program,BinaryFormat,Binary) -> + send_bin(Binary), + cast(5774, <<Program:?GLuint,BinaryFormat:?GLenum>>). + +%% @spec (Program::integer(),Pname::enum(),Value::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramParameter.xml">external</a> documentation. +-spec programParameteri(integer(),enum(),integer()) -> ok. +programParameteri(Program,Pname,Value) -> + cast(5775, <<Program:?GLuint,Pname:?GLenum,Value:?GLint>>). + +%% @spec (Pipeline::integer(),Stages::integer(),Program::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glUseProgramStages.xml">external</a> documentation. +-spec useProgramStages(integer(),integer(),integer()) -> ok. +useProgramStages(Pipeline,Stages,Program) -> + cast(5776, <<Pipeline:?GLuint,Stages:?GLbitfield,Program:?GLuint>>). + +%% @spec (Pipeline::integer(),Program::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glActiveShaderProgram.xml">external</a> documentation. +-spec activeShaderProgram(integer(),integer()) -> ok. +activeShaderProgram(Pipeline,Program) -> + cast(5777, <<Pipeline:?GLuint,Program:?GLuint>>). + +%% @spec (Type::enum(),Strings::[string()]) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glCreateShaderProgramv.xml">external</a> documentation. +-spec createShaderProgramv(enum(),[string()]) -> integer(). +createShaderProgramv(Type,Strings) -> + StringsTemp = list_to_binary([[Str|[0]] || Str <- Strings ]), + call(5778, <<Type:?GLenum,(length(Strings)):?GLuint,(size(StringsTemp)):?GLuint,(StringsTemp)/binary,0:((8-((size(StringsTemp)+0) rem 8)) rem 8)>>). + +%% @spec (Pipeline::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindProgramPipeline.xml">external</a> documentation. +-spec bindProgramPipeline(integer()) -> ok. +bindProgramPipeline(Pipeline) -> + cast(5779, <<Pipeline:?GLuint>>). + +%% @spec (Pipelines::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDeleteProgramPipelines.xml">external</a> documentation. +-spec deleteProgramPipelines([integer()]) -> ok. +deleteProgramPipelines(Pipelines) -> + cast(5780, <<(length(Pipelines)):?GLuint, + (<< <<C:?GLuint>> || C <- Pipelines>>)/binary,0:(((1+length(Pipelines)) rem 2)*32)>>). + +%% @spec (N::integer()) -> [integer()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGenProgramPipelines.xml">external</a> documentation. +-spec genProgramPipelines(integer()) -> [integer()]. +genProgramPipelines(N) -> + call(5781, <<N:?GLsizei>>). + +%% @spec (Pipeline::integer()) -> 0|1 +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glIsProgramPipeline.xml">external</a> documentation. +-spec isProgramPipeline(integer()) -> 0|1. +isProgramPipeline(Pipeline) -> + call(5782, <<Pipeline:?GLuint>>). + +%% @spec (Pipeline::integer(),Pname::enum()) -> integer() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipeline.xml">external</a> documentation. +-spec getProgramPipelineiv(integer(),enum()) -> integer(). +getProgramPipelineiv(Pipeline,Pname) -> + call(5783, <<Pipeline:?GLuint,Pname:?GLenum>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1i(integer(),integer(),integer()) -> ok. +programUniform1i(Program,Location,V0) -> + cast(5784, <<Program:?GLuint,Location:?GLint,V0:?GLint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1iv(integer(),integer(),[integer()]) -> ok. +programUniform1iv(Program,Location,Value) -> + cast(5785, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<C:?GLint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>). + +%% @spec (Program::integer(),Location::integer(),V0::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1f(integer(),integer(),float()) -> ok. +programUniform1f(Program,Location,V0) -> + cast(5786, <<Program:?GLuint,Location:?GLint,V0:?GLfloat>>). + +%% @spec (Program::integer(),Location::integer(),Value::[float()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1fv(integer(),integer(),[float()]) -> ok. +programUniform1fv(Program,Location,Value) -> + cast(5787, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<C:?GLfloat>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>). + +%% @spec (Program::integer(),Location::integer(),V0::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1d(integer(),integer(),float()) -> ok. +programUniform1d(Program,Location,V0) -> + cast(5788, <<Program:?GLuint,Location:?GLint,V0:?GLdouble>>). + +%% @spec (Program::integer(),Location::integer(),Value::[float()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1dv(integer(),integer(),[float()]) -> ok. +programUniform1dv(Program,Location,Value) -> + cast(5789, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32, + (<< <<C:?GLdouble>> || C <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1ui(integer(),integer(),integer()) -> ok. +programUniform1ui(Program,Location,V0) -> + cast(5790, <<Program:?GLuint,Location:?GLint,V0:?GLuint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[integer()]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform1uiv(integer(),integer(),[integer()]) -> ok. +programUniform1uiv(Program,Location,Value) -> + cast(5791, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<C:?GLuint>> || C <- Value>>)/binary,0:(((1+length(Value)) rem 2)*32)>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2i(integer(),integer(),integer(),integer()) -> ok. +programUniform2i(Program,Location,V0,V1) -> + cast(5792, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2iv(integer(),integer(),[{integer(),integer()}]) -> ok. +programUniform2iv(Program,Location,Value) -> + cast(5793, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLint,V2:?GLint>> || {V1,V2} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2f(integer(),integer(),float(),float()) -> ok. +programUniform2f(Program,Location,V0,V1) -> + cast(5794, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2fv(integer(),integer(),[{float(),float()}]) -> ok. +programUniform2fv(Program,Location,Value) -> + cast(5795, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat>> || {V1,V2} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2d(integer(),integer(),float(),float()) -> ok. +programUniform2d(Program,Location,V0,V1) -> + cast(5796, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2dv(integer(),integer(),[{float(),float()}]) -> ok. +programUniform2dv(Program,Location,Value) -> + cast(5797, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble>> || {V1,V2} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2ui(integer(),integer(),integer(),integer()) -> ok. +programUniform2ui(Program,Location,V0,V1) -> + cast(5798, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform2uiv(integer(),integer(),[{integer(),integer()}]) -> ok. +programUniform2uiv(Program,Location,Value) -> + cast(5799, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLuint,V2:?GLuint>> || {V1,V2} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3i(integer(),integer(),integer(),integer(),integer()) -> ok. +programUniform3i(Program,Location,V0,V1,V2) -> + cast(5800, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3iv(integer(),integer(),[{integer(),integer(),integer()}]) -> ok. +programUniform3iv(Program,Location,Value) -> + cast(5801, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLint,V2:?GLint,V3:?GLint>> || {V1,V2,V3} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3f(integer(),integer(),float(),float(),float()) -> ok. +programUniform3f(Program,Location,V0,V1,V2) -> + cast(5802, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3fv(integer(),integer(),[{float(),float(),float()}]) -> ok. +programUniform3fv(Program,Location,Value) -> + cast(5803, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>> || {V1,V2,V3} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3d(integer(),integer(),float(),float(),float()) -> ok. +programUniform3d(Program,Location,V0,V1,V2) -> + cast(5804, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3dv(integer(),integer(),[{float(),float(),float()}]) -> ok. +programUniform3dv(Program,Location,Value) -> + cast(5805, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>> || {V1,V2,V3} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3ui(integer(),integer(),integer(),integer(),integer()) -> ok. +programUniform3ui(Program,Location,V0,V1,V2) -> + cast(5806, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform3uiv(integer(),integer(),[{integer(),integer(),integer()}]) -> ok. +programUniform3uiv(Program,Location,Value) -> + cast(5807, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint>> || {V1,V2,V3} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4i(integer(),integer(),integer(),integer(),integer(),integer()) -> ok. +programUniform4i(Program,Location,V0,V1,V2,V3) -> + cast(5808, <<Program:?GLuint,Location:?GLint,V0:?GLint,V1:?GLint,V2:?GLint,V3:?GLint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4iv(integer(),integer(),[{integer(),integer(),integer(),integer()}]) -> ok. +programUniform4iv(Program,Location,Value) -> + cast(5809, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4f(integer(),integer(),float(),float(),float(),float()) -> ok. +programUniform4f(Program,Location,V0,V1,V2,V3) -> + cast(5810, <<Program:?GLuint,Location:?GLint,V0:?GLfloat,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4fv(integer(),integer(),[{float(),float(),float(),float()}]) -> ok. +programUniform4fv(Program,Location,Value) -> + cast(5811, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::float(),V1::float(),V2::float(),V3::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4d(integer(),integer(),float(),float(),float(),float()) -> ok. +programUniform4d(Program,Location,V0,V1,V2,V3) -> + cast(5812, <<Program:?GLuint,Location:?GLint,V0:?GLdouble,V1:?GLdouble,V2:?GLdouble,V3:?GLdouble>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4dv(integer(),integer(),[{float(),float(),float(),float()}]) -> ok. +programUniform4dv(Program,Location,Value) -> + cast(5813, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),V0::integer(),V1::integer(),V2::integer(),V3::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4ui(integer(),integer(),integer(),integer(),integer(),integer()) -> ok. +programUniform4ui(Program,Location,V0,V1,V2,V3) -> + cast(5814, <<Program:?GLuint,Location:?GLint,V0:?GLuint,V1:?GLuint,V2:?GLuint,V3:?GLuint>>). + +%% @spec (Program::integer(),Location::integer(),Value::[{integer(),integer(),integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniform.xml">external</a> documentation. +-spec programUniform4uiv(integer(),integer(),[{integer(),integer(),integer(),integer()}]) -> ok. +programUniform4uiv(Program,Location,Value) -> + cast(5815, <<Program:?GLuint,Location:?GLint,(length(Value)):?GLuint, + (<< <<V1:?GLuint,V2:?GLuint,V3:?GLuint,V4:?GLuint>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix2fv(integer(),integer(),0|1,[{float(),float(),float(),float()}]) -> ok. +programUniformMatrix2fv(Program,Location,Transpose,Value) -> + cast(5816, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3fv(Program,Location,Transpose,Value) -> + cast(5817, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4fv(Program,Location,Transpose,Value) -> + cast(5818, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat,V13:?GLfloat,V14:?GLfloat,V15:?GLfloat,V16:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix2dv(integer(),integer(),0|1,[{float(),float(),float(),float()}]) -> ok. +programUniformMatrix2dv(Program,Location,Transpose,Value) -> + cast(5819, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble>> || {V1,V2,V3,V4} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3dv(Program,Location,Transpose,Value) -> + cast(5820, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix.xml">external</a> documentation. +-spec programUniformMatrix4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4dv(Program,Location,Transpose,Value) -> + cast(5821, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble,V13:?GLdouble,V14:?GLdouble,V15:?GLdouble,V16:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation. +-spec programUniformMatrix2x3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix2x3fv(Program,Location,Transpose,Value) -> + cast(5822, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation. +-spec programUniformMatrix3x2fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3x2fv(Program,Location,Transpose,Value) -> + cast(5823, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation. +-spec programUniformMatrix2x4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix2x4fv(Program,Location,Transpose,Value) -> + cast(5824, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation. +-spec programUniformMatrix4x2fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4x2fv(Program,Location,Transpose,Value) -> + cast(5825, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation. +-spec programUniformMatrix3x4fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3x4fv(Program,Location,Transpose,Value) -> + cast(5826, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation. +-spec programUniformMatrix4x3fv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4x3fv(Program,Location,Transpose,Value) -> + cast(5827, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:24,(length(Value)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat,V5:?GLfloat,V6:?GLfloat,V7:?GLfloat,V8:?GLfloat,V9:?GLfloat,V10:?GLfloat,V11:?GLfloat,V12:?GLfloat>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation. +-spec programUniformMatrix2x3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix2x3dv(Program,Location,Transpose,Value) -> + cast(5828, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation. +-spec programUniformMatrix3x2dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3x2dv(Program,Location,Transpose,Value) -> + cast(5829, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble>> || {V1,V2,V3,V4,V5,V6} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix2x.xml">external</a> documentation. +-spec programUniformMatrix2x4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix2x4dv(Program,Location,Transpose,Value) -> + cast(5830, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation. +-spec programUniformMatrix4x2dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4x2dv(Program,Location,Transpose,Value) -> + cast(5831, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix3x.xml">external</a> documentation. +-spec programUniformMatrix3x4dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix3x4dv(Program,Location,Transpose,Value) -> + cast(5832, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Program::integer(),Location::integer(),Transpose::0|1,Value::[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glProgramUniformMatrix4x.xml">external</a> documentation. +-spec programUniformMatrix4x3dv(integer(),integer(),0|1,[{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()}]) -> ok. +programUniformMatrix4x3dv(Program,Location,Transpose,Value) -> + cast(5833, <<Program:?GLuint,Location:?GLint,Transpose:?GLboolean,0:56,(length(Value)):?GLuint,0:32, + (<< <<V1:?GLdouble,V2:?GLdouble,V3:?GLdouble,V4:?GLdouble,V5:?GLdouble,V6:?GLdouble,V7:?GLdouble,V8:?GLdouble,V9:?GLdouble,V10:?GLdouble,V11:?GLdouble,V12:?GLdouble>> || {V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12} <- Value>>)/binary>>). + +%% @spec (Pipeline::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glValidateProgramPipeline.xml">external</a> documentation. +-spec validateProgramPipeline(integer()) -> ok. +validateProgramPipeline(Pipeline) -> + cast(5834, <<Pipeline:?GLuint>>). + +%% @spec (Pipeline::integer(),BufSize::integer()) -> string() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetProgramPipelineInfoLog.xml">external</a> documentation. +-spec getProgramPipelineInfoLog(integer(),integer()) -> string(). +getProgramPipelineInfoLog(Pipeline,BufSize) -> + call(5835, <<Pipeline:?GLuint,BufSize:?GLsizei>>). + +%% @spec (Index::integer(),X::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation. +-spec vertexAttribL1d(integer(),float()) -> ok. +vertexAttribL1d(Index,X) -> + cast(5836, <<Index:?GLuint,0:32,X:?GLdouble>>). + +%% @spec (Index::integer(),X::float(),Y::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation. +-spec vertexAttribL2d(integer(),float(),float()) -> ok. +vertexAttribL2d(Index,X,Y) -> + cast(5837, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble>>). + +%% @spec (Index::integer(),X::float(),Y::float(),Z::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation. +-spec vertexAttribL3d(integer(),float(),float(),float()) -> ok. +vertexAttribL3d(Index,X,Y,Z) -> + cast(5838, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble>>). + +%% @spec (Index::integer(),X::float(),Y::float(),Z::float(),W::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribL.xml">external</a> documentation. +-spec vertexAttribL4d(integer(),float(),float(),float(),float()) -> ok. +vertexAttribL4d(Index,X,Y,Z,W) -> + cast(5839, <<Index:?GLuint,0:32,X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + +%% @spec (Index,{X}) -> ok +%% @equiv vertexAttribL1d(Index,X) +-spec vertexAttribL1dv(integer(),{float()}) -> ok. +vertexAttribL1dv(Index,{X}) -> vertexAttribL1d(Index,X). + +%% @spec (Index,{X,Y}) -> ok +%% @equiv vertexAttribL2d(Index,X,Y) +-spec vertexAttribL2dv(integer(),{float(),float()}) -> ok. +vertexAttribL2dv(Index,{X,Y}) -> vertexAttribL2d(Index,X,Y). + +%% @spec (Index,{X,Y,Z}) -> ok +%% @equiv vertexAttribL3d(Index,X,Y,Z) +-spec vertexAttribL3dv(integer(),{float(),float(),float()}) -> ok. +vertexAttribL3dv(Index,{X,Y,Z}) -> vertexAttribL3d(Index,X,Y,Z). + +%% @spec (Index,{X,Y,Z,W}) -> ok +%% @equiv vertexAttribL4d(Index,X,Y,Z,W) +-spec vertexAttribL4dv(integer(),{float(),float(),float(),float()}) -> ok. +vertexAttribL4dv(Index,{X,Y,Z,W}) -> vertexAttribL4d(Index,X,Y,Z,W). + +%% @spec (Index::integer(),Size::integer(),Type::enum(),Stride::integer(),Pointer::offset()|mem()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glVertexAttribLPointer.xml">external</a> documentation. +-spec vertexAttribLPointer(integer(),integer(),enum(),integer(),offset()|mem()) -> ok. +vertexAttribLPointer(Index,Size,Type,Stride,Pointer) when is_integer(Pointer) -> + cast(5840, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei,Pointer:?GLuint>>); +vertexAttribLPointer(Index,Size,Type,Stride,Pointer) -> + send_bin(Pointer), + cast(5841, <<Index:?GLuint,Size:?GLint,Type:?GLenum,Stride:?GLsizei>>). + +%% @spec (Index::integer(),Pname::enum()) -> {float(),float(),float(),float()} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetVertexAttribL.xml">external</a> documentation. +-spec getVertexAttribLdv(integer(),enum()) -> {float(),float(),float(),float()}. +getVertexAttribLdv(Index,Pname) -> + call(5842, <<Index:?GLuint,Pname:?GLenum>>). + +%% @spec (First::integer(),V::[{float(),float(),float(),float()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportArrayv.xml">external</a> documentation. +-spec viewportArrayv(integer(),[{float(),float(),float(),float()}]) -> ok. +viewportArrayv(First,V) -> + cast(5843, <<First:?GLuint,(length(V)):?GLuint, + (<< <<V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>> || {V1,V2,V3,V4} <- V>>)/binary>>). + +%% @spec (Index::integer(),X::float(),Y::float(),W::float(),H::float()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation. +-spec viewportIndexedf(integer(),float(),float(),float(),float()) -> ok. +viewportIndexedf(Index,X,Y,W,H) -> + cast(5844, <<Index:?GLuint,X:?GLfloat,Y:?GLfloat,W:?GLfloat,H:?GLfloat>>). + +%% @spec (Index::integer(),V::{float(),float(),float(),float()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glViewportIndexed.xml">external</a> documentation. +-spec viewportIndexedfv(integer(),{float(),float(),float(),float()}) -> ok. +viewportIndexedfv(Index,{V1,V2,V3,V4}) -> + cast(5845, <<Index:?GLuint,V1:?GLfloat,V2:?GLfloat,V3:?GLfloat,V4:?GLfloat>>). + +%% @spec (First::integer(),V::[{integer(),integer(),integer(),integer()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorArrayv.xml">external</a> documentation. +-spec scissorArrayv(integer(),[{integer(),integer(),integer(),integer()}]) -> ok. +scissorArrayv(First,V) -> + cast(5846, <<First:?GLuint,(length(V)):?GLuint, + (<< <<V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>> || {V1,V2,V3,V4} <- V>>)/binary>>). + +%% @spec (Index::integer(),Left::integer(),Bottom::integer(),Width::integer(),Height::integer()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation. +-spec scissorIndexed(integer(),integer(),integer(),integer(),integer()) -> ok. +scissorIndexed(Index,Left,Bottom,Width,Height) -> + cast(5847, <<Index:?GLuint,Left:?GLint,Bottom:?GLint,Width:?GLsizei,Height:?GLsizei>>). + +%% @spec (Index::integer(),V::{integer(),integer(),integer(),integer()}) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glScissorIndexe.xml">external</a> documentation. +-spec scissorIndexedv(integer(),{integer(),integer(),integer(),integer()}) -> ok. +scissorIndexedv(Index,{V1,V2,V3,V4}) -> + cast(5848, <<Index:?GLuint,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + +%% @spec (First::integer(),V::[{clamp(),clamp()}]) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeArrayv.xml">external</a> documentation. +-spec depthRangeArrayv(integer(),[{clamp(),clamp()}]) -> ok. +depthRangeArrayv(First,V) -> + cast(5849, <<First:?GLuint,0:32,(length(V)):?GLuint,0:32, + (<< <<V1:?GLclampd,V2:?GLclampd>> || {V1,V2} <- V>>)/binary>>). + +%% @spec (Index::integer(),N::clamp(),F::clamp()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthRangeIndexe.xml">external</a> documentation. +-spec depthRangeIndexed(integer(),clamp(),clamp()) -> ok. +depthRangeIndexed(Index,N,F) -> + cast(5850, <<Index:?GLuint,0:32,N:?GLclampd,F:?GLclampd>>). + +%% @spec (Target::enum(),Index::integer()) -> [float()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetFloati_v.xml">external</a> documentation. +-spec getFloati_v(enum(),integer()) -> [float()]. +getFloati_v(Target,Index) -> + call(5851, <<Target:?GLenum,Index:?GLuint>>). + +%% @spec (Target::enum(),Index::integer()) -> [float()] +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDoublei_v.xml">external</a> documentation. +-spec getDoublei_v(enum(),integer()) -> [float()]. +getDoublei_v(Target,Index) -> + call(5852, <<Target:?GLenum,Index:?GLuint>>). + +%% @spec (Source::enum(),Type::enum(),Severity::enum(),Ids::[integer()],Enabled::0|1) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageControlARB.xml">external</a> documentation. +-spec debugMessageControlARB(enum(),enum(),enum(),[integer()],0|1) -> ok. +debugMessageControlARB(Source,Type,Severity,Ids,Enabled) -> + cast(5853, <<Source:?GLenum,Type:?GLenum,Severity:?GLenum,(length(Ids)):?GLuint, + (<< <<C:?GLuint>> || C <- Ids>>)/binary,0:(((length(Ids)) rem 2)*32),Enabled:?GLboolean>>). + +%% @spec (Source::enum(),Type::enum(),Id::integer(),Severity::enum(),Buf::string()) -> ok +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDebugMessageInsertARB.xml">external</a> documentation. +-spec debugMessageInsertARB(enum(),enum(),integer(),enum(),string()) -> ok. +debugMessageInsertARB(Source,Type,Id,Severity,Buf) -> + cast(5854, <<Source:?GLenum,Type:?GLenum,Id:?GLuint,Severity:?GLenum,(list_to_binary([Buf|[0]]))/binary,0:((8-((length(Buf)+ 1) rem 8)) rem 8)>>). + +%% @spec (Count::integer(),Bufsize::integer()) -> {integer(),Sources::[enum()],Types::[enum()],Ids::[integer()],Severities::[enum()],MessageLog::[string()]} +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetDebugMessageLogARB.xml">external</a> documentation. +-spec getDebugMessageLogARB(integer(),integer()) -> {integer(),[enum()],[enum()],[integer()],[enum()],[string()]}. +getDebugMessageLogARB(Count,Bufsize) -> + call(5855, <<Count:?GLuint,Bufsize:?GLsizei>>). + +%% @spec () -> enum() +%% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glGetGraphicsResetStatusARB.xml">external</a> documentation. +-spec getGraphicsResetStatusARB() -> enum(). +getGraphicsResetStatusARB() -> + call(5856, <<>>). %% @spec () -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glResizeBuffersMESA.xml">external</a> documentation. +-spec resizeBuffersMESA() -> ok. resizeBuffersMESA() -> - wxe_util:cast(5676, <<>>). + cast(5857, <<>>). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4dMESA.xml">external</a> documentation. +-spec windowPos4dMESA(float(),float(),float(),float()) -> ok. windowPos4dMESA(X,Y,Z,W) -> - wxe_util:cast(5677, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). + cast(5858, <<X:?GLdouble,Y:?GLdouble,Z:?GLdouble,W:?GLdouble>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv windowPos4dMESA(X,Y,Z,W) +-spec windowPos4dvMESA({float(),float(),float(),float()}) -> ok. windowPos4dvMESA({X,Y,Z,W}) -> windowPos4dMESA(X,Y,Z,W). %% @spec (X::float(),Y::float(),Z::float(),W::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4fMESA.xml">external</a> documentation. +-spec windowPos4fMESA(float(),float(),float(),float()) -> ok. windowPos4fMESA(X,Y,Z,W) -> - wxe_util:cast(5678, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). + cast(5859, <<X:?GLfloat,Y:?GLfloat,Z:?GLfloat,W:?GLfloat>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv windowPos4fMESA(X,Y,Z,W) +-spec windowPos4fvMESA({float(),float(),float(),float()}) -> ok. windowPos4fvMESA({X,Y,Z,W}) -> windowPos4fMESA(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4iMESA.xml">external</a> documentation. +-spec windowPos4iMESA(integer(),integer(),integer(),integer()) -> ok. windowPos4iMESA(X,Y,Z,W) -> - wxe_util:cast(5679, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). + cast(5860, <<X:?GLint,Y:?GLint,Z:?GLint,W:?GLint>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv windowPos4iMESA(X,Y,Z,W) +-spec windowPos4ivMESA({integer(),integer(),integer(),integer()}) -> ok. windowPos4ivMESA({X,Y,Z,W}) -> windowPos4iMESA(X,Y,Z,W). %% @spec (X::integer(),Y::integer(),Z::integer(),W::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glWindowPos4sMESA.xml">external</a> documentation. +-spec windowPos4sMESA(integer(),integer(),integer(),integer()) -> ok. windowPos4sMESA(X,Y,Z,W) -> - wxe_util:cast(5680, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). + cast(5861, <<X:?GLshort,Y:?GLshort,Z:?GLshort,W:?GLshort>>). %% @spec ({X,Y,Z,W}) -> ok %% @equiv windowPos4sMESA(X,Y,Z,W) +-spec windowPos4svMESA({integer(),integer(),integer(),integer()}) -> ok. windowPos4svMESA({X,Y,Z,W}) -> windowPos4sMESA(X,Y,Z,W). %% @spec (Zmin::clamp(),Zmax::clamp()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glDepthBoundsEXT.xml">external</a> documentation. +-spec depthBoundsEXT(clamp(),clamp()) -> ok. depthBoundsEXT(Zmin,Zmax) -> - wxe_util:cast(5681, <<Zmin:?GLclampd,Zmax:?GLclampd>>). + cast(5862, <<Zmin:?GLclampd,Zmax:?GLclampd>>). %% @spec (StencilTagBits::integer(),StencilClearTag::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/glStencilClearTagEXT.xml">external</a> documentation. +-spec stencilClearTagEXT(integer(),integer()) -> ok. stencilClearTagEXT(StencilTagBits,StencilClearTag) -> - wxe_util:cast(5682, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>). + cast(5863, <<StencilTagBits:?GLsizei,StencilClearTag:?GLuint>>). diff --git a/lib/wx/src/gen/gl_debug.hrl b/lib/wx/src/gen/gl_debug.hrl deleted file mode 100644 index 0b8086f24e..0000000000 --- a/lib/wx/src/gen/gl_debug.hrl +++ /dev/null @@ -1,697 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2008-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 is generated DO NOT EDIT - -gldebug_table() -> -[ - {5037, {gl, accum, 0}}, - {5038, {gl, alphaFunc, 0}}, - {5039, {gl, areTexturesResident, 0}}, - {5040, {gl, arrayElement, 0}}, - {5041, {gl, 'begin', 0}}, - {5042, {gl, bindTexture, 0}}, - {5043, {gl, bitmap, 0}}, - {5044, {gl, bitmap, 0}}, - {5045, {gl, blendFunc, 0}}, - {5046, {gl, callList, 0}}, - {5047, {gl, callLists, 0}}, - {5048, {gl, clear, 0}}, - {5049, {gl, clearAccum, 0}}, - {5050, {gl, clearColor, 0}}, - {5051, {gl, clearDepth, 0}}, - {5052, {gl, clearIndex, 0}}, - {5053, {gl, clearStencil, 0}}, - {5054, {gl, clipPlane, 0}}, - {5055, {gl, color3b, 0}}, - {5056, {gl, color3d, 0}}, - {5057, {gl, color3f, 0}}, - {5058, {gl, color3i, 0}}, - {5059, {gl, color3s, 0}}, - {5060, {gl, color3ub, 0}}, - {5061, {gl, color3ui, 0}}, - {5062, {gl, color3us, 0}}, - {5063, {gl, color4b, 0}}, - {5064, {gl, color4d, 0}}, - {5065, {gl, color4f, 0}}, - {5066, {gl, color4i, 0}}, - {5067, {gl, color4s, 0}}, - {5068, {gl, color4ub, 0}}, - {5069, {gl, color4ui, 0}}, - {5070, {gl, color4us, 0}}, - {5071, {gl, colorMask, 0}}, - {5072, {gl, colorMaterial, 0}}, - {5073, {gl, colorPointer, 0}}, - {5074, {gl, colorPointer, 0}}, - {5075, {gl, copyPixels, 0}}, - {5076, {gl, copyTexImage1D, 0}}, - {5077, {gl, copyTexImage2D, 0}}, - {5078, {gl, copyTexSubImage1D, 0}}, - {5079, {gl, copyTexSubImage2D, 0}}, - {5080, {gl, cullFace, 0}}, - {5081, {gl, deleteLists, 0}}, - {5082, {gl, deleteTextures, 0}}, - {5083, {gl, depthFunc, 0}}, - {5084, {gl, depthMask, 0}}, - {5085, {gl, depthRange, 0}}, - {5086, {gl, disable, 0}}, - {5087, {gl, disableClientState, 0}}, - {5088, {gl, drawArrays, 0}}, - {5089, {gl, drawBuffer, 0}}, - {5090, {gl, drawElements, 0}}, - {5091, {gl, drawElements, 0}}, - {5092, {gl, drawPixels, 0}}, - {5093, {gl, drawPixels, 0}}, - {5094, {gl, edgeFlag, 0}}, - {5095, {gl, edgeFlagPointer, 0}}, - {5096, {gl, edgeFlagPointer, 0}}, - {5097, {gl, enable, 0}}, - {5098, {gl, enableClientState, 0}}, - {5099, {gl, 'end', 0}}, - {5100, {gl, endList, 0}}, - {5101, {gl, evalCoord1d, 0}}, - {5102, {gl, evalCoord1f, 0}}, - {5103, {gl, evalCoord2d, 0}}, - {5104, {gl, evalCoord2f, 0}}, - {5105, {gl, evalMesh1, 0}}, - {5106, {gl, evalMesh2, 0}}, - {5107, {gl, evalPoint1, 0}}, - {5108, {gl, evalPoint2, 0}}, - {5109, {gl, feedbackBuffer, 0}}, - {5110, {gl, finish, 0}}, - {5111, {gl, flush, 0}}, - {5112, {gl, fogf, 0}}, - {5113, {gl, fogfv, 0}}, - {5114, {gl, fogi, 0}}, - {5115, {gl, fogiv, 0}}, - {5116, {gl, frontFace, 0}}, - {5117, {gl, frustum, 0}}, - {5118, {gl, genLists, 0}}, - {5119, {gl, genTextures, 0}}, - {5120, {gl, getBooleanv, 0}}, - {5121, {gl, getClipPlane, 0}}, - {5122, {gl, getDoublev, 0}}, - {5123, {gl, getError, 0}}, - {5124, {gl, getFloatv, 0}}, - {5125, {gl, getIntegerv, 0}}, - {5126, {gl, getLightfv, 0}}, - {5127, {gl, getLightiv, 0}}, - {5128, {gl, getMapdv, 0}}, - {5129, {gl, getMapfv, 0}}, - {5130, {gl, getMapiv, 0}}, - {5131, {gl, getMaterialfv, 0}}, - {5132, {gl, getMaterialiv, 0}}, - {5133, {gl, getPixelMapfv, 0}}, - {5134, {gl, getPixelMapuiv, 0}}, - {5135, {gl, getPixelMapusv, 0}}, - {5136, {gl, getPolygonStipple, 0}}, - {5137, {gl, getString, 0}}, - {5138, {gl, getTexEnvfv, 0}}, - {5139, {gl, getTexEnviv, 0}}, - {5140, {gl, getTexGendv, 0}}, - {5141, {gl, getTexGenfv, 0}}, - {5142, {gl, getTexGeniv, 0}}, - {5143, {gl, getTexImage, 0}}, - {5144, {gl, getTexLevelParameterfv, 0}}, - {5145, {gl, getTexLevelParameteriv, 0}}, - {5146, {gl, getTexParameterfv, 0}}, - {5147, {gl, getTexParameteriv, 0}}, - {5148, {gl, hint, 0}}, - {5149, {gl, indexMask, 0}}, - {5150, {gl, indexPointer, 0}}, - {5151, {gl, indexPointer, 0}}, - {5152, {gl, indexd, 0}}, - {5153, {gl, indexf, 0}}, - {5154, {gl, indexi, 0}}, - {5155, {gl, indexs, 0}}, - {5156, {gl, indexub, 0}}, - {5157, {gl, initNames, 0}}, - {5158, {gl, interleavedArrays, 0}}, - {5159, {gl, interleavedArrays, 0}}, - {5160, {gl, isEnabled, 0}}, - {5161, {gl, isList, 0}}, - {5162, {gl, isTexture, 0}}, - {5163, {gl, lightModelf, 0}}, - {5164, {gl, lightModelfv, 0}}, - {5165, {gl, lightModeli, 0}}, - {5166, {gl, lightModeliv, 0}}, - {5167, {gl, lightf, 0}}, - {5168, {gl, lightfv, 0}}, - {5169, {gl, lighti, 0}}, - {5170, {gl, lightiv, 0}}, - {5171, {gl, lineStipple, 0}}, - {5172, {gl, lineWidth, 0}}, - {5173, {gl, listBase, 0}}, - {5174, {gl, loadIdentity, 0}}, - {5175, {gl, loadMatrixd, 0}}, - {5176, {gl, loadMatrixf, 0}}, - {5177, {gl, loadName, 0}}, - {5178, {gl, logicOp, 0}}, - {5179, {gl, map1d, 0}}, - {5180, {gl, map1f, 0}}, - {5181, {gl, map2d, 0}}, - {5182, {gl, map2f, 0}}, - {5183, {gl, mapGrid1d, 0}}, - {5184, {gl, mapGrid1f, 0}}, - {5185, {gl, mapGrid2d, 0}}, - {5186, {gl, mapGrid2f, 0}}, - {5187, {gl, materialf, 0}}, - {5188, {gl, materialfv, 0}}, - {5189, {gl, materiali, 0}}, - {5190, {gl, materialiv, 0}}, - {5191, {gl, matrixMode, 0}}, - {5192, {gl, multMatrixd, 0}}, - {5193, {gl, multMatrixf, 0}}, - {5194, {gl, newList, 0}}, - {5195, {gl, normal3b, 0}}, - {5196, {gl, normal3d, 0}}, - {5197, {gl, normal3f, 0}}, - {5198, {gl, normal3i, 0}}, - {5199, {gl, normal3s, 0}}, - {5200, {gl, normalPointer, 0}}, - {5201, {gl, normalPointer, 0}}, - {5202, {gl, ortho, 0}}, - {5203, {gl, passThrough, 0}}, - {5204, {gl, pixelMapfv, 0}}, - {5205, {gl, pixelMapuiv, 0}}, - {5206, {gl, pixelMapusv, 0}}, - {5207, {gl, pixelStoref, 0}}, - {5208, {gl, pixelStorei, 0}}, - {5209, {gl, pixelTransferf, 0}}, - {5210, {gl, pixelTransferi, 0}}, - {5211, {gl, pixelZoom, 0}}, - {5212, {gl, pointSize, 0}}, - {5213, {gl, polygonMode, 0}}, - {5214, {gl, polygonOffset, 0}}, - {5215, {gl, polygonStipple, 0}}, - {5216, {gl, popAttrib, 0}}, - {5217, {gl, popClientAttrib, 0}}, - {5218, {gl, popMatrix, 0}}, - {5219, {gl, popName, 0}}, - {5220, {gl, prioritizeTextures, 0}}, - {5221, {gl, pushAttrib, 0}}, - {5222, {gl, pushClientAttrib, 0}}, - {5223, {gl, pushMatrix, 0}}, - {5224, {gl, pushName, 0}}, - {5225, {gl, rasterPos2d, 0}}, - {5226, {gl, rasterPos2f, 0}}, - {5227, {gl, rasterPos2i, 0}}, - {5228, {gl, rasterPos2s, 0}}, - {5229, {gl, rasterPos3d, 0}}, - {5230, {gl, rasterPos3f, 0}}, - {5231, {gl, rasterPos3i, 0}}, - {5232, {gl, rasterPos3s, 0}}, - {5233, {gl, rasterPos4d, 0}}, - {5234, {gl, rasterPos4f, 0}}, - {5235, {gl, rasterPos4i, 0}}, - {5236, {gl, rasterPos4s, 0}}, - {5237, {gl, readBuffer, 0}}, - {5238, {gl, readPixels, 0}}, - {5239, {gl, rectd, 0}}, - {5240, {gl, rectdv, 0}}, - {5241, {gl, rectf, 0}}, - {5242, {gl, rectfv, 0}}, - {5243, {gl, recti, 0}}, - {5244, {gl, rectiv, 0}}, - {5245, {gl, rects, 0}}, - {5246, {gl, rectsv, 0}}, - {5247, {gl, renderMode, 0}}, - {5248, {gl, rotated, 0}}, - {5249, {gl, rotatef, 0}}, - {5250, {gl, scaled, 0}}, - {5251, {gl, scalef, 0}}, - {5252, {gl, scissor, 0}}, - {5253, {gl, selectBuffer, 0}}, - {5254, {gl, shadeModel, 0}}, - {5255, {gl, stencilFunc, 0}}, - {5256, {gl, stencilMask, 0}}, - {5257, {gl, stencilOp, 0}}, - {5258, {gl, texCoord1d, 0}}, - {5259, {gl, texCoord1f, 0}}, - {5260, {gl, texCoord1i, 0}}, - {5261, {gl, texCoord1s, 0}}, - {5262, {gl, texCoord2d, 0}}, - {5263, {gl, texCoord2f, 0}}, - {5264, {gl, texCoord2i, 0}}, - {5265, {gl, texCoord2s, 0}}, - {5266, {gl, texCoord3d, 0}}, - {5267, {gl, texCoord3f, 0}}, - {5268, {gl, texCoord3i, 0}}, - {5269, {gl, texCoord3s, 0}}, - {5270, {gl, texCoord4d, 0}}, - {5271, {gl, texCoord4f, 0}}, - {5272, {gl, texCoord4i, 0}}, - {5273, {gl, texCoord4s, 0}}, - {5274, {gl, texCoordPointer, 0}}, - {5275, {gl, texCoordPointer, 0}}, - {5276, {gl, texEnvf, 0}}, - {5277, {gl, texEnvfv, 0}}, - {5278, {gl, texEnvi, 0}}, - {5279, {gl, texEnviv, 0}}, - {5280, {gl, texGend, 0}}, - {5281, {gl, texGendv, 0}}, - {5282, {gl, texGenf, 0}}, - {5283, {gl, texGenfv, 0}}, - {5284, {gl, texGeni, 0}}, - {5285, {gl, texGeniv, 0}}, - {5286, {gl, texImage1D, 0}}, - {5287, {gl, texImage1D, 0}}, - {5288, {gl, texImage2D, 0}}, - {5289, {gl, texImage2D, 0}}, - {5290, {gl, texParameterf, 0}}, - {5291, {gl, texParameterfv, 0}}, - {5292, {gl, texParameteri, 0}}, - {5293, {gl, texParameteriv, 0}}, - {5294, {gl, texSubImage1D, 0}}, - {5295, {gl, texSubImage1D, 0}}, - {5296, {gl, texSubImage2D, 0}}, - {5297, {gl, texSubImage2D, 0}}, - {5298, {gl, translated, 0}}, - {5299, {gl, translatef, 0}}, - {5300, {gl, vertex2d, 0}}, - {5301, {gl, vertex2f, 0}}, - {5302, {gl, vertex2i, 0}}, - {5303, {gl, vertex2s, 0}}, - {5304, {gl, vertex3d, 0}}, - {5305, {gl, vertex3f, 0}}, - {5306, {gl, vertex3i, 0}}, - {5307, {gl, vertex3s, 0}}, - {5308, {gl, vertex4d, 0}}, - {5309, {gl, vertex4f, 0}}, - {5310, {gl, vertex4i, 0}}, - {5311, {gl, vertex4s, 0}}, - {5312, {gl, vertexPointer, 0}}, - {5313, {gl, vertexPointer, 0}}, - {5314, {gl, viewport, 0}}, - {5315, {gl, blendColor, 0}}, - {5316, {gl, blendEquation, 0}}, - {5317, {gl, drawRangeElements, 0}}, - {5318, {gl, drawRangeElements, 0}}, - {5319, {gl, texImage3D, 0}}, - {5320, {gl, texImage3D, 0}}, - {5321, {gl, texSubImage3D, 0}}, - {5322, {gl, texSubImage3D, 0}}, - {5323, {gl, copyTexSubImage3D, 0}}, - {5324, {gl, colorTable, 0}}, - {5325, {gl, colorTable, 0}}, - {5326, {gl, colorTableParameterfv, 0}}, - {5327, {gl, colorTableParameteriv, 0}}, - {5328, {gl, copyColorTable, 0}}, - {5329, {gl, getColorTable, 0}}, - {5330, {gl, getColorTableParameterfv, 0}}, - {5331, {gl, getColorTableParameteriv, 0}}, - {5332, {gl, colorSubTable, 0}}, - {5333, {gl, colorSubTable, 0}}, - {5334, {gl, copyColorSubTable, 0}}, - {5335, {gl, convolutionFilter1D, 0}}, - {5336, {gl, convolutionFilter1D, 0}}, - {5337, {gl, convolutionFilter2D, 0}}, - {5338, {gl, convolutionFilter2D, 0}}, - {5339, {gl, convolutionParameterf, 0}}, - {5340, {gl, convolutionParameteri, 0}}, - {5341, {gl, copyConvolutionFilter1D, 0}}, - {5342, {gl, copyConvolutionFilter2D, 0}}, - {5343, {gl, getConvolutionFilter, 0}}, - {5344, {gl, getConvolutionParameterfv, 0}}, - {5345, {gl, getConvolutionParameteriv, 0}}, - {5346, {gl, separableFilter2D, 0}}, - {5347, {gl, separableFilter2D, 0}}, - {5348, {gl, getHistogram, 0}}, - {5349, {gl, getHistogramParameterfv, 0}}, - {5350, {gl, getHistogramParameteriv, 0}}, - {5351, {gl, getMinmax, 0}}, - {5352, {gl, getMinmaxParameterfv, 0}}, - {5353, {gl, getMinmaxParameteriv, 0}}, - {5354, {gl, histogram, 0}}, - {5355, {gl, minmax, 0}}, - {5356, {gl, resetHistogram, 0}}, - {5357, {gl, resetMinmax, 0}}, - {5358, {gl, activeTexture, 0}}, - {5359, {gl, sampleCoverage, 0}}, - {5360, {gl, compressedTexImage3D, 0}}, - {5361, {gl, compressedTexImage3D, 0}}, - {5362, {gl, compressedTexImage2D, 0}}, - {5363, {gl, compressedTexImage2D, 0}}, - {5364, {gl, compressedTexImage1D, 0}}, - {5365, {gl, compressedTexImage1D, 0}}, - {5366, {gl, compressedTexSubImage3D, 0}}, - {5367, {gl, compressedTexSubImage3D, 0}}, - {5368, {gl, compressedTexSubImage2D, 0}}, - {5369, {gl, compressedTexSubImage2D, 0}}, - {5370, {gl, compressedTexSubImage1D, 0}}, - {5371, {gl, compressedTexSubImage1D, 0}}, - {5372, {gl, getCompressedTexImage, 0}}, - {5373, {gl, clientActiveTexture, 0}}, - {5374, {gl, multiTexCoord1d, 0}}, - {5375, {gl, multiTexCoord1f, 0}}, - {5376, {gl, multiTexCoord1i, 0}}, - {5377, {gl, multiTexCoord1s, 0}}, - {5378, {gl, multiTexCoord2d, 0}}, - {5379, {gl, multiTexCoord2f, 0}}, - {5380, {gl, multiTexCoord2i, 0}}, - {5381, {gl, multiTexCoord2s, 0}}, - {5382, {gl, multiTexCoord3d, 0}}, - {5383, {gl, multiTexCoord3f, 0}}, - {5384, {gl, multiTexCoord3i, 0}}, - {5385, {gl, multiTexCoord3s, 0}}, - {5386, {gl, multiTexCoord4d, 0}}, - {5387, {gl, multiTexCoord4f, 0}}, - {5388, {gl, multiTexCoord4i, 0}}, - {5389, {gl, multiTexCoord4s, 0}}, - {5390, {gl, loadTransposeMatrixf, 0}}, - {5391, {gl, loadTransposeMatrixd, 0}}, - {5392, {gl, multTransposeMatrixf, 0}}, - {5393, {gl, multTransposeMatrixd, 0}}, - {5394, {gl, blendFuncSeparate, 0}}, - {5395, {gl, multiDrawArrays, 0}}, - {5396, {gl, pointParameterf, 0}}, - {5397, {gl, pointParameterfv, 0}}, - {5398, {gl, pointParameteri, 0}}, - {5399, {gl, pointParameteriv, 0}}, - {5400, {gl, fogCoordf, 0}}, - {5401, {gl, fogCoordd, 0}}, - {5402, {gl, fogCoordPointer, 0}}, - {5403, {gl, fogCoordPointer, 0}}, - {5404, {gl, secondaryColor3b, 0}}, - {5405, {gl, secondaryColor3d, 0}}, - {5406, {gl, secondaryColor3f, 0}}, - {5407, {gl, secondaryColor3i, 0}}, - {5408, {gl, secondaryColor3s, 0}}, - {5409, {gl, secondaryColor3ub, 0}}, - {5410, {gl, secondaryColor3ui, 0}}, - {5411, {gl, secondaryColor3us, 0}}, - {5412, {gl, secondaryColorPointer, 0}}, - {5413, {gl, secondaryColorPointer, 0}}, - {5414, {gl, windowPos2d, 0}}, - {5415, {gl, windowPos2f, 0}}, - {5416, {gl, windowPos2i, 0}}, - {5417, {gl, windowPos2s, 0}}, - {5418, {gl, windowPos3d, 0}}, - {5419, {gl, windowPos3f, 0}}, - {5420, {gl, windowPos3i, 0}}, - {5421, {gl, windowPos3s, 0}}, - {5422, {gl, genQueries, 0}}, - {5423, {gl, deleteQueries, 0}}, - {5424, {gl, isQuery, 0}}, - {5425, {gl, beginQuery, 0}}, - {5426, {gl, endQuery, 0}}, - {5427, {gl, getQueryiv, 0}}, - {5428, {gl, getQueryObjectiv, 0}}, - {5429, {gl, getQueryObjectuiv, 0}}, - {5430, {gl, bindBuffer, 0}}, - {5431, {gl, deleteBuffers, 0}}, - {5432, {gl, genBuffers, 0}}, - {5433, {gl, isBuffer, 0}}, - {5434, {gl, bufferData, 0}}, - {5435, {gl, bufferData, 0}}, - {5436, {gl, bufferSubData, 0}}, - {5437, {gl, bufferSubData, 0}}, - {5438, {gl, getBufferSubData, 0}}, - {5439, {gl, getBufferParameteriv, 0}}, - {5440, {gl, blendEquationSeparate, 0}}, - {5441, {gl, drawBuffers, 0}}, - {5442, {gl, stencilOpSeparate, 0}}, - {5443, {gl, stencilFuncSeparate, 0}}, - {5444, {gl, stencilMaskSeparate, 0}}, - {5445, {gl, attachShader, 0}}, - {5446, {gl, bindAttribLocation, 0}}, - {5447, {gl, compileShader, 0}}, - {5448, {gl, createProgram, 0}}, - {5449, {gl, createShader, 0}}, - {5450, {gl, deleteProgram, 0}}, - {5451, {gl, deleteShader, 0}}, - {5452, {gl, detachShader, 0}}, - {5453, {gl, disableVertexAttribArray, 0}}, - {5454, {gl, enableVertexAttribArray, 0}}, - {5455, {gl, getActiveAttrib, 0}}, - {5456, {gl, getActiveUniform, 0}}, - {5457, {gl, getAttachedShaders, 0}}, - {5458, {gl, getAttribLocation, 0}}, - {5459, {gl, getProgramiv, 0}}, - {5460, {gl, getProgramInfoLog, 0}}, - {5461, {gl, getShaderiv, 0}}, - {5462, {gl, getShaderInfoLog, 0}}, - {5463, {gl, getShaderSource, 0}}, - {5464, {gl, getUniformLocation, 0}}, - {5465, {gl, getUniformfv, 0}}, - {5466, {gl, getUniformiv, 0}}, - {5467, {gl, getVertexAttribdv, 0}}, - {5468, {gl, getVertexAttribfv, 0}}, - {5469, {gl, getVertexAttribiv, 0}}, - {5470, {gl, isProgram, 0}}, - {5471, {gl, isShader, 0}}, - {5472, {gl, linkProgram, 0}}, - {5473, {gl, shaderSource, 0}}, - {5474, {gl, useProgram, 0}}, - {5475, {gl, uniform1f, 0}}, - {5476, {gl, uniform2f, 0}}, - {5477, {gl, uniform3f, 0}}, - {5478, {gl, uniform4f, 0}}, - {5479, {gl, uniform1i, 0}}, - {5480, {gl, uniform2i, 0}}, - {5481, {gl, uniform3i, 0}}, - {5482, {gl, uniform4i, 0}}, - {5483, {gl, uniform1fv, 0}}, - {5484, {gl, uniform2fv, 0}}, - {5485, {gl, uniform3fv, 0}}, - {5486, {gl, uniform4fv, 0}}, - {5487, {gl, uniform1iv, 0}}, - {5488, {gl, uniform2iv, 0}}, - {5489, {gl, uniform3iv, 0}}, - {5490, {gl, uniform4iv, 0}}, - {5491, {gl, uniformMatrix2fv, 0}}, - {5492, {gl, uniformMatrix3fv, 0}}, - {5493, {gl, uniformMatrix4fv, 0}}, - {5494, {gl, validateProgram, 0}}, - {5495, {gl, vertexAttrib1d, 0}}, - {5496, {gl, vertexAttrib1f, 0}}, - {5497, {gl, vertexAttrib1s, 0}}, - {5498, {gl, vertexAttrib2d, 0}}, - {5499, {gl, vertexAttrib2f, 0}}, - {5500, {gl, vertexAttrib2s, 0}}, - {5501, {gl, vertexAttrib3d, 0}}, - {5502, {gl, vertexAttrib3f, 0}}, - {5503, {gl, vertexAttrib3s, 0}}, - {5504, {gl, vertexAttrib4Nbv, 0}}, - {5505, {gl, vertexAttrib4Niv, 0}}, - {5506, {gl, vertexAttrib4Nsv, 0}}, - {5507, {gl, vertexAttrib4Nub, 0}}, - {5508, {gl, vertexAttrib4Nuiv, 0}}, - {5509, {gl, vertexAttrib4Nusv, 0}}, - {5510, {gl, vertexAttrib4bv, 0}}, - {5511, {gl, vertexAttrib4d, 0}}, - {5512, {gl, vertexAttrib4f, 0}}, - {5513, {gl, vertexAttrib4iv, 0}}, - {5514, {gl, vertexAttrib4s, 0}}, - {5515, {gl, vertexAttrib4ubv, 0}}, - {5516, {gl, vertexAttrib4uiv, 0}}, - {5517, {gl, vertexAttrib4usv, 0}}, - {5518, {gl, vertexAttribPointer, 0}}, - {5519, {gl, vertexAttribPointer, 0}}, - {5520, {gl, uniformMatrix2x3fv, 0}}, - {5521, {gl, uniformMatrix3x2fv, 0}}, - {5522, {gl, uniformMatrix2x4fv, 0}}, - {5523, {gl, uniformMatrix4x2fv, 0}}, - {5524, {gl, uniformMatrix3x4fv, 0}}, - {5525, {gl, uniformMatrix4x3fv, 0}}, - {5526, {gl, colorMaski, 0}}, - {5527, {gl, getBooleani_v, 0}}, - {5528, {gl, getIntegeri_v, 0}}, - {5529, {gl, enablei, 0}}, - {5530, {gl, disablei, 0}}, - {5531, {gl, isEnabledi, 0}}, - {5532, {gl, beginTransformFeedback, 0}}, - {5533, {gl, endTransformFeedback, 0}}, - {5534, {gl, bindBufferRange, 0}}, - {5535, {gl, bindBufferBase, 0}}, - {5536, {gl, transformFeedbackVaryings, 0}}, - {5537, {gl, getTransformFeedbackVarying, 0}}, - {5538, {gl, clampColor, 0}}, - {5539, {gl, beginConditionalRender, 0}}, - {5540, {gl, endConditionalRender, 0}}, - {5541, {gl, vertexAttribIPointer, 0}}, - {5542, {gl, vertexAttribIPointer, 0}}, - {5543, {gl, getVertexAttribIiv, 0}}, - {5544, {gl, getVertexAttribIuiv, 0}}, - {5545, {gl, getUniformuiv, 0}}, - {5546, {gl, bindFragDataLocation, 0}}, - {5547, {gl, getFragDataLocation, 0}}, - {5548, {gl, uniform1ui, 0}}, - {5549, {gl, uniform2ui, 0}}, - {5550, {gl, uniform3ui, 0}}, - {5551, {gl, uniform4ui, 0}}, - {5552, {gl, uniform1uiv, 0}}, - {5553, {gl, uniform2uiv, 0}}, - {5554, {gl, uniform3uiv, 0}}, - {5555, {gl, uniform4uiv, 0}}, - {5556, {gl, texParameterIiv, 0}}, - {5557, {gl, texParameterIuiv, 0}}, - {5558, {gl, getTexParameterIiv, 0}}, - {5559, {gl, getTexParameterIuiv, 0}}, - {5560, {gl, clearBufferiv, 0}}, - {5561, {gl, clearBufferuiv, 0}}, - {5562, {gl, clearBufferfv, 0}}, - {5563, {gl, clearBufferfi, 0}}, - {5564, {gl, getStringi, 0}}, - {5565, {gl, vertexAttribI1i, 0}}, - {5566, {gl, vertexAttribI2i, 0}}, - {5567, {gl, vertexAttribI3i, 0}}, - {5568, {gl, vertexAttribI4i, 0}}, - {5569, {gl, vertexAttribI1ui, 0}}, - {5570, {gl, vertexAttribI2ui, 0}}, - {5571, {gl, vertexAttribI3ui, 0}}, - {5572, {gl, vertexAttribI4ui, 0}}, - {5573, {gl, vertexAttribI4bv, 0}}, - {5574, {gl, vertexAttribI4sv, 0}}, - {5575, {gl, vertexAttribI4ubv, 0}}, - {5576, {gl, vertexAttribI4usv, 0}}, - {5577, {gl, drawArraysInstanced, 0}}, - {5578, {gl, drawElementsInstanced, 0}}, - {5579, {gl, drawElementsInstanced, 0}}, - {5580, {gl, texBuffer, 0}}, - {5581, {gl, primitiveRestartIndex, 0}}, - {5582, {gl, loadTransposeMatrixfARB, 0}}, - {5583, {gl, loadTransposeMatrixdARB, 0}}, - {5584, {gl, multTransposeMatrixfARB, 0}}, - {5585, {gl, multTransposeMatrixdARB, 0}}, - {5586, {gl, weightbvARB, 0}}, - {5587, {gl, weightsvARB, 0}}, - {5588, {gl, weightivARB, 0}}, - {5589, {gl, weightfvARB, 0}}, - {5590, {gl, weightdvARB, 0}}, - {5591, {gl, weightubvARB, 0}}, - {5592, {gl, weightusvARB, 0}}, - {5593, {gl, weightuivARB, 0}}, - {5594, {gl, vertexBlendARB, 0}}, - {5595, {gl, currentPaletteMatrixARB, 0}}, - {5596, {gl, matrixIndexubvARB, 0}}, - {5597, {gl, matrixIndexusvARB, 0}}, - {5598, {gl, matrixIndexuivARB, 0}}, - {5599, {gl, programStringARB, 0}}, - {5600, {gl, bindProgramARB, 0}}, - {5601, {gl, deleteProgramsARB, 0}}, - {5602, {gl, genProgramsARB, 0}}, - {5603, {gl, programEnvParameter4dARB, 0}}, - {5604, {gl, programEnvParameter4dvARB, 0}}, - {5605, {gl, programEnvParameter4fARB, 0}}, - {5606, {gl, programEnvParameter4fvARB, 0}}, - {5607, {gl, programLocalParameter4dARB, 0}}, - {5608, {gl, programLocalParameter4dvARB, 0}}, - {5609, {gl, programLocalParameter4fARB, 0}}, - {5610, {gl, programLocalParameter4fvARB, 0}}, - {5611, {gl, getProgramEnvParameterdvARB, 0}}, - {5612, {gl, getProgramEnvParameterfvARB, 0}}, - {5613, {gl, getProgramLocalParameterdvARB, 0}}, - {5614, {gl, getProgramLocalParameterfvARB, 0}}, - {5615, {gl, getProgramStringARB, 0}}, - {5616, {gl, deleteObjectARB, 0}}, - {5617, {gl, getHandleARB, 0}}, - {5618, {gl, detachObjectARB, 0}}, - {5619, {gl, createShaderObjectARB, 0}}, - {5620, {gl, shaderSourceARB, 0}}, - {5621, {gl, compileShaderARB, 0}}, - {5622, {gl, createProgramObjectARB, 0}}, - {5623, {gl, attachObjectARB, 0}}, - {5624, {gl, linkProgramARB, 0}}, - {5625, {gl, useProgramObjectARB, 0}}, - {5626, {gl, validateProgramARB, 0}}, - {5627, {gl, getObjectParameterfvARB, 0}}, - {5628, {gl, getObjectParameterivARB, 0}}, - {5629, {gl, getInfoLogARB, 0}}, - {5630, {gl, getAttachedObjectsARB, 0}}, - {5631, {gl, getUniformLocationARB, 0}}, - {5632, {gl, getActiveUniformARB, 0}}, - {5633, {gl, getUniformfvARB, 0}}, - {5634, {gl, getUniformivARB, 0}}, - {5635, {gl, getShaderSourceARB, 0}}, - {5636, {gl, bindAttribLocationARB, 0}}, - {5637, {gl, getActiveAttribARB, 0}}, - {5638, {gl, getAttribLocationARB, 0}}, - {5639, {gl, isRenderbuffer, 0}}, - {5640, {gl, bindRenderbuffer, 0}}, - {5641, {gl, deleteRenderbuffers, 0}}, - {5642, {gl, genRenderbuffers, 0}}, - {5643, {gl, renderbufferStorage, 0}}, - {5644, {gl, getRenderbufferParameteriv, 0}}, - {5645, {gl, isFramebuffer, 0}}, - {5646, {gl, bindFramebuffer, 0}}, - {5647, {gl, deleteFramebuffers, 0}}, - {5648, {gl, genFramebuffers, 0}}, - {5649, {gl, checkFramebufferStatus, 0}}, - {5650, {gl, framebufferTexture1D, 0}}, - {5651, {gl, framebufferTexture2D, 0}}, - {5652, {gl, framebufferTexture3D, 0}}, - {5653, {gl, framebufferRenderbuffer, 0}}, - {5654, {gl, getFramebufferAttachmentParameteriv, 0}}, - {5655, {gl, generateMipmap, 0}}, - {5656, {gl, blitFramebuffer, 0}}, - {5657, {gl, renderbufferStorageMultisample, 0}}, - {5658, {gl, framebufferTextureLayer, 0}}, - {5659, {gl, programParameteriARB, 0}}, - {5660, {gl, framebufferTextureARB, 0}}, - {5661, {gl, framebufferTextureFaceARB, 0}}, - {5662, {gl, vertexAttribDivisorARB, 0}}, - {5663, {gl, flushMappedBufferRange, 0}}, - {5664, {gl, bindVertexArray, 0}}, - {5665, {gl, deleteVertexArrays, 0}}, - {5666, {gl, genVertexArrays, 0}}, - {5667, {gl, isVertexArray, 0}}, - {5668, {gl, getUniformIndices, 0}}, - {5669, {gl, getActiveUniformsiv, 0}}, - {5670, {gl, getActiveUniformName, 0}}, - {5671, {gl, getUniformBlockIndex, 0}}, - {5672, {gl, getActiveUniformBlockiv, 0}}, - {5673, {gl, getActiveUniformBlockName, 0}}, - {5674, {gl, uniformBlockBinding, 0}}, - {5675, {gl, copyBufferSubData, 0}}, - {5676, {gl, resizeBuffersMESA, 0}}, - {5677, {gl, windowPos4dMESA, 0}}, - {5678, {gl, windowPos4fMESA, 0}}, - {5679, {gl, windowPos4iMESA, 0}}, - {5680, {gl, windowPos4sMESA, 0}}, - {5681, {gl, depthBoundsEXT, 0}}, - {5682, {gl, stencilClearTagEXT, 0}}, - {5010, {glu, build1DMipmapLevels, 0}}, - {5011, {glu, build1DMipmaps, 0}}, - {5012, {glu, build2DMipmapLevels, 0}}, - {5013, {glu, build2DMipmaps, 0}}, - {5014, {glu, build3DMipmapLevels, 0}}, - {5015, {glu, build3DMipmaps, 0}}, - {5016, {glu, checkExtension, 0}}, - {5017, {glu, cylinder, 0}}, - {5018, {glu, deleteQuadric, 0}}, - {5019, {glu, disk, 0}}, - {5020, {glu, errorString, 0}}, - {5021, {glu, getString, 0}}, - {5022, {glu, lookAt, 0}}, - {5023, {glu, newQuadric, 0}}, - {5024, {glu, ortho2D, 0}}, - {5025, {glu, partialDisk, 0}}, - {5026, {glu, perspective, 0}}, - {5027, {glu, pickMatrix, 0}}, - {5028, {glu, project, 0}}, - {5029, {glu, quadricDrawStyle, 0}}, - {5030, {glu, quadricNormals, 0}}, - {5031, {glu, quadricOrientation, 0}}, - {5032, {glu, quadricTexture, 0}}, - {5033, {glu, scaleImage, 0}}, - {5034, {glu, sphere, 0}}, - {5035, {glu, unProject, 0}}, - {5036, {glu, unProject4, 0}}, - {-1, {mod, func, -1}} -]. - diff --git a/lib/wx/src/gen/glu.erl b/lib/wx/src/gen/glu.erl index d410c4663d..c16f0cf125 100644 --- a/lib/wx/src/gen/glu.erl +++ b/lib/wx/src/gen/glu.erl @@ -25,14 +25,13 @@ %% %% Booleans are represented by integers 0 and 1. -%% @type wx_mem(). see wx.erl on memory allocation functions +%% @type mem(). memory block %% @type enum(). An integer defined in gl.hrl %% @type offset(). An integer which is an offset in an array %% @type clamp(). A float clamped between 0.0 - 1.0 -module(glu). -compile(inline). --include("wxe.hrl"). -define(GLenum,32/native-unsigned). -define(GLboolean,8/native-unsigned). -define(GLbitfield,32/native-unsigned). @@ -51,6 +50,11 @@ -define(GLintptr,64/native-unsigned). -define(GLUquadric,64/native-unsigned). -define(GLhandleARB,64/native-unsigned). +-define(GLsync,64/native-unsigned). +-define(GLuint64,64/native-unsigned). +-define(GLint64,64/native-signed). +-type enum() :: non_neg_integer(). +-type mem() :: binary() | tuple(). -export([tesselate/2,build1DMipmapLevels/9,build1DMipmaps/6,build2DMipmapLevels/10, build2DMipmaps/7,build3DMipmapLevels/11,build3DMipmaps/8,checkExtension/2, @@ -59,7 +63,7 @@ quadricDrawStyle/2,quadricNormals/2,quadricOrientation/2,quadricTexture/2, scaleImage/9,sphere/4,unProject/6,unProject4/9]). - +-import(gl, [call/2,cast/2,send_bin/1]). %% API %% @spec (Vec3, [Vec3]) -> {Triangles, VertexPos} @@ -73,159 +77,184 @@ %% vertex positions, it starts with the vertices in Vs and %% may contain newly created vertices in the end. tesselate({Nx,Ny,Nz}, Vs) -> - wxe_util:call(5000, <<(length(Vs)):32/native,0:32, + call(5000, <<(length(Vs)):32/native,0:32, Nx:?GLdouble,Ny:?GLdouble,Nz:?GLdouble, (<< <<Vx:?GLdouble,Vy:?GLdouble,Vz:?GLdouble >> || {Vx,Vy,Vz} <- Vs>>)/binary >>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild1DMipmapLevels.xml">external</a> documentation. +-spec build1DMipmapLevels(enum(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer(). build1DMipmapLevels(Target,InternalFormat,Width,Format,Type,Level,Base,Max,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5010, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). + send_bin(Data), + call(5010, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild1DMipmaps.xml">external</a> documentation. +-spec build1DMipmaps(enum(),integer(),integer(),enum(),enum(),binary()) -> integer(). build1DMipmaps(Target,InternalFormat,Width,Format,Type,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5011, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Data), + call(5011, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild2DMipmapLevels.xml">external</a> documentation. +-spec build2DMipmapLevels(enum(),integer(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer(). build2DMipmapLevels(Target,InternalFormat,Width,Height,Format,Type,Level,Base,Max,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5012, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). + send_bin(Data), + call(5012, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild2DMipmaps.xml">external</a> documentation. +-spec build2DMipmaps(enum(),integer(),integer(),integer(),enum(),enum(),binary()) -> integer(). build2DMipmaps(Target,InternalFormat,Width,Height,Format,Type,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5013, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Data), + call(5013, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Format:?GLenum,Type:?GLenum>>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Level::integer(),Base::integer(),Max::integer(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild3DMipmapLevels.xml">external</a> documentation. +-spec build3DMipmapLevels(enum(),integer(),integer(),integer(),integer(),enum(),enum(),integer(),integer(),integer(),binary()) -> integer(). build3DMipmapLevels(Target,InternalFormat,Width,Height,Depth,Format,Type,Level,Base,Max,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5014, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). + send_bin(Data), + call(5014, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum,Level:?GLint,Base:?GLint,Max:?GLint>>). %% @spec (Target::enum(),InternalFormat::integer(),Width::integer(),Height::integer(),Depth::integer(),Format::enum(),Type::enum(),Data::binary()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluBuild3DMipmaps.xml">external</a> documentation. +-spec build3DMipmaps(enum(),integer(),integer(),integer(),integer(),enum(),enum(),binary()) -> integer(). build3DMipmaps(Target,InternalFormat,Width,Height,Depth,Format,Type,Data) -> - wxe_util:send_bin(Data), - wxe_util:call(5015, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>). + send_bin(Data), + call(5015, <<Target:?GLenum,InternalFormat:?GLint,Width:?GLsizei,Height:?GLsizei,Depth:?GLsizei,Format:?GLenum,Type:?GLenum>>). -%% @spec (ExtName::[integer()],ExtString::[integer()]) -> 0|1 +%% @spec (ExtName::string(),ExtString::string()) -> 0|1 %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCheckExtension.xml">external</a> documentation. +-spec checkExtension(string(),string()) -> 0|1. checkExtension(ExtName,ExtString) -> - wxe_util:call(5016, <<(length(ExtName)):?GLuint, - (<< <<C:?GLubyte>> || C <- ExtName>>)/binary,0:((8-((length(ExtName)+ 4) rem 8)) rem 8),(length(ExtString)):?GLuint, - (<< <<C:?GLubyte>> || C <- ExtString>>)/binary,0:((8-((length(ExtString)+ 4) rem 8)) rem 8)>>). + call(5016, <<(list_to_binary([ExtName|[0]]))/binary,0:((8-((length(ExtName)+ 1) rem 8)) rem 8),(list_to_binary([ExtString|[0]]))/binary,0:((8-((length(ExtString)+ 1) rem 8)) rem 8)>>). %% @spec (Quad::integer(),Base::float(),Top::float(),Height::float(),Slices::integer(),Stacks::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluCylinder.xml">external</a> documentation. +-spec cylinder(integer(),float(),float(),float(),integer(),integer()) -> ok. cylinder(Quad,Base,Top,Height,Slices,Stacks) -> - wxe_util:cast(5017, <<Quad:?GLUquadric,Base:?GLdouble,Top:?GLdouble,Height:?GLdouble,Slices:?GLint,Stacks:?GLint>>). + cast(5017, <<Quad:?GLUquadric,Base:?GLdouble,Top:?GLdouble,Height:?GLdouble,Slices:?GLint,Stacks:?GLint>>). %% @spec (Quad::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluDeleteQuadric.xml">external</a> documentation. +-spec deleteQuadric(integer()) -> ok. deleteQuadric(Quad) -> - wxe_util:cast(5018, <<Quad:?GLUquadric>>). + cast(5018, <<Quad:?GLUquadric>>). %% @spec (Quad::integer(),Inner::float(),Outer::float(),Slices::integer(),Loops::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluDisk.xml">external</a> documentation. +-spec disk(integer(),float(),float(),integer(),integer()) -> ok. disk(Quad,Inner,Outer,Slices,Loops) -> - wxe_util:cast(5019, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint>>). + cast(5019, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint>>). %% @spec (Error::enum()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluErrorString.xml">external</a> documentation. +-spec errorString(enum()) -> string(). errorString(Error) -> - wxe_util:call(5020, <<Error:?GLenum>>). + call(5020, <<Error:?GLenum>>). %% @spec (Name::enum()) -> string() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluGetString.xml">external</a> documentation. +-spec getString(enum()) -> string(). getString(Name) -> - wxe_util:call(5021, <<Name:?GLenum>>). + call(5021, <<Name:?GLenum>>). %% @spec (EyeX::float(),EyeY::float(),EyeZ::float(),CenterX::float(),CenterY::float(),CenterZ::float(),UpX::float(),UpY::float(),UpZ::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml">external</a> documentation. +-spec lookAt(float(),float(),float(),float(),float(),float(),float(),float(),float()) -> ok. lookAt(EyeX,EyeY,EyeZ,CenterX,CenterY,CenterZ,UpX,UpY,UpZ) -> - wxe_util:cast(5022, <<EyeX:?GLdouble,EyeY:?GLdouble,EyeZ:?GLdouble,CenterX:?GLdouble,CenterY:?GLdouble,CenterZ:?GLdouble,UpX:?GLdouble,UpY:?GLdouble,UpZ:?GLdouble>>). + cast(5022, <<EyeX:?GLdouble,EyeY:?GLdouble,EyeZ:?GLdouble,CenterX:?GLdouble,CenterY:?GLdouble,CenterZ:?GLdouble,UpX:?GLdouble,UpY:?GLdouble,UpZ:?GLdouble>>). %% @spec () -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluNewQuadric.xml">external</a> documentation. +-spec newQuadric() -> integer(). newQuadric() -> - wxe_util:call(5023, <<>>). + call(5023, <<>>). %% @spec (Left::float(),Right::float(),Bottom::float(),Top::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluOrtho2D.xml">external</a> documentation. +-spec ortho2D(float(),float(),float(),float()) -> ok. ortho2D(Left,Right,Bottom,Top) -> - wxe_util:cast(5024, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble>>). + cast(5024, <<Left:?GLdouble,Right:?GLdouble,Bottom:?GLdouble,Top:?GLdouble>>). %% @spec (Quad::integer(),Inner::float(),Outer::float(),Slices::integer(),Loops::integer(),Start::float(),Sweep::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPartialDisk.xml">external</a> documentation. +-spec partialDisk(integer(),float(),float(),integer(),integer(),float(),float()) -> ok. partialDisk(Quad,Inner,Outer,Slices,Loops,Start,Sweep) -> - wxe_util:cast(5025, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint,Start:?GLdouble,Sweep:?GLdouble>>). + cast(5025, <<Quad:?GLUquadric,Inner:?GLdouble,Outer:?GLdouble,Slices:?GLint,Loops:?GLint,Start:?GLdouble,Sweep:?GLdouble>>). %% @spec (Fovy::float(),Aspect::float(),ZNear::float(),ZFar::float()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml">external</a> documentation. +-spec perspective(float(),float(),float(),float()) -> ok. perspective(Fovy,Aspect,ZNear,ZFar) -> - wxe_util:cast(5026, <<Fovy:?GLdouble,Aspect:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). + cast(5026, <<Fovy:?GLdouble,Aspect:?GLdouble,ZNear:?GLdouble,ZFar:?GLdouble>>). -%% @spec (X::float(),Y::float(),DelX::float(),DelY::float(),Viewport::{integer()}) -> ok +%% @spec (X::float(),Y::float(),DelX::float(),DelY::float(),Viewport::{integer(),integer(),integer(),integer()}) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluPickMatrix.xml">external</a> documentation. +-spec pickMatrix(float(),float(),float(),float(),{integer(),integer(),integer(),integer()}) -> ok. pickMatrix(X,Y,DelX,DelY,{V1,V2,V3,V4}) -> - wxe_util:cast(5027, <<X:?GLdouble,Y:?GLdouble,DelX:?GLdouble,DelY:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + cast(5027, <<X:?GLdouble,Y:?GLdouble,DelX:?GLdouble,DelY:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). -%% @spec (ObjX::float(),ObjY::float(),ObjZ::float(),Model::{float()},Proj::{float()},View::{integer()}) -> {integer(),WinX::float(),WinY::float(),WinZ::float()} +%% @spec (ObjX::float(),ObjY::float(),ObjZ::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()}) -> {integer(),WinX::float(),WinY::float(),WinZ::float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluProject.xml">external</a> documentation. +-spec project(float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()}) -> {integer(),float(),float(),float()}. project(ObjX,ObjY,ObjZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4}) -> - wxe_util:call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>); + call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>); project(ObjX,ObjY,ObjZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4}) -> - wxe_util:call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + call(5028, <<ObjX:?GLdouble,ObjY:?GLdouble,ObjZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). %% @spec (Quad::integer(),Draw::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricDrawStyle.xml">external</a> documentation. +-spec quadricDrawStyle(integer(),enum()) -> ok. quadricDrawStyle(Quad,Draw) -> - wxe_util:cast(5029, <<Quad:?GLUquadric,Draw:?GLenum>>). + cast(5029, <<Quad:?GLUquadric,Draw:?GLenum>>). %% @spec (Quad::integer(),Normal::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricNormals.xml">external</a> documentation. +-spec quadricNormals(integer(),enum()) -> ok. quadricNormals(Quad,Normal) -> - wxe_util:cast(5030, <<Quad:?GLUquadric,Normal:?GLenum>>). + cast(5030, <<Quad:?GLUquadric,Normal:?GLenum>>). %% @spec (Quad::integer(),Orientation::enum()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricOrientation.xml">external</a> documentation. +-spec quadricOrientation(integer(),enum()) -> ok. quadricOrientation(Quad,Orientation) -> - wxe_util:cast(5031, <<Quad:?GLUquadric,Orientation:?GLenum>>). + cast(5031, <<Quad:?GLUquadric,Orientation:?GLenum>>). %% @spec (Quad::integer(),Texture::0|1) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluQuadricTexture.xml">external</a> documentation. +-spec quadricTexture(integer(),0|1) -> ok. quadricTexture(Quad,Texture) -> - wxe_util:cast(5032, <<Quad:?GLUquadric,Texture:?GLboolean>>). + cast(5032, <<Quad:?GLUquadric,Texture:?GLboolean>>). -%% @spec (Format::enum(),WIn::integer(),HIn::integer(),TypeIn::enum(),DataIn::binary(),WOut::integer(),HOut::integer(),TypeOut::enum(),DataOut::wx:wx_mem()) -> integer() +%% @spec (Format::enum(),WIn::integer(),HIn::integer(),TypeIn::enum(),DataIn::binary(),WOut::integer(),HOut::integer(),TypeOut::enum(),DataOut::mem()) -> integer() %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluScaleImage.xml">external</a> documentation. +-spec scaleImage(enum(),integer(),integer(),enum(),binary(),integer(),integer(),enum(),mem()) -> integer(). scaleImage(Format,WIn,HIn,TypeIn,DataIn,WOut,HOut,TypeOut,DataOut) -> - wxe_util:send_bin(DataIn), - wxe_util:send_bin(DataOut#wx_mem.bin), - wxe_util:call(5033, <<Format:?GLenum,WIn:?GLsizei,HIn:?GLsizei,TypeIn:?GLenum,WOut:?GLsizei,HOut:?GLsizei,TypeOut:?GLenum>>). + send_bin(DataIn), + send_bin(DataOut), + call(5033, <<Format:?GLenum,WIn:?GLsizei,HIn:?GLsizei,TypeIn:?GLenum,WOut:?GLsizei,HOut:?GLsizei,TypeOut:?GLenum>>). %% @spec (Quad::integer(),Radius::float(),Slices::integer(),Stacks::integer()) -> ok %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluSphere.xml">external</a> documentation. +-spec sphere(integer(),float(),integer(),integer()) -> ok. sphere(Quad,Radius,Slices,Stacks) -> - wxe_util:cast(5034, <<Quad:?GLUquadric,Radius:?GLdouble,Slices:?GLint,Stacks:?GLint>>). + cast(5034, <<Quad:?GLUquadric,Radius:?GLdouble,Slices:?GLint,Stacks:?GLint>>). -%% @spec (WinX::float(),WinY::float(),WinZ::float(),Model::{float()},Proj::{float()},View::{integer()}) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float()} +%% @spec (WinX::float(),WinY::float(),WinZ::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()}) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml">external</a> documentation. +-spec unProject(float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()}) -> {integer(),float(),float(),float()}. unProject(WinX,WinY,WinZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4}) -> - wxe_util:call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>); + call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>); unProject(WinX,WinY,WinZ,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4}) -> - wxe_util:call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). + call(5035, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint>>). -%% @spec (WinX::float(),WinY::float(),WinZ::float(),ClipW::float(),Model::{float()},Proj::{float()},View::{integer()},NearVal::float(),FarVal::float()) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float(),ObjW::float()} +%% @spec (WinX::float(),WinY::float(),WinZ::float(),ClipW::float(),Model::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},Proj::{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},View::{integer(),integer(),integer(),integer()},NearVal::float(),FarVal::float()) -> {integer(),ObjX::float(),ObjY::float(),ObjZ::float(),ObjW::float()} %% @doc See <a href="http://www.opengl.org/sdk/docs/man/xhtml/gluUnProject.xml">external</a> documentation. +-spec unProject4(float(),float(),float(),float(),{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float(),float()},{integer(),integer(),integer(),integer()},float(),float()) -> {integer(),float(),float(),float(),float()}. unProject4(WinX,WinY,WinZ,ClipW,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12,M13,M14,M15,M16},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16},{V1,V2,V3,V4},NearVal,FarVal) -> - wxe_util:call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>); + call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,M13:?GLdouble,M14:?GLdouble,M15:?GLdouble,M16:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,P13:?GLdouble,P14:?GLdouble,P15:?GLdouble,P16:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>); unProject4(WinX,WinY,WinZ,ClipW,{M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M11,M12},{P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12},{V1,V2,V3,V4},NearVal,FarVal) -> - wxe_util:call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>). + call(5036, <<WinX:?GLdouble,WinY:?GLdouble,WinZ:?GLdouble,ClipW:?GLdouble,M1:?GLdouble,M2:?GLdouble,M3:?GLdouble,0:?GLdouble,M4:?GLdouble,M5:?GLdouble,M6:?GLdouble,0:?GLdouble,M7:?GLdouble,M8:?GLdouble,M9:?GLdouble,0:?GLdouble,M10:?GLdouble,M11:?GLdouble,M12:?GLdouble,1:?GLdouble,P1:?GLdouble,P2:?GLdouble,P3:?GLdouble,0:?GLdouble,P4:?GLdouble,P5:?GLdouble,P6:?GLdouble,0:?GLdouble,P7:?GLdouble,P8:?GLdouble,P9:?GLdouble,0:?GLdouble,P10:?GLdouble,P11:?GLdouble,P12:?GLdouble,1:?GLdouble,V1:?GLint,V2:?GLint,V3:?GLint,V4:?GLint,NearVal:?GLdouble,FarVal:?GLdouble>>). diff --git a/lib/wx/src/gen/wxGLCanvas.erl b/lib/wx/src/gen/wxGLCanvas.erl index 3e0d1bd9ae..032d42535d 100644 --- a/lib/wx/src/gen/wxGLCanvas.erl +++ b/lib/wx/src/gen/wxGLCanvas.erl @@ -144,8 +144,10 @@ getContext(#wx_ref{type=ThisT,ref=ThisRef}) -> %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvassetcurrent">external documentation</a>. setCurrent(#wx_ref{type=ThisT,ref=ThisRef}) -> ?CLASS(ThisT,wxGLCanvas), - wxe_util:cast(?wxGLCanvas_SetCurrent, - <<ThisRef:32/?UI>>). + _Result = wxe_util:cast(?wxGLCanvas_SetCurrent, + <<ThisRef:32/?UI>>), + {ok, _} = wxe_master:init_opengl(), + _Result. %% @spec (This::wxGLCanvas()) -> ok %% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxglcanvas.html#wxglcanvasswapbuffers">external documentation</a>. diff --git a/lib/wx/src/gen/wxSystemSettings.erl b/lib/wx/src/gen/wxSystemSettings.erl new file mode 100644 index 0000000000..3f7e0a1ad6 --- /dev/null +++ b/lib/wx/src/gen/wxSystemSettings.erl @@ -0,0 +1,79 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2008-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 is generated DO NOT EDIT + +%% @doc See external documentation: <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html">wxSystemSettings</a>. +%% @type wxSystemSettings(). An object reference, The representation is internal +%% and can be changed without notice. It can't be used for comparsion +%% stored on disc or distributed for use on other nodes. + +-module(wxSystemSettings). +-include("wxe.hrl"). +-export([getColour/1,getFont/1,getMetric/1,getMetric/2,getScreenType/0]). + +%% inherited exports +-export([parent_class/1]). + +%% @hidden +parent_class(_Class) -> erlang:error({badtype, ?MODULE}). + +%% @spec (Index::WxSystemColour) -> wx:colour() +%% WxSystemColour = integer() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetcolour">external documentation</a>. +%%<br /> WxSystemColour is one of ?wxSYS_COLOUR_SCROLLBAR | ?wxSYS_COLOUR_BACKGROUND | ?wxSYS_COLOUR_DESKTOP | ?wxSYS_COLOUR_ACTIVECAPTION | ?wxSYS_COLOUR_INACTIVECAPTION | ?wxSYS_COLOUR_MENU | ?wxSYS_COLOUR_WINDOW | ?wxSYS_COLOUR_WINDOWFRAME | ?wxSYS_COLOUR_MENUTEXT | ?wxSYS_COLOUR_WINDOWTEXT | ?wxSYS_COLOUR_CAPTIONTEXT | ?wxSYS_COLOUR_ACTIVEBORDER | ?wxSYS_COLOUR_INACTIVEBORDER | ?wxSYS_COLOUR_APPWORKSPACE | ?wxSYS_COLOUR_HIGHLIGHT | ?wxSYS_COLOUR_HIGHLIGHTTEXT | ?wxSYS_COLOUR_BTNFACE | ?wxSYS_COLOUR_3DFACE | ?wxSYS_COLOUR_BTNSHADOW | ?wxSYS_COLOUR_3DSHADOW | ?wxSYS_COLOUR_GRAYTEXT | ?wxSYS_COLOUR_BTNTEXT | ?wxSYS_COLOUR_INACTIVECAPTIONTEXT | ?wxSYS_COLOUR_BTNHIGHLIGHT | ?wxSYS_COLOUR_BTNHILIGHT | ?wxSYS_COLOUR_3DHIGHLIGHT | ?wxSYS_COLOUR_3DHILIGHT | ?wxSYS_COLOUR_3DDKSHADOW | ?wxSYS_COLOUR_3DLIGHT | ?wxSYS_COLOUR_INFOTEXT | ?wxSYS_COLOUR_INFOBK | ?wxSYS_COLOUR_LISTBOX | ?wxSYS_COLOUR_HOTLIGHT | ?wxSYS_COLOUR_GRADIENTACTIVECAPTION | ?wxSYS_COLOUR_GRADIENTINACTIVECAPTION | ?wxSYS_COLOUR_MENUHILIGHT | ?wxSYS_COLOUR_MENUBAR | ?wxSYS_COLOUR_LISTBOXTEXT | ?wxSYS_COLOUR_MAX +getColour(Index) + when is_integer(Index) -> + wxe_util:call(?wxSystemSettings_GetColour, + <<Index:32/?UI>>). + +%% @spec (Index::WxSystemFont) -> wxFont:wxFont() +%% WxSystemFont = integer() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetfont">external documentation</a>. +%%<br /> WxSystemFont is one of ?wxSYS_OEM_FIXED_FONT | ?wxSYS_ANSI_FIXED_FONT | ?wxSYS_ANSI_VAR_FONT | ?wxSYS_SYSTEM_FONT | ?wxSYS_DEVICE_DEFAULT_FONT | ?wxSYS_DEFAULT_PALETTE | ?wxSYS_SYSTEM_FIXED_FONT | ?wxSYS_DEFAULT_GUI_FONT | ?wxSYS_ICONTITLE_FONT +getFont(Index) + when is_integer(Index) -> + wxe_util:call(?wxSystemSettings_GetFont, + <<Index:32/?UI>>). + +%% @spec (Index::WxSystemMetric) -> integer() +%% @equiv getMetric(Index, []) +getMetric(Index) + when is_integer(Index) -> + getMetric(Index, []). + +%% @spec (Index::WxSystemMetric, [Option]) -> integer() +%% Option = {win, wxWindow:wxWindow()} +%% WxSystemMetric = integer() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetmetric">external documentation</a>. +%%<br /> WxSystemMetric is one of ?wxSYS_MOUSE_BUTTONS | ?wxSYS_BORDER_X | ?wxSYS_BORDER_Y | ?wxSYS_CURSOR_X | ?wxSYS_CURSOR_Y | ?wxSYS_DCLICK_X | ?wxSYS_DCLICK_Y | ?wxSYS_DRAG_X | ?wxSYS_DRAG_Y | ?wxSYS_EDGE_X | ?wxSYS_EDGE_Y | ?wxSYS_HSCROLL_ARROW_X | ?wxSYS_HSCROLL_ARROW_Y | ?wxSYS_HTHUMB_X | ?wxSYS_ICON_X | ?wxSYS_ICON_Y | ?wxSYS_ICONSPACING_X | ?wxSYS_ICONSPACING_Y | ?wxSYS_WINDOWMIN_X | ?wxSYS_WINDOWMIN_Y | ?wxSYS_SCREEN_X | ?wxSYS_SCREEN_Y | ?wxSYS_FRAMESIZE_X | ?wxSYS_FRAMESIZE_Y | ?wxSYS_SMALLICON_X | ?wxSYS_SMALLICON_Y | ?wxSYS_HSCROLL_Y | ?wxSYS_VSCROLL_X | ?wxSYS_VSCROLL_ARROW_X | ?wxSYS_VSCROLL_ARROW_Y | ?wxSYS_VTHUMB_Y | ?wxSYS_CAPTION_Y | ?wxSYS_MENU_Y | ?wxSYS_NETWORK_PRESENT | ?wxSYS_PENWINDOWS_PRESENT | ?wxSYS_SHOW_SOUNDS | ?wxSYS_SWAP_BUTTONS +getMetric(Index, Options) + when is_integer(Index),is_list(Options) -> + MOpts = fun({win, #wx_ref{type=WinT,ref=WinRef}}, Acc) -> ?CLASS(WinT,wxWindow),[<<1:32/?UI,WinRef:32/?UI>>|Acc]; + (BadOpt, _) -> erlang:error({badoption, BadOpt}) end, + BinOpt = list_to_binary(lists:foldl(MOpts, [<<0:32>>], Options)), + wxe_util:call(?wxSystemSettings_GetMetric, + <<Index:32/?UI, 0:32,BinOpt/binary>>). + +%% @spec () -> WxSystemScreenType +%% WxSystemScreenType = integer() +%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxsystemsettings.html#wxsystemsettingsgetscreentype">external documentation</a>. +%%<br /> WxSystemScreenType is one of ?wxSYS_SCREEN_NONE | ?wxSYS_SCREEN_TINY | ?wxSYS_SCREEN_PDA | ?wxSYS_SCREEN_SMALL | ?wxSYS_SCREEN_DESKTOP +getScreenType() -> + wxe_util:call(?wxSystemSettings_GetScreenType, + <<>>). + diff --git a/lib/wx/src/wx.erl b/lib/wx/src/wx.erl index 14abd0d817..9d76f3bc42 100644 --- a/lib/wx/src/wx.erl +++ b/lib/wx/src/wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -96,7 +96,8 @@ new() -> %% @doc Starts a wx server. %% Option may be {debug, Level}, see debug/1. new(Options) when is_list(Options) -> - #wx_env{} = wxe_server:start(), + #wx_env{port=Port} = wxe_server:start(), + put(opengl_port, Port), Debug = proplists:get_value(debug, Options, 0), debug(Debug), null(). @@ -121,8 +122,9 @@ get_env() -> %% @spec (wx_env()) -> ok %% @doc Sets the process wx environment, allows this process to use %% another process wx environment. -set_env(#wx_env{sv=Pid} = Env) -> - put(?WXE_IDENTIFIER, Env), +set_env(#wx_env{sv=Pid, port=Port} = Env) -> + put(?WXE_IDENTIFIER, Env), + put(opengl_port, Port), %% wxe_util:cast(?REGISTER_PID, <<>>), wxe_server:register_me(Pid), ok. diff --git a/lib/wx/src/wxe.hrl b/lib/wx/src/wxe.hrl index bb70a03bfe..bd34b13385 100644 --- a/lib/wx/src/wxe.hrl +++ b/lib/wx/src/wxe.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -50,6 +50,8 @@ -define(WXE_CB_START, 8). %% Used for event-callback start -define(WXE_DEBUG_DRIVER, 9). %% Set debug %%-define(WXE_DEBUG_PING, 10). %% debug ping (when using debugger it's needed) --define(WXE_BIN_INCR, 5001). %% Binary refc incr --define(WXE_BIN_DECR, 5002). %% Binary refc decr +-define(WXE_BIN_INCR, 11). %% Binary refc incr +-define(WXE_BIN_DECR, 12). %% Binary refc decr +-define(WXE_INIT_OPENGL, 13). %% Binary refc decr + -include("gen/wxe_funcs.hrl"). diff --git a/lib/wx/src/wxe_master.erl b/lib/wx/src/wxe_master.erl index 5ab76a77cf..d8592c133b 100644 --- a/lib/wx/src/wxe_master.erl +++ b/lib/wx/src/wxe_master.erl @@ -28,7 +28,7 @@ -behaviour(gen_server). %% API --export([start/0, init_port/0]). +-export([start/0, init_port/0, init_opengl/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -38,8 +38,8 @@ users, %% List of wx servers, needed ?? driver}). %% Driver name so wx_server can create it's own port +-include("wxe.hrl"). -include("gen/wxe_debug.hrl"). --include("gen/gl_debug.hrl"). -define(DRIVER, "wxe_driver"). @@ -74,6 +74,14 @@ init_port() -> receive wx_port_initiated -> ok end, {Port, CBport}. + +%%-------------------------------------------------------------------- +%% Initlizes the opengl library +%%-------------------------------------------------------------------- +init_opengl() -> + GLLib = wxe_util:wxgl_dl(), + wxe_util:call(?WXE_INIT_OPENGL, <<(list_to_binary(GLLib))/binary, 0:8>>). + %%==================================================================== %% gen_server callbacks %%==================================================================== @@ -87,7 +95,7 @@ init_port() -> %%-------------------------------------------------------------------- init([]) -> DriverName = ?DRIVER, - PrivDir = priv_dir(), + PrivDir = wxe_util:priv_dir(?DRIVER), erlang:group_leader(whereis(init), self()), case catch erlang:system_info(smp_support) of true -> ok; @@ -127,7 +135,6 @@ init([]) -> wx_debug_info = ets:new(wx_debug_info, [named_table]), wx_non_consts = ets:new(wx_non_consts, [named_table]), true = ets:insert(wx_debug_info, wxdebug_table()), - true = ets:insert(wx_debug_info, gldebug_table()), spawn_link(fun() -> debug_ping(Port) end), receive {wx_consts, List} -> @@ -205,108 +212,9 @@ code_change(_OldVsn, State, _Extra) -> %%%%%%%%%%%% INTERNAL %%%%%%%%%%%%%%%%%%%%%%%% -%% If you want anything done, do it yourself. - -priv_dir() -> - Type = erlang:system_info(system_architecture), - {file, Path} = code:is_loaded(?MODULE), - Priv = case filelib:is_regular(Path) of - true -> - Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]), - filename:join(strip(Path, Beam), "priv"); - false -> - code:priv_dir(wx) - end, - try - {ok, Dirs0} = file:list_dir(Priv), - Dirs1 = split_dirs(Dirs0), - Dirs = lists:reverse(lists:sort(Dirs1)), - - Best = best_dir(hd(split_dirs([Type])),Dirs, Priv), - filename:join(Priv, Best) - catch _:_ -> - error_logger:format("WX ERROR: Could not find suitable \'~s\' for ~s in: ~s~n", - [?DRIVER, Type, Priv]), - erlang:error({load_driver, "No driver found"}) - end. - -best_dir(Dir, Dirs0, Priv) -> - Dirs = [{D,D} || D <- Dirs0], - best_dir(Dir, Dirs, [], Priv). - -best_dir(Pre, [{[],_}|R], Acc, Priv) -> %% Empty skip'em - best_dir(Pre, R, Acc, Priv); -best_dir(Pre, [{Pre,Dir}|R], Acc, Priv) -> - Real = dir_app(lists:reverse(Dir)), - case file:list_dir(filename:join(Priv,Real)) of - {ok, Fs} -> - case lists:any(fun(File) -> filename:rootname(File) =:= ?DRIVER end, Fs) of - true -> Real; %% Found dir and it contains a driver - false -> best_dir(Pre, R, Acc, Priv) - end; - _ -> - best_dir(Pre, R, Acc, Priv) - end; -best_dir(Pre, [{[_|F],Dir}|R], Acc, Priv) -> - best_dir(Pre, R, [{F,Dir}|Acc], Priv); -best_dir(_Pre, [], [],_) -> throw(no_dir); %% Nothing found -best_dir([_|Pre], [], Acc, Priv) -> - best_dir(Pre, lists:reverse(Acc), [], Priv); -best_dir([], _, _,_) -> throw(no_dir). %% Nothing found - -split_dirs(Dirs0) -> - ToInt = fun(Str) -> - try - list_to_integer(Str) - catch _:_ -> Str - end - end, - Split = fun(Dir) -> - Toks = tokens(Dir,".-"), - lists:reverse([ToInt(Str) || Str <- Toks]) - end, - lists:map(Split,Dirs0). - -dir_app([]) -> []; -dir_app([Dir]) -> Dir; -dir_app(Dir) -> - dir_app2(Dir). -dir_app2([Int]) when is_integer(Int) -> - integer_to_list(Int); -dir_app2([Str]) when is_list(Str) -> - Str; -dir_app2([Head|Rest]) when is_integer(Head) -> - integer_to_list(Head) ++ dir_app2(Rest); -dir_app2([Head|Rest]) when is_list(Head) -> - Head ++ dir_app2(Rest). - -strip(Src, Src) -> - []; -strip([H|R], Src) -> - [H| strip(R, Src)]. - - debug_ping(Port) -> timer:sleep(1*333), _R = (catch erlang:port_call(Port, 0, [])), %% io:format("Erlang ping ~p ~n", [_R]), debug_ping(Port). -tokens(S,Seps) -> - tokens1(S, Seps, []). - -tokens1([C|S], Seps, Toks) -> - case lists:member(C, Seps) of - true -> tokens1(S, Seps, [[C]|Toks]); - false -> tokens2(S, Seps, Toks, [C]) - end; -tokens1([], _Seps, Toks) -> - lists:reverse(Toks). - -tokens2([C|S], Seps, Toks, Cs) -> - case lists:member(C, Seps) of - true -> tokens1(S, Seps, [[C], lists:reverse(Cs) |Toks]); - false -> tokens2(S, Seps, Toks, [C|Cs]) - end; -tokens2([], _Seps, Toks, Cs) -> - lists:reverse([lists:reverse(Cs)|Toks]). diff --git a/lib/wx/src/wxe_util.erl b/lib/wx/src/wxe_util.erl index a2fb4641c9..02bca62486 100644 --- a/lib/wx/src/wxe_util.erl +++ b/lib/wx/src/wxe_util.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -32,8 +32,9 @@ get_const/1,colour_bin/1,datetime_bin/1, to_bool/1,from_bool/1]). --include("wxe.hrl"). +-export([wxgl_dl/0, priv_dir/1]). +-include("wxe.hrl"). to_bool(0) -> false; to_bool(_) -> true. @@ -199,3 +200,47 @@ check_previous() -> erlang:error({Error, MF}) after 0 -> ok end. + +%% Get gl dynamic library + +wxgl_dl() -> + DynLib0 = "erl_gl", + PrivDir = priv_dir(DynLib0), + DynLib = case os:type() of + {win32,_} -> + DynLib0 ++ ".dll"; + _ -> + DynLib0 ++ ".so" + end, + filename:join(PrivDir, DynLib). + +priv_dir(Driver0) -> + {file, Path} = code:is_loaded(?MODULE), + Priv = case filelib:is_regular(Path) of + true -> + Beam = filename:join(["ebin/",atom_to_list(?MODULE) ++ ".beam"]), + filename:join(strip(Path, Beam), "priv"); + false -> + code:priv_dir(wx) + end, + Driver = case os:type() of + {win32,_} -> + Driver0 ++ ".dll"; + _ -> + Driver0 ++ ".so" + end, + + case file:read_file_info(filename:join(Priv, Driver)) of + {ok, _} -> + Priv; + {error, _} -> + error_logger:format("ERROR: Could not find \'~s\' in: ~s~n", + [Driver, Priv]), + erlang:error({load_driver, "No driver found"}) + end. + +strip(Src, Src) -> + []; +strip([H|R], Src) -> + [H| strip(R, Src)]. + diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl index 6f43247d74..7b8d510d40 100644 --- a/lib/wx/test/wx_class_SUITE.erl +++ b/lib/wx/test/wx_class_SUITE.erl @@ -58,7 +58,8 @@ all(suite) -> helpFrame, htmlWindow, listCtrlSort, - radioBox + radioBox, + systemSettings ]. %% The test cases @@ -392,3 +393,17 @@ radioBox(Config) -> wxWindow:show(Frame), wx_test_lib:wx_destroy(Frame,Config). + + +systemSettings(TestInfo) when is_atom(TestInfo) -> wx_test_lib:tc_info(TestInfo); +systemSettings(Config) -> + Wx = wx:new(), + Frame = wxFrame:new(Wx, ?wxID_ANY, "Frame"), + + ?m({_,_,_,_}, wxSystemSettings:getColour(?wxSYS_COLOUR_DESKTOP)), + ?mt(wxFont, wxSystemSettings:getFont(?wxSYS_SYSTEM_FONT)), + ?m(true, is_integer(wxSystemSettings:getMetric(?wxSYS_MOUSE_BUTTONS))), + ?m(true, is_integer(wxSystemSettings:getScreenType())), + + wxWindow:show(Frame), + wx_test_lib:wx_destroy(Frame,Config). diff --git a/lib/wx/test/wx_opengl_SUITE.erl b/lib/wx/test/wx_opengl_SUITE.erl index ce4651bcb1..778d089bce 100644 --- a/lib/wx/test/wx_opengl_SUITE.erl +++ b/lib/wx/test/wx_opengl_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -91,7 +91,7 @@ canvas(Config) -> ?m(true, wxWindow:show(Frame)), ?m(false, wx:is_null(wxGLCanvas:getContext(Canvas))), - ?m({'EXIT', {{no_gl_context,_},_}}, gl:getString(?GL_VENDOR)), + ?m({'EXIT', {{error, no_gl_context,_},_}}, gl:getString(?GL_VENDOR)), ?m(ok, wxGLCanvas:setCurrent(Canvas)), io:format("Vendor: ~s~n", [gl:getString(?GL_VENDOR)]), @@ -113,7 +113,7 @@ canvas(Config) -> Data = {?FACES,?VS}, drawBox(0, Data), ?m(ok, wxGLCanvas:swapBuffers(Canvas)), - + ?m([], flush()), Env = wx:get_env(), Tester = self(), spawn_link(fun() -> @@ -125,10 +125,23 @@ canvas(Config) -> %% This may fail when window is deleted catch draw_loop(2,Data,Canvas) end), - ?m_receive(works), + ?m([], flush()), + io:format("Undef func ~p ~n", [catch gl:uniform1d(2, 0.75)]), + timer:sleep(500), + ?m([], flush()), wx_test_lib:wx_destroy(Frame, Config). - + +flush() -> + flush([]). + +flush(Collected) -> + receive Msg -> + flush([Msg|Collected]) + after 1 -> + lists:reverse(Collected) + end. + draw_loop(Deg,Data,Canvas) -> timer:sleep(15), drawBox(Deg,Data), @@ -136,6 +149,7 @@ draw_loop(Deg,Data,Canvas) -> draw_loop(Deg+1, Data,Canvas). + drawBox(Deg,{Fs,Vs}) -> gl:matrixMode(?GL_MODELVIEW), gl:loadIdentity(), diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc index 9d184152d1..3b9eaa309c 100644 --- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc +++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc @@ -1,7 +1,7 @@ %%-*-erlang-*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2009. All Rights Reserved. +%% Copyright Ericsson AB 2008-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 @@ -934,6 +934,13 @@ parse_att_value(?STRING_REST("&", Rest), State, Stop, Acc) -> parse_att_value(Rest1, State2, Stop, ParsedValue ++ Acc); {external_general, Name, _} -> ?fatal_error(State1, "External parsed entity reference in attribute value: " ++ Name); + {not_found, Name} -> + case State#xmerl_sax_parser_state.skip_external_dtd of + false -> + ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared + true -> + parse_att_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc) + end; {unparsed, Name, _} -> ?fatal_error(State1, "Unparsed entity reference in attribute value: " ++ Name) end; @@ -1098,6 +1105,13 @@ parse_content(?STRING_REST("&", Rest), State, Acc, _IgnorableWS) -> {external_general, _, {PubId, SysId}} -> State2 = parse_external_entity(State1, PubId, SysId), parse_content(Rest1, State2, Acc, false); + {not_found, Name} -> + case State#xmerl_sax_parser_state.skip_external_dtd of + false -> + ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared + true -> + parse_content(Rest1, State1, ";" ++ lists:reverse(Name) ++ "&" ++ Acc, false) + end; {unparsed, Name, _} -> ?fatal_error(State1, "Unparsed entity reference in content: " ++ Name) end; @@ -1357,7 +1371,7 @@ look_up_reference(Name, HaveToExist, State) -> yes -> ?fatal_error(State, "Entity not declared: " ++ Name); %%WFC: Entity Declared no -> - ?fatal_error(State, "Entity not declared: " ++ Name) %%VC: Entity Declared + {not_found, Name} %%VC: Entity Declared end; false -> {not_found, Name} @@ -1869,7 +1883,14 @@ parse_doctype_decl(?STRING_REST("%", Rest), State) -> parse_doctype_decl(?APPEND_STRING(IValue, Rest1), State1); {external_parameter, _, {PubId, SysId}} -> State2 = parse_external_entity(State1#xmerl_sax_parser_state{file_type = entity}, PubId, SysId), - parse_doctype_decl(Rest1, State2) + parse_doctype_decl(Rest1, State2); + {not_found, Name} -> + case State#xmerl_sax_parser_state.skip_external_dtd of + false -> + ?fatal_error(State1, "Entity not declared: " ++ Name); %%WFC: Entity Declared + true -> + parse_doctype_decl(Rest1, State1) + end end; parse_doctype_decl(?STRING_REST("<!", Rest1), State) -> parse_doctype_decl_1(Rest1, State); @@ -2443,7 +2464,7 @@ parse_ndata(Bytes, State) -> %% Acc = string() %% Result : {Value, Rest, State} %% Value = string() -%% Description: Parse an attribute value +%% Description: Parse an entity value %%---------------------------------------------------------------------- parse_entity_value(?STRING_EMPTY, State, undefined, Acc) -> {Acc, [], State}; %% stop clause when parsing references @@ -2473,7 +2494,7 @@ parse_entity_value(?STRING_REST("&", Rest), State, Stop, Acc) -> {external_general, Name, _} -> parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc); {not_found, Name} -> - parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc); + parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc); {unparsed, Name, _} -> ?fatal_error(State1, "Unparsed entity reference in entity value: " ++ Name) end; @@ -2490,7 +2511,15 @@ parse_entity_value(?STRING_REST("%", Rest), #xmerl_sax_parser_state{file_type=Ty IValue = ?TO_INPUT_FORMAT(" " ++ RefValue ++ " "), parse_entity_value(?APPEND_STRING(IValue, Rest1), State1, Stop, Acc); {external_parameter, _, {_PubId, _SysId}} -> - ?fatal_error(State1, "Parameter references in entity value not supported yet.") + ?fatal_error(State1, "Parameter references in entity value not supported yet."); + {not_found, Name} -> + case State#xmerl_sax_parser_state.skip_external_dtd of + false -> + ?fatal_error(State1, "Entity not declared: " ++ Name); %%VC: Entity Declared + true -> + parse_entity_value(Rest1, State1, Stop, ";" ++ lists:reverse(Name) ++ "&" ++ Acc) + end + end end; parse_entity_value(?STRING_UNBOUND_REST(Stop, Rest), State, Stop, Acc) -> diff --git a/lib/xmerl/src/xmerl_scan.erl b/lib/xmerl/src/xmerl_scan.erl index e2e6f95c4a..e07d495fc7 100644 --- a/lib/xmerl/src/xmerl_scan.erl +++ b/lib/xmerl/src/xmerl_scan.erl @@ -34,7 +34,9 @@ %% See also <a href="xmerl_examples.html">tutorial</a> on customization %% functions. %% </p> +%% <p> %% Possible options are: +%% </p> %% <dl> %% <dt><code>{acc_fun, Fun}</code></dt> %% <dd>Call back function to accumulate contents of entity.</dd> diff --git a/lib/xmerl/src/xmerl_xpath.erl b/lib/xmerl/src/xmerl_xpath.erl index 182a186d2c..e654a8ef1d 100644 --- a/lib/xmerl/src/xmerl_xpath.erl +++ b/lib/xmerl/src/xmerl_xpath.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2009. All Rights Reserved. +%% 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 @@ -57,7 +57,9 @@ %% @type option_list(). <p>Options allows to customize the behaviour of the %% XPath scanner. %% </p> +%% <p> %% Possible options are: +%% </p> %% <dl> %% <dt><code>{namespace, #xmlNamespace}</code></dt> %% <dd>Set namespace nodes, from XmlNamspace, in xmlContext</dd> diff --git a/lib/xmerl/src/xmerl_xsd.erl b/lib/xmerl/src/xmerl_xsd.erl index 1aedc9e270..c0923520c2 100644 --- a/lib/xmerl/src/xmerl_xsd.erl +++ b/lib/xmerl/src/xmerl_xsd.erl @@ -29,7 +29,9 @@ %% @type option_list(). <p>Options allow to customize the behaviour of the %% validation. %% </p> +%% <p> %% Possible options are : +%% </p> %% <dl> %% <dt><code>{tab2file,boolean()}</code></dt> %% <dd>Enables saving of abstract structure on file for debugging @@ -46,6 +48,7 @@ %% <dd>It is possible by this option to provide a state with process %% information from an earlier validation.</dd> %% </dl> +%% @end %%%------------------------------------------------------------------- -module(xmerl_xsd). diff --git a/make/emd2exml.in b/make/emd2exml.in index 17cb0a0b57..ea1085cf71 100644 --- a/make/emd2exml.in +++ b/make/emd2exml.in @@ -44,6 +44,7 @@ -define(DELAYED_TOC_IX, 1). -define(DELAYED_START_IX, 2). +-compile({no_auto_import,[error/2]}). -mode(compile). -export([main/1]). diff --git a/make/otp.mk.in b/make/otp.mk.in index 6ae7c5b456..bf287be416 100644 --- a/make/otp.mk.in +++ b/make/otp.mk.in @@ -209,6 +209,8 @@ MAN9DIR = $(DOCDIR)/man9 TEXDIR = . +SPECDIR = $(DOCDIR)/specs + # HTML & GIF files that always are generated and must be delivered SGML_COLL_FILES = $(SGML_APPLICATION_FILES) $(SGML_PART_FILES) XML_COLL_FILES = $(XML_APPLICATION_FILES) $(XML_PART_FILES) @@ -237,41 +239,52 @@ FOP = @FOP@ DOCGEN=$(ERL_TOP)/lib/erl_docgen +SPECS_ESRC = ../../src +# Extract specifications and types from Erlang source files (-spec, -type) +$(SPECDIR)/specs_%.xml: $(SPECS_ESRC)/%.erl + escript $(DOCGEN)/priv/bin/specs_gen.escript $(SPECS_FLAGS) -o$(dir $@) $< -$(MAN1DIR)/%.1:: %.xml +$(MAN1DIR)/%.1: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< -$(MAN2DIR)/%.2:: %.xml +$(MAN2DIR)/%.2: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< -$(MAN3DIR)/%.3:: %.xml +ifneq ($(wildcard $(SPECDIR)),) +$(MAN3DIR)/%.3: %.xml $(SPECDIR)/specs_%.xml + date=`date +"%B %e %Y"`; \ + specs_file=`pwd`/$(SPECDIR)/specs_$*.xml; \ + xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --stringparam specs_file "$$specs_file" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< +else +$(MAN3DIR)/%.3: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< +endif # left for compatability -$(MAN4DIR)/%.4:: %.xml +$(MAN4DIR)/%.4: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< -$(MAN4DIR)/%.5:: %.xml +$(MAN4DIR)/%.5: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< # left for compatability -$(MAN6DIR)/%.6:: %_app.xml +$(MAN6DIR)/%.6: %_app.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< -$(MAN6DIR)/%.7:: %_app.xml +$(MAN6DIR)/%.7: %_app.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< -$(MAN9DIR)/%.9:: %.xml +$(MAN9DIR)/%.9: %.xml date=`date +"%B %e %Y"`; \ xsltproc --output "$@" --stringparam company "Ericsson AB" --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_man_entities $(DOCGEN)/priv/xsl/db_man.xsl $< diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk index 7d433e738c..8058e634d4 100644 --- a/make/otp_release_targets.mk +++ b/make/otp_release_targets.mk @@ -21,13 +21,30 @@ # Targets for the new documentation support # ---------------------------------------------------- +ifneq ($(TOP_SPECS_FILE),) +TOP_SPECS_PARAM = --stringparam specs_file "`pwd`/$(TOP_SPECS_FILE)" +endif + +MOD2APP = $(ERL_TOP)/make/$(TARGET)/mod2app.xml +ifneq ($(wildcard $(MOD2APP)),) +MOD2APP_PARAM = --stringparam mod2app_file "$(MOD2APP)" +endif + ifeq ($(TOPDOC),) -$(HTMLDIR)/index.html: $(XML_FILES) +$(HTMLDIR)/index.html: $(XML_FILES) $(SPECS_FILES) date=`date +"%B %e %Y"`; \ - $(XSLTPROC) --noout --stringparam outdir $(HTMLDIR) --stringparam docgen "$(DOCGEN)" --stringparam topdocdir "$(TOPDOCDIR)" \ - --stringparam pdfdir "$(PDFDIR)" \ - --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \ - -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml + $(XSLTPROC) --noout \ + --stringparam outdir $(HTMLDIR) \ + --stringparam docgen "$(DOCGEN)" \ + --stringparam topdocdir "$(TOPDOCDIR)" \ + --stringparam pdfdir "$(PDFDIR)" \ + --xinclude $(TOP_SPECS_PARAM) $(MOD2APP_PARAM) \ + --stringparam gendate "$$date" \ + --stringparam appname "$(APPLICATION)" \ + --stringparam appver "$(VSN)" \ + -path $(DOCGEN)/priv/docbuilder_dtd \ + -path $(DOCGEN)/priv/dtd_html_entities \ + $(DOCGEN)/priv/xsl/db_html.xsl book.xml endif $(HTMLDIR)/users_guide.html: $(XML_FILES) @@ -37,14 +54,17 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES) --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \ -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_html.xsl book.xml - -%.fo: $(XML_FILES) +%.fo: $(XML_FILES) $(SPECS_FILES) date=`date +"%B %e %Y"`; \ - $(XSLTPROC) --stringparam docgen "$(DOCGEN)" --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" \ - --stringparam appver "$(VSN)" --xinclude \ - -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@ - - + $(XSLTPROC) \ + --stringparam docgen "$(DOCGEN)" \ + --stringparam gendate "$$date" \ + --stringparam appname "$(APPLICATION)" \ + --stringparam appver "$(VSN)" \ + --xinclude $(TOP_SPECS_PARAM) \ + -path $(DOCGEN)/priv/docbuilder_dtd \ + -path $(DOCGEN)/priv/dtd_html_entities \ + $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@ # ------------------------------------------------------------------------ # The following targets just exist in the documentation directory @@ -1178,7 +1178,7 @@ case "$1" in esac ;; primary) echo "Primary bootstrap is under version control since R13"; - echo "Use {prepare,update,commit}_primary if you really are"; + echo "Use update_primary if you really are"; echo "updating the primary bootstrap...";; boot) do_boot;; diff --git a/system/doc/top/Makefile b/system/doc/top/Makefile index 148fefaf13..aac90fcaa4 100644 --- a/system/doc/top/Makefile +++ b/system/doc/top/Makefile @@ -246,7 +246,7 @@ release_docs_spec: docs $(INSTALL_DATA) $(INDEX_FILES) $(MAN_INDEX) $(TOP_HTML_FILES) $(RELSYSDIR) $(INSTALL_DIR) $(RELSYSDIR)/docbuild $(INSTALL_DATA) $(INDEX_SCRIPT) $(MAN_INDEX_SCRIPT) $(JAVASCRIPT_BUILD_SCRIPT) \ - $(INDEX_SCRIPT_SRC) $(MAN_INDEX_SCRIPT_SRC) $(JAVASCRIPT_BUILD_SCRIPT_SRC) \ + $(INDEX_SRC) $(MAN_INDEX_SRC) $(JAVASCRIPT_BUILD_SCRIPT_SRC) \ $(TEMPLATES) $(RELSYSDIR)/docbuild diff --git a/system/doc/top/src/erl_html_tools.erl b/system/doc/top/src/erl_html_tools.erl index fef56331fc..599268804e 100644 --- a/system/doc/top/src/erl_html_tools.erl +++ b/system/doc/top/src/erl_html_tools.erl @@ -40,7 +40,8 @@ group_order() -> {test, "Test"}, {doc, "Documentation"}, {orb, "Object Request Broker & IDL"}, - {misc, "Miscellaneous"} + {misc, "Miscellaneous"}, + {eric, "Ericsson Internal"} ]. top_index() -> diff --git a/system/doc/tutorial/c_port.xmlsrc b/system/doc/tutorial/c_port.xmlsrc index 7e6034807b..b4caa07578 100644 --- a/system/doc/tutorial/c_port.xmlsrc +++ b/system/doc/tutorial/c_port.xmlsrc @@ -70,7 +70,7 @@ loop(Port) -> {call, Caller, Msg} -> Port ! {self(), {command, encode(Msg)}}, receive -\011{Port, {data, Data}} -> + {Port, {data, Data}} -> Caller ! {complex, decode(Data)} end, loop(Port) |