1: %%
    2: %% %CopyrightBegin%
    3: %% 
    4: %% Copyright Ericsson AB 2006-2011. All Rights Reserved.
    5: %% 
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %% 
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %% 
   17: %% %CopyrightEnd%
   18: %%
   19: 
   20: %% Originally based on Per Gustafsson's test suite.
   21: %%
   22: 
   23: -module(bs_bincomp_SUITE).
   24: 
   25: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   26: 	 init_per_group/2,end_per_group/2,
   27: 	 byte_aligned/1,bit_aligned/1,extended_byte_aligned/1,
   28: 	 extended_bit_aligned/1,mixed/1,tracing/1]).
   29: 
   30: -include_lib("common_test/include/ct.hrl").
   31: 
   32: suite() -> [{ct_hooks,[ts_install_cth]}].
   33: 
   34: all() -> 
   35:     [byte_aligned, bit_aligned, extended_byte_aligned,
   36:      extended_bit_aligned, mixed, tracing].
   37: 
   38: groups() -> 
   39:     [].
   40: 
   41: init_per_suite(Config) ->
   42:     Config.
   43: 
   44: end_per_suite(_Config) ->
   45:     ok.
   46: 
   47: init_per_group(_GroupName, Config) ->
   48:     Config.
   49: 
   50: end_per_group(_GroupName, Config) ->
   51:     Config.
   52: 
   53: 
   54: 
   55: byte_aligned(Config) when is_list(Config) ->
   56:   <<"abcdefg">> = << <<(X+32)>> || <<X>> <= <<"ABCDEFG">> >>,
   57:   <<1:32/little,2:32/little,3:32/little,4:32/little>> =
   58:     << <<X:32/little>> || <<X:32>> <= <<1:32,2:32,3:32,4:32>> >>,
   59:   <<1:32/little,2:32/little,3:32/little,4:32/little>> =
   60:     << <<X:32/little>> || <<X:16>> <= <<1:16,2:16,3:16,4:16>> >>,
   61:   ok.
   62: 
   63: bit_aligned(Config) when is_list(Config) ->
   64:   <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = 
   65:     << <<(X+32):7>> || <<X>> <= <<"ABCDEFG">> >>,
   66:   <<"ABCDEFG">> = 
   67:     << <<(X-32)>> || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> >>,
   68:   <<1:31/little,2:31/little,3:31/little,4:31/little>> =
   69:     << <<X:31/little>> || <<X:31>> <= <<1:31,2:31,3:31,4:31>> >>,
   70:   <<1:31/little,2:31/little,3:31/little,4:31/little>> =
   71:     << <<X:31/little>> || <<X:15>> <= <<1:15,2:15,3:15,4:15>> >>,
   72:   ok.
   73: 
   74: extended_byte_aligned(Config) when is_list(Config) ->
   75:   <<"abcdefg">> = << <<(X+32)>> || X <- "ABCDEFG" >>,
   76:   "abcdefg" = [(X+32) || <<X>> <= <<"ABCDEFG">>],
   77:   <<1:32/little,2:32/little,3:32/little,4:32/little>> =
   78:     << <<X:32/little>> || X <- [1,2,3,4] >>,
   79:   [256,512,768,1024] =
   80:     [X || <<X:16/little>> <= <<1:16,2:16,3:16,4:16>>],
   81:   ok.
   82: 
   83: extended_bit_aligned(Config) when is_list(Config) ->
   84:   <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>> = 
   85:     << <<(X+32):7>> || X <- "ABCDEFG" >>,
   86:   "ABCDEFG" = [(X-32) || <<X:7>> <= <<$a:7,$b:7,$c:7,$d:7,$e:7,$f:7,$g:7>>],
   87:   <<1:31/little,2:31/little,3:31/little,4:31/little>> =
   88:     << <<X:31/little>> || X <- [1,2,3,4] >>,
   89:   [256,512,768,1024] =
   90:     [X || <<X:15/little>> <= <<1:15,2:15,3:15,4:15>>],
   91:   ok.
   92: 
   93: mixed(Config) when is_list(Config) ->
   94:   <<2,3,3,4,4,5,5,6>> =  
   95:     << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>> >>,
   96:   <<2,3,3,4,4,5,5,6>> =  
   97:     << <<(X+Y)>> || <<X>> <= <<1,2,3,4>>, Y <- [1,2] >>,
   98:   <<2,3,3,4,4,5,5,6>> =  
   99:     << <<(X+Y)>> || X <- [1,2,3,4], Y <- [1,2] >>,
  100:   [2,3,3,4,4,5,5,6] =  
  101:     [(X+Y) || <<X>> <= <<1,2,3,4>>, <<Y>> <= <<1,2>>],
  102:   [2,3,3,4,4,5,5,6] =  
  103:     [(X+Y) || <<X>> <= <<1,2,3,4>>, Y <- [1,2]],
  104:   <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =  
  105:     << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>> >>,
  106:   <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =  
  107:     << <<(X+Y):3>> || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2] >>,
  108:   <<2:3,3:3,3:3,4:3,4:3,5:3,5:3,6:3>> =  
  109:     << <<(X+Y):3>> || X <- [1,2,3,4], Y <- [1,2] >>,
  110:   [2,3,3,4,4,5,5,6] =  
  111:     [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, <<Y:3>> <= <<1:3,2:3>>],
  112:   [2,3,3,4,4,5,5,6] =  
  113:     [(X+Y) || <<X:3>> <= <<1:3,2:3,3:3,4:3>>, Y <- [1,2]],
  114:   ok.
  115: 
  116: %% OTP-8179: Call tracing on binary comprehensions would cause a crash.
  117: tracing(Config) when is_list(Config) ->
  118:     Self = self(),
  119:     Tracer = spawn_opt(fun() -> tracer(Self, 0) end,
  120: 		       [link,{priority,max}]),
  121:     Pattern = [{'_',[],[{return_trace}]}],
  122:     erlang:trace_pattern({?MODULE,'_','_'}, Pattern, [local]),
  123:     erlang:trace(self(), true, [call,{tracer,Tracer}]),
  124:     random_binaries(1000),
  125:     Tracer ! done,
  126:     receive
  127: 	{Tracer,N} ->
  128: 	    {comment,integer_to_list(N) ++ " trace messages"}
  129:     end.
  130: 
  131: random_binary() ->
  132:     Seq = [1,2,3,4,5,6,7,8,9,10],
  133:     << <<($a + random:uniform($z - $a)):8>> || _ <- Seq >>.
  134: 
  135: random_binaries(N) when N > 0 ->
  136:     random_binary(),
  137:     random_binaries(N - 1);
  138: random_binaries(_) -> ok.
  139: 
  140: tracer(Parent, N) ->
  141:     receive
  142: 	Msg ->
  143: 	    case Msg of
  144: 		done ->
  145: 		    Parent ! {self(),N};
  146: 		_ ->
  147: 		    tracer(Parent, N+1)
  148: 	    end
  149:     end.