diff options
Diffstat (limited to 'lib')
449 files changed, 7731 insertions, 4373 deletions
diff --git a/lib/appmon/doc/src/Makefile b/lib/appmon/doc/src/Makefile index 743f123c06..2bf560ee6b 100644 --- a/lib/appmon/doc/src/Makefile +++ b/lib/appmon/doc/src/Makefile @@ -107,14 +107,14 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/appmon/doc/src/notes.xml b/lib/appmon/doc/src/notes.xml index 4e917f3d0d..04b2b0d8ba 100644 --- a/lib/appmon/doc/src/notes.xml +++ b/lib/appmon/doc/src/notes.xml @@ -30,6 +30,26 @@ </header> <p>This document describes the changes made to the Appmon application.</p> +<section><title>Appmon 2.1.14.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + <section><title>Appmon 2.1.14</title> <section><title>Improvements and New Features</title> diff --git a/lib/appmon/priv/Makefile b/lib/appmon/priv/Makefile index 9af4fbd228..8920923c98 100644 --- a/lib/appmon/priv/Makefile +++ b/lib/appmon/priv/Makefile @@ -57,8 +57,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(HELP_FILES) $(TOOLBAR_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(HELP_FILES) $(TOOLBAR_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/appmon/src/Makefile b/lib/appmon/src/Makefile index 43f4f085b8..9ee7c92a4d 100644 --- a/lib/appmon/src/Makefile +++ b/lib/appmon/src/Makefile @@ -92,10 +92,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/appmon/vsn.mk b/lib/appmon/vsn.mk index 047f1eadc1..0654468b42 100644 --- a/lib/appmon/vsn.mk +++ b/lib/appmon/vsn.mk @@ -1 +1 @@ -APPMON_VSN = 2.1.14 +APPMON_VSN = 2.1.14.1 diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile index 8c06be56f8..903cf32838 100644 --- a/lib/asn1/c_src/Makefile +++ b/lib/asn1/c_src/Makefile @@ -110,10 +110,10 @@ $(NIF_SHARED_OBJ_FILE): $(NIF_OBJ_FILES) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_PROGRAM) $(NIF_SHARED_OBJ_FILE) $(RELSYSDIR)/priv/lib - $(INSTALL_DIR) $(RELSYSDIR)/c_src - $(INSTALL_DATA) *.c $(RELSYSDIR)/c_src + $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_PROGRAM) $(NIF_SHARED_OBJ_FILE) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DIR) "$(RELSYSDIR)/c_src" + $(INSTALL_DATA) *.c "$(RELSYSDIR)/c_src" release_docs_spec: diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile index 20bd00a3b8..9ef5750353 100644 --- a/lib/asn1/doc/src/Makefile +++ b/lib/asn1/doc/src/Makefile @@ -119,13 +119,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml index 9b6c482c0a..b5422c9083 100644 --- a/lib/asn1/doc/src/notes.xml +++ b/lib/asn1/doc/src/notes.xml @@ -31,6 +31,32 @@ <p>This document describes the changes made to the asn1 application.</p> +<section><title>Asn1 1.7</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Some ASN.1 INTEGER type and SEQUENCE constructor variants + previously not handled by the ASN.1 compiler are now + correctly handled</p> + <p> + Own Id: OTP-9688</p> + </item> + <item> + <p> + An INTEGER with a value constraint where unions are used + e.g. X1 ::= INTEGER (1..4 | 6 | 8 | 10 | 20) is not + handled correctly. For PER the value is encoded in wrong + number of bits.</p> + <p> + Own Id: OTP-9946</p> + </item> + </list> + </section> + +</section> + <section><title>Asn1 1.6.19</title> <section><title>Improvements and New Features</title> diff --git a/lib/asn1/src/Makefile b/lib/asn1/src/Makefile index 5614cbea91..4bd49aa93b 100644 --- a/lib/asn1/src/Makefile +++ b/lib/asn1/src/Makefile @@ -153,16 +153,16 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(APP_SRC) $(APPUP_SRC) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(APP_SRC) $(APPUP_SRC) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(EXAMPLES) "$(RELSYSDIR)/examples" # there are no include files to be used by the user -#$(INSTALL_DIR) $(RELSYSDIR)/include -#$(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include +#$(INSTALL_DIR) "$(RELSYSDIR)/include" +#$(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/asn1/src/asn1ct_check.erl b/lib/asn1/src/asn1ct_check.erl index 187339fb53..494a2eddd9 100644 --- a/lib/asn1/src/asn1ct_check.erl +++ b/lib/asn1/src/asn1ct_check.erl @@ -5991,17 +5991,25 @@ generate_automatic_tags1([H|T],[TagNo|TagNos]) when is_record(H,'ComponentType') type={default,'IMPLICIT'}, form= 0 }]}, % PRIMITIVE [H#'ComponentType'{typespec=NewTs}|generate_automatic_tags1(T,[TagNo+1|TagNos])]; -generate_automatic_tags1([ExtMark|T],[_TagNo|TagNos]) -> % EXTENSIONMARK +generate_automatic_tags1([ExtMark = #'EXTENSIONMARK'{}|T],[_TagNo|TagNos]) -> [ExtMark | generate_automatic_tags1(T,TagNos)]; +generate_automatic_tags1([H|T],TagList) -> % ExtensionAdditionGroup etc are just ignored + [H | generate_automatic_tags1(T,TagList)]; generate_automatic_tags1([],_) -> []. -any_manual_tag([#'ComponentType'{typespec=#type{tag=[]}}|Rest]) -> - any_manual_tag(Rest); -any_manual_tag([#'EXTENSIONMARK'{}|Rest]) -> - any_manual_tag(Rest); -any_manual_tag([_|_Rest]) -> +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Returns true if there is at least one ComponentType with a manually +%% specified tag. No manual tag is indicated by typespec=#type{tag=[]} +%% so we check if we find a tag =/= [] and return true in that case +%% all other things in the componentlist like (EXTENSIONMARK, +%% ExtensionAdditionGroup,...) except ComponentType is simply +%% ignored/skipped +any_manual_tag([#'ComponentType'{typespec=#type{tag=Tag}}|_Rest]) + when Tag =/= []-> true; +any_manual_tag([_|Rest]) -> + any_manual_tag(Rest); any_manual_tag([]) -> false. diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl index e07680f10b..5f5138ef23 100644 --- a/lib/asn1/src/asn1ct_constructed_per.erl +++ b/lib/asn1/src/asn1ct_constructed_per.erl @@ -100,18 +100,26 @@ gen_encode_constructed(Erule,Typename,D) when is_record(D,type) -> case Ext of {ext,_,NumExt} when NumExt > 0 -> 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); + {extgrouppos,[]} -> % no extenstionAdditionGroup + ok; + {extgrouppos,ExtGroupPosLenList} -> + ExtGroupFun = + fun({ExtActualGroupPos,ExtGroupVirtualPos,ExtGroupLen}) -> + Elements = + make_elements(ExtGroupVirtualPos+1, + "Val1", + lists:seq(1,ExtGroupLen)), + emit([ + {next,val}," = case [X || X <- [",Elements, + "],X =/= asn1_NOVALUE] of",nl, + "[] -> ",{curr,val},";",nl, + "_ -> setelement(",{asis,ExtActualGroupPos+1},",", + {curr,val},",", + "{extaddgroup,", Elements,"})",nl, + "end,",nl]), + asn1ct_name:new(val) + end, + lists:foreach(ExtGroupFun,ExtGroupPosLenList); _ -> % no extensionAdditionGroup ok end, @@ -279,9 +287,9 @@ gen_decode_constructed(Erules,Typename,D) when is_record(D,type) -> {false,false,false} end end, - NewCompList = wrap_compList(CompList), +%% NewCompList = wrap_compList(CompList), {AccTerm,AccBytes} = - gen_dec_components_call(Erules,Typename,NewCompList,MaybeComma2,DecObjInf,Ext,length(Optionals)), + gen_dec_components_call(Erules,Typename,CompList,MaybeComma2,DecObjInf,Ext,length(Optionals)), case asn1ct_name:all(term) of [] -> emit(MaybeComma2); % no components at all _ -> emit({com,nl}) @@ -689,24 +697,28 @@ ext_length([],_,Acc) -> Acc. extgroup_pos_and_length(CompList) when is_list(CompList) -> - noextgroup; + {extgrouppos,[]}; 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). - + ActualPos = length(RootList) +1, + %% position to get and deliver data in the record to the user + VirtualPos = ActualPos, + %% position to encode/decode the extaddgroup as an opentype sequence + extgrouppos(ExtList,ActualPos,VirtualPos,[]); +extgroup_pos_and_length({RootList,ExtList,_Rl2}) -> + extgroup_pos_and_length({RootList,ExtList}). + +extgrouppos([{'ExtensionAdditionGroup',_Num}|T],ActualPos,VirtualPos,Acc) -> + extgrouppos(T,ActualPos,VirtualPos,0,Acc); +extgrouppos([_|T],ActualPos,VirtualPos,Acc) -> + extgrouppos(T,ActualPos+1,VirtualPos+1,Acc); +extgrouppos([],_,_,Acc) -> + {extgrouppos,lists:reverse(Acc)}. + +extgrouppos(['ExtensionAdditionGroupEnd'|T],ActualPos,VirtualPos,Len,Acc) -> + extgrouppos(T,ActualPos+1,VirtualPos+Len,[{ActualPos,VirtualPos,Len}|Acc]); +extgrouppos([_|T],ActualPos,VirtualPos,Len,Acc) -> + extgrouppos(T,ActualPos,VirtualPos,Len+1,Acc). + gen_dec_extension_value(_) -> @@ -817,19 +829,21 @@ add_textual_order1(Cs,NumIn) -> end, NumIn,Cs). -gen_enc_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DynamicEnc,Ext) -> - gen_enc_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DynamicEnc,Ext); -gen_enc_components_call(Erule,TopType,{CompList,ExtList},MaybeComma,DynamicEnc,Ext) -> +gen_enc_components_call(Erule,TopType,{Root,ExtList},MaybeComma,DynamicEnc,Ext) -> + gen_enc_components_call(Erule,TopType,{Root,ExtList,[]},MaybeComma,DynamicEnc,Ext); +gen_enc_components_call(Erule,TopType,CL={Root,ExtList,Root2},MaybeComma,DynamicEnc,Ext) -> %% The type has extensionmarker - Rpos = gen_enc_components_call1(Erule,TopType,CompList,1,MaybeComma,DynamicEnc,noext), + Rpos = gen_enc_components_call1(Erule,TopType,Root++Root2,1,MaybeComma,DynamicEnc,noext), case Ext of {ext,_,ExtNum} when ExtNum > 0 -> emit([nl, ",Extensions",nl]); + _ -> true end, %handle extensions - NewExtList = wrap_extensionAdditionGroups(ExtList), + {extgrouppos,ExtGroupPosLen} = extgroup_pos_and_length(CL), + NewExtList = wrap_extensionAdditionGroups(ExtList,ExtGroupPosLen), gen_enc_components_call1(Erule,TopType,NewExtList,Rpos,MaybeComma,DynamicEnc,Ext); gen_enc_components_call(Erule,TopType, CompList, MaybeComma, DynamicEnc, Ext) -> %% The type has no extensionmarker @@ -938,7 +952,7 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> Atype = case Type of #type{def=#'ObjectClassFieldType'{type=InnerType}} -> - InnerType; + InnerType; _ -> asn1ct_gen:get_inner(Type#type.def) end, @@ -948,6 +962,7 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> emit(["?RT_PER:encode_open_type(dummy,?RT_PER:complete("]); _ -> true end, + case Atype of {typefield,_} -> case DynamicEnc of @@ -1023,20 +1038,22 @@ gen_enc_line(Erule,TopType,Cname,Type,Element, _Pos,DynamicEnc,Ext) -> emit("))"); _ -> true end. -gen_dec_components_call(Erule,TopType,{Root1,ExtList,Root2},MaybeComma,DecInfObj,Ext,NumberOfOptionals) -> - gen_dec_components_call(Erule,TopType,{Root1++Root2,ExtList},MaybeComma,DecInfObj,Ext,NumberOfOptionals); -gen_dec_components_call(Erule,TopType,{CompList,ExtList},MaybeComma, +gen_dec_components_call(Erule,TopType,{Root,ExtList},MaybeComma, DecInfObj,Ext,NumberOfOptionals) -> + gen_dec_components_call(Erule,TopType,{Root,ExtList,[]},MaybeComma,DecInfObj,Ext,NumberOfOptionals); +gen_dec_components_call(Erule,TopType,CL={Root1,ExtList,Root2},MaybeComma,DecInfObj,Ext,NumberOfOptionals) -> %% The type has extensionmarker - OptTable = create_optionality_table(CompList), + + OptTable = create_optionality_table(Root1++Root2), {Rpos,AccTerm,AccBytes} = - gen_dec_components_call1(Erule,TopType, CompList, 1, OptTable, + gen_dec_components_call1(Erule,TopType, Root1++Root2, 1, OptTable, MaybeComma,DecInfObj,noext,[],[], NumberOfOptionals), emit([",",nl,"{Extensions,",{next,bytes},"} = "]), emit(["?RT_PER:getextension(Ext,",{curr,bytes},"),",nl]), asn1ct_name:new(bytes), - NewExtList = wrap_extensionAdditionGroups(ExtList), + {extgrouppos,ExtGroupPosLen} = extgroup_pos_and_length(CL), + NewExtList = wrap_extensionAdditionGroups(ExtList,ExtGroupPosLen), {_Epos,AccTermE,AccBytesE} = gen_dec_components_call1(Erule,TopType,NewExtList,Rpos, OptTable, "",DecInfObj,Ext,[],[],NumberOfOptionals), @@ -1233,8 +1250,7 @@ gen_dec_line(Erule,TopType,Cname,Type,Pos,DecInfObj,Ext,Prop) -> "} = ?RT_PER:decode_open_type(",{curr,bytes}, ", []),",nl]), emit([indent(2),"case (catch ObjFun(", - {asis,Name}, - ",",{curr,tmpterm},",telltype,", + {asis,Name},",",{curr,tmpterm},",telltype,", {asis,RestFieldNames},")) of", nl]), emit([indent(4),"{'EXIT',",{curr,reason},"} ->",nl]), emit([indent(6),"exit({'Type not ", @@ -1596,42 +1612,44 @@ flat_complist({Rl1,El,Rl2}) -> Rl1 ++ El ++ Rl2; flat_complist({Rl,El}) -> Rl ++ El; flat_complist(CompList) -> CompList. -wrap_compList({Root1,Ext,Root2}) -> - {Root1,wrap_extensionAdditionGroups(Ext),Root2}; -wrap_compList({Root1,Ext}) -> - {Root1,wrap_extensionAdditionGroups(Ext)}; -wrap_compList(CompList) -> - CompList. +%%wrap_compList({Root1,Ext,Root2}) -> +%% {Root1,wrap_extensionAdditionGroups(Ext),Root2}; +%%wrap_compList({Root1,Ext}) -> +%% {Root1,wrap_extensionAdditionGroups(Ext)}; +%%wrap_compList(CompList) -> +%% CompList. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Will convert all componentTypes following 'ExtensionAdditionGroup' %% up to the matching 'ExtensionAdditionGroupEnd' into one componentType %% of type SEQUENCE with the componentTypes as components %% -wrap_extensionAdditionGroups(ExtCompList) -> - wrap_extensionAdditionGroups(ExtCompList,[],0). +wrap_extensionAdditionGroups(ExtCompList,ExtGroupPosLen) -> + wrap_extensionAdditionGroups(ExtCompList,ExtGroupPosLen,[],0,0). -wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest],Acc,0) -> - {ExtGroupCompList= - [#'ComponentType'{textual_order=TextPos}|_], - ['ExtensionAdditionGroupEnd'|Rest2]} = +wrap_extensionAdditionGroups([{'ExtensionAdditionGroup',_Number}|Rest], + [{ActualPos,_,_}|ExtGroupPosLenRest],Acc,_ExtAddGroupDiff,ExtGroupNum) -> + {ExtGroupCompList,['ExtensionAdditionGroupEnd'|Rest2]} = lists:splitwith(fun(#'ComponentType'{}) -> true; (_) -> false end, Rest), - wrap_extensionAdditionGroups(Rest2, + wrap_extensionAdditionGroups(Rest2,ExtGroupPosLenRest, [#'ComponentType'{ - name='ExtAddGroup', % FIXME: handles ony one ExtAddGroup - typespec=#type{def=#'SEQUENCE'{ - extaddgroup=1,% FIXME: handles only one + name=list_to_atom("ExtAddGroup"++ + integer_to_list(ExtGroupNum+1)), + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=ExtGroupNum+1, components=ExtGroupCompList}}, - textual_order = TextPos, - prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1); -wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T],Acc,ExtAddGroupDiff) when is_integer(Tord) -> - wrap_extensionAdditionGroups(T,[H#'ComponentType'{ - textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff); -wrap_extensionAdditionGroups([H|T],Acc,ExtAddGroupDiff) -> - wrap_extensionAdditionGroups(T,[H|Acc],ExtAddGroupDiff); -wrap_extensionAdditionGroups([],Acc,_) -> + textual_order = ActualPos, + prop='OPTIONAL'}|Acc],length(ExtGroupCompList)-1, + ExtGroupNum+1); +wrap_extensionAdditionGroups([H=#'ComponentType'{textual_order=Tord}|T], + ExtAddGrpLenPos,Acc,ExtAddGroupDiff,ExtGroupNum) when is_integer(Tord) -> + wrap_extensionAdditionGroups(T,ExtAddGrpLenPos,[H#'ComponentType'{ + textual_order=Tord - ExtAddGroupDiff}|Acc],ExtAddGroupDiff,ExtGroupNum); +wrap_extensionAdditionGroups([H|T],ExtAddGrpLenPos,Acc,ExtAddGroupDiff,ExtGroupNum) -> + wrap_extensionAdditionGroups(T,ExtAddGrpLenPos,[H|Acc],ExtAddGroupDiff,ExtGroupNum); +wrap_extensionAdditionGroups([],_,Acc,_,_) -> lists:reverse(Acc). diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl index 59b4b3d261..5f42eacbdc 100644 --- a/lib/asn1/src/asn1ct_gen_per.erl +++ b/lib/asn1/src/asn1ct_gen_per.erl @@ -1405,19 +1405,21 @@ get_object_field(Name,ObjectFields) -> %% have been specified within a SEQUENCE, therefore we construct a fake sequence type here %% so that we can generate code for it extaddgroup2sequence(ExtList) -> - extaddgroup2sequence(ExtList,[]). + extaddgroup2sequence(ExtList,0,[]). -extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> +extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],ExtNum,Acc) -> Number = case Number0 of undefined -> 1; _ -> Number0 end, {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), - extaddgroup2sequence(T2,[#'ComponentType'{ - name='ExtAddGroup', - typespec=#type{def=#'SEQUENCE'{ - extaddgroup=Number, - components=ExtGroupComps}}, - prop='OPTIONAL'}|Acc]); -extaddgroup2sequence([C|T],Acc) -> - extaddgroup2sequence(T,[C|Acc]); -extaddgroup2sequence([],Acc) -> + extaddgroup2sequence(T2,ExtNum+1, + [#'ComponentType'{ + name=list_to_atom("ExtAddGroup"++ + integer_to_list(ExtNum+1)), + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=Number, + components=ExtGroupComps}}, + prop='OPTIONAL'}|Acc]); +extaddgroup2sequence([C|T],ExtNum,Acc) -> + extaddgroup2sequence(T,ExtNum,[C|Acc]); +extaddgroup2sequence([],_,Acc) -> lists:reverse(Acc). diff --git a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl index 4add659d79..eda0faad3c 100644 --- a/lib/asn1/src/asn1ct_gen_per_rt2ct.erl +++ b/lib/asn1/src/asn1ct_gen_per_rt2ct.erl @@ -1808,19 +1808,21 @@ dec_enumerated_cases([],_,_) -> %% have been specified within a SEQUENCE, therefore we construct a fake sequence type here %% so that we can generate code for it extaddgroup2sequence(ExtList) -> - extaddgroup2sequence(ExtList,[]). + extaddgroup2sequence(ExtList,0,[]). -extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],Acc) -> +extaddgroup2sequence([{'ExtensionAdditionGroup',Number0}|T],ExtNum,Acc) -> Number = case Number0 of undefined -> 1; _ -> Number0 end, {ExtGroupComps,['ExtensionAdditionGroupEnd'|T2]} = lists:splitwith(fun(Elem) -> is_record(Elem,'ComponentType') end,T), - extaddgroup2sequence(T2,[#'ComponentType'{ - name='ExtAddGroup', - typespec=#type{def=#'SEQUENCE'{ - extaddgroup=Number, - components=ExtGroupComps}}, - prop='OPTIONAL'}|Acc]); -extaddgroup2sequence([C|T],Acc) -> - extaddgroup2sequence(T,[C|Acc]); -extaddgroup2sequence([],Acc) -> + extaddgroup2sequence(T2,ExtNum+1, + [#'ComponentType'{ + name=list_to_atom("ExtAddGroup"++ + integer_to_list(ExtNum+1)), + typespec=#type{def=#'SEQUENCE'{ + extaddgroup=Number, + components=ExtGroupComps}}, + prop='OPTIONAL'}|Acc]); +extaddgroup2sequence([C|T],ExtNum,Acc) -> + extaddgroup2sequence(T,ExtNum,[C|Acc]); +extaddgroup2sequence([],_,Acc) -> lists:reverse(Acc). diff --git a/lib/asn1/src/asn1ct_parser2.erl b/lib/asn1/src/asn1ct_parser2.erl index 007d390a1b..7301f49085 100644 --- a/lib/asn1/src/asn1ct_parser2.erl +++ b/lib/asn1/src/asn1ct_parser2.erl @@ -769,9 +769,11 @@ resolve_module(_Type, Current, undefined) -> Current; resolve_module(Type, Current, Imports) -> case [Mod || #'SymbolsFromModule'{symbols = S, module = Mod} <- Imports, - #'Externaltypereference'{type = T} <- S, + #'Externaltypereference'{type = T} <- S, Type == T] of - [#'Externaltypereference'{type = Mod}] -> Mod; + [#'Externaltypereference'{type = Mod}|_] -> Mod; + %% This allows the same symbol to be imported several times + %% which ought to be checked elsewhere and flagged as an error [] -> Current end. diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile index 1621abbec9..6e6374baf1 100644 --- a/lib/asn1/test/Makefile +++ b/lib/asn1/test/Makefile @@ -156,13 +156,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/asn1_SUITE_data - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) asn1.spec asn1.cover $(INSTALL_PROGS) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - cd asn1_SUITE_data; tar cfh $(RELSYSDIR)/asn1_SUITE_data.tar * - cd $(RELSYSDIR)/asn1_SUITE_data; tar xf $(RELSYSDIR)/asn1_SUITE_data.tar - rm $(RELSYSDIR)/asn1_SUITE_data.tar + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/asn1_SUITE_data" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) asn1.spec asn1.cover $(INSTALL_PROGS) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + cd asn1_SUITE_data; tar cfh "$(RELSYSDIR)/asn1_SUITE_data.tar" * + cd "$(RELSYSDIR)/asn1_SUITE_data"; tar xf "$(RELSYSDIR)/asn1_SUITE_data.tar" + rm "$(RELSYSDIR)/asn1_SUITE_data.tar" release_docs_spec: diff --git a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn index fc244c30a2..cacef8b922 100644 --- a/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn +++ b/lib/asn1/test/asn1_SUITE_data/Extension-Addition-Group.asn @@ -79,4 +79,22 @@ Ax3 ::= SEQUENCE { } -- { a 253, b TRUE, s {sa 17, sb TRUE, sextaddgroup 11}} + +-- This is to test the case with more than one ExtensionAdditionGroup +-- which did not work before + +AS-Config ::= SEQUENCE { + a INTEGER, + b BOOLEAN, + c OCTET STRING, + ..., + [[ sourceSystemInformationBlockType1Ext OCTET STRING OPTIONAL, + sourceOtherConfig-r9 INTEGER + ]], + [[ sourceSCellConfigList-r10 OCTET STRING OPTIONAL + ]] +} + + + END diff --git a/lib/common_test/doc/src/Makefile b/lib/common_test/doc/src/Makefile index d9651f13b0..2ec6952710 100644 --- a/lib/common_test/doc/src/Makefile +++ b/lib/common_test/doc/src/Makefile @@ -158,18 +158,18 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 - $(INSTALL_DATA) $(MAN1DIR)/* $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DATA) $(MAN1DIR)/* "$(RELEASE_PATH)/man/man1" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/common_test/doc/src/common_test_app.xml b/lib/common_test/doc/src/common_test_app.xml index c7f6c7ce5c..6babdb93af 100644 --- a/lib/common_test/doc/src/common_test_app.xml +++ b/lib/common_test/doc/src/common_test_app.xml @@ -187,9 +187,13 @@ test case is allowed to execute (including <c>init_per_testcase/2</c> and <c>end_per_testcase/2</c>). If the timetrap time is exceeded, the test case fails with reason - <c>timetrap_timeout</c>. If a <c>TimeFunc</c> function is specified, - it will be called initially and must return a value on - <c>TimeVal</c> format.</p> + <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to + set a new timetrap by returning a <c>TimeVal</c>. It may also be + used to trigger a timetrap timeout by, at some point, returning a + value other than a <c>TimeVal</c>. (See the + <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> + for details). + </p> <p>The <c>require</c> tag specifies configuration variables that are required by test cases (and/or configuration functions) @@ -313,9 +317,12 @@ test case is allowed to execute (including <c>init_per_testcase/2</c> and <c>end_per_testcase/2</c>). If the timetrap time is exceeded, the test case fails with reason - <c>timetrap_timeout</c>. If a <c>TimeFunc</c> function is specified, - it will be called initially and must return a value on - <c>TimeVal</c> format.</p> + <c>timetrap_timeout</c>. A <c>TimeFunc</c> function can be used to + set a new timetrap by returning a <c>TimeVal</c>. It may also be + used to trigger a timetrap timeout by, at some point, returning a + value other than a <c>TimeVal</c>. (See the + <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> + for details).</p> <p>The <c>require</c> tag specifies configuration variables that are required by test cases (and/or configuration functions) @@ -494,9 +501,12 @@ exceeded, the test case fails with reason <c>timetrap_timeout</c>. <c>init_per_testcase/2</c> and <c>end_per_testcase/2</c> are included in the - timetrap time. If a <c>TimeFunc</c> function is specified, - it will be called before the test case (or <c>init_per_testcase/2</c>) - and must return a value on <c>TimeVal</c> format.</p> + timetrap time. A <c>TimeFunc</c> function can be used to + set a new timetrap by returning a <c>TimeVal</c>. It may also be + used to trigger a timetrap timeout by, at some point, returning a + value other than a <c>TimeVal</c>. (See the + <seealso marker="write_test_chapter#timetraps">User's Guide</seealso> + for details).</p> <p>The <c>require</c> tag specifies configuration variables that are required by the test case (and/or <c>init/end_per_testcase/2</c>). diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml index da0b6b2d65..050b8774ca 100644 --- a/lib/common_test/doc/src/notes.xml +++ b/lib/common_test/doc/src/notes.xml @@ -32,6 +32,308 @@ <file>notes.xml</file> </header> +<section><title>Common_Test 1.6.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Common Test adds the test suite directories to the code + path before executing the tests. These directories should + also be removed from the code path at the end of the test + run, which, prior to this fix, was not performed.</p> + <p> + Own Id: OTP-9595</p> + </item> + <item> + <p> + An entry is now created in the index.html file (i.e. the + overview file for the test run) for each repeated test + during a test run. This was previously not the case. Note + that in the top level (logdir) index file, however, only + the last test result is listed. For example, given the + test spec: + [{merge_tests,false},{dirs,"test1"},{dirs,"test1"}]. In + the index file for the test run (under + Logdir/ct_run.Node.Date.Time), both tests are listed. In + the top level index file (under Logdir), only the last + test is listed (one has to find the previous results + through the all_runs.html file).</p> + <p> + Own Id: OTP-9634 Aux Id: seq11924 </p> + </item> + <item> + <p> + After a test case timeout or abortion, the + end_per_testcase function executes on a new dedicated + process. The group leader for this process should be set + to the IO server for the test case, which was not done + properly. The result of this error was that no warnings + about end_per_testcase failing or timing out were ever + printed in the test case log. Also, help functions such + as e.g. test_server:stop_node/1, attempting to + synchronize with the IO server, would hang. The fault has + been corrected.</p> + <p> + Own Id: OTP-9666</p> + </item> + <item> + <p> + The ct:get_status/0 function would cause the calling + process to receive 'DOWN' messages if no tests were + running at the time of the call. This bug has been fixed.</p> + <p> + Own Id: OTP-9830 Aux Id: seq11975 </p> + </item> + <item> + <p> + A deadlock situation could occur if Common Test is + forwarding error_handler printouts to Test Server at the + same time a new test case is starting. This error has + been fixed.</p> + <p> + Own Id: OTP-9894</p> + </item> + <item> + <p> + A link to the ct_run program is now created, as expected, + in the installation bin directory (default + /usr/local/bin) during 'make install'.</p> + <p> + Own Id: OTP-9898</p> + </item> + <item> + <p> + Using the repeat, duration or until option with + ct:run_test/1, would cause an infinite loop. This has + been fixed.</p> + <p> + Own Id: OTP-9899</p> + </item> + <item> + <p> + Two or more test cases executing in parallel and printing + to screen at the same time with ct:pal/2/3 or + ct:print/2/3 could write into each other's "slots" and + create a mess of mixed strings. In order to avoid this, + only a single IO message is now ever sent per printout + call.</p> + <p> + Own Id: OTP-9900 Aux Id: OTP-9904 </p> + </item> + <item> + <p> + When a test case was killed because of a timetrap + timeout, the current location (suite, case and line) was + not printed correctly in the log files. This has been + corrected.</p> + <p> + Own Id: OTP-9930 Aux Id: seq12002 </p> + </item> + <item> + <p> + The wrong exit location was printed in the log file when + ct:fail/1 or ct_fail/2 was called.</p> + <p> + Own Id: OTP-9933 Aux Id: seq12002 </p> + </item> + <item> + <p> + Test Server and Common Test would add new error handlers + with each test run and fail to remove previously added + ones. In the case of Test Server, this would only happen + if SASL was not running on the test node. This has been + fixed.</p> + <p> + Own Id: OTP-9941 Aux Id: seq12009 </p> + </item> + <item> + <p> + If a test case process was terminated due to an exit + signal from a linked process, Test Server failed to + report the correct name of the suite and case to the + framework. This has been corrected.</p> + <p> + Own Id: OTP-9958 Aux Id: OTP-9855 </p> + </item> + <item> + <p> + When starting a test with ct_run and adding a directory + to the code path using -pa or -pz (preceding -erl_args), + Common Test would delete any existing directory in the + code path with the same base name (see + filename:basename/1) as the directory being added. This + has been fixed.</p> + <p> + Own Id: OTP-9964</p> + </item> + <item> + <p> + If passing two or more directories with the same base + name (see filename:basename/1) to Common Test with ct_run + -pa, only one of the directories would actually be added.</p> + <p> + Own Id: OTP-9975 Aux Id: seq12019 </p> + </item> + <item> + <p> + Configuration data required by the group info function + was deleted before the call to post_end_per_group, which + made it impossible for the hook function to read and use + the data in question. This has been fixed.</p> + <p> + Own Id: OTP-9989</p> + </item> + <item> + <p> + Disabling built-in hooks in a test specification was + ignored, this has now been fixed.</p> + <p> + Own Id: OTP-10009</p> + </item> + <item> + <p> + Various typographical errors corrected in documentation + for common_test, driver, erl_driver and windows + installation instructions. (Thanks to Tuncer Ayaz)</p> + <p> + Own Id: OTP-10037</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new optional feature has been introduced that enables + Common Test to generate priv_dir directory names that are + unique for each test case or config function. The name of + the option/flag is 'create_priv_dir' and it can be set to + value 'auto_per_run' (which is the default, existing, + behaviour), or 'auto_per_tc' or 'manual_per_tc'. If + 'auto_per_tc' is used, Test Server creates a dedicated + priv_dir automatically for each test case (which can be + very expensive in case of many and/or repeated cases). If + 'manual_per_tc' is used, the user needs to create the + priv_dir explicitly by calling the new function + ct:make_priv_dir/0.</p> + <p> + Own Id: OTP-9659 Aux Id: seq11930 </p> + </item> + <item> + <p> + A column for test case group name has been added to the + suite overview HTML log file.</p> + <p> + Own Id: OTP-9730 Aux Id: seq11952 </p> + </item> + <item> + <p> + It is now possible to use the post_end_per_testcase CT + hook function to print a comment for a test case in the + overview log file, even if the test case gets killed by a + timetrap or unknown exit signal, or if the + end_per_testcase function times out.</p> + <p> + Own Id: OTP-9855 Aux Id: seq11979 </p> + </item> + <item> + <p> + The pre- and post CT hook functions are now always called + for all configuration functions, even for configuration + functions that are not implemented in the test suite.</p> + <p> + Own Id: OTP-9880 Aux Id: seq11993 </p> + </item> + <item> + <p> + Common Test will now print error information (with a time + stamp) in the test case log file immediately when a test + case fails. This makes it easier to see when, in time, + the fault actually occured, and aid the job of locating + relevant trace and debug printouts in the log.</p> + <p> + Own Id: OTP-9904 Aux Id: seq11985, OTP-9900 </p> + </item> + <item> + <p> + Test Server has been modified to check the SASL + errlog_type parameter when receiving an error logger + event, so that it doesn't print reports of type that the + user has disabled.</p> + <p> + Own Id: OTP-9955 Aux Id: seq12013 </p> + </item> + <item> + <p> + The test specification term 'skip_groups' was implemented + in Common Test v1.6. It was never documented however, + which has now been attended to. Please see the Test + Specifications chapter in the User's Guide for + information.</p> + <p> + Own Id: OTP-9972</p> + </item> + <item> + <p> + The Common Test Master has been updated to use a CSS + style sheet for the html log files.</p> + <p> + Own Id: OTP-9973</p> + </item> + <item> + <p> + If the init_per_group/2 and end_per_group/2 functions are + not implemented in the test suite, Common Test calls it's + own local init- and end functions - previously named + ct_init_per_group/2 and ct_end_per_group/2 - when a group + is executed. These functions have been renamed + init_per_group/2 and end_per_group/2 respectively. Note + that this may affect any user event handler identifying + events by the old names.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9986 Aux Id: OTP-9992 </p> + </item> + <item> + <p> + By specifying a user defined function ({M,F,A} or fun) as + timetrap value, either by means of an info function or by + calling ct:timetrap/1, it is now possible to set a + timetrap that will be triggered when the user function + returns.</p> + <p> + Own Id: OTP-9988 Aux Id: OTP-9501, seq11894 </p> + </item> + <item> + <p> + If the optional configuration functions init_per_suite/1 + and end_per_suite/1 are not implemented in the test + suite, local Common Test versions of these functions are + called instead, and will be displayed in the overview log + file. Any printouts made by the pre- or + post_init_per_suite and pre- or post_end_per_suite hook + functions are saved in the log files for these functions.</p> + <p> + Own Id: OTP-9992</p> + </item> + <item> + <p> + A hook has been added to common test which outputs + surefire XML for usage together with CI tools such as + Jenkins. To enable the hook pass '-ct_hooks cth_surefire' + to ct_run. See the CTH documentation for more details.</p> + <p> + Own Id: OTP-9995</p> + </item> + </list> + </section> + +</section> + <section><title>Common_Test 1.6</title> <section><title>Improvements and New Features</title> diff --git a/lib/common_test/doc/src/write_test_chapter.xml b/lib/common_test/doc/src/write_test_chapter.xml index eec7628b6f..7b7e7af8ea 100644 --- a/lib/common_test/doc/src/write_test_chapter.xml +++ b/lib/common_test/doc/src/write_test_chapter.xml @@ -872,34 +872,63 @@ <marker id="timetraps"></marker> <title>Timetrap timeouts</title> <p>The default time limit for a test case is 30 minutes, unless a - <c>timetrap</c> is specified either by the suite info function - or a test case info function. The timetrap timeout value defined - in <c>suite/0</c> is the value that will be used for each test case - in the suite (as well as for the configuration functions - <c>init_per_suite/1</c> and <c>end_per_suite</c>). A timetrap timeout - value set with the test case info function will override the value set - by <c>suite/0</c>, but only for that particular test case.</p> - <p>It is also possible to set/reset a timetrap during test case (or - configuration function) execution. This is done by calling - <c>ct:timetrap/1</c>. This function will cancel the current timetrap - and start a new one.</p> + <c>timetrap</c> is specified either by the suite-, group-, + or test case info function. The timetrap timeout value defined by + <c>suite/0</c> is the value that will be used for each test case + in the suite (as well as for the configuration functions + <c>init_per_suite/1</c>, <c>end_per_suite/1</c>, <c>init_per_group/2</c>, + and <c>end_per_group/2</c>). A timetrap value defined by + <c>group(GroupName)</c> overrides one defined by <c>suite()</c> + and will be used for each test case in group <c>GroupName</c>, and any + of its sub-groups. If a timetrap value is defined by <c>group/1</c> + for a sub-group, it overrides that of its higher level groups. Timetrap + values set by individual test cases (by means of the test case info + function) overrides both group- and suite- level timetraps.</p> + + <p>It is also possible to dynamically set/reset a timetrap during the + excution of a test case, or configuration function. This is done by calling + <c>ct:timetrap/1</c>. This function cancels the current timetrap + and starts a new one (that stays active until timeout, or end of the + current function).</p> + <p>Timetrap values can be extended with a multiplier value specified at - startup with the <c>multiply_timetraps</c> option. It is also possible - to let Test Server decide to scale up timetrap timeout values - automatically, e.g. if tools such as cover or trace are running during - the test. This feature is disabled by default and can be enabled with - the <c>scale_timetraps</c> start option.</p> + startup with the <c>multiply_timetraps</c> option. It is also possible + to let the test server decide to scale up timetrap timeout values + automatically, e.g. if tools such as cover or trace are running during + the test. This feature is disabled by default and can be enabled with + the <c>scale_timetraps</c> start option.</p> + <p>If a test case needs to suspend itself for a time that also gets - multipled by <c>multiply_timetraps</c>, and possibly scaled up if - <c>scale_timetraps</c> is enabled, the function <c>ct:sleep/1</c> - may be called.</p> - <p>A function (<c>fun</c> or <c>MFA</c>) may be specified as timetrap value - in the suite- and test case info function, e.g:</p> - <p><c>{timetrap,{test_utils,get_timetrap_value,[?MODULE,system_start]}}</c></p> - <p>The function will be called initially by Common Test (before execution - of the suite or the test case) and must return a time value such as an - integer (millisec), or a <c>{SecMinOrHourTag,Time}</c> tuple. More - information can be found in the <c>common_test</c> reference manual.</p> + multipled by <c>multiply_timetraps</c> (and possibly also scaled up if + <c>scale_timetraps</c> is enabled), the function <c>ct:sleep/1</c> + may be used (instead of e.g. <c>timer:sleep/1</c>).</p> + + <p>A function (<c>fun/0</c> or <c>MFA</c>) may be specified as + timetrap value in the suite-, group- and test case info function, as + well as argument to the <c>ct:timetrap/1</c> function. Examples:</p> + + <p><c>{timetrap,{my_test_utils,timetrap,[?MODULE,system_start]}}</c></p> + <p><c>ct:timetrap(fun() -> my_timetrap(TestCaseName, Config) end)</c></p> + + <p>The user timetrap function may be used for two things:</p> + <list> + <item>To act as a timetrap - the timeout is triggered when the + function returns.</item> + <item>To return a timetrap time value (other than a function).</item> + </list> + <p>Before execution of the timetrap function (which is performed + on a parallel, dedicated timetrap process), Common Test cancels + any previously set timer for the test case or configuration function. + When the timetrap function returns, the timeout is triggered, <em>unless</em> + the return value is a valid timetrap time, such as an integer, + or a <c>{SecMinOrHourTag,Time}</c> tuple (see the + <seealso marker="common_test">common_test reference manual</seealso> for + details). If a time value is returned, a new timetrap is started + to generate a timeout after the specified time.</p> + + <p>The user timetrap function may of course return a time value after a delay, + and if so, the effective timetrap time is the delay time <em>plus</em> the + returned time.</p> </section> <section> diff --git a/lib/common_test/priv/Makefile.in b/lib/common_test/priv/Makefile.in index d9033f6ef1..8be6248e17 100644 --- a/lib/common_test/priv/Makefile.in +++ b/lib/common_test/priv/Makefile.in @@ -85,12 +85,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk ifeq ($(XNIX),true) release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) "$(RELSYSDIR)/priv" else release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) "$(RELSYSDIR)/priv" endif release_docs_spec: @@ -125,8 +125,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(FILES) $(IMAGES) $(CSS) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/common_test/src/Makefile b/lib/common_test/src/Makefile index 6a16c6f3af..037a686963 100644 --- a/lib/common_test/src/Makefile +++ b/lib/common_test/src/Makefile @@ -133,12 +133,12 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) "$(RELSYSDIR)/include" release_tests_spec: opt $(INSTALL_DIR) $(RELEASE_PATH)/common_test_test diff --git a/lib/common_test/test/Makefile b/lib/common_test/test/Makefile index 2a52f8ed74..560a0b0d5a 100644 --- a/lib/common_test/test/Makefile +++ b/lib/common_test/test/Makefile @@ -97,10 +97,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR) - $(INSTALL_DATA) common_test.spec $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) $(COVERFILE) "$(RELSYSDIR)" + $(INSTALL_DATA) common_test.spec "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/compiler/doc/src/Makefile b/lib/compiler/doc/src/Makefile index ee41a7074f..308e9c4d02 100644 --- a/lib/compiler/doc/src/Makefile +++ b/lib/compiler/doc/src/Makefile @@ -99,14 +99,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index 84e9922847..b577e5ca4f 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -333,7 +333,8 @@ module.beam: module.erl \ <tag><c>{d,Macro,Value}</c></tag> <item> <p>Defines a macro <c>Macro</c> to have the value - <c>Value</c>. The default is <c>true</c>.</p> + <c>Value</c>. <c>Macro</c> is of type atom, and <c>Value</c> can be any term. + The default <c>Value</c> is <c>true</c>.</p> </item> <tag><c>{parse_transform,Module}</c></tag> diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index 3f53a71764..e2a921a6f2 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -31,6 +31,75 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 4.8.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + In rare circumstance, the compiler could crash when + compiling a case statement. (Thanks to Hakan Mattsson.)</p> + <p> + Own Id: OTP-9842</p> + </item> + <item> + <p>Calling a guard test (such as is_list/1) from the + top-level in a guard, would cause a compiler crash if + there was a local definition with the same name. + Corrected to reject the program with an error + message.</p> + <p> + Own Id: OTP-9866</p> + </item> + <item> + <p>Using <c>get/1</c> in a <c>try</c> block could in some + cases cause an internal compiler error. (Thanks to Eric + Merritt.)</p> + <p> + Own Id: OTP-9867</p> + </item> + <item> + <p> + An unexported on_load function would not get run if the + module was compiled with the <c>inline</c> option. + (Thanks to Yiannis Tsiouris.)</p> + <p> + Own Id: OTP-9910</p> + </item> + <item> + <p> + Fixed a discrepancy in compile_info</p> + <p> + The BEAM disassembler used the atom 'none' to signify the + absence of a compile_info chunk in a .beam file. This + clashed with the type declaration of the compile_info + field of a #beam_file{} record as containing a list. Now + [] signifies the absence of this chunk. This simplifies + the code and avoids a dialyzer warning.</p> + <p> + Own Id: OTP-9917</p> + </item> + <item> + <p> + Fix typo in `compile' doc: unmatched parenthesis (Thanks + to Ricardo Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9919</p> + </item> + <item> + <p>In a <c>try</c>...<c>catch</c> statement that always + returned <c>false</c>, the compiler would remove calls to + BIFs that could not cause an exception (such as + <c>put/2</c>). Example of such code: <c>try put(K, V), + false catch _:_ -> false end.</c></p> + <p> + Own Id: OTP-9982</p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 4.8</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile index 3415517fff..56c45d369c 100644 --- a/lib/compiler/src/Makefile +++ b/lib/compiler/src/Makefile @@ -163,11 +163,11 @@ $(EBIN)/cerl_inline.beam: $(ESRC)/cerl_inline.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/src" $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(EXTRA_FILES) \ - $(YRL_FILE) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(INSTALL_FILES) $(RELSYSDIR)/ebin + $(YRL_FILE) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(INSTALL_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl index ba9cde1de0..68bc83433e 100644 --- a/lib/compiler/src/sys_pre_expand.erl +++ b/lib/compiler/src/sys_pre_expand.erl @@ -42,7 +42,7 @@ compile=[], %Compile flags attributes=[], %Attributes callbacks=[], %Callbacks - defined=[], %Defined functions + defined, %Defined functions (gb_set) vcount=0, %Variable counter func=[], %Current function arity=[], %Arity for current function @@ -83,7 +83,7 @@ module(Fs0, Opts0) -> {Efs,St2} = expand_pmod(Tfs, St1), %% Get the correct list of exported functions. Exports = case member(export_all, St2#expand.compile) of - true -> St2#expand.defined; + true -> gb_sets:to_list(St2#expand.defined); false -> St2#expand.exports end, %% Generate all functions from stored info. @@ -106,10 +106,11 @@ expand_pmod(Fs0, St0) -> true -> Ps0 end, + Def = gb_sets:to_list(St0#expand.defined), {Fs1,Xs,Ds} = sys_expand_pmod:forms(Fs0, Ps, St0#expand.exports, - St0#expand.defined), - St1 = St0#expand{exports=Xs, defined=Ds}, + Def), + St1 = St0#expand{exports=Xs,defined=gb_sets:from_list(Ds)}, {Fs2,St2} = add_instance(Ps, Fs1, St1), {Fs3,St3} = ensure_new(Base, Ps0, Fs2, St2), {Fs3,St3#expand{attributes = [{abstract, 0, [true]} @@ -159,7 +160,7 @@ add_func(Name, Args, Body, Fs, St) -> F = {function,0,Name,A,[{clause,0,Args,[],Body}]}, NA = {Name,A}, {[F|Fs],St#expand{exports=add_element(NA, St#expand.exports), - defined=add_element(NA, St#expand.defined)}}. + defined=gb_sets:add_element(NA, St#expand.defined)}}. %% define_function(Form, State) -> State. %% Add function to defined if form is a function. @@ -168,7 +169,7 @@ define_functions(Forms, #expand{defined=Predef}=St) -> Fs = foldl(fun({function,_,N,A,_Cs}, Acc) -> [{N,A}|Acc]; (_, Acc) -> Acc end, Predef, Forms), - St#expand{defined=ordsets:from_list(Fs)}. + St#expand{defined=gb_sets:from_list(Fs)}. module_attrs(#expand{attributes=Attributes}=St) -> Attrs = [{attribute,Line,Name,Val} || {Name,Line,Val} <- Attributes], @@ -187,7 +188,7 @@ module_predef_func_beh_info(#expand{callbacks=Callbacks,defined=Defined, PreDef=[{behaviour_info,1}], PreExp=PreDef, {[gen_beh_info(Callbacks)], - St#expand{defined=union(from_list(PreDef), Defined), + St#expand{defined=gb_sets:union(gb_sets:from_list(PreDef), Defined), exports=union(from_list(PreExp), Exports)}}. gen_beh_info(Callbacks) -> @@ -215,7 +216,8 @@ module_predef_funcs_mod_info(St) -> [{clause,0,[{var,0,'X'}],[], [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}}, [{atom,0,St#expand.module},{var,0,'X'}]}]}]}], - St#expand{defined=union(from_list(PreDef), St#expand.defined), + St#expand{defined=gb_sets:union(gb_sets:from_list(PreDef), + St#expand.defined), exports=union(from_list(PreExp), St#expand.exports)}}. %% forms(Forms, State) -> @@ -721,4 +723,4 @@ imported(F, A, St) -> end. defined(F, A, St) -> - ordsets:is_element({F,A}, St#expand.defined). + gb_sets:is_element({F,A}, St#expand.defined). diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile index e13ad4ae90..e047166ade 100644 --- a/lib/compiler/test/Makefile +++ b/lib/compiler/test/Makefile @@ -154,12 +154,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) compiler.spec compiler.cover \ - $(EMAKEFILE) $(ERL_FILES) $(CORE_FILES) $(RELSYSDIR) + $(EMAKEFILE) $(ERL_FILES) $(CORE_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) $(NO_OPT_ERL_FILES) $(POST_OPT_ERL_FILES) \ - $(INLINE_ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INLINE_ERL_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 416c2f08bb..c9c28cf9a2 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 4.8 +COMPILER_VSN = 4.8.1 diff --git a/lib/cosEvent/doc/src/Makefile b/lib/cosEvent/doc/src/Makefile index 6a9b4201d7..4a0a7429e9 100644 --- a/lib/cosEvent/doc/src/Makefile +++ b/lib/cosEvent/doc/src/Makefile @@ -137,13 +137,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosEvent/src/Makefile b/lib/cosEvent/src/Makefile index f8e751f218..1825beacc5 100644 --- a/lib/cosEvent/src/Makefile +++ b/lib/cosEvent/src/Makefile @@ -197,14 +197,14 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) ../info $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) ../info "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosEvent/test/Makefile b/lib/cosEvent/test/Makefile index c3f07c156f..d5350d8293 100644 --- a/lib/cosEvent/test/Makefile +++ b/lib/cosEvent/test/Makefile @@ -141,11 +141,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ - $(RELSYSDIR)/$(IDLOUTDIR) + "$(RELSYSDIR)/$(IDLOUTDIR)" diff --git a/lib/cosEventDomain/doc/src/Makefile b/lib/cosEventDomain/doc/src/Makefile index cd159c623c..4e54b0fb55 100644 --- a/lib/cosEventDomain/doc/src/Makefile +++ b/lib/cosEventDomain/doc/src/Makefile @@ -131,13 +131,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosEventDomain/src/Makefile b/lib/cosEventDomain/src/Makefile index 409cac47f1..41a31b332f 100644 --- a/lib/cosEventDomain/src/Makefile +++ b/lib/cosEventDomain/src/Makefile @@ -166,14 +166,14 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) ../info $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) ../info "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosEventDomain/test/Makefile b/lib/cosEventDomain/test/Makefile index 160c8565e8..9349067eb5 100644 --- a/lib/cosEventDomain/test/Makefile +++ b/lib/cosEventDomain/test/Makefile @@ -98,8 +98,8 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" diff --git a/lib/cosFileTransfer/doc/src/Makefile b/lib/cosFileTransfer/doc/src/Makefile index d9c68987e4..706dec00ce 100644 --- a/lib/cosFileTransfer/doc/src/Makefile +++ b/lib/cosFileTransfer/doc/src/Makefile @@ -134,13 +134,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosFileTransfer/src/Makefile b/lib/cosFileTransfer/src/Makefile index 1d51304f6b..1bb765db73 100644 --- a/lib/cosFileTransfer/src/Makefile +++ b/lib/cosFileTransfer/src/Makefile @@ -176,12 +176,12 @@ $(TARGET_FILES): IDL-GENERATED include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosFileTransfer/test/Makefile b/lib/cosFileTransfer/test/Makefile index b46fb35356..177ad7616b 100644 --- a/lib/cosFileTransfer/test/Makefile +++ b/lib/cosFileTransfer/test/Makefile @@ -126,8 +126,8 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" diff --git a/lib/cosNotification/doc/src/Makefile b/lib/cosNotification/doc/src/Makefile index 5caee09ec5..d970818928 100644 --- a/lib/cosNotification/doc/src/Makefile +++ b/lib/cosNotification/doc/src/Makefile @@ -159,13 +159,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosNotification/src/Makefile b/lib/cosNotification/src/Makefile index 92225c6cfd..7b8b73aa11 100644 --- a/lib/cosNotification/src/Makefile +++ b/lib/cosNotification/src/Makefile @@ -367,12 +367,12 @@ $(GEN_YECC_ERL_FILES) $(GEN_YECC_HRL_FILES): cosNotification_Grammar.yrl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(YECC_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(IDL_FILES) $(YECC_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(YECC_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(IDL_FILES) $(YECC_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosNotification/test/Makefile b/lib/cosNotification/test/Makefile index f509370430..17b60a8e9f 100644 --- a/lib/cosNotification/test/Makefile +++ b/lib/cosNotification/test/Makefile @@ -128,6 +128,7 @@ ERL_COMPILE_FLAGS += \ $(ERL_IDL_FLAGS) \ -pa $(ERL_TOP)/lib/orber/include \ -pa $(ERL_TOP)/internal_tools/test_server/ebin \ + -pa $(ERL_TOP)/lib/cosEvent/ebin \ -pa $(ERL_TOP)/lib/cosNotification/ebin \ -pa $(ERL_TOP)/lib/cosNotification/test/idl_output \ -pa $(ERL_TOP)/lib/cosTime/ebin \ @@ -182,11 +183,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ - $(RELSYSDIR)/$(IDLOUTDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + "$(RELSYSDIR)/$(IDLOUTDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" diff --git a/lib/cosProperty/doc/src/Makefile b/lib/cosProperty/doc/src/Makefile index 50f2e06f6c..9bfacc27bd 100644 --- a/lib/cosProperty/doc/src/Makefile +++ b/lib/cosProperty/doc/src/Makefile @@ -136,13 +136,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosProperty/src/Makefile b/lib/cosProperty/src/Makefile index 8060421b4e..cb2c56743c 100644 --- a/lib/cosProperty/src/Makefile +++ b/lib/cosProperty/src/Makefile @@ -176,12 +176,12 @@ $(TARGET_FILES): IDL-GENERATED include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosProperty/test/Makefile b/lib/cosProperty/test/Makefile index f6e0d0dbba..d85b8a655a 100644 --- a/lib/cosProperty/test/Makefile +++ b/lib/cosProperty/test/Makefile @@ -120,11 +120,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) -# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" +# $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" # $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ -# $(RELSYSDIR)/$(IDLOUTDIR) +# "$(RELSYSDIR)/$(IDLOUTDIR)" diff --git a/lib/cosTime/doc/src/Makefile b/lib/cosTime/doc/src/Makefile index 4e97b07cf4..f89c022c4a 100644 --- a/lib/cosTime/doc/src/Makefile +++ b/lib/cosTime/doc/src/Makefile @@ -130,13 +130,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosTime/src/Makefile b/lib/cosTime/src/Makefile index 18c25ca8f1..35f16edcef 100644 --- a/lib/cosTime/src/Makefile +++ b/lib/cosTime/src/Makefile @@ -195,12 +195,12 @@ $(TARGET_FILES): IDL-GENERATED include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosTime/test/Makefile b/lib/cosTime/test/Makefile index a07b27eecb..ab4d140537 100644 --- a/lib/cosTime/test/Makefile +++ b/lib/cosTime/test/Makefile @@ -126,11 +126,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) -# $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" +# $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" # $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ -# $(RELSYSDIR)/$(IDLOUTDIR) +# "$(RELSYSDIR)/$(IDLOUTDIR)" diff --git a/lib/cosTransactions/doc/src/Makefile b/lib/cosTransactions/doc/src/Makefile index 4341ec04a3..4edad9829b 100644 --- a/lib/cosTransactions/doc/src/Makefile +++ b/lib/cosTransactions/doc/src/Makefile @@ -134,13 +134,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/cosTransactions/examples/Makefile b/lib/cosTransactions/examples/Makefile index 24cd12202a..0408cad75d 100644 --- a/lib/cosTransactions/examples/Makefile +++ b/lib/cosTransactions/examples/Makefile @@ -149,9 +149,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(JAVA_FILES) $(IDL_FILES) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(INETRC_EXAMPLE) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) $(JAVA_FILES) $(IDL_FILES) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(INETRC_EXAMPLE) "$(RELSYSDIR)/examples" @tar cf - java_output | (cd $(RELSYSDIR); tar xf -) release_docs_spec: diff --git a/lib/cosTransactions/src/Makefile b/lib/cosTransactions/src/Makefile index 3c799ca0ca..0922a21641 100644 --- a/lib/cosTransactions/src/Makefile +++ b/lib/cosTransactions/src/Makefile @@ -170,11 +170,11 @@ $(TARGET_FILES): IDL-GENERATED include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILE) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_GEN_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILE) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_GEN_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/cosTransactions/test/Makefile b/lib/cosTransactions/test/Makefile index 0bc8c007da..80f4b6c624 100644 --- a/lib/cosTransactions/test/Makefile +++ b/lib/cosTransactions/test/Makefile @@ -142,11 +142,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) \ - $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ - $(RELSYSDIR)/$(IDLOUTDIR) + "$(RELSYSDIR)/$(IDLOUTDIR)" diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 285537643e..cfc9a447e0 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -85,7 +85,7 @@ DYNAMIC_CRYPTO_LIB=@SSL_DYNAMIC_ONLY@ ifeq ($(DYNAMIC_CRYPTO_LIB),yes) SSL_DED_LD_RUNTIME_LIBRARY_PATH = @SSL_DED_LD_RUNTIME_LIBRARY_PATH@ -CRYPTO_LINK_LIB=$(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -l$(SSL_CRYPTO_LIBNAME) -l$(SSL_SSL_LIBNAME) +CRYPTO_LINK_LIB=$(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -l$(SSL_CRYPTO_LIBNAME) else SSL_DED_LD_RUNTIME_LIBRARY_PATH= CRYPTO_LINK_LIB=$(SSL_LIBDIR)/lib$(SSL_CRYPTO_LIBNAME).a @@ -133,11 +133,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/obj - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_DATA) $(NIF_MAKEFILE) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(OBJS) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(NIF_LIB) $(RELSYSDIR)/priv/lib + $(INSTALL_DIR) "$(RELSYSDIR)/priv/obj" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DATA) $(NIF_MAKEFILE) "$(RELSYSDIR)/priv/obj" + $(INSTALL_PROGRAM) $(OBJS) "$(RELSYSDIR)/priv/obj" + $(INSTALL_PROGRAM) $(NIF_LIB) "$(RELSYSDIR)/priv/lib" release_docs_spec: diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c index 4dc62421d2..4be593e208 100644 --- a/lib/crypto/c_src/crypto.c +++ b/lib/crypto/c_src/crypto.c @@ -1456,10 +1456,37 @@ static ERL_NIF_TERM rc2_cbc_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM a return ret; } +static int get_rsa_private_key(ErlNifEnv* env, ERL_NIF_TERM key, RSA *rsa) +{ + /* key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C] */ + ERL_NIF_TERM head, tail; + + if (!enif_get_list_cell(env, key, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->e) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->n) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->d) + || (!enif_is_empty_list(env, tail) && + (!enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->p) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->q) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->dmp1) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->dmq1) + || !enif_get_list_cell(env, tail, &head, &tail) + || !get_bn_from_mpint(env, head, &rsa->iqmp) + || !enif_is_empty_list(env, tail)))) { + return 0; + } + return 1; +} + static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Type,Data,Key=[E,N,D]) */ +{/* (Type,Data,Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C]) */ ErlNifBinary data_bin, ret_bin; - ERL_NIF_TERM head, tail; unsigned char hmacbuf[SHA_DIGEST_LENGTH]; unsigned rsa_s_len; RSA *rsa = RSA_new(); @@ -1470,13 +1497,7 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar else goto badarg; if (!inspect_mpint(env,argv[1],&data_bin) - || !enif_get_list_cell(env, argv[2], &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->e) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->n) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->d) - || !enif_is_empty_list(env,tail)) { + || !get_rsa_private_key(env, argv[2], rsa)) { badarg: RSA_free(rsa); return enif_make_badarg(env); @@ -1623,20 +1644,13 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER } static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{/* (Data, PublKey=[E,N,D], Padding, IsEncrypt) */ +{/* (Data, Key=[E,N,D]|[E,N,D,P1,P2,E1,E2,C], Padding, IsEncrypt) */ ErlNifBinary data_bin, ret_bin; - ERL_NIF_TERM head, tail; int padding, i; RSA* rsa = RSA_new(); if (!enif_inspect_binary(env, argv[0], &data_bin) - || !enif_get_list_cell(env, argv[1], &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->e) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->n) - || !enif_get_list_cell(env, tail, &head, &tail) - || !get_bn_from_mpint(env, head, &rsa->d) - || !enif_is_empty_list(env,tail) + || !get_rsa_private_key(env, argv[1], rsa) || !rsa_pad(argv[2], &padding)) { RSA_free(rsa); diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index 03aaba939b..00ae70fb4a 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -100,16 +100,16 @@ clean clean_docs clean_tex: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 8cb893cd1c..19db6c9dd4 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -870,10 +870,15 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <fsummary>Sign the data using rsa with the given key.</fsummary> <type> <v>Data = Mpint</v> - <v>Key = [E, N, D]</v> + <v>Key = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v> <v>E, N, D = Mpint</v> <d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and <c>D</c> is the private exponent.</d> + <v>P1, P2, E1, E2, C = Mpint</v> + <d>The longer key format contains redundant information that will make + the calculation faster. <c>P1,P2</c> are first and second prime factors. + <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient. + Terminology is taken from RFC 3447.</d> <v>DigestType = md5 | sha</v> <d>The default <c>DigestType</c> is sha.</d> <v>Mpint = binary()</v> @@ -943,10 +948,15 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <fsummary>Decrypts ChipherText using the private Key.</fsummary> <type> <v>ChipherText = binary()</v> - <v>PrivateKey = [E, N, D]</v> + <v>PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v> <v>E, N, D = Mpint</v> <d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and <c>D</c> is the private exponent.</d> + <v>P1, P2, E1, E2, C = Mpint</v> + <d>The longer key format contains redundant information that will make + the calculation faster. <c>P1,P2</c> are first and second prime factors. + <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient. + Terminology is taken from RFC 3447.</d> <v>Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding</v> <v>PlainText = binary()</v> </type> @@ -965,10 +975,15 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]> <fsummary>Encrypts Msg using the private Key.</fsummary> <type> <v>PlainText = binary()</v> - <v>PrivateKey = [E, N, D]</v> - <v>E, N, D = Mpint</v> + <v>PrivateKey = [E, N, D] | [E, N, D, P1, P2, E1, E2, C]</v> + <v>E, N, D = Mpint</v> <d>Where <c>E</c> is the public exponent, <c>N</c> is public modulus and <c>D</c> is the private exponent.</d> + <v>P1, P2, E1, E2, C = Mpint</v> + <d>The longer key format contains redundant information that will make + the calculation faster. <c>P1,P2</c> are first and second prime factors. + <c>E1,E2</c> are first and second exponents. <c>C</c> is the CRT coefficient. + Terminology is taken from RFC 3447.</d> <v>Padding = rsa_pkcs1_padding | rsa_no_padding</v> <v>ChipherText = binary()</v> </type> diff --git a/lib/crypto/src/Makefile b/lib/crypto/src/Makefile index 0e886ce8bf..ddafb9168f 100644 --- a/lib/crypto/src/Makefile +++ b/lib/crypto/src/Makefile @@ -83,11 +83,11 @@ docs: 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_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) \ - $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile index 3150bd472d..ec8136b455 100644 --- a/lib/crypto/test/Makefile +++ b/lib/crypto/test/Makefile @@ -75,9 +75,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: release_tests_spec: $(TEST_TARGET) - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) crypto.spec crypto.cover $(RELTEST_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile index 1c0bbaf9d2..bc11ed7f46 100644 --- a/lib/debugger/doc/src/Makefile +++ b/lib/debugger/doc/src/Makefile @@ -110,12 +110,12 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - (/bin/cp -rf $(HTMLDIR) $(RELSYSDIR)/doc) - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc") + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml index 4d8bd8ebe4..593bf715bf 100644 --- a/lib/debugger/doc/src/notes.xml +++ b/lib/debugger/doc/src/notes.xml @@ -32,6 +32,22 @@ <p>This document describes the changes made to the Debugger application.</p> +<section><title>Debugger 3.2.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fixed disappearing breakpoints bug, reported by Ricardo + Catalinas Jim�nez.</p> + <p> + Own Id: OTP-9950</p> + </item> + </list> + </section> + +</section> + <section><title>Debugger 3.2.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/debugger/priv/Makefile b/lib/debugger/priv/Makefile index 1036a5666b..2f3002331b 100644 --- a/lib/debugger/priv/Makefile +++ b/lib/debugger/priv/Makefile @@ -54,8 +54,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(TOOLBAR_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(TOOLBAR_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/debugger/src/Makefile b/lib/debugger/src/Makefile index be9a2d13cb..1f9d6f2058 100644 --- a/lib/debugger/src/Makefile +++ b/lib/debugger/src/Makefile @@ -129,9 +129,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(TOOLBOX_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(TARGET_TOOLBOX_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(TOOLBOX_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(TARGET_TOOLBOX_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/debugger/test/Makefile b/lib/debugger/test/Makefile index 3dfbed31ff..bf948ce8b0 100644 --- a/lib/debugger/test/Makefile +++ b/lib/debugger/test/Makefile @@ -98,10 +98,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) debugger.spec debugger.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) debugger.spec debugger.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/debugger/test/bs_construct_SUITE.erl b/lib/debugger/test/bs_construct_SUITE.erl index cf943677be..e0bda7eac8 100644 --- a/lib/debugger/test/bs_construct_SUITE.erl +++ b/lib/debugger/test/bs_construct_SUITE.erl @@ -477,7 +477,6 @@ mem_leak(0, _) -> ok; mem_leak(N, B) -> ?line big_bin(B, <<23>>), ?line {'EXIT',{badarg,_}} = (catch big_bin(B, bad)), - maybe_gc(), mem_leak(N-1, B). big_bin(B1, B2) -> @@ -490,13 +489,6 @@ big_bin(B1, B2) -> make_bin(0, Acc) -> Acc; make_bin(N, Acc) -> make_bin(N-1, <<Acc/binary,Acc/binary>>). -maybe_gc() -> - case erlang:system_info(heap_type) of - shared -> erlang:garbage_collect(); - hybrid -> erlang:garbage_collect(); - private -> ok - end. - -define(COF(Int0), ?line (fun(Int) -> true = <<Int:32/float>> =:= <<(float(Int)):32/float>>, diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk index 01ff0eb9a8..5b572f5f20 100644 --- a/lib/debugger/vsn.mk +++ b/lib/debugger/vsn.mk @@ -1 +1 @@ -DEBUGGER_VSN = 3.2.7 +DEBUGGER_VSN = 3.2.8 diff --git a/lib/dialyzer/doc/src/Makefile b/lib/dialyzer/doc/src/Makefile index 45b0ffa5ff..a827281cc5 100644 --- a/lib/dialyzer/doc/src/Makefile +++ b/lib/dialyzer/doc/src/Makefile @@ -100,13 +100,13 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index f100865b56..934cdba437 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the Dialyzer application.</p> +<section><title>Dialyzer 2.5.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> Handle <c>nowarn_unused_function</c> the same way as + the compiler does. </p> + <p> + Own Id: OTP-9833</p> + </item> + </list> + </section> + +</section> + <section><title>Dialyzer 2.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/src/Makefile b/lib/dialyzer/src/Makefile index 04f3b844c4..63cc1c98f1 100644 --- a/lib/dialyzer/src/Makefile +++ b/lib/dialyzer/src/Makefile @@ -63,7 +63,10 @@ MODULES = \ dialyzer_plt \ dialyzer_races \ dialyzer_succ_typings \ + dialyzer_timing \ dialyzer_typesig \ + dialyzer_coordinator \ + dialyzer_worker \ dialyzer_utils HRL_FILES= dialyzer.hrl dialyzer_gui_wx.hrl @@ -152,10 +155,10 @@ $(EBIN)/dialyzer_utils.beam: dialyzer.hrl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/src" $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(EXTRA_FILES) \ - $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(INSTALL_FILES) $(RELSYSDIR)/ebin + "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(INSTALL_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/dialyzer/src/dialyzer.hrl b/lib/dialyzer/src/dialyzer.hrl index 5e089d1773..1b999a7b99 100644 --- a/lib/dialyzer/src/dialyzer.hrl +++ b/lib/dialyzer/src/dialyzer.hrl @@ -110,6 +110,7 @@ -type label() :: non_neg_integer(). -type rep_mode() :: 'quiet' | 'normal' | 'verbose'. -type start_from() :: 'byte_code' | 'src_code'. +-type mfa_or_funlbl() :: label() | mfa(). %%-------------------------------------------------------------------- %% Record declarations used by various files @@ -126,11 +127,14 @@ use_contracts = true :: boolean(), race_detection = false :: boolean(), behaviours_chk = false :: boolean(), + timing = false :: boolean() | 'debug', + timing_server :: dialyzer_timing:timing_server(), callgraph_file = "" :: file:filename()}). -record(options, {files = [] :: [file:filename()], files_rec = [] :: [file:filename()], analysis_type = succ_typings :: anal_type1(), + timing = false :: boolean() | 'debug', defines = [] :: [dial_define()], from = byte_code :: start_from(), get_warnings = maybe :: boolean() | 'maybe', @@ -152,3 +156,12 @@ forms = [] :: [{_, _}]}). %%-------------------------------------------------------------------- + +-define(timing(Server, Msg, Var, Expr), + begin + dialyzer_timing:start_stamp(Server, Msg), + Var = Expr, + dialyzer_timing:end_stamp(Server), + Var + end). +-define(timing(Server, Msg, Expr),?timing(Server, Msg, _T, Expr)). diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 2c4622155a..3bbde12481 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -30,6 +30,15 @@ -export([start/3]). +-export([compile_init_result/0, + add_to_result/4, + start_compilation/2, + continue_compilation/2]). + +-export_type([compile_init_data/0, + one_file_result/0, + compile_result/0]). + -include("dialyzer.hrl"). -record(analysis_state, @@ -43,7 +52,8 @@ parent :: pid(), plt :: dialyzer_plt:plt(), start_from = byte_code :: start_from(), - use_contracts = true :: boolean() + use_contracts = true :: boolean(), + timing_server :: dialyzer_timing:timing_server() }). -record(server_state, {parent :: pid(), legal_warnings :: [dial_warn_tag()]}). @@ -55,12 +65,15 @@ -spec start(pid(), [dial_warn_tag()], #analysis{}) -> 'ok'. start(Parent, LegalWarnings, Analysis) -> + TimingServer = dialyzer_timing:init(Analysis#analysis.timing), RacesOn = ordsets:is_element(?WARN_RACE_CONDITION, LegalWarnings), - Analysis0 = Analysis#analysis{race_detection = RacesOn}, + Analysis0 = + Analysis#analysis{race_detection = RacesOn, timing_server = TimingServer}, Analysis1 = expand_files(Analysis0), Analysis2 = run_analysis(Analysis1), State = #server_state{parent = Parent, legal_warnings = LegalWarnings}, - loop(State, Analysis2, none). + loop(State, Analysis2, none), + dialyzer_timing:stop(TimingServer). run_analysis(Analysis) -> Self = self(), @@ -122,7 +135,8 @@ analysis_start(Parent, Analysis) -> plt = Plt, parent = Parent, start_from = Analysis#analysis.start_from, - use_contracts = Analysis#analysis.use_contracts + use_contracts = Analysis#analysis.use_contracts, + timing_server = Analysis#analysis.timing_server }, Files = ordsets:from_list(Analysis#analysis.files), {Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State), @@ -146,7 +160,8 @@ analysis_start(Parent, Analysis) -> dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes, TmpCServer1), TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2), - dialyzer_contracts:process_contract_remote_types(TmpCServer3) + ?timing(State#analysis_state.timing_server, "remote", + dialyzer_contracts:process_contract_remote_types(TmpCServer3)) catch throw:{error, _ErrorMsg} = Error -> exit(Error) end, @@ -174,72 +189,66 @@ analysis_start(Parent, Analysis) -> send_codeserver_plt(Parent, CServer, State3#analysis_state.plt), send_analysis_done(Parent, Plt2, State3#analysis_state.doc_plt). -analyze_callgraph(Callgraph, State) -> - Codeserver = State#analysis_state.codeserver, - Parent = State#analysis_state.parent, - DocPlt = State#analysis_state.doc_plt, +analyze_callgraph(Callgraph, #analysis_state{codeserver = Codeserver, + doc_plt = DocPlt, + timing_server = TimingServer, + parent = Parent} = State) -> Plt = dialyzer_plt:insert_callbacks(State#analysis_state.plt, Codeserver), - Callgraph1 = dialyzer_callgraph:finalize(Callgraph), {NewPlt, NewDocPlt} = case State#analysis_state.analysis_type of plt_build -> - {dialyzer_succ_typings:analyze_callgraph(Callgraph1, Plt, - Codeserver, Parent), - DocPlt}; + NewPlt0 = + dialyzer_succ_typings:analyze_callgraph(Callgraph, Plt, Codeserver, + TimingServer, Parent), + {NewPlt0, DocPlt}; succ_typings -> NoWarn = State#analysis_state.no_warn_unused, {Warnings, NewPlt0, NewDocPlt0} = - dialyzer_succ_typings:get_warnings(Callgraph1, Plt, DocPlt, - Codeserver, NoWarn, Parent), + dialyzer_succ_typings:get_warnings(Callgraph, Plt, DocPlt, Codeserver, + NoWarn, TimingServer, Parent), send_warnings(State#analysis_state.parent, Warnings), {NewPlt0, NewDocPlt0} end, - dialyzer_callgraph:delete(Callgraph1), + dialyzer_callgraph:delete(Callgraph), State#analysis_state{plt = NewPlt, doc_plt = NewDocPlt}. %%-------------------------------------------------------------------- %% Build the callgraph and fill the codeserver. %%-------------------------------------------------------------------- +-record(compile_init,{ + callgraph :: dialyzer_callgraph:callgraph(), + codeserver :: dialyzer_codeserver:codeserver(), + defines = [] :: [dial_define()], + include_dirs = [] :: [file:filename()], + start_from = byte_code :: start_from(), + use_contracts = true :: boolean() + }). + +make_compile_init(#analysis_state{codeserver = Codeserver, + defines = Defs, + include_dirs = Dirs, + use_contracts = UseContracts, + start_from = StartFrom}, Callgraph) -> + #compile_init{callgraph = Callgraph, + codeserver = Codeserver, + defines = [{d, Macro, Val} || {Macro, Val} <- Defs], + include_dirs = [{i, D} || D <- Dirs], + use_contracts = UseContracts, + start_from = StartFrom}. + compile_and_store(Files, #analysis_state{codeserver = CServer, - defines = Defs, - include_dirs = Dirs, - parent = Parent, - use_contracts = UseContracts, - start_from = StartFrom - } = State) -> + timing_server = Timing, + parent = Parent} = State) -> send_log(Parent, "Reading files and computing callgraph... "), {T1, _} = statistics(runtime), - Includes = [{i, D} || D <- Dirs], - Defines = [{d, Macro, Val} || {Macro, Val} <- Defs], Callgraph = dialyzer_callgraph:new(), - Fun = case StartFrom of - src_code -> - fun(File, {TmpCG, TmpCServer, TmpFailed, TmpNoWarn, TmpMods}) -> - case compile_src(File, Includes, Defines, TmpCG, - TmpCServer, UseContracts) of - {error, Reason} -> - {TmpCG, TmpCServer, [{File, Reason}|TmpFailed], TmpNoWarn, - TmpMods}; - {ok, NewCG, NoWarn, NewCServer, Mod} -> - {NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn, - [Mod|TmpMods]} - end - end; - byte_code -> - 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} -> - {NewCG, NewCServer, TmpFailed, NoWarn++TmpNoWarn, - [Mod|TmpMods]} - end - end - end, - {NewCallgraph1, NewCServer, Failed, NoWarn, Modules} = - lists:foldl(Fun, {Callgraph, CServer, [], [], []}, Files), + CompileInit = make_compile_init(State, Callgraph), + {{Failed, NoWarn, Modules}, NextLabel} = + ?timing(Timing, "compile", _C1, + dialyzer_coordinator:parallel_job(compile, Files, + CompileInit, Timing)), + CServer2 = dialyzer_codeserver:set_next_core_label(NextLabel, CServer), case Failed =:= [] of true -> NewFiles = lists:zip(lists:reverse(Modules), Files), @@ -255,11 +264,56 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, {T2, _} = statistics(runtime), Msg1 = io_lib:format("done in ~.2f secs\nRemoving edges... ", [(T2-T1)/1000]), send_log(Parent, Msg1), - NewCallgraph2 = cleanup_callgraph(State, NewCServer, NewCallgraph1, Modules), + Callgraph = + ?timing(Timing, "clean", _C2, + cleanup_callgraph(State, CServer2, Callgraph, Modules)), {T3, _} = statistics(runtime), Msg2 = io_lib:format("done in ~.2f secs\n", [(T3-T2)/1000]), send_log(Parent, Msg2), - {NewCallgraph2, sets:from_list(NoWarn), NewCServer}. + {Callgraph, sets:from_list(NoWarn), CServer2}. + +-type compile_init_data() :: #compile_init{}. +-type error_reason() :: string(). +-type compile_result() :: {[{file:filename(), error_reason()}], [mfa()], + [module()]}. %%opaque +-type one_file_result() :: {error, error_reason()} | + {ok, [dialyzer_callgraph:callgraph_edge()], + [mfa_or_funlbl()], [mfa()], module()}. %%opaque +-type compile_mid_data() :: {module(), cerl:cerl(), [mfa()], + dialyzer_callgraph:callgraph(), + dialyzer_codeserver:codeserver()}. + +-spec compile_init_result() -> compile_result(). + +compile_init_result() -> {[], [], []}. + +-spec add_to_result(file:filename(), one_file_result(), compile_result(), + compile_init_data()) -> compile_result(). + +add_to_result(File, NewData, {Failed, NoWarn, Mods}, InitData) -> + case NewData of + {error, Reason} -> + {[{File, Reason}|Failed], NoWarn, Mods}; + {ok, V, E, NewNoWarn, Mod} -> + Callgraph = InitData#compile_init.callgraph, + dialyzer_callgraph:add_edges(E, V, Callgraph), + {Failed, NewNoWarn ++ NoWarn, [Mod|Mods]} + end. + +-spec start_compilation(file:filename(), compile_init_data()) -> + {error, error_reason()} |{ok, integer(), compile_mid_data()}. + +start_compilation(File, + #compile_init{callgraph = Callgraph, codeserver = Codeserver, + defines = Defines, include_dirs = IncludeD, + use_contracts = UseContracts, + start_from = StartFrom}) -> + case StartFrom of + src_code -> + compile_src(File, IncludeD, Defines, Callgraph, Codeserver, UseContracts); + byte_code -> + compile_byte(File, Callgraph, Codeserver, UseContracts) + end. cleanup_callgraph(#analysis_state{plt = InitPlt, parent = Parent, codeserver = CodeServer @@ -348,14 +402,18 @@ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, UseContracts) -> store_core(Mod, Core, NoWarn, Callgraph, CServer) -> Exp = get_exports_from_core(Core), - OldExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer), - NewExpTypes = get_exported_types_from_core(Core), - MergedExpTypes = sets:union(NewExpTypes, OldExpTypes), - CServer1 = dialyzer_codeserver:insert_exports(Exp, CServer), - CServer2 = dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes, - CServer1), - {LabeledCore, CServer3} = label_core(Core, CServer2), - store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer3, NoWarn). + ExpTypes = get_exported_types_from_core(Core), + CServer = dialyzer_codeserver:insert_exports(Exp, CServer), + CServer = dialyzer_codeserver:insert_temp_exported_types(ExpTypes, CServer), + CoreTree = cerl:from_records(Core), + {ok, cerl_trees:size(CoreTree), {Mod, CoreTree, NoWarn, Callgraph, CServer}}. + +-spec continue_compilation(integer(), compile_mid_data()) -> one_file_result(). + +continue_compilation(NextLabel, {Mod, CoreTree, NoWarn, Callgraph, CServer}) -> + {LabeledTree, _NewNextLabel} = cerl_trees:label(CoreTree, NextLabel), + LabeledCore = cerl:to_records(LabeledTree), + store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, NoWarn, CServer). abs_get_nowarn(Abs, M) -> Opts = lists:flatten([C || {attribute, _, compile, C} <- Abs]), @@ -388,18 +446,11 @@ get_exports_from_core(Core) -> M = cerl:atom_val(cerl:module_name(Tree)), [{M, F, A} || {F, A} <- Exports2]. -label_core(Core, CServer) -> - NextLabel = dialyzer_codeserver:get_next_core_label(CServer), - CoreTree = cerl:from_records(Core), - {LabeledTree, NewNextLabel} = cerl_trees:label(CoreTree, NextLabel), - {cerl:to_records(LabeledTree), - dialyzer_codeserver:set_next_core_label(NewNextLabel, CServer)}. - -store_code_and_build_callgraph(Mod, Core, Callgraph, CServer, NoWarn) -> +store_code_and_build_callgraph(Mod, Core, Callgraph, NoWarn, CServer) -> CoreTree = cerl:from_records(Core), - NewCallgraph = dialyzer_callgraph:scan_core_tree(CoreTree, Callgraph), - CServer2 = dialyzer_codeserver:insert(Mod, CoreTree, CServer), - {ok, NewCallgraph, NoWarn, CServer2, Mod}. + {Vertices, Edges} = dialyzer_callgraph:scan_core_tree(CoreTree, Callgraph), + CServer = dialyzer_codeserver:insert(Mod, CoreTree, CServer), + {ok, Vertices, Edges, NoWarn, Mod}. %%-------------------------------------------------------------------- %% Utilities diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl index 127e906135..b84071b95c 100644 --- a/lib/dialyzer/src/dialyzer_behaviours.erl +++ b/lib/dialyzer/src/dialyzer_behaviours.erl @@ -30,7 +30,7 @@ -module(dialyzer_behaviours). --export([check_callbacks/4, get_behaviour_apis/1, +-export([check_callbacks/5, get_behaviour_apis/1, translate_behaviour_api_call/5, translatable_behaviours/1, translate_callgraph/3]). @@ -47,15 +47,16 @@ -record(state, {plt :: dialyzer_plt:plt(), codeserver :: dialyzer_codeserver:codeserver(), filename :: file:filename(), - behlines :: [{behaviour(), non_neg_integer()}]}). + behlines :: [{behaviour(), non_neg_integer()}], + records :: dict()}). %%-------------------------------------------------------------------- --spec check_callbacks(module(), [{cerl:cerl(), cerl:cerl()}], +-spec check_callbacks(module(), [{cerl:cerl(), cerl:cerl()}], dict(), dialyzer_plt:plt(), dialyzer_codeserver:codeserver()) -> [dial_warning()]. -check_callbacks(Module, Attrs, Plt, Codeserver) -> +check_callbacks(Module, Attrs, Records, Plt, Codeserver) -> {Behaviours, BehLines} = get_behaviours(Attrs), case Behaviours of [] -> []; @@ -64,7 +65,7 @@ check_callbacks(Module, Attrs, Plt, Codeserver) -> {_Var,Code} = dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver), File = get_file(cerl:get_ann(Code)), State = #state{plt = Plt, filename = File, behlines = BehLines, - codeserver = Codeserver}, + codeserver = Codeserver, records = Records}, Warnings = get_warnings(Module, Behaviours, State), [add_tag_file_line(Module, W, State) || W <- Warnings] end. @@ -92,24 +93,21 @@ get_warnings(Module, [Behaviour|Rest], State, Acc) -> check_behaviour(Module, Behaviour, #state{plt = Plt} = State, Acc) -> case dialyzer_plt:lookup_callbacks(Plt, Behaviour) of - [] -> [{callback_info_missing, [Behaviour]}|Acc]; - Callbacks -> check_all_callbacks(Module, Behaviour, Callbacks, State, Acc) + none -> [{callback_info_missing, [Behaviour]}|Acc]; + {value, Callbacks} -> + check_all_callbacks(Module, Behaviour, Callbacks, State, Acc) end. check_all_callbacks(_Module, _Behaviour, [], _State, Acc) -> Acc; check_all_callbacks(Module, Behaviour, [Cb|Rest], - #state{plt = Plt, codeserver = Codeserver} = State, Acc) -> + #state{plt = Plt, codeserver = Codeserver, + records = Records} = State, Acc) -> {{Behaviour, Function, Arity}, {{_BehFile, _BehLine}, Callback}} = Cb, CbMFA = {Module, Function, Arity}, CbReturnType = dialyzer_contracts:get_contract_return(Callback), CbArgTypes = dialyzer_contracts:get_contract_args(Callback), - Records = - case dict:find(Module, dialyzer_codeserver:get_records(Codeserver)) of - {ok, V} -> V; - error -> dict:new() - end, Acc0 = Acc, Acc1 = case dialyzer_plt:lookup(Plt, CbMFA) of @@ -282,8 +280,8 @@ translate_callgraph([{Behaviour,_}|Behaviours], Module, Callgraph) -> DirectCalls = [{From, {Module, Fun, Arity}} || {From, To} <- UsedCalls,{API, {Fun, Arity, _Ord}} <- Calls, To =:= API], - NewCallgraph = dialyzer_callgraph:add_edges(DirectCalls, Callgraph), - translate_callgraph(Behaviours, Module, NewCallgraph); + dialyzer_callgraph:add_edges(DirectCalls, Callgraph), + translate_callgraph(Behaviours, Module, Callgraph); translate_callgraph([], _Module, Callgraph) -> Callgraph. diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl index effd619bde..64e0ee88af 100644 --- a/lib/dialyzer/src/dialyzer_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_callgraph.erl @@ -28,6 +28,7 @@ -module(dialyzer_callgraph). -export([add_edges/2, + add_edges/3, all_nodes/1, delete/1, finalize/1, @@ -43,12 +44,15 @@ %% module_postorder/1, module_postorder_from_funs/2, new/0, + get_depends_on/2, + get_required_by/2, in_neighbours/2, renew_race_info/4, + renew_race_code/2, + renew_race_public_tables/2, reset_from_funs/2, scan_core_tree/2, strip_module_deps/2, - take_scc/1, remove_external/1, to_dot/2, to_ps/3]). @@ -57,15 +61,14 @@ get_race_code/1, get_race_detection/1, race_code_new/1, put_digraph/2, put_race_code/2, put_race_detection/2, put_named_tables/2, put_public_tables/2, put_behaviour_api_calls/2, - get_behaviour_api_calls/1]). + get_behaviour_api_calls/1, dispose_race_server/1, duplicate/1]). --export_type([callgraph/0, mfa_or_funlbl/0]). +-export_type([callgraph/0, mfa_or_funlbl/0, callgraph_edge/0]). -include("dialyzer.hrl"). %%---------------------------------------------------------------------- --type mfa_or_funlbl() :: label() | mfa(). -type scc() :: [mfa_or_funlbl()]. -type mfa_calls() :: [{mfa_or_funlbl(), mfa_or_funlbl()}]. @@ -78,9 +81,6 @@ %% digraph - A digraph representing the callgraph. %% Nodes are represented as MFAs or labels. %% esc - A set of all escaping functions as reported by dialyzer_dep. -%% postorder - A list of strongly connected components of the callgraph -%% sorted in a topological bottom-up order. -%% This is produced by calling finalize/1. %% name_map - A mapping from label to MFA. %% rev_name_map - A reverse mapping of the name_map. %% rec_var_map - A dict mapping from letrec bound labels to function names. @@ -91,29 +91,42 @@ %%----------------------------------------------------------------------------- -record(callgraph, {digraph = digraph:new() :: digraph(), - esc = sets:new() :: set(), - name_map = dict:new() :: dict(), - rev_name_map = dict:new() :: dict(), - postorder = [] :: [scc()], - rec_var_map = dict:new() :: dict(), - self_rec = sets:new() :: set(), - calls = dict:new() :: dict(), - race_code = dict:new() :: dict(), - public_tables = [] :: [label()], - named_tables = [] :: [string()], + active_digraph :: active_digraph(), + esc :: ets:tid(), + name_map :: ets:tid(), + rev_name_map :: ets:tid(), + rec_var_map :: ets:tid(), + self_rec :: ets:tid(), + calls :: ets:tid(), race_detection = false :: boolean(), - beh_api_calls = [] :: [{mfa(), mfa()}]}). + race_data_server = new_race_data_server() :: pid()}). + +-record(race_data_state, {race_code = dict:new() :: dict(), + public_tables = [] :: [label()], + named_tables = [] :: [string()], + beh_api_calls = [] :: [{mfa(), mfa()}]}). %% Exported Types -type callgraph() :: #callgraph{}. +-type active_digraph() :: {'d', digraph()} | {'e', ets:tid(), ets:tid()}. + %%---------------------------------------------------------------------- -spec new() -> callgraph(). new() -> - #callgraph{}. + [ETSEsc, ETSNameMap, ETSRevNameMap, ETSRecVarMap, ETSSelfRec, ETSCalls] = + [ets:new(N,[public, {read_concurrency, true}]) || + N <- [callgraph_esc, callgraph_name_map, callgraph_rev_name_map, + callgraph_rec_var_map, callgraph_self_rec, callgraph_calls]], + #callgraph{esc = ETSEsc, + name_map = ETSNameMap, + rev_name_map = ETSRevNameMap, + rec_var_map = ETSRecVarMap, + self_rec = ETSSelfRec, + calls = ETSCalls}. -spec delete(callgraph()) -> 'true'. @@ -129,32 +142,32 @@ all_nodes(#callgraph{digraph = DG}) -> lookup_rec_var(Label, #callgraph{rec_var_map = RecVarMap}) when is_integer(Label) -> - dict:find(Label, RecVarMap). + ets_lookup_dict(Label, RecVarMap). -spec lookup_call_site(label(), callgraph()) -> 'error' | {'ok', [_]}. % XXX: refine lookup_call_site(Label, #callgraph{calls = Calls}) when is_integer(Label) -> - dict:find(Label, Calls). + ets_lookup_dict(Label, Calls). -spec lookup_name(label(), callgraph()) -> 'error' | {'ok', mfa()}. lookup_name(Label, #callgraph{name_map = NameMap}) when is_integer(Label) -> - dict:find(Label, NameMap). + ets_lookup_dict(Label, NameMap). -spec lookup_label(mfa_or_funlbl(), callgraph()) -> 'error' | {'ok', integer()}. lookup_label({_,_,_} = MFA, #callgraph{rev_name_map = RevNameMap}) -> - dict:find(MFA, RevNameMap); + ets_lookup_dict(MFA, RevNameMap); lookup_label(Label, #callgraph{}) when is_integer(Label) -> {ok, Label}. -spec in_neighbours(mfa_or_funlbl(), callgraph()) -> 'none' | [mfa_or_funlbl(),...]. -in_neighbours(Label, #callgraph{digraph = Digraph, name_map = NameMap}) +in_neighbours(Label, #callgraph{digraph = Digraph} = CG) when is_integer(Label) -> - Name = case dict:find(Label, NameMap) of + Name = case lookup_name(Label, CG) of {ok, Val} -> Val; error -> Label end, @@ -165,34 +178,27 @@ in_neighbours({_, _, _} = MFA, #callgraph{digraph = Digraph}) -> -spec is_self_rec(mfa_or_funlbl(), callgraph()) -> boolean(). is_self_rec(MfaOrLabel, #callgraph{self_rec = SelfRecs}) -> - sets:is_element(MfaOrLabel, SelfRecs). + ets_lookup_set(MfaOrLabel, SelfRecs). -spec is_escaping(label(), callgraph()) -> boolean(). is_escaping(Label, #callgraph{esc = Esc}) when is_integer(Label) -> - sets:is_element(Label, Esc). + ets_lookup_set(Label, Esc). -type callgraph_edge() :: {mfa_or_funlbl(),mfa_or_funlbl()}. --spec add_edges([callgraph_edge()], callgraph()) -> callgraph(). +-spec add_edges([callgraph_edge()], callgraph()) -> ok. -add_edges([], CG) -> - CG; -add_edges(Edges, #callgraph{digraph = Digraph} = CG) -> - CG#callgraph{digraph = digraph_add_edges(Edges, Digraph)}. +add_edges([], _CG) -> + ok; +add_edges(Edges, #callgraph{digraph = Digraph}) -> + digraph_add_edges(Edges, Digraph). --spec add_edges([callgraph_edge()], [mfa_or_funlbl()], callgraph()) -> callgraph(). +-spec add_edges([callgraph_edge()], [mfa_or_funlbl()], callgraph()) -> ok. add_edges(Edges, MFAs, #callgraph{digraph = DG} = CG) -> - DG = digraph_confirm_vertices(MFAs, DG), + digraph_confirm_vertices(MFAs, DG), add_edges(Edges, CG). --spec take_scc(callgraph()) -> 'none' | {'ok', scc(), callgraph()}. - -take_scc(#callgraph{postorder = [SCC|SCCs]} = CG) -> - {ok, SCC, CG#callgraph{postorder = SCCs}}; -take_scc(#callgraph{postorder = []}) -> - none. - -spec remove_external(callgraph()) -> {callgraph(), [tuple()]}. remove_external(#callgraph{digraph = DG} = CG) -> @@ -221,13 +227,25 @@ find_non_local_calls([{Label1, Label2}|Left], Set) when is_integer(Label1), find_non_local_calls([], Set) -> sets:to_list(Set). --spec renew_race_info(callgraph(), dict(), [label()], [string()]) -> - callgraph(). +-spec get_depends_on(scc() | module(), callgraph()) -> [scc()]. + +get_depends_on(SCC, #callgraph{active_digraph = {'e', Out, _In}}) -> + case ets_lookup_dict(SCC, Out) of + {ok, Value} -> Value; + error -> [] + end; +get_depends_on(SCC, #callgraph{active_digraph = {'d', DG}}) -> + digraph:out_neighbours(DG, SCC). + +-spec get_required_by(scc() | module(), callgraph()) -> [scc()]. -renew_race_info(CG, RaceCode, PublicTables, NamedTables) -> - CG#callgraph{race_code = RaceCode, - public_tables = PublicTables, - named_tables = NamedTables}. +get_required_by(SCC, #callgraph{active_digraph = {'e', _Out, In}}) -> + case ets_lookup_dict(SCC, In) of + {ok, Value} -> Value; + error -> [] + end; +get_required_by(SCC, #callgraph{active_digraph = {'d', DG}}) -> + digraph:in_neighbours(DG, SCC). %%---------------------------------------------------------------------- %% Handling of modules & SCCs @@ -238,32 +256,37 @@ renew_race_info(CG, RaceCode, PublicTables, NamedTables) -> modules(#callgraph{digraph = DG}) -> ordsets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]). --spec module_postorder(callgraph()) -> [[module()]]. +-spec module_postorder(callgraph()) -> {[module()], {'d', digraph()}}. module_postorder(#callgraph{digraph = DG}) -> - {MDG, _Nodes} = get_module_digraph_and_nodes(DG), - MDG1 = digraph_utils:condensation(MDG), - PostOrder = digraph_utils:postorder(MDG1), - PostOrder1 = sort_sccs_internally(PostOrder, MDG), - digraph:delete(MDG1), - digraph_delete(MDG), - PostOrder1. + Edges = lists:foldl(fun edge_fold/2, sets:new(), digraph_edges(DG)), + Nodes = sets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]), + MDG = digraph:new([acyclic]), + digraph_confirm_vertices(sets:to_list(Nodes), MDG), + Foreach = fun({M1,M2}) -> digraph:add_edge(MDG, M1, M2) end, + lists:foreach(Foreach, sets:to_list(Edges)), + {digraph_utils:topsort(MDG), {'d', MDG}}. + +edge_fold({{M1,_,_},{M2,_,_}}, Set) -> + case M1 =/= M2 of + true -> sets:add_element({M1,M2},Set); + false -> Set + end; +edge_fold(_, Set) -> Set. -get_module_digraph_and_nodes(DG) -> - Edges = digraph_edges(DG), - Nodes = ordsets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]), - MDG = digraph:new(), - MDG = digraph_confirm_vertices(Nodes, MDG), - MDG = create_module_digraph(Edges, MDG), - {MDG, Nodes}. %% The module deps of a module are modules that depend on the module -spec module_deps(callgraph()) -> dict(). module_deps(#callgraph{digraph = DG}) -> - {MDG, Nodes} = get_module_digraph_and_nodes(DG), + Edges = lists:foldl(fun edge_fold/2, sets:new(), digraph_edges(DG)), + Nodes = sets:from_list([M || {M,_F,_A} <- digraph_vertices(DG)]), + MDG = digraph:new(), + digraph_confirm_vertices(sets:to_list(Nodes), MDG), + Foreach = fun({M1,M2}) -> digraph:add_edge(MDG, M1, M2) end, + lists:foreach(Foreach, sets:to_list(Edges)), Deps = [{N, ordsets:from_list(digraph:in_neighbours(MDG, N))} - || N <- Nodes], + || N <- sets:to_list(Nodes)], digraph_delete(MDG), dict:from_list(Deps). @@ -276,52 +299,42 @@ strip_module_deps(ModDeps, StripSet) -> FilterFun2 = fun(_Key, ValSet) -> ValSet =/= [] end, dict:filter(FilterFun2, ModDeps1). -sort_sccs_internally(PO, MDG) -> - sort_sccs_internally(PO, MDG, []). - -sort_sccs_internally([SCC|SCCs], MDG, Acc) -> - case SCC of - [_, _, _ | _] -> % length(SCC) >= 3 - TmpDG = digraph_utils:subgraph(MDG, SCC), - NewSCC = digraph_utils:postorder(TmpDG), - digraph_delete(TmpDG), - sort_sccs_internally(SCCs, MDG, [NewSCC|Acc]); - _ -> - sort_sccs_internally(SCCs, MDG, [SCC|Acc]) - end; -sort_sccs_internally([], _MDG, Acc) -> - lists:reverse(Acc). - -create_module_digraph([{{M, _, _}, {M, _, _}}|Left], MDG) -> - create_module_digraph(Left, MDG); -create_module_digraph([{{M1, _, _}, {M2, _, _}}|Left], MDG) -> - create_module_digraph(Left, digraph_add_edge(M1, M2, MDG)); -create_module_digraph([{_, _}|Left], MDG) -> - create_module_digraph(Left, MDG); -create_module_digraph([], MDG) -> - MDG. - --spec finalize(callgraph()) -> callgraph(). +-spec finalize(callgraph()) -> {[scc()], callgraph()}. finalize(#callgraph{digraph = DG} = CG) -> - CG#callgraph{postorder = digraph_finalize(DG)}. + {ActiveDG, Postorder} = condensation(DG), + {Postorder, CG#callgraph{active_digraph = ActiveDG}}. --spec reset_from_funs([mfa_or_funlbl()], callgraph()) -> callgraph(). +-spec reset_from_funs([mfa_or_funlbl()], callgraph()) -> {[scc()], callgraph()}. -reset_from_funs(Funs, #callgraph{digraph = DG} = CG) -> +reset_from_funs(Funs, #callgraph{digraph = DG, active_digraph = ADG} = CG) -> + active_digraph_delete(ADG), SubGraph = digraph_reaching_subgraph(Funs, DG), - Postorder = digraph_finalize(SubGraph), + {NewActiveDG, Postorder} = condensation(SubGraph), digraph_delete(SubGraph), - CG#callgraph{postorder = Postorder}. + {Postorder, CG#callgraph{active_digraph = NewActiveDG}}. --spec module_postorder_from_funs([mfa_or_funlbl()], callgraph()) -> [[module()]]. +-spec module_postorder_from_funs([mfa_or_funlbl()], callgraph()) -> + {[module()], callgraph()}. -module_postorder_from_funs(Funs, #callgraph{digraph = DG} = CG) -> +module_postorder_from_funs(Funs, #callgraph{digraph = DG, + active_digraph = ADG} = CG) -> + active_digraph_delete(ADG), SubGraph = digraph_reaching_subgraph(Funs, DG), - PO = module_postorder(CG#callgraph{digraph = SubGraph}), + {PO, Active} = module_postorder(CG#callgraph{digraph = SubGraph}), digraph_delete(SubGraph), - PO. - + {PO, CG#callgraph{active_digraph = Active}}. + +ets_lookup_dict(Key, Table) -> + try ets:lookup_element(Table, Key, 2) of + Val -> {ok, Val} + catch + _:_ -> error + end. + +ets_lookup_set(Key, Table) -> + ets:lookup(Table, Key) =/= []. + %%---------------------------------------------------------------------- %% Core code %%---------------------------------------------------------------------- @@ -330,36 +343,37 @@ module_postorder_from_funs(Funs, #callgraph{digraph = DG} = CG) -> %% The set of labels in the tree must be disjoint from the set of %% labels already occuring in the callgraph. --spec scan_core_tree(cerl:c_module(), callgraph()) -> callgraph(). +-spec scan_core_tree(cerl:c_module(), callgraph()) -> + {[mfa_or_funlbl()], [callgraph_edge()]}. -scan_core_tree(Tree, #callgraph{calls = OldCalls, - esc = OldEsc, - name_map = OldNameMap, - rec_var_map = OldRecVarMap, - rev_name_map = OldRevNameMap, - self_rec = OldSelfRec} = CG) -> +scan_core_tree(Tree, #callgraph{calls = ETSCalls, + esc = ETSEsc, + name_map = ETSNameMap, + rec_var_map = ETSRecVarMap, + rev_name_map = ETSRevNameMap, + self_rec = ETSSelfRec}) -> %% Build name map and recursion variable maps. - {NewNameMap, NewRevNameMap, NewRecVarMap} = - build_maps(Tree, OldRecVarMap, OldNameMap, OldRevNameMap), - + build_maps(Tree, ETSRecVarMap, ETSNameMap, ETSRevNameMap), + %% First find the module-local dependencies. {Deps0, EscapingFuns, Calls} = dialyzer_dep:analyze(Tree), - NewCalls = dict:merge(fun(_Key, Val, Val) -> Val end, OldCalls, Calls), - NewEsc = sets:union(sets:from_list(EscapingFuns), OldEsc), + true = ets:insert(ETSCalls, dict:to_list(Calls)), + true = ets:insert(ETSEsc, [{E} || E <- EscapingFuns]), + LabelEdges = get_edges_from_deps(Deps0), %% Find the self recursive functions. Named functions get both the %% key and their name for convenience. SelfRecs0 = lists:foldl(fun({Key, Key}, Acc) -> - case dict:find(Key, NewNameMap) of + case ets_lookup_dict(Key, ETSNameMap) of error -> [Key|Acc]; {ok, Name} -> [Key, Name|Acc] end; (_, Acc) -> Acc end, [], LabelEdges), - SelfRecs = sets:union(sets:from_list(SelfRecs0), OldSelfRec), + true = ets:insert(ETSSelfRec, [{S} || S <- SelfRecs0]), - NamedEdges1 = name_edges(LabelEdges, NewNameMap), + NamedEdges1 = name_edges(LabelEdges, ETSNameMap), %% We need to scan for inter-module calls since these are not tracked %% by dialyzer_dep. Note that the caller is always recorded as the @@ -378,27 +392,25 @@ scan_core_tree(Tree, #callgraph{calls = OldCalls, NewNamedEdges1 = [E || {From, To} = E <- NamedEdges1, From =/= top, To =/= top], NamedEdges3 = NewNamedEdges1 ++ NewNamedEdges2, - CG1 = add_edges(NamedEdges3, Names3, CG), - CG1#callgraph{calls = NewCalls, - esc = NewEsc, - name_map = NewNameMap, - rec_var_map = NewRecVarMap, - rev_name_map = NewRevNameMap, - self_rec = SelfRecs}. - -build_maps(Tree, RecVarMap, NameMap, RevNameMap) -> + {Names3, NamedEdges3}. + +build_maps(Tree, ETSRecVarMap, ETSNameMap, ETSRevNameMap) -> %% We only care about the named (top level) functions. The anonymous %% functions will be analysed together with their parents. Defs = cerl:module_defs(Tree), Mod = cerl:atom_val(cerl:module_name(Tree)), - lists:foldl(fun({Var, Function}, {AccNameMap, AccRevNameMap, AccRecVarMap}) -> - FunName = cerl:fname_id(Var), - Arity = cerl:fname_arity(Var), - MFA = {Mod, FunName, Arity}, - {dict:store(get_label(Function), MFA, AccNameMap), - dict:store(MFA, get_label(Function), AccRevNameMap), - dict:store(get_label(Var), MFA, AccRecVarMap)} - end, {NameMap, RevNameMap, RecVarMap}, Defs). + Fun = + fun({Var, Function}) -> + FunName = cerl:fname_id(Var), + Arity = cerl:fname_arity(Var), + MFA = {Mod, FunName, Arity}, + FunLabel = get_label(Function), + VarLabel = get_label(Var), + true = ets:insert(ETSNameMap, {FunLabel, MFA}), + true = ets:insert(ETSRevNameMap, {MFA, FunLabel}), + true = ets:insert(ETSRecVarMap, {VarLabel, MFA}) + end, + lists:foreach(Fun, Defs). get_edges_from_deps(Deps) -> %% Convert the dependencies as produced by dialyzer_dep to a list of @@ -411,22 +423,22 @@ get_edges_from_deps(Deps) -> end, [], Deps), lists:flatten(Edges). -name_edges(Edges, NameMap) -> +name_edges(Edges, ETSNameMap) -> %% If a label is present in the name map it is renamed. Otherwise %% keep the label as the identity. MapFun = fun(X) -> - case dict:find(X, NameMap) of + case ets_lookup_dict(X, ETSNameMap) of error -> X; {ok, MFA} -> MFA end end, - name_edges(Edges, MapFun, NameMap, []). + name_edges(Edges, MapFun, []). -name_edges([{From, To}|Left], MapFun, NameMap, Acc) -> +name_edges([{From, To}|Left], MapFun, Acc) -> NewFrom = MapFun(From), NewTo = MapFun(To), - name_edges(Left, MapFun, NameMap, [{NewFrom, NewTo}|Acc]); -name_edges([], _MapFun, _NameMap, Acc) -> + name_edges(Left, MapFun, [{NewFrom, NewTo}|Acc]); +name_edges([], _MapFun, Acc) -> Acc. scan_core_funs(Tree) -> @@ -478,9 +490,10 @@ get_label(T) -> %%---------------------------------------------------------------------- digraph_add_edges([{From, To}|Left], DG) -> - digraph_add_edges(Left, digraph_add_edge(From, To, DG)); -digraph_add_edges([], DG) -> - DG. + digraph_add_edge(From, To, DG), + digraph_add_edges(Left, DG); +digraph_add_edges([], _DG) -> + ok. digraph_add_edge(From, To, DG) -> case digraph:vertex(DG, From) of @@ -492,13 +505,13 @@ digraph_add_edge(From, To, DG) -> {To, _} -> ok end, digraph:add_edge(DG, {From, To}, From, To, []), - DG. + ok. digraph_confirm_vertices([MFA|Left], DG) -> digraph:add_vertex(DG, MFA, confirmed), digraph_confirm_vertices(Left, DG); -digraph_confirm_vertices([], DG) -> - DG. +digraph_confirm_vertices([], _DG) -> + ok. digraph_remove_external(DG) -> Vertices = digraph:vertices(DG), @@ -522,6 +535,12 @@ remove_unconfirmed([], DG, Unconfirmed) -> digraph_delete(DG) -> digraph:delete(DG). +active_digraph_delete({'d', DG}) -> + digraph:delete(DG); +active_digraph_delete({'e', Out, In}) -> + ets:delete(Out), + ets:delete(In). + digraph_edges(DG) -> digraph:edges(DG). @@ -534,75 +553,6 @@ digraph_in_neighbours(V, DG) -> List -> List end. -%% Pick all the independent nodes (leaves) from one module. Then try -%% to stay within the module until no more independent nodes can be -%% chosen. Then pick a new module and so on. -%% -%% Note that an SCC that ranges over more than one module is -%% considered to belong to all modules to make sure that we do not -%% lose any nodes. - -digraph_postorder(Digraph) -> - %% Remove all self-edges for SCCs. - Edges = [digraph:edge(Digraph, E) || E <- digraph:edges(Digraph)], - SelfEdges = [E || {E, V, V, _} <- Edges], - true = digraph:del_edges(Digraph, SelfEdges), - %% Determine the first module outside of the loop. - Leaves = digraph_leaves(Digraph), - case Leaves =:= [] of - true -> []; - false -> - {Module, Taken} = take_sccs_from_fresh_module(Leaves), - true = digraph:del_vertices(Digraph, Taken), - digraph_postorder(Digraph, Module, [Taken]) - end. - -digraph_postorder(Digraph, LastModule, Acc) -> - Leaves = digraph_leaves(Digraph), - case Leaves =:= [] of - true -> lists:append(lists:reverse(Acc)); - false -> - case [SCC || SCC <- Leaves, scc_belongs_to_module(SCC, LastModule)] of - [] -> - {NewModule, NewTaken} = take_sccs_from_fresh_module(Leaves), - true = digraph:del_vertices(Digraph, NewTaken), - digraph_postorder(Digraph, NewModule, [NewTaken|Acc]); - NewTaken -> - true = digraph:del_vertices(Digraph, NewTaken), - digraph_postorder(Digraph, LastModule, [NewTaken|Acc]) - end - end. - -digraph_leaves(Digraph) -> - [V || V <- digraph:vertices(Digraph), digraph:out_degree(Digraph, V) =:= 0]. - -take_sccs_from_fresh_module(Leaves) -> - NewModule = find_module(hd(Leaves)), - {NewModule, - [SCC || SCC <- Leaves, scc_belongs_to_module(SCC, NewModule)]}. - --spec scc_belongs_to_module(scc(), module()) -> boolean(). - -scc_belongs_to_module([Label|Left], Module) when is_integer(Label) -> - scc_belongs_to_module(Left, Module); -scc_belongs_to_module([{M, _, _}|Left], Module) -> - if M =:= Module -> true; - true -> scc_belongs_to_module(Left, Module) - end; -scc_belongs_to_module([], _Module) -> - false. - --spec find_module(scc()) -> module(). - -find_module([{M, _, _}|_]) -> M; -find_module([Label|Left]) when is_integer(Label) -> find_module(Left). - -digraph_finalize(DG) -> - DG1 = digraph_utils:condensation(DG), - Postorder = digraph_postorder(DG1), - digraph:delete(DG1), - Postorder. - digraph_reaching_subgraph(Funs, DG) -> Vertices = digraph_utils:reaching(Funs, DG), digraph_utils:subgraph(DG, Vertices). @@ -611,20 +561,71 @@ digraph_reaching_subgraph(Funs, DG) -> %% Races %%---------------------------------------------------------------------- +-spec renew_race_info(callgraph(), dict(), [label()], [string()]) -> + callgraph(). + +renew_race_info(#callgraph{race_data_server = RaceDataServer} = CG, + RaceCode, PublicTables, NamedTables) -> + ok = race_data_server_cast( + {renew_race_info, {RaceCode, PublicTables, NamedTables}}, + RaceDataServer), + CG. + +renew_race_info({RaceCode, PublicTables, NamedTables}, + #race_data_state{} = State) -> + State#race_data_state{race_code = RaceCode, + public_tables = PublicTables, + named_tables = NamedTables}. + +-spec renew_race_code(dialyzer_races:races(), callgraph()) -> callgraph(). + +renew_race_code(Races, #callgraph{race_data_server = RaceDataServer} = CG) -> + Fun = dialyzer_races:get_curr_fun(Races), + FunArgs = dialyzer_races:get_curr_fun_args(Races), + Code = lists:reverse(dialyzer_races:get_race_list(Races)), + ok = race_data_server_cast( + {renew_race_code, {Fun, FunArgs, Code}}, + RaceDataServer), + CG. + +renew_race_code_handler({Fun, FunArgs, Code}, + #race_data_state{race_code = RaceCode} = State) -> + State#race_data_state{race_code = dict:store(Fun, [FunArgs, Code], RaceCode)}. + +-spec renew_race_public_tables(label(), callgraph()) -> callgraph(). + +renew_race_public_tables(VarLabel, + #callgraph{race_data_server = RaceDataServer} = CG) -> + ok = + race_data_server_cast({renew_race_public_tables, VarLabel}, RaceDataServer), + CG. + +renew_race_public_tables_handler(VarLabel, + #race_data_state{public_tables = PT} + = State) -> + State#race_data_state{public_tables = ordsets:add_element(VarLabel, PT)}. + -spec cleanup(callgraph()) -> callgraph(). -cleanup(#callgraph{digraph = Digraph, - name_map = NameMap, - rev_name_map = RevNameMap, - public_tables = PublicTables, - named_tables = NamedTables, - race_code = RaceCode}) -> +cleanup(#callgraph{digraph = Digraph, + name_map = NameMap, + rev_name_map = RevNameMap, + race_data_server = RaceDataServer}) -> #callgraph{digraph = Digraph, - name_map = NameMap, - rev_name_map = RevNameMap, - public_tables = PublicTables, - named_tables = NamedTables, - race_code = RaceCode}. + name_map = NameMap, + rev_name_map = RevNameMap, + race_data_server = race_data_server_call(dup, RaceDataServer)}. + +-spec duplicate(callgraph()) -> callgraph(). + +duplicate(#callgraph{race_data_server = RaceDataServer} = Callgraph) -> + Callgraph#callgraph{ + race_data_server = race_data_server_call(dup, RaceDataServer)}. + +-spec dispose_race_server(callgraph()) -> ok. + +dispose_race_server(#callgraph{race_data_server = RaceDataServer}) -> + race_data_server_cast(stop, RaceDataServer). -spec get_digraph(callgraph()) -> digraph(). @@ -633,28 +634,34 @@ get_digraph(#callgraph{digraph = Digraph}) -> -spec get_named_tables(callgraph()) -> [string()]. -get_named_tables(#callgraph{named_tables = NamedTables}) -> - NamedTables. +get_named_tables(#callgraph{race_data_server = RaceDataServer}) -> + race_data_server_call(get_named_tables, RaceDataServer). -spec get_public_tables(callgraph()) -> [label()]. -get_public_tables(#callgraph{public_tables = PT}) -> - PT. +get_public_tables(#callgraph{race_data_server = RaceDataServer}) -> + race_data_server_call(get_public_tables, RaceDataServer). -spec get_race_code(callgraph()) -> dict(). -get_race_code(#callgraph{race_code = RaceCode}) -> - RaceCode. +get_race_code(#callgraph{race_data_server = RaceDataServer}) -> + race_data_server_call(get_race_code, RaceDataServer). -spec get_race_detection(callgraph()) -> boolean(). get_race_detection(#callgraph{race_detection = RD}) -> RD. +-spec get_behaviour_api_calls(callgraph()) -> [{mfa(), mfa()}]. + +get_behaviour_api_calls(#callgraph{race_data_server = RaceDataServer}) -> + race_data_server_call(get_behaviour_api_calls, RaceDataServer). + -spec race_code_new(callgraph()) -> callgraph(). -race_code_new(Callgraph) -> - Callgraph#callgraph{race_code = dict:new()}. +race_code_new(#callgraph{race_data_server = RaceDataServer} = CG) -> + ok = race_data_server_cast(race_code_new, RaceDataServer), + CG. -spec put_digraph(digraph(), callgraph()) -> callgraph(). @@ -663,8 +670,9 @@ put_digraph(Digraph, Callgraph) -> -spec put_race_code(dict(), callgraph()) -> callgraph(). -put_race_code(RaceCode, Callgraph) -> - Callgraph#callgraph{race_code = RaceCode}. +put_race_code(RaceCode, #callgraph{race_data_server = RaceDataServer} = CG) -> + ok = race_data_server_cast({put_race_code, RaceCode}, RaceDataServer), + CG. -spec put_race_detection(boolean(), callgraph()) -> callgraph(). @@ -673,13 +681,79 @@ put_race_detection(RaceDetection, Callgraph) -> -spec put_named_tables([string()], callgraph()) -> callgraph(). -put_named_tables(NamedTables, Callgraph) -> - Callgraph#callgraph{named_tables = NamedTables}. +put_named_tables(NamedTables, + #callgraph{race_data_server = RaceDataServer} = CG) -> + ok = race_data_server_cast({put_named_tables, NamedTables}, RaceDataServer), + CG. -spec put_public_tables([label()], callgraph()) -> callgraph(). -put_public_tables(PublicTables, Callgraph) -> - Callgraph#callgraph{public_tables = PublicTables}. +put_public_tables(PublicTables, + #callgraph{race_data_server = RaceDataServer} = CG) -> + ok = race_data_server_cast({put_public_tables, PublicTables}, RaceDataServer), + CG. + +-spec put_behaviour_api_calls([{mfa(), mfa()}], callgraph()) -> callgraph(). + +put_behaviour_api_calls(Calls, + #callgraph{race_data_server = RaceDataServer} = CG) -> + ok = race_data_server_cast({put_behaviour_api_calls, Calls}, RaceDataServer), + CG. + + +new_race_data_server() -> + spawn_link(fun() -> race_data_server_loop(#race_data_state{}) end). + +race_data_server_loop(State) -> + receive + {call, From, Ref, Query} -> + Reply = race_data_server_handle_call(Query, State), + From ! {Ref, Reply}, + race_data_server_loop(State); + {cast, stop} -> + ok; + {cast, Message} -> + NewState = race_data_server_handle_cast(Message, State), + race_data_server_loop(NewState) + end. + +race_data_server_call(Query, Server) -> + Ref = make_ref(), + Server ! {call, self(), Ref, Query}, + receive + {Ref, Reply} -> Reply + end. + +race_data_server_cast(Message, Server) -> + Server ! {cast, Message}, + ok. + +race_data_server_handle_cast(race_code_new, State) -> + State#race_data_state{race_code = dict:new()}; +race_data_server_handle_cast({Tag, Data}, State) -> + case Tag of + renew_race_info -> renew_race_info(Data, State); + renew_race_code -> renew_race_code_handler(Data, State); + renew_race_public_tables -> renew_race_public_tables_handler(Data, State); + put_race_code -> State#race_data_state{race_code = Data}; + put_public_tables -> State#race_data_state{public_tables = Data}; + put_named_tables -> State#race_data_state{named_tables = Data}; + put_behaviour_api_calls -> State#race_data_state{beh_api_calls = Data} + end. + +race_data_server_handle_call(Query, + #race_data_state{race_code = RaceCode, + public_tables = PublicTables, + named_tables = NamedTables, + beh_api_calls = BehApiCalls} + = State) -> + case Query of + dup -> spawn_link(fun() -> race_data_server_loop(State) end); + get_race_code -> RaceCode; + get_public_tables -> PublicTables; + get_named_tables -> NamedTables; + get_behaviour_api_calls -> BehApiCalls + end. %%============================================================================= %% Utilities for 'dot' @@ -695,7 +769,7 @@ to_dot(#callgraph{digraph = DG, esc = Esc} = CG, File) -> end end, Escaping = [{Fun(L), {color, red}} - || L <- sets:to_list(Esc), L =/= external], + || L <- [E || {E} <- ets:tab2list(Esc)], L =/= external], Vertices = digraph_edges(DG), hipe_dot:translate_list(Vertices, File, "CG", Escaping). @@ -708,14 +782,41 @@ to_ps(#callgraph{} = CG, File, Args) -> _ = os:cmd(Command), ok. -%------------------------------------------------------------------------------- - --spec put_behaviour_api_calls([{mfa(), mfa()}], callgraph()) -> callgraph(). - -put_behaviour_api_calls(Calls, Callgraph) -> - Callgraph#callgraph{beh_api_calls = Calls}. - --spec get_behaviour_api_calls(callgraph()) -> [{mfa(), mfa()}]. - -get_behaviour_api_calls(Callgraph) -> - Callgraph#callgraph.beh_api_calls. +condensation(G) -> + SCs = digraph_utils:strong_components(G), + V2I = ets:new(condensation_v2i, []), + I2C = ets:new(condensation_i2c, []), + I2I = ets:new(condensation_i2i, [bag]), + CFun = + fun(SC, N) -> + lists:foreach(fun(V) -> true = ets:insert(V2I, {V,N}) end, SC), + true = ets:insert(I2C, {N, SC}), + N + 1 + end, + lists:foldl(CFun, 1, SCs), + Fun1 = + fun({V1, V2}) -> + I1 = ets:lookup_element(V2I, V1, 2), + I2 = ets:lookup_element(V2I, V2, 2), + case I1 =:= I2 of + true -> true; + false -> ets:insert(I2I, {I1, I2}) + end + end, + lists:foreach(Fun1, digraph:edges(G)), + Fun3 = + fun({I1, I2}, {Out, In}) -> + SC1 = ets:lookup_element(I2C, I1, 2), + SC2 = ets:lookup_element(I2C, I2, 2), + {dict:append(SC1, SC2, Out), dict:append(SC2, SC1, In)} + end, + {OutDict, InDict} = ets:foldl(Fun3, {dict:new(), dict:new()}, I2I), + [OutETS, InETS] = + [ets:new(Name,[{read_concurrency, true}]) || + Name <- [callgraph_deps_out, callgraph_deps_in]], + ets:insert(OutETS, dict:to_list(OutDict)), + ets:insert(InETS, dict:to_list(InDict)), + ets:delete(V2I), + ets:delete(I2C), + ets:delete(I2I), + {{'e', OutETS, InETS}, SCs}. diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index 04a0db890f..5d253e77fa 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -188,6 +188,7 @@ plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) -> ok -> case Opts#options.output_plt of none -> ok; + InitPlt -> ok; OutPlt -> {ok, Binary} = file:read_file(InitPlt), ok = file:write_file(OutPlt, Binary) @@ -393,7 +394,8 @@ do_analysis(Files, Options, Plt, PltInfo) -> defines = Options#options.defines, include_dirs = Options#options.include_dirs, files = Files, - start_from = Options#options.from, + start_from = Options#options.from, + timing = Options#options.timing, plt = Plt, use_contracts = Options#options.use_contracts, callgraph_file = Options#options.callgraph_file}, diff --git a/lib/dialyzer/src/dialyzer_cl_parse.erl b/lib/dialyzer/src/dialyzer_cl_parse.erl index ff8fc39a5e..205b97ccf9 100644 --- a/lib/dialyzer/src/dialyzer_cl_parse.erl +++ b/lib/dialyzer/src/dialyzer_cl_parse.erl @@ -164,6 +164,13 @@ cl(["--src"|T]) -> cl(["--no_spec"|T]) -> put(dialyzer_options_use_contracts, false), cl(T); +cl(["--statistics"|T]) -> + put(dialyzer_timing, true), + cl(T); +cl(["--resources"|T]) -> + put(dialyzer_options_report_mode, quiet), + put(dialyzer_timing, debug), + cl(T); cl(["-v"|_]) -> io:format("Dialyzer version "++?VSN++"\n"), erlang:halt(?RET_NOTHING_SUSPICIOUS); @@ -250,6 +257,7 @@ init() -> put(dialyzer_output_format, formatted), put(dialyzer_filename_opt, basename), put(dialyzer_options_check_plt, DefaultOpts#options.check_plt), + put(dialyzer_timing, DefaultOpts#options.timing), ok. append_defines([Def, Val]) -> @@ -290,6 +298,7 @@ cl_options() -> {filename_opt, get(dialyzer_filename_opt)}, {analysis_type, get(dialyzer_options_analysis_type)}, {get_warnings, get(dialyzer_options_get_warnings)}, + {timing, get(dialyzer_timing)}, {callgraph_file, get(dialyzer_callgraph_file)} |common_options()]. @@ -351,7 +360,7 @@ help_message() -> [--apps applications] [-o outfile] [--build_plt] [--add_to_plt] [--remove_from_plt] [--check_plt] [--no_check_plt] [--plt_info] [--get_warnings] - [--no_native] [--fullpath] + [--no_native] [--fullpath] [--statistics] Options: files_or_dirs (for backwards compatibility also as: -c files_or_dirs) Use Dialyzer from the command line to detect defects in the @@ -418,6 +427,9 @@ Options: Make Dialyzer a bit more quiet. --verbose Make Dialyzer a bit more verbose. + --statistics + Prints information about the progress of execution (analysis phases, + time spent in each and size of the relative input). --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. diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl index f1e87affbd..9989118671 100644 --- a/lib/dialyzer/src/dialyzer_codeserver.erl +++ b/lib/dialyzer/src/dialyzer_codeserver.erl @@ -52,9 +52,7 @@ new/0, set_next_core_label/2, set_temp_records/2, - store_records/3, store_temp_records/3, - store_contracts/3, store_temp_contracts/4]). -export_type([codeserver/0]). @@ -63,85 +61,159 @@ %%-------------------------------------------------------------------- --record(codeserver, {table_pid :: pid(), - exported_types = sets:new() :: set(), % set(mfa()) - temp_exported_types = sets:new() :: set(), % set(mfa()) - exports = sets:new() :: set(), % set(mfa()) - next_core_label = 0 :: label(), - records = dict:new() :: dict(), - temp_records = dict:new() :: dict(), - contracts = dict:new() :: dict(), - callbacks = dict:new() :: dict(), - temp_contracts = dict:new() :: dict(), - temp_callbacks = dict:new() :: dict() +-type dict_ets() :: ets:tid(). +-type set_ets() :: ets:tid(). + +-record(codeserver, {next_core_label = 0 :: label(), + code :: dict_ets(), + exported_types :: set_ets(), % set(mfa()) + records :: dict_ets(), + contracts :: dict_ets(), + callbacks :: dict_ets(), + exports :: 'clean' | set_ets(), % set(mfa()) + temp_exported_types :: 'clean' | set_ets(), % set(mfa()) + temp_records :: 'clean' | dict_ets(), + temp_contracts :: 'clean' | dict_ets(), + temp_callbacks :: 'clean' | dict_ets() }). -opaque codeserver() :: #codeserver{}. %%-------------------------------------------------------------------- +ets_dict_find(Key, Table) -> + try ets:lookup_element(Table, Key, 2) of + Val -> {ok, Val} + catch + _:_ -> error + end. + +ets_dict_store(Key, Element, Table) -> + true = ets:insert(Table, {Key, Element}), + Table. + +ets_dict_store_dict(Dict, Table) -> + true = ets:insert(Table, dict:to_list(Dict)). + +ets_dict_to_dict(Table) -> + Fold = fun({Key,Value}, Dict) -> dict:store(Key, Value, Dict) end, + ets:foldl(Fold, dict:new(), Table). + +ets_set_is_element(Key, Table) -> + case ets:lookup(Table, Key) of + [] -> false; + _ -> true + end. + +ets_set_insert_set(Set, Table) -> + ets_set_insert_list(sets:to_list(Set), Table). + +ets_set_insert_list(List, Table) -> + true = ets:insert(Table, [{E} || E <- List]). + +ets_set_to_set(Table) -> + Fold = fun({E}, Set) -> sets:add_element(E, Set) end, + ets:foldl(Fold, sets:new(), Table). + +ets_read_concurrent_table(Name) -> + ets:new(Name,[{read_concurrency, true}]). + +%%-------------------------------------------------------------------- + -spec new() -> codeserver(). new() -> - #codeserver{table_pid = table__new()}. + CodeOptions = [compressed, public, {read_concurrency, true}], + Code = ets:new(dialyzer_codeserver_code, CodeOptions), + TempOptions = [public, {write_concurrency, true}], + [Exports, TempExportedTypes, TempRecords, TempContracts, TempCallbacks] = + [ets:new(Name, TempOptions) || + Name <- + [dialyzer_codeserver_exports, dialyzer_codeserver_temp_exported_types, + dialyzer_codeserver_temp_records, dialyzer_codeserver_temp_contracts, + dialyzer_codeserver_temp_callbacks]], + #codeserver{code = Code, + exports = Exports, + temp_exported_types = TempExportedTypes, + temp_records = TempRecords, + temp_contracts = TempContracts, + temp_callbacks = TempCallbacks}. -spec delete(codeserver()) -> 'ok'. -delete(#codeserver{table_pid = TablePid}) -> - table__delete(TablePid). +delete(#codeserver{code = Code, exported_types = ExportedTypes, + records = Records, contracts = Contracts, + callbacks = Callbacks}) -> + lists:foreach(fun ets:delete/1, + [Code, ExportedTypes, Records, Contracts, Callbacks]). -spec insert(atom(), cerl:c_module(), codeserver()) -> codeserver(). insert(Mod, ModCode, CS) -> - NewTablePid = table__insert(CS#codeserver.table_pid, Mod, ModCode), - CS#codeserver{table_pid = NewTablePid}. + Name = cerl:module_name(ModCode), + Exports = cerl:module_exports(ModCode), + Attrs = cerl:module_attrs(ModCode), + Defs = cerl:module_defs(ModCode), + As = cerl:get_ann(ModCode), + Funs = + [{{Mod, cerl:fname_id(Var), cerl:fname_arity(Var)}, + Val} || Val = {Var, _Fun} <- Defs], + Keys = [Key || {Key, _Value} <- Funs], + ModEntry = {Mod, {Name, Exports, Attrs, Keys, As}}, + true = ets:insert(CS#codeserver.code, [ModEntry|Funs]), + CS. + +-spec get_temp_exported_types(codeserver()) -> set(). + +get_temp_exported_types(#codeserver{temp_exported_types = TempExpTypes}) -> + ets_set_to_set(TempExpTypes). -spec insert_temp_exported_types(set(), codeserver()) -> codeserver(). insert_temp_exported_types(Set, CS) -> - CS#codeserver{temp_exported_types = Set}. + TempExportedTypes = CS#codeserver.temp_exported_types, + true = ets_set_insert_set(Set, TempExportedTypes), + CS. -spec insert_exports([mfa()], codeserver()) -> codeserver(). insert_exports(List, #codeserver{exports = Exports} = CS) -> - Set = sets:from_list(List), - NewExports = sets:union(Exports, Set), - CS#codeserver{exports = NewExports}. + true = ets_set_insert_list(List, Exports), + CS. -spec is_exported(mfa(), codeserver()) -> boolean(). is_exported(MFA, #codeserver{exports = Exports}) -> - sets:is_element(MFA, Exports). + ets_set_is_element(MFA, Exports). -spec get_exported_types(codeserver()) -> set(). % set(mfa()) get_exported_types(#codeserver{exported_types = ExpTypes}) -> - ExpTypes. - --spec get_temp_exported_types(codeserver()) -> set(). - -get_temp_exported_types(#codeserver{temp_exported_types = TempExpTypes}) -> - TempExpTypes. + ets_set_to_set(ExpTypes). -spec get_exports(codeserver()) -> set(). % set(mfa()) get_exports(#codeserver{exports = Exports}) -> - Exports. + ets_set_to_set(Exports). -spec finalize_exported_types(set(), codeserver()) -> codeserver(). finalize_exported_types(Set, CS) -> - CS#codeserver{exported_types = Set, temp_exported_types = sets:new()}. + ExportedTypes = ets_read_concurrent_table(dialyzer_codeserver_exported_types), + true = ets_set_insert_set(Set, ExportedTypes), + TempExpTypes = CS#codeserver.temp_exported_types, + true = ets:delete(TempExpTypes), + CS#codeserver{exported_types = ExportedTypes, temp_exported_types = clean}. -spec lookup_mod_code(atom(), codeserver()) -> cerl:c_module(). lookup_mod_code(Mod, CS) when is_atom(Mod) -> - table__lookup(CS#codeserver.table_pid, Mod). + table__lookup(CS#codeserver.code, Mod). -spec lookup_mfa_code(mfa(), codeserver()) -> {cerl:c_var(), cerl:c_fun()}. lookup_mfa_code({_M, _F, _A} = MFA, CS) -> - table__lookup(CS#codeserver.table_pid, MFA). + table__lookup(CS#codeserver.code, MFA). -spec get_next_core_label(codeserver()) -> label(). @@ -153,20 +225,10 @@ get_next_core_label(#codeserver{next_core_label = NCL}) -> set_next_core_label(NCL, CS) -> CS#codeserver{next_core_label = NCL}. --spec store_records(atom(), dict(), codeserver()) -> codeserver(). - -store_records(Mod, Dict, #codeserver{records = RecDict} = CS) - when is_atom(Mod) -> - case dict:size(Dict) =:= 0 of - true -> CS; - false -> CS#codeserver{records = dict:store(Mod, Dict, RecDict)} - end. - -spec lookup_mod_records(atom(), codeserver()) -> dict(). -lookup_mod_records(Mod, #codeserver{records = RecDict}) - when is_atom(Mod) -> - case dict:find(Mod, RecDict) of +lookup_mod_records(Mod, #codeserver{records = RecDict}) when is_atom(Mod) -> + case ets_dict_find(Mod, RecDict) of error -> dict:new(); {ok, Dict} -> Dict end. @@ -174,7 +236,7 @@ lookup_mod_records(Mod, #codeserver{records = RecDict}) -spec get_records(codeserver()) -> dict(). get_records(#codeserver{records = RecDict}) -> - RecDict. + ets_dict_to_dict(RecDict). -spec store_temp_records(atom(), dict(), codeserver()) -> codeserver(). @@ -182,59 +244,58 @@ store_temp_records(Mod, Dict, #codeserver{temp_records = TempRecDict} = CS) when is_atom(Mod) -> case dict:size(Dict) =:= 0 of true -> CS; - false -> CS#codeserver{temp_records = dict:store(Mod, Dict, TempRecDict)} + false -> CS#codeserver{temp_records = ets_dict_store(Mod, Dict, TempRecDict)} end. -spec get_temp_records(codeserver()) -> dict(). get_temp_records(#codeserver{temp_records = TempRecDict}) -> - TempRecDict. + ets_dict_to_dict(TempRecDict). -spec set_temp_records(dict(), codeserver()) -> codeserver(). set_temp_records(Dict, CS) -> - CS#codeserver{temp_records = Dict}. + true = ets:delete(CS#codeserver.temp_records), + TempRecords = ets:new(dialyzer_codeserver_temp_records,[]), + true = ets_dict_store_dict(Dict, TempRecords), + CS#codeserver{temp_records = TempRecords}. -spec finalize_records(dict(), codeserver()) -> codeserver(). finalize_records(Dict, CS) -> - CS#codeserver{records = Dict, temp_records = dict:new()}. - --spec store_contracts(atom(), dict(), codeserver()) -> codeserver(). - -store_contracts(Mod, Dict, #codeserver{contracts = C} = CS) when is_atom(Mod) -> - case dict:size(Dict) =:= 0 of - true -> CS; - false -> CS#codeserver{contracts = dict:store(Mod, Dict, C)} - end. + true = ets:delete(CS#codeserver.temp_records), + Records = ets_read_concurrent_table(dialyzer_codeserver_records), + true = ets_dict_store_dict(Dict, Records), + CS#codeserver{records = Records, temp_records = clean}. -spec lookup_mod_contracts(atom(), codeserver()) -> dict(). lookup_mod_contracts(Mod, #codeserver{contracts = ContDict}) when is_atom(Mod) -> - case dict:find(Mod, ContDict) of + case ets_dict_find(Mod, ContDict) of error -> dict:new(); - {ok, Dict} -> Dict + {ok, Keys} -> + dict:from_list([get_contract_pair(Key, ContDict)|| Key <- Keys]) end. +get_contract_pair(Key, ContDict) -> + {Key, ets:lookup_element(ContDict, Key, 2)}. + -spec lookup_mfa_contract(mfa(), codeserver()) -> 'error' | {'ok', dialyzer_contracts:file_contract()}. -lookup_mfa_contract({M,_F,_A} = MFA, #codeserver{contracts = ContDict}) -> - case dict:find(M, ContDict) of - error -> error; - {ok, Dict} -> dict:find(MFA, Dict) - end. +lookup_mfa_contract(MFA, #codeserver{contracts = ContDict}) -> + ets_dict_find(MFA, ContDict). -spec get_contracts(codeserver()) -> dict(). get_contracts(#codeserver{contracts = ContDict}) -> - ContDict. + ets_dict_to_dict(ContDict). --spec get_callbacks(codeserver()) -> dict(). +-spec get_callbacks(codeserver()) -> list(). get_callbacks(#codeserver{callbacks = CallbDict}) -> - CallbDict. + ets:tab2list(CallbDict). -spec store_temp_contracts(atom(), dict(), dict(), codeserver()) -> codeserver(). @@ -246,91 +307,44 @@ store_temp_contracts(Mod, SpecDict, CallbackDict, CS1 = case dict:size(SpecDict) =:= 0 of true -> CS; - false -> CS#codeserver{temp_contracts = dict:store(Mod, SpecDict, Cn)} + false -> + CS#codeserver{temp_contracts = ets_dict_store(Mod, SpecDict, Cn)} end, case dict:size(CallbackDict) =:= 0 of true -> CS1; - false -> CS1#codeserver{temp_callbacks = dict:store(Mod, CallbackDict, Cb)} + false -> + CS1#codeserver{temp_callbacks = ets_dict_store(Mod, CallbackDict, Cb)} end. -spec get_temp_contracts(codeserver()) -> {dict(), dict()}. get_temp_contracts(#codeserver{temp_contracts = TempContDict, temp_callbacks = TempCallDict}) -> - {TempContDict, TempCallDict}. + {ets_dict_to_dict(TempContDict), ets_dict_to_dict(TempCallDict)}. -spec finalize_contracts(dict(), dict(), codeserver()) -> codeserver(). -finalize_contracts(CnDict, CbDict, CS) -> - CS#codeserver{contracts = CnDict, - callbacks = CbDict, - temp_contracts = dict:new(), - temp_callbacks = dict:new() - }. - -table__new() -> - spawn_link(fun() -> table__loop(none, dict:new()) end). - -table__delete(TablePid) -> - TablePid ! stop, - ok. - -table__lookup(TablePid, Key) -> - TablePid ! {self(), lookup, Key}, - receive - {TablePid, Key, Ans} -> Ans - end. - -table__insert(TablePid, Key, Val) -> - TablePid ! {insert, [{Key, term_to_binary(Val, [compressed])}]}, - TablePid. - -table__loop(Cached, Map) -> - receive - stop -> ok; - {Pid, lookup, {M, F, A} = MFA} -> - {NewCached, Ans} = - case Cached of - {M, Tree} -> - Val = find_fun(F, A, Tree), - {Cached, Val}; - _ -> - Tree = fetch_and_expand(M, Map), - Val = find_fun(F, A, Tree), - {{M, Tree}, Val} - end, - Pid ! {self(), MFA, Ans}, - table__loop(NewCached, Map); - {Pid, lookup, Mod} when is_atom(Mod) -> - Ans = case Cached of - {Mod, Tree} -> Tree; - _ -> fetch_and_expand(Mod, Map) - end, - Pid ! {self(), Mod, Ans}, - table__loop({Mod, Ans}, Map); - {insert, List} -> - NewMap = lists:foldl(fun({Key, Val}, AccMap) -> - dict:store(Key, Val, AccMap) - end, Map, List), - table__loop(Cached, NewMap) - end. - -fetch_and_expand(Mod, Map) -> - try - Bin = dict:fetch(Mod, Map), - binary_to_term(Bin) - catch - _:_ -> - S = atom_to_list(Mod), - Msg = "found no module named '" ++ S ++ "' in the analyzed files", - exit({error, Msg}) - end. - -find_fun(F, A, Tree) -> - Pred = - fun({Var, _Fun}) -> - (cerl:fname_id(Var) =/= F) orelse - (cerl:fname_arity(Var) =/= A) - end, - [Val|_] = lists:dropwhile(Pred, cerl:module_defs(Tree)), - Val. +finalize_contracts(SpecDict, CallbackDict, CS) -> + Contracts = ets_read_concurrent_table(dialyzer_codeserver_contracts), + Callbacks = ets_read_concurrent_table(dialyzer_codeserver_callbacks), + Contracts = dict:fold(fun decompose_spec_dict/3, Contracts, SpecDict), + Callbacks = dict:fold(fun decompose_cb_dict/3, Callbacks, CallbackDict), + CS#codeserver{contracts = Contracts, callbacks = Callbacks, + temp_contracts = clean, temp_callbacks = clean}. + +decompose_spec_dict(Mod, Dict, Table) -> + Keys = dict:fetch_keys(Dict), + true = ets:insert(Table, dict:to_list(Dict)), + true = ets:insert(Table, {Mod, Keys}), + Table. + +decompose_cb_dict(_Mod, Dict, Table) -> + true = ets:insert(Table, dict:to_list(Dict)), + Table. + +table__lookup(TablePid, M) when is_atom(M) -> + {Name, Exports, Attrs, Keys, As} = ets:lookup_element(TablePid, M, 2), + Defs = [table__lookup(TablePid, Key) || Key <- Keys], + cerl:ann_c_module(As, Name, Exports, Attrs, Defs); +table__lookup(TablePid, MFA) -> + ets:lookup_element(TablePid, MFA, 2). diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 2b78b736ab..76f23d00b9 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -344,7 +344,7 @@ insert_constraints([{subtype, Type1, Type2}|Left], Dict) -> false -> %% A lot of things should change to add supertypes throw({error, io_lib:format("First argument of is_subtype constraint " - "must be a type variable\n", [])}) + "must be a type variable: ~p\n", [Type1])}) end; insert_constraints([], Dict) -> Dict. @@ -385,9 +385,8 @@ contract_from_form([{type, _L1, bounded_fun, RecDict, FileLine, TypeAcc, FormAcc) -> TypeFun = fun(ExpTypes, AllRecords) -> - Constr1 = [constraint_from_form(C, RecDict, ExpTypes, AllRecords) - || C <- Constr], - VarDict = insert_constraints(Constr1, dict:new()), + {Constr1, VarDict} = + process_constraints(Constr, RecDict, ExpTypes, AllRecords), Type = erl_types:t_from_form(Form, RecDict, VarDict), NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords), {NewType, Constr1} @@ -398,18 +397,66 @@ contract_from_form([{type, _L1, bounded_fun, contract_from_form([], _RecDict, _FileLine, TypeAcc, FormAcc) -> {lists:reverse(TypeAcc), lists:reverse(FormAcc)}. -constraint_from_form({type, _, constraint, [{atom, _, is_subtype}, - [Type1, Type2]]}, RecDict, - ExpTypes, AllRecords) -> - T1 = erl_types:t_from_form(Type1, RecDict), - T2 = erl_types:t_from_form(Type2, RecDict), - T3 = erl_types:t_solve_remote(T1, ExpTypes, AllRecords), - T4 = erl_types:t_solve_remote(T2, ExpTypes, AllRecords), - {subtype, T3, T4}; -constraint_from_form({type, _, constraint, [{atom,_,Name}, List]}, _RecDict, - _ExpTypes, _AllRecords) -> - N = length(List), - throw({error, io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])}). +process_constraints(Constrs, RecDict, ExpTypes, AllRecords) -> + Init = initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords), + constraints_fixpoint(Init, RecDict, ExpTypes, AllRecords). + +initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords) -> + initialize_constraints(Constrs, RecDict, ExpTypes, AllRecords, []). + +initialize_constraints([], _RecDict, _ExpTypes, _AllRecords, Acc) -> + Acc; +initialize_constraints([Constr|Rest], RecDict, ExpTypes, AllRecords, Acc) -> + case Constr of + {type, _, constraint, [{atom, _, is_subtype}, [Type1, Type2]]} -> + T1 = final_form(Type1, RecDict, ExpTypes, AllRecords, dict:new()), + Entry = {T1, Type2}, + initialize_constraints(Rest, RecDict, ExpTypes, AllRecords, [Entry|Acc]); + {type, _, constraint, [{atom,_,Name}, List]} -> + N = length(List), + throw({error, + io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])}) + end. + +constraints_fixpoint(Constrs, RecDict, ExpTypes, AllRecords) -> + VarDict = + constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, dict:new()), + constraints_fixpoint(VarDict, Constrs, RecDict, ExpTypes, AllRecords). + +constraints_fixpoint(OldVarDict, Constrs, RecDict, ExpTypes, AllRecords) -> + NewVarDict = + constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, OldVarDict), + case NewVarDict of + OldVarDict -> + DictFold = + fun(Key, Value, Acc) -> + [{subtype, erl_types:t_var(Key), Value}|Acc] + end, + FinalConstrs = dict:fold(DictFold, [], NewVarDict), + {FinalConstrs, NewVarDict}; + _Other -> + constraints_fixpoint(NewVarDict, Constrs, RecDict, ExpTypes, AllRecords) + end. + +-define(TYPE_LIMIT, 4). + +final_form(Form, RecDict, ExpTypes, AllRecords, VarDict) -> + T1 = erl_types:t_from_form(Form, RecDict, VarDict), + T2 = erl_types:t_solve_remote(T1, ExpTypes, AllRecords), + erl_types:t_limit(T2, ?TYPE_LIMIT). + +constraints_to_dict(Constrs, RecDict, ExpTypes, AllRecords, VarDict) -> + Subtypes = + constraints_to_subs(Constrs, RecDict, ExpTypes, AllRecords, VarDict, []), + insert_constraints(Subtypes, dict:new()). + +constraints_to_subs([], _RecDict, _ExpTypes, _AllRecords, _VarDict, Acc) -> + Acc; +constraints_to_subs([C|Rest], RecDict, ExpTypes, AllRecords, VarDict, Acc) -> + {T1, Form2} = C, + T2 = final_form(Form2, RecDict, ExpTypes, AllRecords, VarDict), + NewAcc = [{subtype, T1, T2}|Acc], + constraints_to_subs(Rest, RecDict, ExpTypes, AllRecords, VarDict, NewAcc). %% Gets the most general domain of a list of domains of all %% the overloaded contracts diff --git a/lib/dialyzer/src/dialyzer_coordinator.erl b/lib/dialyzer/src/dialyzer_coordinator.erl new file mode 100644 index 0000000000..5719132215 --- /dev/null +++ b/lib/dialyzer/src/dialyzer_coordinator.erl @@ -0,0 +1,250 @@ +%% -*- erlang-indent-level: 2 -*- +%%----------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-2011. 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 : dialyzer_coordinator.erl +%%% Authors : Stavros Aronis <[email protected]> +%%%------------------------------------------------------------------- + +-module(dialyzer_coordinator). + +%%% Export for dialyzer main process +-export([parallel_job/4]). + +%%% Exports for all possible workers +-export([wait_activation/0, job_done/3]). + +%%% Exports for the typesig and dataflow analysis workers +-export([sccs_to_pids/2, request_activation/1]). + +%%% Exports for the compilation workers +-export([get_next_label/2]). + +-export_type([coordinator/0, mode/0, init_data/0, result/0]). + +%%-------------------------------------------------------------------- + +-type collector() :: pid(). +-type regulator() :: pid(). +-type scc_to_pid() :: ets:tid() | 'unused'. + +-type coordinator() :: {collector(), regulator(), scc_to_pid()}. %%opaque +-type timing() :: dialyzer_timing:timing_server(). + +-type scc() :: [mfa_or_funlbl()]. +-type mode() :: 'typesig' | 'dataflow' | 'compile' | 'warnings'. + +-type compile_jobs() :: [file:filename()]. +-type typesig_jobs() :: [scc()]. +-type dataflow_jobs() :: [module()]. +-type warnings_jobs() :: [module()]. + +-type compile_init_data() :: dialyzer_analysis_callgraph:compile_init_data(). +-type typesig_init_data() :: dialyzer_succ_typings:typesig_init_data(). +-type dataflow_init_data() :: dialyzer_succ_typings:dataflow_init_data(). +-type warnings_init_data() :: dialyzer_succ_typings:warnings_init_data(). + +-type compile_result() :: dialyzer_analysis_callgraph:compile_result(). +-type typesig_result() :: [mfa_or_funlbl()]. +-type dataflow_result() :: [mfa_or_funlbl()]. +-type warnings_result() :: [dial_warning()]. + +-type init_data() :: compile_init_data() | typesig_init_data() | + dataflow_init_data() | warnings_init_data(). + +-type result() :: compile_result() | typesig_result() | + dataflow_result() | warnings_result(). + +-type job() :: scc() | module() | file:filename(). +-type job_result() :: dialyzer_analysis_callgraph:one_file_result() | + typesig_result() | dataflow_result() | warnings_result(). + +-record(state, {mode :: mode(), + active = 0 :: integer(), + result :: result(), + next_label = 0 :: integer(), + init_data :: init_data(), + regulator :: regulator(), + scc_to_pid :: scc_to_pid() + }). + +-include("dialyzer.hrl"). + +%%-------------------------------------------------------------------- + +-spec parallel_job('compile', compile_jobs(), compile_init_data(), timing()) -> + {compile_result(), integer()}; + ('typesig', typesig_jobs(), typesig_init_data(), timing()) -> + typesig_result(); + ('dataflow', dataflow_jobs(), dataflow_init_data(), + timing()) -> dataflow_result(); + ('warnings', warnings_jobs(), warnings_init_data(), + timing()) -> warnings_result(). + +parallel_job(Mode, Jobs, InitData, Timing) -> + State = spawn_jobs(Mode, Jobs, InitData, Timing), + collect_result(State). + +spawn_jobs(Mode, Jobs, InitData, Timing) -> + Collector = self(), + Regulator = spawn_regulator(), + TypesigOrDataflow = (Mode =:= 'typesig') orelse (Mode =:= 'dataflow'), + SCCtoPID = + case TypesigOrDataflow of + true -> ets:new(scc_to_pid, [{read_concurrency, true}]); + false -> unused + end, + Coordinator = {Collector, Regulator, SCCtoPID}, + Fold = + fun(Job, Count) -> + Pid = dialyzer_worker:launch(Mode, Job, InitData, Coordinator), + case TypesigOrDataflow of + true -> true = ets:insert(SCCtoPID, {Job, Pid}); + false -> request_activation(Regulator, Pid) + end, + Count + 1 + end, + JobCount = lists:foldl(Fold, 0, Jobs), + Unit = + case Mode of + 'typesig' -> "SCCs"; + _ -> "modules" + end, + dialyzer_timing:send_size_info(Timing, JobCount, Unit), + InitResult = + case Mode of + 'compile' -> dialyzer_analysis_callgraph:compile_init_result(); + _ -> [] + end, + #state{mode = Mode, active = JobCount, result = InitResult, next_label = 0, + init_data = InitData, regulator = Regulator, scc_to_pid = SCCtoPID}. + +collect_result(#state{mode = Mode, active = Active, result = Result, + next_label = NextLabel, init_data = InitData, + regulator = Regulator, scc_to_pid = SCCtoPID} = State) -> + receive + {next_label_request, Estimation, Pid} -> + Pid ! {next_label_reply, NextLabel}, + collect_result(State#state{next_label = NextLabel + Estimation}); + {done, Job, Data} -> + NewResult = update_result(Mode, InitData, Job, Data, Result), + case Active of + 1 -> + kill_regulator(Regulator), + case Mode of + 'compile' -> + {NewResult, NextLabel}; + X when X =:= 'typesig'; X =:= 'dataflow' -> + ets:delete(SCCtoPID), + NewResult; + 'warnings' -> + NewResult + end; + N -> + collect_result(State#state{result = NewResult, active = N - 1}) + end + end. + +update_result(Mode, InitData, Job, Data, Result) -> + case Mode of + 'compile' -> + dialyzer_analysis_callgraph:add_to_result(Job, Data, Result, + InitData); + X when X =:= 'typesig'; X =:= 'dataflow' -> + dialyzer_succ_typings:lookup_names(Data, InitData) ++ Result; + 'warnings' -> + Data ++ Result + end. + +-spec sccs_to_pids([scc() | module()], coordinator()) -> + {[dialyzer_worker:worker()], [scc() | module()]}. + +sccs_to_pids(SCCs, {_Collector, _Regulator, SCCtoPID}) -> + Fold = + fun(SCC, {Pids, Unknown}) -> + try ets:lookup_element(SCCtoPID, SCC, 2) of + Result -> {[Result|Pids], Unknown} + catch + _:_ -> {Pids, [SCC|Unknown]} + end + end, + lists:foldl(Fold, {[], []}, SCCs). + +-spec job_done(job(), job_result(), coordinator()) -> ok. + +job_done(Job, Result, {Collector, Regulator, _SCCtoPID}) -> + Regulator ! done, + Collector ! {done, Job, Result}, + ok. + +-spec get_next_label(integer(), coordinator()) -> integer(). + +get_next_label(EstimatedSize, {Collector, _Regulator, _SCCtoPID}) -> + Collector ! {next_label_request, EstimatedSize, self()}, + receive + {next_label_reply, NextLabel} -> NextLabel + end. + +-spec wait_activation() -> ok. + +wait_activation() -> + receive activate -> ok end. + +activate_pid(Pid) -> + Pid ! activate. + +-spec request_activation(coordinator()) -> ok. + +request_activation({_Collector, Regulator, _SCCtoPID}) -> + Regulator ! {req, self()}, + wait_activation(). + +request_activation(Regulator, Pid) -> + Regulator ! {req, Pid}. + +spawn_regulator() -> + InitTickets = dialyzer_utils:parallelism(), + spawn_link(fun() -> regulator_loop(InitTickets, queue:new()) end). + +regulator_loop(Tickets, Queue) -> + receive + {req, Pid} -> + case Tickets of + 0 -> + regulator_loop(0, queue:in(Pid, Queue)); + N -> + activate_pid(Pid), + regulator_loop(N-1, Queue) + end; + done -> + {Waiting, NewQueue} = queue:out(Queue), + NewTickets = + case Waiting of + empty -> Tickets + 1; + {value, Pid} -> + activate_pid(Pid), + Tickets + end, + regulator_loop(NewTickets, NewQueue); + stop -> ok + end. + +kill_regulator(Regulator) -> + Regulator ! stop. diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index bd375b04fa..cb376daf68 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -32,13 +32,11 @@ %% Data structure interfaces. -export([state__add_warning/2, state__cleanup/1, + state__duplicate/1, dispose_state/1, state__get_callgraph/1, state__get_races/1, state__get_records/1, state__put_callgraph/2, state__put_races/2, state__records_only/1]). -%% Debug and test interfaces. --export([get_top_level_signatures/2, pp/1]). - -export_type([state/0]). -include("dialyzer.hrl"). @@ -67,7 +65,7 @@ %%-define(DEBUG, true). %%-define(DEBUG_PP, true). -%%-define(DOT, true). +%%-define(DEBUG_TIME, true). -ifdef(DEBUG). -import(erl_types, [t_to_string/1]). @@ -111,7 +109,7 @@ -spec get_warnings(cerl:c_module(), dialyzer_plt:plt(), dialyzer_callgraph:callgraph(), dict(), set()) -> - {[dial_warning()], dict(), dict(), [label()], [string()]}. + {[dial_warning()], dict()}. get_warnings(Tree, Plt, Callgraph, Records, NoWarnUnused) -> State1 = analyze_module(Tree, Plt, Callgraph, Records, true), @@ -119,145 +117,14 @@ get_warnings(Tree, Plt, Callgraph, Records, NoWarnUnused) -> State3 = state__renew_warnings(state__get_warnings(State2, NoWarnUnused), State2), State4 = state__get_race_warnings(State3), - Callgraph1 = State2#state.callgraph, - {State4#state.warnings, state__all_fun_types(State4), - dialyzer_callgraph:get_race_code(Callgraph1), - dialyzer_callgraph:get_public_tables(Callgraph1), - dialyzer_callgraph:get_named_tables(Callgraph1)}. + {State4#state.warnings, state__all_fun_types(State4)}. -spec get_fun_types(cerl:c_module(), dialyzer_plt:plt(), - dialyzer_callgraph:callgraph(), dict()) -> - {dict(), dict(), [label()], [string()]}. + dialyzer_callgraph:callgraph(), dict()) -> dict(). get_fun_types(Tree, Plt, Callgraph, Records) -> State = analyze_module(Tree, Plt, Callgraph, Records, false), - Callgraph1 = State#state.callgraph, - {state__all_fun_types(State), - dialyzer_callgraph:get_race_code(Callgraph1), - dialyzer_callgraph:get_public_tables(Callgraph1), - dialyzer_callgraph:get_named_tables(Callgraph1)}. - -%%-------------------------------------------------------------------- - --spec pp(file:filename()) -> 'ok'. - -pp(File) -> - {ok, Code} = dialyzer_utils:get_core_from_src(File, [no_copt]), - Plt = get_def_plt(), - AnnTree = annotate_module(Code, Plt), - io:put_chars(cerl_prettypr:format(AnnTree, [{hook, cerl_typean:pp_hook()}])), - io:nl(). - -%%-------------------------------------------------------------------- -%% This is used in the testsuite. - --spec get_top_level_signatures(cerl:c_module(), dict()) -> - [{{atom(), arity()}, erl_types:erl_type()}]. - -get_top_level_signatures(Code, Records) -> - {Tree, _} = cerl_trees:label(cerl:from_records(Code)), - Callgraph0 = dialyzer_callgraph:new(), - Callgraph1 = dialyzer_callgraph:scan_core_tree(Tree, Callgraph0), - {Callgraph2, _} = dialyzer_callgraph:remove_external(Callgraph1), - Callgraph = dialyzer_callgraph:finalize(Callgraph2), - to_dot(Callgraph), - Plt = get_def_plt(), - FunTypes = get_fun_types(Tree, Plt, Callgraph, Records), - FunTypes1 = lists:foldl(fun({V, F}, Acc) -> - Label = get_label(F), - case dict:find(Label, Acc) of - error -> - Arity = cerl:fname_arity(V), - Type = t_fun(lists:duplicate(Arity, - t_none()), - t_none()), - dict:store(Label, Type, Acc); - {ok, _} -> Acc - end - end, FunTypes, cerl:module_defs(Tree)), - dialyzer_callgraph:delete(Callgraph), - Sigs = [{{cerl:fname_id(V), cerl:fname_arity(V)}, - dict:fetch(get_label(F), FunTypes1)} - || {V, F} <- cerl:module_defs(Tree)], - ordsets:from_list(Sigs). - -get_def_plt() -> - try - dialyzer_plt:from_file(dialyzer_plt:get_default_plt()) - catch - throw:{dialyzer_error, _} -> dialyzer_plt:new() - end. - -%%% =========================================================================== -%%% -%%% Annotate all top level funs. -%%% -%%% =========================================================================== - -annotate_module(Code, Plt) -> - {Tree, _} = cerl_trees:label(cerl:from_records(Code)), - Callgraph0 = dialyzer_callgraph:new(), - Callgraph1 = dialyzer_callgraph:scan_core_tree(Tree, Callgraph0), - {Callgraph2, _} = dialyzer_callgraph:remove_external(Callgraph1), - Callgraph = dialyzer_callgraph:finalize(Callgraph2), - State = analyze_module(Tree, Plt, Callgraph), - Res = annotate(Tree, State), - dialyzer_callgraph:delete(Callgraph), - Res. - -annotate(Tree, State) -> - case cerl:subtrees(Tree) of - [] -> set_type(Tree, State); - List -> - NewSubTrees = [[annotate(Subtree, State) || Subtree <- Group] - || Group <- List], - NewTree = cerl:update_tree(Tree, NewSubTrees), - set_type(NewTree, State) - end. - -set_type(Tree, State) -> - case cerl:type(Tree) of - 'fun' -> - Type = state__fun_type(Tree, State), - case t_is_any(Type) of - true -> - cerl:set_ann(Tree, delete_ann(typesig, cerl:get_ann(Tree))); - false -> - cerl:set_ann(Tree, append_ann(typesig, Type, cerl:get_ann(Tree))) - end; - apply -> - case state__find_apply_return(Tree, State) of - unknown -> Tree; - ReturnType -> - case t_is_any(ReturnType) of - true -> - cerl:set_ann(Tree, delete_ann(type, cerl:get_ann(Tree))); - false -> - cerl:set_ann(Tree, append_ann(type, ReturnType, - cerl:get_ann(Tree))) - end - end; - _ -> - Tree - end. - -append_ann(Tag, Val, [X | Xs]) -> - if tuple_size(X) >= 1, element(1, X) =:= Tag -> - append_ann(Tag, Val, Xs); - true -> - [X | append_ann(Tag, Val, Xs)] - end; -append_ann(Tag, Val, []) -> - [{Tag, Val}]. - -delete_ann(Tag, [X | Xs]) -> - if tuple_size(X) >= 1, element(1, X) =:= Tag -> - delete_ann(Tag, Xs); - true -> - [X | delete_ann(Tag, Xs)] - end; -delete_ann(_, []) -> - []. + state__all_fun_types(State). %%% =========================================================================== %%% @@ -265,56 +132,46 @@ delete_ann(_, []) -> %%% %%% =========================================================================== -analyze_module(Tree, Plt, Callgraph) -> - analyze_module(Tree, Plt, Callgraph, dict:new(), false). - analyze_module(Tree, Plt, Callgraph, Records, GetWarnings) -> debug_pp(Tree, false), Module = cerl:atom_val(cerl:module_name(Tree)), RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), - RaceCode = dialyzer_callgraph:get_race_code(Callgraph), BehaviourTranslations = case RaceDetection of true -> dialyzer_behaviours:translatable_behaviours(Tree); false -> [] end, TopFun = cerl:ann_c_fun([{label, top}], [], Tree), - State = state__new(dialyzer_callgraph:race_code_new(Callgraph), - TopFun, Plt, Module, Records, BehaviourTranslations), + State = + state__new(Callgraph, TopFun, Plt, Module, Records, BehaviourTranslations), State1 = state__race_analysis(not GetWarnings, State), State2 = analyze_loop(State1), case GetWarnings of true -> State3 = state__set_warning_mode(State2), State4 = analyze_loop(State3), - State5 = state__restore_race_code(RaceCode, State4), %% EXPERIMENTAL: Turn all behaviour API calls into calls to the %% respective callback module's functions. case BehaviourTranslations of - [] -> dialyzer_races:race(State5); + [] -> dialyzer_races:race(State4); Behaviours -> - Callgraph2 = State5#state.callgraph, - Digraph = dialyzer_callgraph:get_digraph(Callgraph2), + Digraph = dialyzer_callgraph:get_digraph(State4#state.callgraph), TranslatedCallgraph = dialyzer_behaviours:translate_callgraph(Behaviours, Module, - Callgraph2), + Callgraph), St = - dialyzer_races:race(State5#state{callgraph = TranslatedCallgraph}), - Callgraph3 = dialyzer_callgraph:put_digraph(Digraph, - St#state.callgraph), - St#state{callgraph = Callgraph3} + dialyzer_races:race(State4#state{callgraph = TranslatedCallgraph}), + FinalCallgraph = dialyzer_callgraph:put_digraph(Digraph, + St#state.callgraph), + St#state{callgraph = FinalCallgraph} end; false -> - Callgraph1 = State2#state.callgraph, - RaceCode1 = dialyzer_callgraph:get_race_code(Callgraph1), - state__restore_race_code( - dict:merge(fun (_K, V1, _V2) -> V1 end, - RaceCode, RaceCode1), State2) + State2 end. -analyze_loop(#state{callgraph = Callgraph, races = Races} = State) -> +analyze_loop(State) -> case state__get_work(State) of none -> State; {Fun, NewState1} -> @@ -340,10 +197,9 @@ analyze_loop(#state{callgraph = Callgraph, races = Races} = State) -> Map1 = enter_type_lists(Vars, ArgTypes, Map), Body = cerl:fun_body(Fun), FunLabel = get_label(Fun), - RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), - RaceAnalysis = dialyzer_races:get_race_analysis(Races), + IsRaceAnalysisEnabled = is_race_analysis_enabled(State), NewState3 = - case RaceDetection andalso RaceAnalysis of + case IsRaceAnalysisEnabled of true -> NewState2 = state__renew_curr_fun( state__lookup_name(FunLabel, NewState1), FunLabel, @@ -357,17 +213,8 @@ analyze_loop(#state{callgraph = Callgraph, races = Races} = State) -> [state__lookup_name(get_label(Fun), State), t_to_string(t_fun(ArgTypes, BodyType))]), NewState5 = - case RaceDetection andalso RaceAnalysis of - true -> - Races1 = NewState4#state.races, - Code = lists:reverse(dialyzer_races:get_race_list(Races1)), - Callgraph1 = - renew_code(dialyzer_races:get_curr_fun(Races1), - dialyzer_races:get_curr_fun_args(Races1), - Code, - state__warning_mode(NewState4), - NewState4#state.callgraph), - NewState4#state{callgraph = Callgraph1}; + case IsRaceAnalysisEnabled of + true -> renew_race_code(NewState4); false -> NewState4 end, NewState6 = @@ -582,9 +429,7 @@ handle_apply_or_call([{local, external}|Left], Args, ArgTypes, Map, Tree, State, ArgTypes, t_any()); handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], Args, ArgTypes, Map, Tree, - #state{callgraph = Callgraph, races = Races, - opaques = Opaques} = State, - AccArgTypes, AccRet) -> + #state{opaques = Opaques} = State, AccArgTypes, AccRet) -> Any = t_any(), AnyArgs = [Any || _ <- Args], GenSig = {AnyArgs, fun(_) -> t_any() end}, @@ -680,8 +525,7 @@ handle_apply_or_call([{TypeOfApply, {Fun, Sig, Contr, LocalRet}}|Left], ?debug("ContrRet: ~s\n", [erl_types:t_to_string(CRange(TmpArgTypes))]), ?debug("SigRet: ~s\n", [erl_types:t_to_string(SigRange)]), State1 = - case dialyzer_callgraph:get_race_detection(Callgraph) andalso - dialyzer_races:get_race_analysis(Races) of + case is_race_analysis_enabled(State) of true -> Ann = cerl:get_ann(Tree), File = get_file(Ann), @@ -1047,20 +891,17 @@ handle_call(Tree, Map, State) -> %%---------------------------------------- -handle_case(Tree, Map, #state{callgraph = Callgraph} = State) -> +handle_case(Tree, Map, State) -> Arg = cerl:case_arg(Tree), Clauses = filter_match_fail(cerl:case_clauses(Tree)), {State1, Map1, ArgType} = SMA = traverse(Arg, Map, State), case t_is_none_or_unit(ArgType) of true -> SMA; false -> - Races = State1#state.races, State2 = - case dialyzer_callgraph:get_race_detection(Callgraph) andalso - dialyzer_races:get_race_analysis(Races) of + case is_race_analysis_enabled(State) of true -> - RaceList = dialyzer_races:get_race_list(Races), - RaceListSize = dialyzer_races:get_race_list_size(Races), + {RaceList, RaceListSize} = get_race_list_and_size(State1), state__renew_race_list([beg_case|RaceList], RaceListSize + 1, State1); false -> State1 @@ -1094,9 +935,8 @@ handle_cons(Tree, Map, State) -> %%---------------------------------------- -handle_let(Tree, Map, #state{callgraph = Callgraph, races = Races} = State) -> - RaceAnalysis = dialyzer_races:get_race_analysis(Races), - RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), +handle_let(Tree, Map, State) -> + IsRaceAnalysisEnabled = is_race_analysis_enabled(State), Arg = cerl:let_arg(Tree), Vars = cerl:let_vars(Tree), {Map0, State0} = @@ -1104,10 +944,9 @@ handle_let(Tree, Map, #state{callgraph = Callgraph, races = Races} = State) -> true -> [Var] = Vars, {enter_subst(Var, Arg, Map), - case RaceDetection andalso RaceAnalysis of + case IsRaceAnalysisEnabled of true -> - RaceList = dialyzer_races:get_race_list(Races), - RaceListSize = dialyzer_races:get_race_list_size(Races), + {RaceList, RaceListSize} = get_race_list_and_size(State), state__renew_race_list( [dialyzer_races:let_tag_new(Var, Arg)|RaceList], RaceListSize + 1, State); @@ -1117,9 +956,8 @@ handle_let(Tree, Map, #state{callgraph = Callgraph, races = Races} = State) -> end, Body = cerl:let_body(Tree), {State1, Map1, ArgTypes} = SMA = traverse(Arg, Map0, State0), - Callgraph1 = State1#state.callgraph, - Callgraph2 = - case RaceDetection andalso RaceAnalysis andalso cerl:is_c_call(Arg) of + State2 = + case IsRaceAnalysisEnabled andalso cerl:is_c_call(Arg) of true -> Mod = cerl:call_module(Arg), Name = cerl:call_name(Arg), @@ -1127,16 +965,11 @@ handle_let(Tree, Map, #state{callgraph = Callgraph, races = Races} = State) -> cerl:concrete(Mod) =:= ets andalso cerl:is_literal(Name) andalso cerl:concrete(Name) =:= new of - true -> - NewTable = dialyzer_races:get_new_table(State1#state.races), - renew_public_tables(Vars, NewTable, - state__warning_mode(State1), - Callgraph1); - false -> Callgraph1 + true -> renew_race_public_tables(Vars, State1); + false -> State1 end; - false -> Callgraph1 + false -> State1 end, - State2 = State1#state{callgraph = Callgraph2}, case t_is_none_or_unit(ArgTypes) of true -> SMA; false -> @@ -1167,16 +1000,13 @@ handle_module(Tree, Map, State) -> %%---------------------------------------- -handle_receive(Tree, Map, - #state{callgraph = Callgraph, races = Races} = State) -> +handle_receive(Tree, Map, State) -> Clauses = filter_match_fail(cerl:receive_clauses(Tree)), Timeout = cerl:receive_timeout(Tree), State1 = - case dialyzer_callgraph:get_race_detection(Callgraph) andalso - dialyzer_races:get_race_analysis(Races) of + case is_race_analysis_enabled(State) of true -> - RaceList = dialyzer_races:get_race_list(Races), - RaceListSize = dialyzer_races:get_race_list_size(Races), + {RaceList, RaceListSize} = get_race_list_and_size(State), state__renew_race_list([beg_case|RaceList], RaceListSize + 1, State); false -> State @@ -1299,16 +1129,13 @@ handle_tuple(Tree, Map, State) -> %%---------------------------------------- %% Clauses %% -handle_clauses([C|Left], Arg, ArgType, OrigArgType, - #state{callgraph = Callgraph, races = Races} = State, - CaseTypes, MapIn, Acc, ClauseAcc) -> - RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), - RaceAnalysis = dialyzer_races:get_race_analysis(Races), +handle_clauses([C|Left], Arg, ArgType, OrigArgType, State, CaseTypes, MapIn, + Acc, ClauseAcc) -> + IsRaceAnalysisEnabled = is_race_analysis_enabled(State), State1 = - case RaceDetection andalso RaceAnalysis of + case IsRaceAnalysisEnabled of true -> - RaceList = dialyzer_races:get_race_list(Races), - RaceListSize = dialyzer_races:get_race_list_size(Races), + {RaceList, RaceListSize} = get_race_list_and_size(State), state__renew_race_list( [dialyzer_races:beg_clause_new(Arg, cerl:clause_pats(C), cerl:clause_guard(C))| @@ -1319,11 +1146,9 @@ handle_clauses([C|Left], Arg, ArgType, OrigArgType, {State2, ClauseMap, BodyType, NewArgType} = do_clause(C, Arg, ArgType, OrigArgType, MapIn, State1), {NewClauseAcc, State3} = - case RaceDetection andalso RaceAnalysis of + case IsRaceAnalysisEnabled of true -> - Races1 = State2#state.races, - RaceList1 = dialyzer_races:get_race_list(Races1), - RaceListSize1 = dialyzer_races:get_race_list_size(Races1), + {RaceList1, RaceListSize1} = get_race_list_and_size(State2), EndClause = dialyzer_races:end_clause_new(Arg, cerl:clause_pats(C), cerl:clause_guard(C)), {[EndClause|ClauseAcc], @@ -1338,30 +1163,25 @@ handle_clauses([C|Left], Arg, ArgType, OrigArgType, end, handle_clauses(Left, Arg, NewArgType, OrigArgType, State3, NewCaseTypes, MapIn, NewAcc, NewClauseAcc); -handle_clauses([], _Arg, _ArgType, _OrigArgType, - #state{callgraph = Callgraph, races = Races} = State, - CaseTypes, _MapIn, Acc, ClauseAcc) -> +handle_clauses([], _Arg, _ArgType, _OrigArgType, State, CaseTypes, _MapIn, Acc, + ClauseAcc) -> State1 = - case dialyzer_callgraph:get_race_detection(Callgraph) andalso - dialyzer_races:get_race_analysis(Races) of + case is_race_analysis_enabled(State) of true -> + {RaceList, RaceListSize} = get_race_list_and_size(State), state__renew_race_list( - [dialyzer_races:end_case_new(ClauseAcc)| - dialyzer_races:get_race_list(Races)], - dialyzer_races:get_race_list_size(Races) + 1, State); + [dialyzer_races:end_case_new(ClauseAcc)|RaceList], + RaceListSize + 1, State); false -> State end, {lists:reverse(Acc), State1, t_sup(CaseTypes)}. -do_clause(C, Arg, ArgType0, OrigArgType, Map, - #state{callgraph = Callgraph, races = Races} = State) -> +do_clause(C, Arg, ArgType0, OrigArgType, Map, State) -> Pats = cerl:clause_pats(C), Guard = cerl:clause_guard(C), Body = cerl:clause_body(C), - RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), - RaceAnalysis = dialyzer_races:get_race_analysis(Races), State1 = - case RaceDetection andalso RaceAnalysis of + case is_race_analysis_enabled(State) of true -> state__renew_fun_args(Pats, State); false -> State @@ -2914,10 +2734,6 @@ state__set_warning_mode(#state{tree_map = TreeMap, fun_tab = FunTab, fun_tab = FunTab, warning_mode = true, races = dialyzer_races:put_race_analysis(true, Races)}. -state__restore_race_code(RaceCode, #state{callgraph = Callgraph} = State) -> - State#state{callgraph = dialyzer_callgraph:put_race_code(RaceCode, - Callgraph)}. - state__race_analysis(Analysis, #state{races = Races} = State) -> State#state{races = dialyzer_races:put_race_analysis(Analysis, Races)}. @@ -3260,21 +3076,6 @@ state__fun_info(Fun, #state{callgraph = CG, fun_tab = FunTab, plt = PLT}) -> ?debug("LocalRet: ~s\n", [t_to_string(LocalRet)]), {Fun, Sig, Contract, LocalRet}. -state__find_apply_return(Tree, #state{callgraph = Callgraph} = State) -> - Apply = get_label(Tree), - case dialyzer_callgraph:lookup_call_site(Apply, Callgraph) of - error -> - unknown; - {ok, List} -> - case lists:member(external, List) of - true -> t_any(); - false -> - FunTypes = [state__fun_type(F, State) || F <- List], - Returns = [t_fun_range(F) || F <- FunTypes], - t_sup(Returns) - end - end. - forward_args(Fun, ArgTypes, #state{work = Work, fun_tab = FunTab} = State) -> {OldArgTypes, OldOut, Fixpoint} = case dict:find(Fun, FunTab) of @@ -3305,6 +3106,16 @@ state__cleanup(#state{callgraph = Callgraph, races = dialyzer_races:cleanup(Races), records = Records}. +-spec state__duplicate(state()) -> state(). + +state__duplicate(#state{callgraph = Callgraph} = State) -> + State#state{callgraph = dialyzer_callgraph:duplicate(Callgraph)}. + +-spec dispose_state(state()) -> ok. + +dispose_state(#state{callgraph = Callgraph}) -> + dialyzer_callgraph:dispose_race_server(Callgraph). + -spec state__get_callgraph(state()) -> dialyzer_callgraph:callgraph(). state__get_callgraph(#state{callgraph = Callgraph}) -> @@ -3342,26 +3153,36 @@ state__records_only(#state{records = Records}) -> %%% %%% =========================================================================== -renew_code(Fun, FunArgs, Code, WarningMode, Callgraph) -> +is_race_analysis_enabled(#state{races = Races, callgraph = Callgraph}) -> + RaceDetection = dialyzer_callgraph:get_race_detection(Callgraph), + RaceAnalysis = dialyzer_races:get_race_analysis(Races), + RaceDetection andalso RaceAnalysis. + +get_race_list_and_size(#state{races = Races}) -> + dialyzer_races:get_race_list_and_size(Races). + +renew_race_code(#state{races = Races, callgraph = Callgraph, + warning_mode = WarningMode} = State) -> case WarningMode of - true -> Callgraph; + true -> State; false -> - RaceCode = dialyzer_callgraph:get_race_code(Callgraph), - dialyzer_callgraph:put_race_code( - dict:store(Fun, [FunArgs, Code], RaceCode), Callgraph) + NewCallgraph = dialyzer_callgraph:renew_race_code(Races, Callgraph), + State#state{callgraph = NewCallgraph} end. -renew_public_tables([Var], Table, WarningMode, Callgraph) -> +renew_race_public_tables([Var], #state{races = Races, callgraph = Callgraph, + warning_mode = WarningMode} = State) -> case WarningMode of - true -> Callgraph; + true -> State; false -> + Table = dialyzer_races:get_new_table(Races), case Table of - no_t -> Callgraph; - _Other -> - VarLabel = get_label(Var), - PTables = dialyzer_callgraph:get_public_tables(Callgraph), - dialyzer_callgraph:put_public_tables( - lists:usort([VarLabel|PTables]), Callgraph) + no_t -> State; + _Other -> + VarLabel = get_label(Var), + NewCallgraph = + dialyzer_callgraph:renew_race_public_tables(VarLabel, Callgraph), + State#state{callgraph = NewCallgraph} end end. @@ -3688,17 +3509,3 @@ strip_annotations(Tree) -> debug_pp(_Tree, _UseHook) -> ok. -endif. - -%%---------------------------------------------------------------------------- - --spec to_dot(dialyzer_callgraph:callgraph()) -> 'ok'. - --ifdef(DOT). -to_dot(CG) -> - dialyzer_callgraph:to_dot(CG). --else. -to_dot(_CG) -> - ok. --endif. - -%%---------------------------------------------------------------------------- diff --git a/lib/dialyzer/src/dialyzer_options.erl b/lib/dialyzer/src/dialyzer_options.erl index 866650a0b2..a1e316d6cc 100644 --- a/lib/dialyzer/src/dialyzer_options.erl +++ b/lib/dialyzer/src/dialyzer_options.erl @@ -194,6 +194,8 @@ build_options([{OptionName, Value} = Term|Rest], Options) -> callgraph_file -> assert_filename(Value), build_options(Rest, Options#options{callgraph_file = Value}); + timing -> + build_options(Rest, Options#options{timing = Value}); _ -> bad_option("Unknown dialyzer command line option", Term) end; diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl index 06eaadad9c..5f64099210 100644 --- a/lib/dialyzer/src/dialyzer_plt.erl +++ b/lib/dialyzer/src/dialyzer_plt.erl @@ -55,7 +55,10 @@ plt_and_info_from_file/1, get_specs/1, get_specs/4, - to_file/4]). + to_file/4, + get_mini_plt/1, + restore_full_plt/2 + ]). %% Debug utilities -export([pp_non_returning/0, pp_mod/1]). @@ -82,7 +85,13 @@ contracts = table_new() :: dict(), callbacks = table_new() :: dict(), exported_types = sets:new() :: set()}). --opaque plt() :: #plt{}. + +-record(mini_plt, {info :: ets:tid(), + contracts :: ets:tid(), + callbacks :: ets:tid() + }). + +-opaque plt() :: #plt{} | #mini_plt{}. -include("dialyzer.hrl"). @@ -132,51 +141,48 @@ delete_list(#plt{info = Info, types = Types, -spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt(). -insert_contract_list(#plt{contracts = Contracts} = PLT, List) -> - PLT#plt{contracts = table_insert_list(Contracts, List)}. +insert_contract_list(#mini_plt{contracts = Contracts} = PLT, List) -> + true = ets:insert(Contracts, List), + PLT. -spec insert_callbacks(plt(), dialyzer_codeserver:codeserver()) -> plt(). insert_callbacks(#plt{callbacks = Callbacks} = Plt, Codeserver) -> - FunPreferNew = fun(_Key, _Val1, Val2) -> Val2 end, - FunDictMerger = - fun(_Key, Value, AccIn) -> dict:merge(FunPreferNew, Value, AccIn) end, - MergedCallbacks = dict:fold(FunDictMerger, dict:new(), - dialyzer_codeserver:get_callbacks(Codeserver)), - List = dict:to_list(MergedCallbacks), + List = dialyzer_codeserver:get_callbacks(Codeserver), Plt#plt{callbacks = table_insert_list(Callbacks, List)}. -spec lookup_contract(plt(), mfa_patt()) -> 'none' | {'value', #contract{}}. -lookup_contract(#plt{contracts = Contracts}, +lookup_contract(#mini_plt{contracts = ETSContracts}, {M, F, _} = MFA) when is_atom(M), is_atom(F) -> - table_lookup(Contracts, MFA). + ets_table_lookup(ETSContracts, MFA). -spec lookup_callbacks(plt(), module()) -> - [{mfa(), {{Filename::string(), Line::pos_integer()}, #contract{}}}]. + 'none' | {'value', [{mfa(), {{Filename::string(), + Line::pos_integer()}, + #contract{}}}]}. -lookup_callbacks(#plt{callbacks = Callbacks}, Mod) when is_atom(Mod) -> - FunModFilter = - fun({M, _F, _A}, _Val) -> M =:= Mod; - ( _Key, _Val) -> false - end, - ModCallbacks = dict:filter(FunModFilter, Callbacks), - dict:to_list(ModCallbacks). +lookup_callbacks(#mini_plt{callbacks = ETSCallbacks}, Mod) when is_atom(Mod) -> + ets_table_lookup(ETSCallbacks, Mod). -type ret_args_types() :: {erl_types:erl_type(), [erl_types:erl_type()]}. -spec insert_list(plt(), [{mfa() | integer(), ret_args_types()}]) -> plt(). -insert_list(#plt{info = Info} = PLT, List) -> - PLT#plt{info = table_insert_list(Info, List)}. +insert_list(#mini_plt{info = Info} = PLT, List) -> + true = ets:insert(Info, List), + PLT. -spec lookup(plt(), integer() | mfa_patt()) -> 'none' | {'value', ret_args_types()}. -lookup(#plt{info = Info}, {M, F, _} = MFA) when is_atom(M), is_atom(F) -> - table_lookup(Info, MFA); -lookup(#plt{info = Info}, Label) when is_integer(Label) -> - table_lookup(Info, Label). +lookup(Plt, {M, F, _} = MFA) when is_atom(M), is_atom(F) -> + lookup_1(Plt, MFA); +lookup(Plt, Label) when is_integer(Label) -> + lookup_1(Plt, Label). + +lookup_1(#mini_plt{info = Info}, MFAorLabel) -> + ets_table_lookup(Info, MFAorLabel). -spec insert_types(plt(), dict()) -> plt(). @@ -503,6 +509,34 @@ init_md5_list_1([], DiffList, Acc) -> init_md5_list_1(Md5List, [], Acc) -> {ok, lists:reverse(Acc, Md5List)}. +-spec get_mini_plt(plt()) -> plt(). + +get_mini_plt(#plt{info = Info, contracts = Contracts, callbacks = Callbacks}) -> + [ETSInfo, ETSContracts, ETSCallbacks] = + [ets:new(Name, [public]) || Name <- [plt_info, plt_contracts, plt_callbacks]], + CallbackList = dict:to_list(Callbacks), + CallbacksByModule = + [{M, [Cb || {{M1,_,_},_} = Cb <- CallbackList, M1 =:= M]} || + M <- lists:usort([M || {{M,_,_},_} <- CallbackList])], + [true, true] = + [ets:insert(ETS, dict:to_list(Data)) || + {ETS, Data} <- [{ETSInfo, Info}, {ETSContracts, Contracts}]], + true = ets:insert(ETSCallbacks, CallbacksByModule), + #mini_plt{info = ETSInfo, contracts = ETSContracts, callbacks = ETSCallbacks}; +get_mini_plt(undefined) -> + undefined. + +-spec restore_full_plt(plt(), plt()) -> plt(). + +restore_full_plt(#mini_plt{info = ETSInfo, contracts = ETSContracts}, Plt) -> + Info = dict:from_list(ets:tab2list(ETSInfo)), + Contracts = dict:from_list(ets:tab2list(ETSContracts)), + ets:delete(ETSContracts), + ets:delete(ETSInfo), + Plt#plt{info = Info, contracts = Contracts}; +restore_full_plt(undefined, undefined) -> + undefined. + %%--------------------------------------------------------------------------- %% Edoc @@ -595,6 +629,13 @@ table_lookup(Plt, Obj) -> {ok, Val} -> {value, Val} end. +ets_table_lookup(Plt, Obj) -> + try ets:lookup_element(Plt, Obj, 2) of + Val -> {value, Val} + catch + _:_ -> none + end. + table_lookup_module(Plt, Mod) -> List = dict:fold(fun(Key, Val, Acc) -> case Key of diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl index cc635b0eef..cdb9f25999 100644 --- a/lib/dialyzer/src/dialyzer_races.erl +++ b/lib/dialyzer/src/dialyzer_races.erl @@ -36,6 +36,7 @@ -export([beg_clause_new/3, cleanup/1, end_case_new/1, end_clause_new/3, get_curr_fun/1, get_curr_fun_args/1, get_new_table/1, get_race_analysis/1, get_race_list/1, get_race_list_size/1, + get_race_list_and_size/1, let_tag_new/2, new/0, put_curr_fun/3, put_fun_args/2, put_race_analysis/2, put_race_list/3]). @@ -346,6 +347,7 @@ fixup_race_list(RaceWarnTag, WarnVarArgs, State) -> DepList2 = fixup_race_list_helper(NewParents, Calls, CurrFun, WarnVarArgs, RaceWarnTag, NewState), + dialyzer_dataflow:dispose_state(CleanState), lists:usort(cleanup_dep_calls(DepList1 ++ DepList2)). fixup_race_list_helper(Parents, Calls, CurrFun, WarnVarArgs, RaceWarnTag, @@ -380,13 +382,15 @@ fixup_race_forward_pullout(CurrFun, CurrFunLabel, Calls, Code, RaceList, InitFun, WarnVarArgs, RaceWarnTag, RaceVarMap, FunDefVars, FunCallVars, FunArgTypes, NestingLevel, State) -> + TState = dialyzer_dataflow:state__duplicate(State), {DepList, NewCurrFun, NewCurrFunLabel, NewCalls, NewCode, NewRaceList, NewRaceVarMap, NewFunDefVars, NewFunCallVars, NewFunArgTypes, NewNestingLevel} = fixup_race_forward(CurrFun, CurrFunLabel, Calls, Code, RaceList, InitFun, WarnVarArgs, RaceWarnTag, RaceVarMap, FunDefVars, FunCallVars, FunArgTypes, NestingLevel, - cleanup_race_code(State)), + cleanup_race_code(TState)), + dialyzer_dataflow:dispose_state(TState), case NewCode of [] -> DepList; [#fun_call{caller = NewCurrFun, callee = Call, arg_types = FunTypes, @@ -2434,6 +2438,12 @@ get_race_list(#races{race_list = RaceList}) -> get_race_list_size(#races{race_list_size = RaceListSize}) -> RaceListSize. +-spec get_race_list_and_size(races()) -> {code(), non_neg_integer()}. + +get_race_list_and_size(#races{race_list = RaceList, + race_list_size = RaceListSize}) -> + {RaceList, RaceListSize}. + -spec let_tag_new(var_to_map1(), var_to_map1()) -> #let_tag{}. let_tag_new(Var, Arg) -> diff --git a/lib/dialyzer/src/dialyzer_succ_typings.erl b/lib/dialyzer/src/dialyzer_succ_typings.erl index 5982603b7b..9ca5a66dab 100644 --- a/lib/dialyzer/src/dialyzer_succ_typings.erl +++ b/lib/dialyzer/src/dialyzer_succ_typings.erl @@ -28,15 +28,22 @@ -module(dialyzer_succ_typings). -export([analyze_callgraph/3, - analyze_callgraph/4, - get_warnings/6]). + analyze_callgraph/5, + get_warnings/7 + ]). -%% These are only intended as debug functions. --export([doit/1, - get_top_level_signatures/3]). +-export([ + find_succ_types_for_scc/2, + refine_one_module/2, + find_required_by/2, + find_depends_on/2, + collect_warnings/2, + lookup_names/2 + ]). + +-export_type([typesig_init_data/0, dataflow_init_data/0, warnings_init_data/0]). %%-define(DEBUG, true). -%%-define(DEBUG_PP, true). -ifdef(DEBUG). -define(debug(X__, Y__), io:format(X__, Y__)). @@ -54,11 +61,20 @@ %% State record -- local to this module -type parent() :: 'none' | pid(). +-type typesig_init_data() :: term(). +-type dataflow_init_data() :: term(). +-type warnings_init_data() :: term(). + +-type fixpoint_init_data() :: typesig_init_data() | dataflow_init_data(). + +-type scc() :: [mfa_or_funlbl()] | [module()]. + -record(st, {callgraph :: dialyzer_callgraph:callgraph(), codeserver :: dialyzer_codeserver:codeserver(), no_warn_unused :: set(), parent = none :: parent(), + timing_server :: dialyzer_timing:timing_server(), plt :: dialyzer_plt:plt()}). %%-------------------------------------------------------------------- @@ -68,60 +84,89 @@ dialyzer_plt:plt(). analyze_callgraph(Callgraph, Plt, Codeserver) -> - analyze_callgraph(Callgraph, Plt, Codeserver, none). + analyze_callgraph(Callgraph, Plt, Codeserver, none, none). -spec analyze_callgraph(dialyzer_callgraph:callgraph(), dialyzer_plt:plt(), - dialyzer_codeserver:codeserver(), parent()) -> + dialyzer_codeserver:codeserver(), + dialyzer_timing:timing_server(), parent()) -> dialyzer_plt:plt(). -analyze_callgraph(Callgraph, Plt, Codeserver, Parent) -> - State = #st{callgraph = Callgraph, plt = Plt, - codeserver = Codeserver, parent = Parent}, - NewState = get_refined_success_typings(State), - NewState#st.plt. +analyze_callgraph(Callgraph, Plt, Codeserver, TimingServer, Parent) -> + NewState = + init_state_and_get_success_typings(Callgraph, Plt, Codeserver, + TimingServer, Parent), + dialyzer_plt:restore_full_plt(NewState#st.plt, Plt). %%-------------------------------------------------------------------- -get_refined_success_typings(State) -> - case find_succ_typings(State) of +init_state_and_get_success_typings(Callgraph, Plt, Codeserver, + TimingServer, Parent) -> + {SCCs, Callgraph1} = + ?timing(TimingServer, "order", dialyzer_callgraph:finalize(Callgraph)), + State = #st{callgraph = Callgraph1, plt = dialyzer_plt:get_mini_plt(Plt), + codeserver = Codeserver, parent = Parent, + timing_server = TimingServer}, + get_refined_success_typings(SCCs, State). + +get_refined_success_typings(SCCs, #st{callgraph = Callgraph, + timing_server = TimingServer} = State) -> + case find_succ_typings(SCCs, State) of {fixpoint, State1} -> State1; {not_fixpoint, NotFixpoint1, State1} -> - Callgraph = State1#st.callgraph, - NotFixpoint2 = [lookup_name(F, Callgraph) || F <- NotFixpoint1], - ModulePostorder = - dialyzer_callgraph:module_postorder_from_funs(NotFixpoint2, Callgraph), - case refine_succ_typings(ModulePostorder, State1) of + {ModulePostorder, ModCallgraph} = + ?timing( + TimingServer, "order", _C1, + dialyzer_callgraph:module_postorder_from_funs(NotFixpoint1, + Callgraph)), + ModState = State1#st{callgraph = ModCallgraph}, + case refine_succ_typings(ModulePostorder, ModState) of {fixpoint, State2} -> State2; - {not_fixpoint, NotFixpoint3, State2} -> - Callgraph1 = State2#st.callgraph, + {not_fixpoint, NotFixpoint2, State2} -> %% Need to reset the callgraph. - NotFixpoint4 = [lookup_name(F, Callgraph1) || F <- NotFixpoint3], - Callgraph2 = dialyzer_callgraph:reset_from_funs(NotFixpoint4, - Callgraph1), - get_refined_success_typings(State2#st{callgraph = Callgraph2}) + {NewSCCs, Callgraph2} = + ?timing(TimingServer, "order", _C2, + dialyzer_callgraph:reset_from_funs(NotFixpoint2, + ModCallgraph)), + NewState = State2#st{callgraph = Callgraph2}, + get_refined_success_typings(NewSCCs, NewState) end end. -type doc_plt() :: 'undefined' | dialyzer_plt:plt(). -spec get_warnings(dialyzer_callgraph:callgraph(), dialyzer_plt:plt(), doc_plt(), dialyzer_codeserver:codeserver(), set(), - pid()) -> + dialyzer_timing:timing_server(), pid()) -> {[dial_warning()], dialyzer_plt:plt(), doc_plt()}. -get_warnings(Callgraph, Plt, DocPlt, Codeserver, NoWarnUnused, Parent) -> - InitState = #st{callgraph = Callgraph, codeserver = Codeserver, - no_warn_unused = NoWarnUnused, parent = Parent, plt = Plt}, - NewState = get_refined_success_typings(InitState), +get_warnings(Callgraph, Plt, DocPlt, Codeserver, + NoWarnUnused, TimingServer, Parent) -> + InitState = + init_state_and_get_success_typings(Callgraph, Plt, Codeserver, + TimingServer, Parent), + NewState = InitState#st{no_warn_unused = NoWarnUnused}, Mods = dialyzer_callgraph:modules(NewState#st.callgraph), - CWarns = dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver, - NewState#st.plt), - get_warnings_from_modules(Mods, NewState, DocPlt, CWarns). - -get_warnings_from_modules([M|Ms], State, DocPlt, Acc) when is_atom(M) -> - send_log(State#st.parent, io_lib:format("Getting warnings for ~w\n", [M])), + MiniPlt = NewState#st.plt, + CWarns = + dialyzer_contracts:get_invalid_contract_warnings(Mods, Codeserver, MiniPlt), + MiniDocPlt = dialyzer_plt:get_mini_plt(DocPlt), + ModWarns = + ?timing(TimingServer, "warning", + get_warnings_from_modules(Mods, NewState, MiniDocPlt)), + {postprocess_warnings(CWarns ++ ModWarns, Codeserver), + dialyzer_plt:restore_full_plt(MiniPlt, Plt), + dialyzer_plt:restore_full_plt(MiniDocPlt, DocPlt)}. + +get_warnings_from_modules(Mods, State, DocPlt) -> #st{callgraph = Callgraph, codeserver = Codeserver, - no_warn_unused = NoWarnUnused, plt = Plt} = State, + no_warn_unused = NoWarnUnused, plt = Plt, + timing_server = TimingServer} = State, + Init = {Codeserver, Callgraph, NoWarnUnused, Plt, DocPlt}, + dialyzer_coordinator:parallel_job(warnings, Mods, Init, TimingServer). + +-spec collect_warnings(module(), warnings_init_data()) -> [dial_warning()]. + +collect_warnings(M, {Codeserver, Callgraph, NoWarnUnused, Plt, DocPlt}) -> ModCode = dialyzer_codeserver:lookup_mod_code(M, Codeserver), Records = dialyzer_codeserver:lookup_mod_records(M, Codeserver), Contracts = dialyzer_codeserver:lookup_mod_contracts(M, Codeserver), @@ -129,28 +174,27 @@ get_warnings_from_modules([M|Ms], State, DocPlt, Acc) when is_atom(M) -> %% Check if there are contracts for functions that do not exist Warnings1 = dialyzer_contracts:contracts_without_fun(Contracts, AllFuns, Callgraph), - {RawWarnings2, FunTypes, RaceCode, PublicTables, NamedTables} = - dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, Records, NoWarnUnused), - {NewAcc, Warnings2} = postprocess_dataflow_warns(RawWarnings2, State, Acc), + {Warnings2, FunTypes} = + dialyzer_dataflow:get_warnings(ModCode, Plt, Callgraph, + Records, NoWarnUnused), Attrs = cerl:module_attrs(ModCode), - Warnings3 = dialyzer_behaviours:check_callbacks(M, Attrs, Plt, Codeserver), - NewDocPlt = insert_into_doc_plt(FunTypes, Callgraph, DocPlt), - NewCallgraph = - dialyzer_callgraph:renew_race_info(Callgraph, RaceCode, PublicTables, - NamedTables), - State1 = st__renew_state_calls(NewCallgraph, State), - get_warnings_from_modules(Ms, State1, NewDocPlt, - [Warnings1, Warnings2, Warnings3|NewAcc]); -get_warnings_from_modules([], #st{plt = Plt}, DocPlt, Acc) -> - {lists:flatten(Acc), Plt, DocPlt}. - -postprocess_dataflow_warns(RawWarnings, State, WarnAcc) -> - postprocess_dataflow_warns(RawWarnings, State, WarnAcc, []). - -postprocess_dataflow_warns([], _State, WAcc, Acc) -> - {WAcc, lists:reverse(Acc)}; + Warnings3 = + dialyzer_behaviours:check_callbacks(M, Attrs, Records, Plt, Codeserver), + DocPlt = insert_into_doc_plt(FunTypes, Callgraph, DocPlt), + lists:flatten([Warnings1, Warnings2, Warnings3]). + +postprocess_warnings(RawWarnings, Codeserver) -> + Pred = + fun({?WARN_CONTRACT_RANGE, _, _}) -> true; + (_) -> false + end, + {CRWarns, NonCRWarns} = lists:partition(Pred, RawWarnings), + postprocess_dataflow_warns(CRWarns, Codeserver, NonCRWarns, []). + +postprocess_dataflow_warns([], _Callgraph, WAcc, Acc) -> + lists:reverse(Acc, WAcc); postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, {CallF, CallL}, Msg}|Rest], - #st{codeserver = Codeserver} = State, WAcc, Acc) -> + Codeserver, WAcc, Acc) -> {contract_range, [Contract, M, F, A, ArgStrings, CRet]} = Msg, case dialyzer_codeserver:lookup_mfa_contract({M,F,A}, Codeserver) of {ok, {{ContrF, _ContrL} = FileLine, _C}} -> @@ -163,87 +207,65 @@ postprocess_dataflow_warns([{?WARN_CONTRACT_RANGE, {CallF, CallL}, Msg}|Rest], (_) -> true end, FilterWAcc = lists:filter(Filter, WAcc), - postprocess_dataflow_warns(Rest, State, FilterWAcc, [W|Acc]); + postprocess_dataflow_warns(Rest, Codeserver, FilterWAcc, [W|Acc]); false -> - postprocess_dataflow_warns(Rest, State, WAcc, Acc) + postprocess_dataflow_warns(Rest, Codeserver, WAcc, Acc) end; error -> %% The contract is not in a module that is currently under analysis. %% We display the warning in the file/line of the call. NewMsg = {contract_range, [Contract, M, F, ArgStrings, CallL, CRet]}, W = {?WARN_CONTRACT_RANGE, {CallF, CallL}, NewMsg}, - postprocess_dataflow_warns(Rest, State, WAcc, [W|Acc]) - end; -postprocess_dataflow_warns([W|Rest], State, Wacc, Acc) -> - postprocess_dataflow_warns(Rest, State, Wacc, [W|Acc]). + postprocess_dataflow_warns(Rest, Codeserver, WAcc, [W|Acc]) + end. -refine_succ_typings(ModulePostorder, State) -> - ?debug("Module postorder: ~p\n", [ModulePostorder]), - refine_succ_typings(ModulePostorder, State, []). - -refine_succ_typings([SCC|SCCs], State, Fixpoint) -> - Msg = io_lib:format("Dataflow of one SCC: ~w\n", [SCC]), - send_log(State#st.parent, Msg), - ?debug("~s\n", [Msg]), - {NewState, FixpointFromScc} = - case SCC of - [M] -> refine_one_module(M, State); - [_|_] -> refine_one_scc(SCC, State) - end, - NewFixpoint = ordsets:union(Fixpoint, FixpointFromScc), - refine_succ_typings(SCCs, NewState, NewFixpoint); -refine_succ_typings([], State, Fixpoint) -> - case Fixpoint =:= [] of +refine_succ_typings(Modules, #st{codeserver = Codeserver, + callgraph = Callgraph, + plt = Plt, + timing_server = Timing} = State) -> + ?debug("Module postorder: ~p\n", [Modules]), + Init = {Codeserver, Callgraph, Plt}, + NotFixpoint = + ?timing(Timing, "refine", + dialyzer_coordinator:parallel_job(dataflow, Modules, Init, Timing)), + ?debug("==================== Dataflow done ====================\n\n", []), + case NotFixpoint =:= [] of true -> {fixpoint, State}; - false -> {not_fixpoint, Fixpoint, State} + false -> {not_fixpoint, NotFixpoint, State} end. --spec refine_one_module(module(), #st{}) -> {#st{}, [label()]}. % ordset +-spec find_depends_on(scc() | module(), fixpoint_init_data()) -> [scc()]. -refine_one_module(M, State) -> - #st{callgraph = Callgraph, codeserver = CodeServer, plt = PLT} = State, +find_depends_on(SCC, {_Codeserver, Callgraph, _Plt}) -> + dialyzer_callgraph:get_depends_on(SCC, Callgraph). + +-spec find_required_by(scc() | module(), fixpoint_init_data()) -> [scc()]. + +find_required_by(SCC, {_Codeserver, Callgraph, _Plt}) -> + dialyzer_callgraph:get_required_by(SCC, Callgraph). + +-spec lookup_names([label()], fixpoint_init_data()) -> [mfa_or_funlbl()]. + +lookup_names(Labels, {_Codeserver, Callgraph, _Plt}) -> + [lookup_name(F, Callgraph) || F <- Labels]. + +-spec refine_one_module(module(), dataflow_init_data()) -> [label()]. % ordset + +refine_one_module(M, {CodeServer, Callgraph, Plt}) -> ModCode = dialyzer_codeserver:lookup_mod_code(M, CodeServer), AllFuns = collect_fun_info([ModCode]), - FunTypes = get_fun_types_from_plt(AllFuns, Callgraph, PLT), Records = dialyzer_codeserver:lookup_mod_records(M, CodeServer), - {NewFunTypes, RaceCode, PublicTables, NamedTables} = - dialyzer_dataflow:get_fun_types(ModCode, PLT, Callgraph, Records), - NewCallgraph = - dialyzer_callgraph:renew_race_info(Callgraph, RaceCode, PublicTables, - NamedTables), + FunTypes = get_fun_types_from_plt(AllFuns, Callgraph, Plt), + NewFunTypes = + dialyzer_dataflow:get_fun_types(ModCode, Plt, Callgraph, Records), case reached_fixpoint(FunTypes, NewFunTypes) of - true -> - State1 = st__renew_state_calls(NewCallgraph, State), - {State1, ordsets:new()}; + true -> []; {false, NotFixpoint} -> ?debug("Not fixpoint\n", []), - NewState = insert_into_plt(dict:from_list(NotFixpoint), State), - NewState1 = st__renew_state_calls(NewCallgraph, NewState), - {NewState1, ordsets:from_list([FunLbl || {FunLbl,_Type} <- NotFixpoint])} + Plt = insert_into_plt(dict:from_list(NotFixpoint), Callgraph, Plt), + [FunLbl || {FunLbl,_Type} <- NotFixpoint] end. -st__renew_state_calls(Callgraph, State) -> - State#st{callgraph = Callgraph}. - -refine_one_scc(SCC, State) -> - refine_one_scc(SCC, State, []). - -refine_one_scc(SCC, State, AccFixpoint) -> - {NewState, FixpointFromScc} = refine_mods_in_scc(SCC, State, []), - case FixpointFromScc =:= [] of - true -> {NewState, AccFixpoint}; - false -> - NewAccFixpoint = ordsets:union(AccFixpoint, FixpointFromScc), - refine_one_scc(SCC, NewState, NewAccFixpoint) - end. - -refine_mods_in_scc([Mod|Mods], State, Fixpoint) -> - {NewState, FixpointFromModule} = refine_one_module(Mod, State), - NewFixpoint = ordsets:union(FixpointFromModule, Fixpoint), - refine_mods_in_scc(Mods, NewState, NewFixpoint); -refine_mods_in_scc([], State, Fixpoint) -> - {State, Fixpoint}. - reached_fixpoint(OldTypes, NewTypes) -> reached_fixpoint(OldTypes, NewTypes, false). @@ -299,31 +321,21 @@ compare_types_1([], [], _Strict, NotFixpoint) -> false -> {false, NotFixpoint} end. -find_succ_typings(State) -> - find_succ_typings(State, []). - -find_succ_typings(#st{callgraph = Callgraph, parent = Parent} = State, - NotFixpoint) -> - case dialyzer_callgraph:take_scc(Callgraph) of - {ok, SCC, NewCallgraph} -> - Msg = io_lib:format("Typesig analysis for SCC: ~w\n", [format_scc(SCC)]), - ?debug("~s", [Msg]), - send_log(Parent, Msg), - {NewState, NewNotFixpoint1} = - analyze_scc(SCC, State#st{callgraph = NewCallgraph}), - NewNotFixpoint2 = ordsets:union(NewNotFixpoint1, NotFixpoint), - find_succ_typings(NewState, NewNotFixpoint2); - none -> - ?debug("==================== Typesig done ====================\n\n", []), - case NotFixpoint =:= [] of - true -> {fixpoint, State}; - false -> {not_fixpoint, NotFixpoint, State} - end +find_succ_typings(SCCs, #st{codeserver = Codeserver, callgraph = Callgraph, + plt = Plt, timing_server = Timing} = State) -> + Init = {Codeserver, Callgraph, Plt}, + NotFixpoint = + ?timing(Timing, "typesig", + dialyzer_coordinator:parallel_job(typesig, SCCs, Init, Timing)), + ?debug("==================== Typesig done ====================\n\n", []), + case NotFixpoint =:= [] of + true -> {fixpoint, State}; + false -> {not_fixpoint, NotFixpoint, State} end. -analyze_scc(SCC, #st{codeserver = Codeserver, - callgraph = Callgraph, - plt = Plt} = State) -> +-spec find_succ_types_for_scc(scc(), typesig_init_data()) -> [mfa_or_funlbl()]. + +find_succ_types_for_scc(SCC, {Codeserver, Callgraph, Plt}) -> SCC_Info = [{MFA, dialyzer_codeserver:lookup_mfa_code(MFA, Codeserver), dialyzer_codeserver:lookup_mod_records(M, Codeserver)} @@ -332,26 +344,18 @@ analyze_scc(SCC, #st{codeserver = Codeserver, || {_, _, _} = MFA <- SCC], Contracts2 = [{MFA, Contract} || {MFA, {ok, Contract}} <- Contracts1], Contracts3 = orddict:from_list(Contracts2), - NextLabel = dialyzer_codeserver:get_next_core_label(Codeserver), - {SuccTypes, PltContracts, NotFixpoint} = - find_succ_types_for_scc(SCC_Info, Contracts3, NextLabel, Callgraph, Plt), - State1 = insert_into_plt(SuccTypes, State), - ContrPlt = dialyzer_plt:insert_contract_list(State1#st.plt, PltContracts), - {State1#st{plt = ContrPlt}, NotFixpoint}. - -find_succ_types_for_scc(SCC_Info, Contracts, NextLabel, Callgraph, Plt) -> - %% Assume that the PLT contains the current propagated types + Label = dialyzer_codeserver:get_next_core_label(Codeserver), AllFuns = collect_fun_info([Fun || {_MFA, {_Var, Fun}, _Rec} <- SCC_Info]), PropTypes = get_fun_types_from_plt(AllFuns, Callgraph, Plt), - FunTypes = dialyzer_typesig:analyze_scc(SCC_Info, NextLabel, - Callgraph, Plt, PropTypes), + %% Assume that the PLT contains the current propagated types + FunTypes = + dialyzer_typesig:analyze_scc(SCC_Info, Label, Callgraph, Plt, PropTypes), AllFunSet = sets:from_list([X || {X, _} <- AllFuns]), - FilteredFunTypes = dict:filter(fun(X, _) -> - sets:is_element(X, AllFunSet) - end, FunTypes), + FilteredFunTypes = + dict:filter(fun(X, _) -> sets:is_element(X, AllFunSet) end, FunTypes), %% Check contracts - PltContracts = dialyzer_contracts:check_contracts(Contracts, Callgraph, - FilteredFunTypes), + PltContracts = + dialyzer_contracts:check_contracts(Contracts3, Callgraph, FilteredFunTypes), ContractFixpoint = lists:all(fun({MFA, _C}) -> %% Check the non-deleted PLT @@ -360,14 +364,14 @@ find_succ_types_for_scc(SCC_Info, Contracts, NextLabel, Callgraph, Plt) -> {value, _} -> true end end, PltContracts), + Plt = insert_into_plt(FilteredFunTypes, Callgraph, Plt), + Plt = dialyzer_plt:insert_contract_list(Plt, PltContracts), case (ContractFixpoint andalso reached_fixpoint_strict(PropTypes, FilteredFunTypes)) of - true -> - {FilteredFunTypes, PltContracts, []}; + true -> []; false -> ?debug("Not fixpoint for: ~w\n", [AllFuns]), - {FilteredFunTypes, PltContracts, - ordsets:from_list([Fun || {Fun, _Arity} <- AllFuns])} + [Fun || {Fun, _Arity} <- AllFuns] end. get_fun_types_from_plt(FunList, Callgraph, Plt) -> @@ -407,10 +411,10 @@ insert_into_doc_plt(FunTypes, Callgraph, DocPlt) -> SuccTypes = format_succ_types(FunTypes, Callgraph), dialyzer_plt:insert_list(DocPlt, SuccTypes). -insert_into_plt(SuccTypes0, #st{callgraph = Callgraph, plt = Plt} = State) -> +insert_into_plt(SuccTypes0, Callgraph, Plt) -> SuccTypes = format_succ_types(SuccTypes0, Callgraph), debug_pp_succ_typings(SuccTypes), - State#st{plt = dialyzer_plt:insert_list(Plt, SuccTypes)}. + dialyzer_plt:insert_list(Plt, SuccTypes). format_succ_types(SuccTypes, Callgraph) -> format_succ_types(dict:to_list(SuccTypes), Callgraph, []). @@ -445,131 +449,3 @@ lookup_name(F, CG) -> error -> F; {ok, Name} -> Name end. - -send_log(none, _Msg) -> - ok; -send_log(Parent, Msg) -> - Parent ! {self(), log, lists:flatten(Msg)}, - ok. - -format_scc(SCC) -> - [MFA || {_M, _F, _A} = MFA <- SCC]. - -%% ============================================================================ -%% -%% Debug interface. -%% -%% ============================================================================ - --spec doit(atom() | file:filename()) -> 'ok'. - -doit(Module) -> - {ok, AbstrCode} = dialyzer_utils:get_abstract_code_from_src(Module), - {ok, Code} = dialyzer_utils:get_core_from_abstract_code(AbstrCode), - {ok, Records} = dialyzer_utils:get_record_and_type_info(AbstrCode), - %% contract typing info in dictionary format - {ok, Contracts, _Callbacks} = - dialyzer_utils:get_spec_info(cerl:concrete(cerl:module_name(Code)), - AbstrCode, Records), - Sigs0 = get_top_level_signatures(Code, Records, Contracts), - M = if is_atom(Module) -> - list_to_atom(filename:basename(atom_to_list(Module))); - is_list(Module) -> - list_to_atom(filename:basename(Module)) - end, - Sigs1 = [{{M, F, A}, Type} || {{F, A}, Type} <- Sigs0], - Sigs = ordsets:from_list(Sigs1), - io:format("==================== Final result ====================\n\n", []), - pp_signatures(Sigs, Records), - ok. - --spec get_top_level_signatures(cerl:c_module(), dict(), dict()) -> - [{{atom(), arity()}, erl_types:erl_type()}]. - -get_top_level_signatures(Code, Records, Contracts) -> - Tree = cerl:from_records(Code), - {LabeledTree, NextLabel} = cerl_trees:label(Tree), - Plt = get_def_plt(), - ModuleName = cerl:atom_val(cerl:module_name(LabeledTree)), - Plt1 = dialyzer_plt:delete_module(Plt, ModuleName), - Plt2 = analyze_module(LabeledTree, NextLabel, Plt1, Records, Contracts), - M = cerl:concrete(cerl:module_name(Tree)), - Functions = [{M, cerl:fname_id(V), cerl:fname_arity(V)} - || {V, _F} <- cerl:module_defs(LabeledTree)], - %% First contracts check - AllContracts = dict:fetch_keys(Contracts), - ErrorContracts = AllContracts -- Functions, - lists:foreach(fun(C) -> - io:format("Contract for non-existing function: ~w\n",[C]) - end, ErrorContracts), - Types = [{MFA, dialyzer_plt:lookup(Plt2, MFA)} || MFA <- Functions], - Sigs = [{{F, A}, erl_types:t_fun(ArgT, RetT)} - || {{_M, F, A}, {value, {RetT, ArgT}}} <- Types], - ordsets:from_list(Sigs). - -get_def_plt() -> - try - dialyzer_plt:from_file(dialyzer_plt:get_default_plt()) - catch - error:no_such_file -> dialyzer_plt:new(); - throw:{dialyzer_error, _} -> dialyzer_plt:new() - end. - -pp_signatures([{{_, module_info, 0}, _}|Left], Records) -> - pp_signatures(Left, Records); -pp_signatures([{{_, module_info, 1}, _}|Left], Records) -> - pp_signatures(Left, Records); -pp_signatures([{{M, F, _A}, Type}|Left], Records) -> - TypeString = - case cerl:is_literal(Type) of -%% Commented out so that dialyzer does not complain -%% false -> -%% "fun(" ++ String = erl_types:t_to_string(Type, Records), -%% string:substr(String, 1, length(String)-1); - true -> - io_lib:format("~w", [cerl:concrete(Type)]) - end, - io:format("~w:~w~s\n", [M, F, TypeString]), - pp_signatures(Left, Records); -pp_signatures([], _Records) -> - ok. - --ifdef(DEBUG_PP). -debug_pp(Tree, _Map) -> - Tree1 = strip_annotations(Tree), - io:put_chars(cerl_prettypr:format(Tree1)), - io:nl(). - -strip_annotations(Tree) -> - cerl_trees:map(fun(T) -> - case cerl:is_literal(T) orelse cerl:is_c_values(T) of - true -> cerl:set_ann(T, []); - false -> - Label = cerl_trees:get_label(T), - cerl:set_ann(T, [{'label', Label}]) - end - end, Tree). --else. -debug_pp(_Tree, _Map) -> - ok. --endif. % DEBUG_PP - -%% -%% Analysis of a single module -%% -analyze_module(LabeledTree, NextLbl, Plt, Records, Contracts) -> - debug_pp(LabeledTree, dict:new()), - CallGraph1 = dialyzer_callgraph:new(), - CallGraph2 = dialyzer_callgraph:scan_core_tree(LabeledTree, CallGraph1), - {CallGraph3, _Ext} = dialyzer_callgraph:remove_external(CallGraph2), - CallGraph4 = dialyzer_callgraph:finalize(CallGraph3), - CodeServer1 = dialyzer_codeserver:new(), - Mod = cerl:concrete(cerl:module_name(LabeledTree)), - CodeServer2 = dialyzer_codeserver:insert(Mod, LabeledTree, CodeServer1), - CodeServer3 = dialyzer_codeserver:set_next_core_label(NextLbl, CodeServer2), - CodeServer4 = dialyzer_codeserver:store_records(Mod, Records, CodeServer3), - CodeServer5 = dialyzer_codeserver:store_contracts(Mod, Contracts, CodeServer4), - Res = analyze_callgraph(CallGraph4, Plt, CodeServer5), - dialyzer_callgraph:delete(CallGraph4), - dialyzer_codeserver:delete(CodeServer5), - Res. diff --git a/lib/dialyzer/src/dialyzer_timing.erl b/lib/dialyzer/src/dialyzer_timing.erl new file mode 100644 index 0000000000..b1a4bdc07c --- /dev/null +++ b/lib/dialyzer/src/dialyzer_timing.erl @@ -0,0 +1,133 @@ +%% -*- erlang-indent-level: 2 -*- +%%------------------------------------------------------------------- +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2006-2012. 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 : dialyzer_timing.erl +%%% Authors : Stavros Aronis <[email protected]> +%%% Description : Timing reports for Dialyzer +%%%------------------------------------------------------------------- + +-module(dialyzer_timing). + +-export([init/1, start_stamp/2, send_size_info/3, end_stamp/1, stop/1]). + +-export_type([timing_server/0]). + +-type timing_server() :: pid() | 'none'. + +-spec init(boolean() | 'debug') -> timing_server(). + +init(Active) -> + case Active of + true -> + io:format("\n"), + spawn_link(fun() -> loop(now(), 0, "") end); + debug -> + io:format("\n"), + spawn_link(fun() -> debug_loop("") end); + false -> none + end. + +loop(LastNow, Size, Unit) -> + receive + {stamp, Msg, Now} -> + io:format(" ~-10s (+~4.2fs):", [Msg, diff(Now, LastNow)]), + loop(Now, 0, ""); + {stamp, Now} -> + SizeStr = + case Size of + 0 -> ""; + _ -> + Data = io_lib:format("~p ~s",[Size, Unit]), + io_lib:format(" (~12s)",[Data]) + end, + io:format("~7.2fs~s\n", [diff(Now, LastNow), SizeStr]), + loop(Now, 0, ""); + {size, NewSize, NewUnit} -> + loop(LastNow, NewSize, NewUnit); + {Pid, stop, Now} -> + io:format(" ~-9s (+~5.2fs)\n", ["",diff(Now, LastNow)]), + Pid ! ok; + {Pid, stop} -> + Pid ! ok + end. + +debug_loop(Phase) -> + receive + Message -> + {Runtime,_} = statistics(wall_clock), + Procs = erlang:system_info(process_count), + ProcMem = erlang:memory(total), + Status = io_lib:format("~12w ~6w ~20w", [Runtime, Procs, ProcMem]), + case Message of + {stamp, Msg, _Now} -> + io:format("~s ~s_start\n", [Status, Msg]), + debug_loop(Msg); + {stamp, _Now} -> + io:format("~s ~s_stop\n", [Status, Phase]), + debug_loop(""); + {Pid, stop, _Now} -> + Pid ! ok; + {Pid, stop} -> + Pid ! ok; + _ -> + debug_loop(Phase) + end + after + 50 -> + {Runtime,_} = statistics(wall_clock), + Procs = erlang:system_info(process_count), + ProcMem = erlang:memory(total), + Status = io_lib:format("~12w ~6w ~20w", [Runtime, Procs, ProcMem]), + io:format("~s\n", [Status]), + debug_loop(Phase) + end. + + +-spec start_stamp(timing_server(), string()) -> ok. + +start_stamp(none, _) -> ok; +start_stamp(Pid, Msg) -> + Pid ! {stamp, Msg, now()}, + ok. + +-spec end_stamp(timing_server()) -> ok. + +end_stamp(none) -> ok; +end_stamp(Pid) -> + Pid ! {stamp, now()}, + ok. + +-spec send_size_info(timing_server(), integer(), string()) -> ok. + +send_size_info(none, _, _) -> ok; +send_size_info(Pid, Size, Unit) -> + Pid ! {size, Size, Unit}, + ok. + +-spec stop(timing_server()) -> ok. + +stop(none) -> ok; +stop(Pid) -> + Pid ! {self(), stop, now()}, + receive ok -> ok end. + +diff(T2, T1) -> + timer:now_diff(T2,T1) / 1000000. diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index d0d27740f3..e997eedf76 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -91,23 +91,25 @@ -type typesig_scc() :: [{mfa(), {cerl:c_var(), cerl:c_fun()}, dict()}]. -type typesig_funmap() :: [{type_var(), type_var()}]. %% Orddict --record(state, {callgraph :: dialyzer_callgraph:callgraph(), - cs = [] :: [constr()], - cmap = dict:new() :: dict(), - fun_map = [] :: typesig_funmap(), - fun_arities = dict:new() :: dict(), - in_match = false :: boolean(), - in_guard = false :: boolean(), - module :: module(), - name_map = dict:new() :: dict(), - next_label :: label(), - self_recs :: [label()], - plt :: dialyzer_plt:plt(), - prop_types = dict:new() :: dict(), - records = dict:new() :: dict(), - opaques = [] :: [erl_types:erl_type()], - scc = [] :: [type_var()], - mfas = [] :: [dialyzer_callgraph:mfa_or_funlbl()] +-type dict_or_ets() :: {'d', dict()} | {'e', ets:tid()}. + +-record(state, {callgraph :: dialyzer_callgraph:callgraph(), + cs = [] :: [constr()], + cmap = {'d', dict:new()} :: dict_or_ets(), + fun_map = [] :: typesig_funmap(), + fun_arities = dict:new() :: dict(), + in_match = false :: boolean(), + in_guard = false :: boolean(), + module :: module(), + name_map = dict:new() :: dict(), + next_label = 0 :: label(), + self_rec :: erl_types:erl_type(), + plt :: dialyzer_plt:plt(), + prop_types = {'d', dict:new()} :: dict_or_ets(), + records = dict:new() :: dict(), + opaques = [] :: [erl_types:erl_type()], + scc = [] :: [type_var()], + mfas :: [tuple()] }). %%----------------------------------------------------------------------------- @@ -1665,7 +1667,12 @@ solve([Fun], State) -> solve([_|_] = SCC, State) -> ?debug("============ Analyzing SCC: ~w ===========\n", [[debug_lookup_name(F) || F <- SCC]]), - solve_scc(SCC, dict:new(), State, false). + {Parallel, NewState} = + case parallel_split(SCC) of + false -> {false, State}; + SplitSCC -> {SplitSCC, minimize_state(State)} + end, + solve_scc(SCC, Parallel, dict:new(), NewState, false). solve_fun(Fun, FunMap, State) -> Cs = state__get_cs(Fun, State), @@ -1680,8 +1687,7 @@ solve_fun(Fun, FunMap, State) -> end, enter_type(Fun, NewType, NewFunMap1). -solve_scc(SCC, Map, State, TryingUnit) -> - State1 = state__mark_as_non_self_rec(SCC, State), +solve_scc(SCC, Parallel, Map, State, TryingUnit) -> Vars0 = [{Fun, state__get_rec_var(Fun, State)} || Fun <- SCC], Vars = [Var || {_, {ok, Var}} <- Vars0], Funs = [Fun || {Fun, {ok, _}} <- Vars0], @@ -1692,9 +1698,12 @@ solve_scc(SCC, Map, State, TryingUnit) -> end, Map, SCC), Map1 = enter_type_lists(Vars, RecTypes, CleanMap), ?debug("Checking SCC: ~w\n", [[debug_lookup_name(F) || F <- SCC]]), - SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State1) end, - Map2 = lists:foldl(SolveFun, Map1, SCC), FunSet = ordsets:from_list([t_var_name(F) || F <- SCC]), + Map2 = + case Parallel of + false -> solve_whole_scc(SCC, Map1, State); + SplitSCC -> solve_whole_scc_parallel(SplitSCC, Map1, State) + end, case maps_are_equal(Map2, Map, FunSet) of true -> ?debug("SCC ~w reached fixpoint\n", [SCC]), @@ -1708,15 +1717,127 @@ solve_scc(SCC, Map, State, TryingUnit) -> true -> t_fun(t_fun_args(T), t_unit()) end || T <- NewTypes], Map3 = enter_type_lists(Funs, UnitTypes, Map2), - solve_scc(SCC, Map3, State, true); + solve_scc(SCC, Parallel, Map3, State, true); false -> + case Parallel of + false -> true; + _ -> dispose_state(State) + end, Map2 end; false -> ?debug("SCC ~w did not reach fixpoint\n", [SCC]), - solve_scc(SCC, Map2, State, TryingUnit) + solve_scc(SCC, Parallel, Map2, State, TryingUnit) + end. + +solve_whole_scc(SCC, Map, State) -> + SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State) end, + lists:foldl(SolveFun, Map, SCC). + +%%------------------------------------------------------------------------------ + +-define(worth_it, 42). + +parallel_split(SCC) -> + Length = length(SCC), + case Length > 2*?worth_it of + false -> false; + true -> + case min(dialyzer_utils:parallelism(), 8) of + 1 -> false; + CPUs -> + FullShare = Length div CPUs + 1, + Unit = max(FullShare, ?worth_it), + split(SCC, Unit, []) + end + end. + +minimize_state(#state{ + cmap = {d, CMap}, + fun_map = FunMap, + fun_arities = FunArities, + self_rec = SelfRec, + prop_types = {d, PropTypes}, + opaques = Opaques + }) -> + ETSCMap = ets:new(cmap,[{read_concurrency, true}]), + ETSPropTypes = ets:new(prop_types,[{read_concurrency, true}]), + true = ets:insert(ETSCMap, dict:to_list(CMap)), + true = ets:insert(ETSPropTypes, dict:to_list(PropTypes)), + #state + {cmap = {e, ETSCMap}, + fun_map = FunMap, + fun_arities = FunArities, + self_rec = SelfRec, + prop_types = {e, ETSPropTypes}, + opaques = Opaques + }. + +dispose_state(#state{cmap = {e, ETSCMap}, + prop_types = {e, ETSPropTypes}}) -> + true = ets:delete(ETSCMap), + true = ets:delete(ETSPropTypes). + +solve_whole_scc_parallel(SplitSCC, Map, State) -> + Workers = spawn_workers(SplitSCC, Map, State), + wait_results(Workers, Map, fold_res_fun(State)). + +spawn_workers(SplitSCC, Map, State) -> + Spawner = solve_scc_spawner(self(), Map, State), + lists:foreach(Spawner, SplitSCC), + length(SplitSCC). + +wait_results(0, Map, _FoldResFun) -> + Map; +wait_results(Pending, Map, FoldResFun) -> + Res = receive_scc_result(), + NewMap = lists:foldl(FoldResFun, Map, Res), + wait_results(Pending-1, NewMap, FoldResFun). + +solve_scc_spawner(Parent, Map, State) -> + fun(SCCPart) -> + spawn_link(fun() -> solve_scc_worker(Parent, SCCPart, Map, State) end) + end. + +split([], _Unit, Acc) -> + Acc; +split(List, Unit, Acc) -> + {Taken, Rest} = + try + lists:split(Unit, List) + catch + _:_ -> {List, []} + end, + split(Rest, Unit, [Taken|Acc]). + +solve_scc_worker(Parent, SCCPart, Map, State) -> + SolveFun = fun(X, Y) -> scc_fold_fun(X, Y, State) end, + FinalMap = lists:foldl(SolveFun, Map, SCCPart), + Res = + [{F, t_limit(unsafe_lookup_type(F, FinalMap), ?TYPE_LIMIT)} || + F <- SCCPart], + send_scc_result(Parent, Res). + +fold_res_fun(State) -> + fun({F, Type}, Map) -> + case state__get_rec_var(F, State) of + {ok, R} -> + enter_type(R, Type, enter_type(F, Type, Map)); + error -> + enter_type(F, Type, Map) + end end. +receive_scc_result() -> + receive + {scc_fun, Res} -> Res + end. + +send_scc_result(Parent, Res) -> + Parent ! {scc_fun, Res}. + +%%------------------------------------------------------------------------------ + scc_fold_fun(F, FunMap, State) -> Deps = get_deps(state__get_cs(F, State)), Cs = mk_constraint_ref(F, Deps), @@ -1787,13 +1908,17 @@ solve_ref_or_list(#constraint_list{type=Type, list = Cs, deps = Deps, id = Id}, {ok, M} -> {M, true} end, ?debug("Checking ref to list: ~w\n", [Id]), - case Check andalso maps_are_equal(OldLocalMap, Map, Deps) of + if + OldLocalMap =:= error -> {error, MapDict}; true -> - ?debug("~w equal ~w\n", [Type, Id]), - {ok, MapDict, Map}; - false -> - ?debug("~w not equal: ~w. Solving\n", [Type, Id]), - solve_clist(Cs, Type, Id, Deps, MapDict, Map, State) + case Check andalso maps_are_equal(OldLocalMap, Map, Deps) of + true -> + ?debug("~w equal ~w\n", [Type, Id]), + {ok, MapDict, Map}; + false -> + ?debug("~w not equal: ~w. Solving\n", [Type, Id]), + solve_clist(Cs, Type, Id, Deps, MapDict, Map, State) + end end. solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> @@ -1802,7 +1927,7 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> ?debug("OldRecType ~s\n", [format_type(RecType0)]), RecType = t_limit(RecType0, ?TYPE_LIMIT), Map1 = enter_type(RecVar, RecType, dict:erase(t_var_name(Id), Map)), - ?debug("\tMap in: ~p\n",[[{X, format_type(Y)}||{X, Y}<-dict:to_list(Map1)]]), + pp_map("Map1", Map1), case solve_ref_or_list(Cs, Map1, MapDict, State) of {error, _} = Error -> case t_is_none(RecType0) of @@ -1815,8 +1940,7 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> Error end; {ok, NewMapDict, NewMap} -> - ?debug("\tMap: ~p\n", - [[{X, format_type(Y)} || {X, Y} <- dict:to_list(NewMap)]]), + pp_map("NewMap", NewMap), NewRecType = unsafe_lookup_type(Id, NewMap), case t_is_equal(NewRecType, RecType0) of true -> @@ -1828,7 +1952,8 @@ solve_self_recursive(Cs, Map, MapDict, Id, RecType0, State) -> solve_clist(Cs, conj, Id, Deps, MapDict, Map, State) -> case solve_cs(Cs, Map, MapDict, State) of - {error, _} = Error -> Error; + {error, NewMapDict} -> + {error, dict:store(Id, error, NewMapDict)}; {ok, NewMapDict, NewMap} = Ret -> case Cs of [_] -> @@ -1850,7 +1975,7 @@ solve_clist(Cs, disj, Id, _Deps, MapDict, Map, State) -> end, {Maps, NewMapDict} = lists:mapfoldl(Fun, MapDict, Cs), case [X || {ok, X} <- Maps] of - [] -> {error, NewMapDict}; + [] -> {error, dict:store(Id, error, NewMapDict)}; MapList -> NewMap = join_maps(MapList), {ok, dict:store(Id, NewMap, NewMapDict), NewMap} @@ -1926,6 +2051,8 @@ solve_subtype(Type, Inf, Map, Opaques) -> %% %% ============================================================================ +join_maps([Map]) -> + Map; join_maps(Maps) -> Keys = lists:foldl(fun(TmpMap, AccKeys) -> [Key || Key <- AccKeys, dict:is_key(Key, TmpMap)] @@ -2079,6 +2206,12 @@ mk_var_no_lit(Var) -> mk_var_no_lit_list(List) -> [mk_var_no_lit(X) || X <- List]. +pp_map(_S, _Map) -> + ?debug("\t~s: ~p\n", + [_S, [{X, lists:flatten(format_type(Y))} || + {X, Y} <- lists:keysort(1, dict:to_list(_Map))]]). + + %% ============================================================================ %% %% The State. @@ -2090,11 +2223,19 @@ new_state(SCC0, NextLabel, CallGraph, Plt, PropTypes) -> NameMap = dict:from_list(List), MFAs = [MFA || {MFA, _Var} <- List], SCC = [mk_var(Fun) || {_MFA, {_Var, Fun}, _Rec} <- SCC0], - SelfRecs = [F || F <- SCC, - dialyzer_callgraph:is_self_rec(t_var_name(F), CallGraph)], + SelfRec = + case SCC of + [OneF] -> + Label = t_var_name(OneF), + case dialyzer_callgraph:is_self_rec(Label, CallGraph) of + true -> OneF; + false -> false + end; + _Many -> false + end, #state{callgraph = CallGraph, name_map = NameMap, next_label = NextLabel, - prop_types = PropTypes, plt = Plt, scc = ordsets:from_list(SCC), - mfas = MFAs, self_recs = ordsets:from_list(SelfRecs)}. + prop_types = {d, PropTypes}, plt = Plt, scc = ordsets:from_list(SCC), + mfas = MFAs, self_rec = SelfRec}. state__set_rec_dict(State, RecDict) -> State#state{records = RecDict}. @@ -2193,14 +2334,21 @@ state__plt(#state{plt = PLT}) -> state__new_constraint_context(State) -> State#state{cs = []}. -state__prop_domain(FunLabel, #state{prop_types = PropTypes}) -> +state__prop_domain(FunLabel, #state{prop_types = {e, ETSPropTypes}}) -> + try ets:lookup_element(ETSPropTypes, FunLabel, 2) of + {_Range_Fun, Dom} -> {ok, Dom}; + FunType -> {ok, t_fun_args(FunType)} + catch + _:_ -> error + end; +state__prop_domain(FunLabel, #state{prop_types = {d, PropTypes}}) -> case dict:find(FunLabel, PropTypes) of error -> error; {ok, {_Range_Fun, Dom}} -> {ok, Dom}; {ok, FunType} -> {ok, t_fun_args(FunType)} end. -state__add_prop_constrs(Tree, #state{prop_types = PropTypes} = State) -> +state__add_prop_constrs(Tree, #state{prop_types = {d, PropTypes}} = State) -> Label = cerl_trees:get_label(Tree), case dict:find(Label, PropTypes) of error -> State; @@ -2263,21 +2411,17 @@ state__mk_vars(N, #state{next_label = NL} = State) -> Vars = [t_var(X) || X <- lists:seq(NL, NewLabel-1)], {State#state{next_label = NewLabel}, Vars}. -state__store_constrs(Id, Cs, #state{cmap = Dict} = State) -> +state__store_constrs(Id, Cs, #state{cmap = {d, Dict}} = State) -> NewDict = dict:store(Id, Cs, Dict), - State#state{cmap = NewDict}. + State#state{cmap = {d, NewDict}}. -state__get_cs(Var, #state{cmap = Dict}) -> +state__get_cs(Var, #state{cmap = {e, ETSDict}}) -> + ets:lookup_element(ETSDict, Var, 2); +state__get_cs(Var, #state{cmap = {d, Dict}}) -> dict:fetch(Var, Dict). -%% The functions here will not be treated as self recursive. -%% These functions will need to be handled as such manually. -state__mark_as_non_self_rec(SCC, #state{self_recs = SelfRecs} = State) -> - %% TODO: Check if the result is always empty and just set it to [] if so. - State#state{self_recs = ordsets:subtract(SelfRecs, ordsets:from_list(SCC))}. - -state__is_self_rec(Fun, #state{self_recs = SelfRecs}) -> - ordsets:is_element(Fun, SelfRecs). +state__is_self_rec(Fun, #state{self_rec = SelfRec}) -> + Fun =:= SelfRec. state__store_funs(Vars0, Funs0, #state{fun_map = Map} = State) -> debug_make_name_map(Vars0, Funs0), @@ -2523,19 +2667,21 @@ enumerate_constraints([#constraint_ref{id = Id} = C|Tail], N, Acc, State) -> enumerate_constraints([#constraint_list{type = conj, list = List} = C|Tail], N, Acc, State) -> %% Separate the flat constraints from the deep ones to make a - %% separate fixpoint interation over the flat ones for speed. - {Flat, Deep} = lists:splitwith(fun(#constraint{}) -> true; + %% separate fixpoint iteration over the flat ones for speed. + {Flat, Deep} = lists:partition(fun(#constraint{}) -> true; (#constraint_list{}) -> false; (#constraint_ref{}) -> false end, List), {NewFlat, N1, State1} = enumerate_constraints(Flat, N, [], State), {NewDeep, N2, State2} = enumerate_constraints(Deep, N1, [], State1), {NewList, N3} = - case shorter_than_two(NewFlat) orelse (NewDeep =:= []) of - true -> {NewFlat ++ NewDeep, N2}; - false -> - {NewCLists, TmpN} = group_constraints_in_components(NewFlat, N2), - {NewCLists ++ NewDeep, TmpN} + if + NewFlat =:= [] -> {NewDeep, N2}; + NewDeep =:= [] -> {NewFlat, N2}; + true -> + TmpCList = mk_conj_constraint_list(NewFlat), + {[TmpCList#constraint_list{id = {list, N2}} | NewDeep], + N2 + 1} end, NewAcc = [C#constraint_list{list = NewList, id = {list, N3}}|Acc], enumerate_constraints(Tail, N3+1, NewAcc, State2); @@ -2549,42 +2695,6 @@ enumerate_constraints([#constraint{} = C|Tail], N, Acc, State) -> enumerate_constraints([], N, Acc, State) -> {lists:reverse(Acc), N, State}. -shorter_than_two([]) -> true; -shorter_than_two([_]) -> true; -shorter_than_two([_|_]) -> false. - -group_constraints_in_components(Cs, N) -> - DepList = [Deps || #constraint{deps = Deps} <- Cs], - case find_dep_components(DepList, []) of - [_] -> {Cs, N}; - [_|_] = Components -> - ConstrComp = [[C || #constraint{deps = D} = C <- Cs, - ordsets:is_subset(D, Comp)] - || Comp <- Components], - lists:mapfoldl(fun(CComp, TmpN) -> - TmpCList = mk_conj_constraint_list(CComp), - {TmpCList#constraint_list{id = {list, TmpN}}, - TmpN + 1} - end, N, ConstrComp) - end. - -find_dep_components([Set|Left], AccComponents) -> - {Component, Ungrouped} = find_dep_components(Left, Set, []), - case Component =:= Set of - true -> find_dep_components(Ungrouped, [Component|AccComponents]); - false -> find_dep_components([Component|Ungrouped], AccComponents) - end; -find_dep_components([], AccComponents) -> - AccComponents. - -find_dep_components([Set|Left], AccSet, Ungrouped) -> - case ordsets:intersection(Set, AccSet) of - [] -> find_dep_components(Left, AccSet, [Set|Ungrouped]); - [_|_] -> find_dep_components(Left, ordsets:union(Set, AccSet), Ungrouped) - end; -find_dep_components([], AccSet, Ungrouped) -> - {AccSet, Ungrouped}. - %% Put the fun ref constraints last in any conjunction since we need %% to separate the environment from the interior of the function. order_fun_constraints(State) -> @@ -2714,13 +2824,24 @@ lookup_record(Records, Tag, Arity) -> -ifdef(DEBUG). format_type(#fun_var{deps = Deps, origin = Origin}) -> - io_lib:format("Fun@L~p(~s)", - [Origin, lists:flatten([format_type(t_var(X))||X<-Deps])]); + L = [format_type(t_var(X)) || X <- Deps], + io_lib:format("Fun@L~p(~s)", [Origin, join_chars(L, ",")]); format_type(Type) -> case cerl:is_literal(Type) of true -> io_lib:format("~w", [cerl:concrete(Type)]); false -> erl_types:t_to_string(Type) end. + +join_chars([], _Sep) -> + []; +join_chars([H | T], Sep) -> + [H | [[Sep,X] || X <- T]]. + +debug_lookup_name(Var) -> + case dict:find(t_var_name(Var), get(dialyzer_typesig_map)) of + error -> Var; + {ok, Name} -> Name + end. -endif. -ifdef(DEBUG_NAME_MAP). @@ -2739,12 +2860,6 @@ debug_make_name_map([Var|VarLeft], [Fun|FunLeft], Map) -> debug_make_name_map([], [], Map) -> Map. -debug_lookup_name(Var) -> - case dict:find(t_var_name(Var), get(dialyzer_typesig_map)) of - error -> Var; - {ok, Name} -> Name - end. - -else. debug_make_name_map(_Vars, _Funs) -> ok. @@ -2755,51 +2870,55 @@ pp_constrs_scc(SCC, State) -> [pp_constrs(Fun, state__get_cs(Fun, State), State) || Fun <- SCC]. pp_constrs(Fun, Cs, State) -> - io:format("Constraints for fun: ~w\n", [debug_lookup_name(Fun)]), + io:format("Constraints for fun: ~w", [debug_lookup_name(Fun)]), MaxDepth = pp_constraints(Cs, State), io:format("Depth: ~w\n", [MaxDepth]). pp_constraints(Cs, State) -> - Res = pp_constraints([Cs], none, 0, 0, State), + Res = pp_constraints([Cs], 0, 0, State), io:nl(), Res. -pp_constraints([List|Tail], Separator, Level, MaxDepth, - State) when is_list(List) -> - pp_constraints(List++Tail, Separator, Level, MaxDepth, State); -pp_constraints([#constraint_ref{id = Id}|Left], Separator, - Level, MaxDepth, State) -> +pp_constraints([List|Tail], Level, MaxDepth, State) when is_list(List) -> + pp_constraints(List++Tail, Level, MaxDepth, State); +pp_constraints([#constraint_ref{id = Id}|Left], Level, MaxDepth, State) -> Cs = state__get_cs(Id, State), + pp_indent(Level), io:format("%Ref ~w%", [t_var_name(Id)]), - pp_constraints([Cs|Left], Separator, Level, MaxDepth, State); -pp_constraints([#constraint{lhs = Lhs, op = Op, rhs = Rhs}], _Separator, - Level, MaxDepth, _State) -> - io:format("~s ~w ~s", [format_type(Lhs), Op, format_type(Rhs)]), + pp_constraints([Cs|Left], Level, MaxDepth, State); +pp_constraints([#constraint{}=C], Level, MaxDepth, _State) -> + pp_op(C, Level), erlang:max(Level, MaxDepth); -pp_constraints([#constraint{lhs = Lhs, op = Op, rhs = Rhs}|Tail], Separator, - Level, MaxDepth, State) -> - io:format("~s ~w ~s ~s ", [format_type(Lhs), Op, format_type(Rhs),Separator]), - pp_constraints(Tail, Separator, Level, MaxDepth, State); +pp_constraints([#constraint{}=C|Tail], Level, MaxDepth, State) -> + pp_op(C, Level), + pp_constraints(Tail, Level, MaxDepth, State); pp_constraints([#constraint_list{type = Type, list = List, id = Id}], - _Separator, Level, MaxDepth, State) -> - io:format("%List ~w(", [Id]), - NewSeparator = case Type of - conj -> "*"; - disj -> "+" - end, - NewMaxDepth = pp_constraints(List, NewSeparator, Level + 1, MaxDepth, State), + Level, MaxDepth, State) -> + pp_indent(Level), + case Type of + conj -> io:format("Conj ~w (", [Id]); + disj -> io:format("Disj ~w (", [Id]) + end, + NewMaxDepth = pp_constraints(List, Level + 1, MaxDepth, State), io:format(")", []), NewMaxDepth; pp_constraints([#constraint_list{type = Type, list = List, id = Id}|Tail], - Separator, Level, MaxDepth, State) -> - io:format("List ~w(", [Id]), - NewSeparator = case Type of - conj -> "*"; - disj -> "+" - end, - NewMaxDepth = pp_constraints(List, NewSeparator, Level+1, MaxDepth, State), - io:format(") ~s\n~s ", [Separator, Separator]), - pp_constraints(Tail, Separator, Level, NewMaxDepth, State). + Level, MaxDepth, State) -> + pp_indent(Level), + case Type of + conj -> io:format("Conj ~w (", [Id]); + disj -> io:format("Disj ~w (", [Id]) + end, + NewMaxDepth = pp_constraints(List, Level+1, MaxDepth, State), + io:format(")", []), + pp_constraints(Tail, Level, NewMaxDepth, State). + +pp_op(#constraint{lhs = Lhs, op = Op, rhs = Rhs}, Level) -> + pp_indent(Level), + io:format("~s ~w ~s", [format_type(Lhs), Op, format_type(Rhs)]). + +pp_indent(Level) -> + io:format("\n~*s", [Level*2, ""]). -else. pp_constrs_scc(_SCC, _State) -> ok. diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index 2a248fb028..149e777e1f 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -43,7 +43,8 @@ pp_hook/0, process_record_remote_types/1, sets_filter/2, - src_compiler_opts/0 + src_compiler_opts/0, + parallelism/0 ]). -include("dialyzer.hrl"). @@ -536,3 +537,12 @@ pp_unit(Unit, Ctxt, Cont) -> pp_atom(Atom) -> String = atom_to_list(cerl:atom_val(Atom)), prettypr:text(String). + +%%------------------------------------------------------------------------------ + +-spec parallelism() -> integer(). + +parallelism() -> + CPUs = erlang:system_info(logical_processors_available), + Schedulers = erlang:system_info(schedulers), + min(CPUs, Schedulers). diff --git a/lib/dialyzer/src/dialyzer_worker.erl b/lib/dialyzer/src/dialyzer_worker.erl new file mode 100644 index 0000000000..50b2e31ed8 --- /dev/null +++ b/lib/dialyzer/src/dialyzer_worker.erl @@ -0,0 +1,189 @@ +%% -*- erlang-indent-level: 2 -*- +%%----------------------------------------------------------------------- +%% %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% +%% + +-module(dialyzer_worker). + +-export([launch/4, sequential/4]). + +-export_type([worker/0]). + +-type worker() :: pid(). %%opaque + +-type mode() :: dialyzer_coordinator:mode(). +-type coordinator() :: dialyzer_coordinator:coordinator(). +-type init_data() :: dialyzer_coordinator:init_data(). +-type result() :: dialyzer_coordinator:result(). + +-record(state, { + mode :: mode(), + job :: mfa_or_funlbl() | file:filename(), + coordinator :: coordinator(), + init_data :: init_data(), + depends_on = [] :: list() + }). + +-include("dialyzer.hrl"). + +%% -define(DEBUG, true). + +-ifdef(DEBUG). +-define(debug(X__, Y__), io:format(X__, Y__)). +-else. +-define(debug(X__, Y__), ok). +-endif. + +%%-------------------------------------------------------------------- + +-spec launch(mode(), [mfa_or_funlbl()], init_data(), coordinator()) -> worker(). + +launch(Mode, Job, InitData, Coordinator) -> + State = #state{mode = Mode, + job = Job, + init_data = InitData, + coordinator = Coordinator}, + InitState = + case Mode of + X when X =:= 'typesig'; X =:= 'dataflow' -> initializing; + X when X =:= 'compile'; X =:= 'warnings' -> running + end, + spawn_link(fun() -> loop(InitState, State) end). + +%%-------------------------------------------------------------------- + +loop(updating, State) -> + ?debug("Update: ~p\n",[State#state.job]), + NextStatus = + case waits_more_success_typings(State) of + true -> waiting; + false -> running + end, + loop(NextStatus, State); +loop(initializing, #state{job = SCC, init_data = InitData} = State) -> + DependsOn = dialyzer_succ_typings:find_depends_on(SCC, InitData), + ?debug("Deps ~p: ~p\n",[State#state.job, DependsOn]), + loop(updating, State#state{depends_on = DependsOn}); +loop(waiting, State) -> + ?debug("Wait: ~p\n",[State#state.job]), + NewState = wait_for_success_typings(State), + loop(updating, NewState); +loop(running, #state{mode = 'compile'} = State) -> + dialyzer_coordinator:wait_activation(), + ?debug("Compile: ~s\n",[State#state.job]), + Result = + case start_compilation(State) of + {ok, EstimatedSize, Data} -> + Label = ask_coordinator_for_label(EstimatedSize, State), + continue_compilation(Label, Data); + {error, _Reason} = Error -> + Error + end, + report_to_coordinator(Result, State); +loop(running, #state{mode = 'warnings'} = State) -> + dialyzer_coordinator:wait_activation(), + ?debug("Warning: ~s\n",[State#state.job]), + Result = collect_warnings(State), + report_to_coordinator(Result, State); +loop(running, #state{mode = Mode} = State) when + Mode =:= 'typesig'; Mode =:= 'dataflow' -> + request_activation(State), + ?debug("Run: ~p\n",[State#state.job]), + NotFixpoint = do_work(State), + ok = broadcast_done(State), + report_to_coordinator(NotFixpoint, State). + +waits_more_success_typings(#state{depends_on = Depends}) -> + Depends =/= []. + +broadcast_done(#state{job = SCC, init_data = InitData, + coordinator = Coordinator}) -> + RequiredBy = dialyzer_succ_typings:find_required_by(SCC, InitData), + {Callers, Unknown} = + dialyzer_coordinator:sccs_to_pids(RequiredBy, Coordinator), + send_done(Callers, SCC), + continue_broadcast_done(Unknown, SCC, Coordinator). + +send_done(Callers, SCC) -> + ?debug("Sending ~p: ~p\n",[SCC, Callers]), + SendSTFun = fun(PID) -> PID ! {done, SCC} end, + lists:foreach(SendSTFun, Callers). + +continue_broadcast_done([], _SCC, _Coordinator) -> ok; +continue_broadcast_done(Rest, SCC, Coordinator) -> + %% This time limit should be greater than the time required + %% by the coordinator to spawn all processes. + timer:sleep(500), + {Callers, Unknown} = dialyzer_coordinator:sccs_to_pids(Rest, Coordinator), + send_done(Callers, SCC), + continue_broadcast_done(Unknown, SCC, Coordinator). + +wait_for_success_typings(#state{depends_on = DependsOn} = State) -> + receive + {done, SCC} -> + ?debug("GOT ~p: ~p\n",[State#state.job, SCC]), + State#state{depends_on = DependsOn -- [SCC]} + after + 5000 -> + ?debug("Still Waiting ~p: ~p\n",[State#state.job, DependsOn]), + State + end. + +request_activation(#state{coordinator = Coordinator}) -> + dialyzer_coordinator:request_activation(Coordinator). + +do_work(#state{mode = Mode, job = Job, init_data = InitData}) -> + case Mode of + typesig -> dialyzer_succ_typings:find_succ_types_for_scc(Job, InitData); + dataflow -> dialyzer_succ_typings:refine_one_module(Job, InitData) + end. + +report_to_coordinator(Result, #state{job = Job, coordinator = Coordinator}) -> + ?debug("Done: ~p\n",[Job]), + dialyzer_coordinator:job_done(Job, Result, Coordinator). + +start_compilation(#state{job = Job, init_data = InitData}) -> + dialyzer_analysis_callgraph:start_compilation(Job, InitData). + +ask_coordinator_for_label(EstimatedSize, #state{coordinator = Coordinator}) -> + dialyzer_coordinator:get_next_label(EstimatedSize, Coordinator). + +continue_compilation(Label, Data) -> + dialyzer_analysis_callgraph:continue_compilation(Label, Data). + +collect_warnings(#state{job = Job, init_data = InitData}) -> + dialyzer_succ_typings:collect_warnings(Job, InitData). + +%%------------------------------------------------------------------------------ + +-type extra() :: label() | 'unused'. + +-spec sequential(mode(), [mfa_or_funlbl()], init_data(), extra()) -> result(). + +sequential('compile', Job, InitData, Extra) -> + case dialyzer_analysis_callgraph:start_compilation(Job, InitData) of + {ok, EstimatedSize, Data} -> + {EstimatedSize, continue_compilation(Extra, Data)}; + {error, _Reason} = Error -> {0, Error} + end; +sequential('typesig', Job, InitData, _Extra) -> + dialyzer_succ_typings:find_succ_types_for_scc(Job, InitData); +sequential('dataflow', Job, InitData, _Extra) -> + dialyzer_succ_typings:refine_one_module(Job, InitData); +sequential('warnings', Job, InitData, _Extra) -> + dialyzer_succ_typings:collect_warnings(Job, InitData). diff --git a/lib/dialyzer/test/Makefile b/lib/dialyzer/test/Makefile index 6a1abce943..9f8a3f1194 100644 --- a/lib/dialyzer/test/Makefile +++ b/lib/dialyzer/test/Makefile @@ -25,10 +25,10 @@ RELSYSDIR = $(RELEASE_PATH)/dialyzer_test include $(ERL_TOP)/make/otp_release_targets.mk release_tests_spec: - $(INSTALL_DIR) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - $(INSTALL_DATA) $(AUXILIARY_FILES) $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) - cd $(RELSYSDIR);\ + $(INSTALL_DIR) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + $(INSTALL_DATA) $(AUXILIARY_FILES) "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + cd "$(RELSYSDIR)";\ erlc dialyzer_common.erl file_utils.erl;\ erl -noshell -run dialyzer_common create_all_suites -s erlang halt diff --git a/lib/dialyzer/test/opaque_SUITE_data/results/queue b/lib/dialyzer/test/opaque_SUITE_data/results/queue index 59ce33f098..c3f04ea64d 100644 --- a/lib/dialyzer/test/opaque_SUITE_data/results/queue +++ b/lib/dialyzer/test/opaque_SUITE_data/results/queue @@ -5,6 +5,7 @@ queue_use.erl:27: The attempt to match a term of type queue() against the patter queue_use.erl:33: Attempt to test for equality between a term of type {[42,...],[]} and a term of opaque type queue() queue_use.erl:36: The attempt to match a term of type queue() against the pattern {F, _R} breaks the opaqueness of the term queue_use.erl:40: The call queue:out({[42,...],[]}) does not have an opaque term of type queue() as 1st argument +queue_use.erl:48: The call queue_use:add_unique(42,#db{p::[],q::queue()}) contains an opaque term as 2nd argument when terms of different types are expected in these positions queue_use.erl:51: The call queue_use:is_in_queue(E::42,DB::#db{p::[],q::queue()}) contains an opaque term as 2nd argument when terms of different types are expected in these positions queue_use.erl:56: The attempt to match a term of type #db{p::[],q::queue()} against the pattern {'db', _, {L1, L2}} breaks the opaqueness of queue() queue_use.erl:62: The call queue_use:tuple_queue({42,'gazonk'}) does not have a term of type {_,queue()} (with opaque subterms) as 1st argument diff --git a/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes new file mode 100644 index 0000000000..8dc0361b0d --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/contracts_with_subtypes @@ -0,0 +1,31 @@ + +contracts_with_subtypes.erl:106: The call contracts_with_subtypes:rec_arg({'a','b'}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:107: The call contracts_with_subtypes:rec_arg({'b','a'}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:108: The call contracts_with_subtypes:rec_arg({'a',{'b','a'}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:109: The call contracts_with_subtypes:rec_arg({'b',{'a','b'}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:110: The call contracts_with_subtypes:rec_arg({'a',{'b',{'a','b'}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:111: The call contracts_with_subtypes:rec_arg({'b',{'a',{'b','a'}}}) breaks the contract (Arg) -> 'ok' when is_subtype(Arg,{'a',A} | {'b',B}), is_subtype(A,'a' | {'b',B}), is_subtype(B,'b' | {'a',A}) +contracts_with_subtypes.erl:142: The pattern 1 can never match the type binary() | string() +contracts_with_subtypes.erl:145: The pattern 'alpha' can never match the type {'ok',X} | {'ok',X,binary() | string()} +contracts_with_subtypes.erl:147: The pattern 42 can never match the type {'ok',_} | {'ok',_,binary() | string()} +contracts_with_subtypes.erl:163: The pattern 'alpha' can never match the type {'ok',X} +contracts_with_subtypes.erl:165: The pattern 42 can never match the type {'ok',X} +contracts_with_subtypes.erl:183: The pattern 'alpha' can never match the type {'ok',X} +contracts_with_subtypes.erl:185: The pattern 42 can never match the type {'ok',X} +contracts_with_subtypes.erl:202: The pattern 1 can never match the type binary() | string() +contracts_with_subtypes.erl:205: The pattern {'ok', _} can never match the type {'ok',X,binary() | string()} +contracts_with_subtypes.erl:206: The pattern 'alpha' can never match the type {'ok',X,binary() | string()} +contracts_with_subtypes.erl:207: The pattern {'ok', 42} can never match the type {'ok',X,binary() | string()} +contracts_with_subtypes.erl:208: The pattern 42 can never match the type {'ok',X,binary() | string()} +contracts_with_subtypes.erl:234: Function flat_ets_new_t/0 has no local return +contracts_with_subtypes.erl:235: The call contracts_with_subtypes:flat_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,'set' | 'ordered_set' | 'bag' | 'duplicate_bag' | 'public' | 'protected' | 'private' | 'named_table' | {'keypos',integer()} | {'heir',pid(),term()} | {'heir','none'} | {'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed') +contracts_with_subtypes.erl:23: Invalid type specification for function contracts_with_subtypes:extract2/0. The success typing is () -> 'something' +contracts_with_subtypes.erl:261: Function factored_ets_new_t/0 has no local return +contracts_with_subtypes.erl:262: The call contracts_with_subtypes:factored_ets_new(12,[]) breaks the contract (Name,Options) -> atom() when is_subtype(Name,atom()), is_subtype(Options,[Option]), is_subtype(Option,Type | Access | 'named_table' | {'keypos',Pos} | {'heir',Pid::pid(),HeirData} | {'heir','none'} | Tweaks), is_subtype(Type,type()), is_subtype(Access,access()), is_subtype(Tweaks,{'write_concurrency',boolean()} | {'read_concurrency',boolean()} | 'compressed'), is_subtype(Pos,pos_integer()), is_subtype(HeirData,term()) +contracts_with_subtypes.erl:77: The call contracts_with_subtypes:foo1(5) breaks the contract (Arg1) -> Res when is_subtype(Arg1,atom()), is_subtype(Res,atom()) +contracts_with_subtypes.erl:78: The call contracts_with_subtypes:foo2(5) breaks the contract (Arg1) -> Res when is_subtype(Arg1,Arg2), is_subtype(Arg2,atom()), is_subtype(Res,atom()) +contracts_with_subtypes.erl:79: The call contracts_with_subtypes:foo3(5) breaks the contract (Arg1) -> Res when is_subtype(Arg2,atom()), is_subtype(Arg1,Arg2), is_subtype(Res,atom()) +contracts_with_subtypes.erl:7: Invalid type specification for function contracts_with_subtypes:extract/0. The success typing is () -> 'something' +contracts_with_subtypes.erl:80: The call contracts_with_subtypes:foo4(5) breaks the contract (Type) -> Type when is_subtype(Type,atom()) +contracts_with_subtypes.erl:81: The call contracts_with_subtypes:foo5(5) breaks the contract (Type::atom()) -> Type::atom() +contracts_with_subtypes.erl:82: The call contracts_with_subtypes:foo6(5) breaks the contract (Type) -> Type when is_subtype(Type,atom()) diff --git a/lib/dialyzer/test/small_SUITE_data/results/port_info_test b/lib/dialyzer/test/small_SUITE_data/results/port_info_test index 9ee863f9eb..863a3d61df 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/port_info_test +++ b/lib/dialyzer/test/small_SUITE_data/results/port_info_test @@ -3,4 +3,5 @@ port_info_test.erl:10: The pattern {'connected', 42} can never match the type 'u port_info_test.erl:14: The pattern {'registered_name', "42"} can never match the type 'undefined' | {'registered_name',atom()} port_info_test.erl:19: The pattern {'output', 42} can never match the type 'undefined' | {'connected',pid()} port_info_test.erl:24: Guard test 'links' =:= Atom::'connected' can never succeed -port_info_test.erl:28: The pattern {'gazonk', _} can never match the type 'undefined' | {'connected' | 'id' | 'input' | 'links' | 'name' | 'output' | 'registered_name',atom() | pid() | [pid() | char()] | integer()} +port_info_test.erl:28: The pattern {'gazonk', _} can never match the type 'undefined' | {'connected' | 'id' | 'input' | 'links' | 'name' | 'os_pid' | 'output' | 'registered_name',atom() | pid() | [pid() | char()] | integer()} +port_info_test.erl:32: The pattern {'os_pid', "42"} can never match the type 'undefined' | {'os_pid','undefined' | non_neg_integer()} diff --git a/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/a.erl b/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/a.erl new file mode 100644 index 0000000000..7efe870b0d --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/a.erl @@ -0,0 +1,9 @@ +-module(a). +-export([g/1]). + +-export_type([a/0, t/0]). +-type a() :: integer(). +-type t() :: a() | maybe_improper_list(t(), t()). + +-spec g(t()) -> t(). +g(X) -> X. diff --git a/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/b.erl b/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/b.erl new file mode 100644 index 0000000000..b08bc5e66c --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/collapse_lists/b.erl @@ -0,0 +1,5 @@ +-module(b). +-export([f/1]). + +-spec f(a:t()) -> a:t(). +f(X) -> a:g(X). diff --git a/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl b/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl new file mode 100644 index 0000000000..d72138d509 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/contracts_with_subtypes.erl @@ -0,0 +1,267 @@ +-module(contracts_with_subtypes). + +-compile(export_all). + +%=============================================================================== + +-spec extract() -> 'ok'. + +extract() -> + case dz_extract() of + {ok, Val} -> Val; + error -> exit(boom) + end. + +-spec dz_extract() -> RetValue when + FileList :: something, + RetValue :: {ok, FileList} | error. + +dz_extract() -> get(foo). + +%------------------------------------------------------------------------------- + +-spec extract2() -> 'ok'. + +extract2() -> + case dz_extract2() of + {ok, Val} -> Val; + error -> exit(boom) + end. + +-spec dz_extract2() -> RetValue when + RetValue :: {ok, FileList} | error, + FileList :: something. + +dz_extract2() -> get(foo). + +%=============================================================================== + +-spec foo1(Arg1) -> Res when + Arg1 :: atom(), + Res :: atom(). + +foo1(X) -> X. + +-spec foo2(Arg1) -> Res when + Arg1 :: Arg2, + Arg2 :: atom(), + Res :: atom(). + +foo2(X) -> X. + +-spec foo3(Arg1) -> Res when + Arg2 :: atom(), + Arg1 :: Arg2, + Res :: atom(). + +foo3(X) -> X. + +-spec foo4(Type) -> Type when is_subtype(Type, atom()). + +foo4(X) -> X. + +-spec foo5(Type :: atom()) -> Type :: atom(). + +foo5(X) -> X. + +-spec foo6(Type) -> Type when Type :: atom(). + +foo6(X) -> X. + +-spec foo7(Type) -> Type. + +foo7(X) -> X. + +%------------------------------------------------------------------------------- + +bar(1) -> foo1(5); +bar(2) -> foo2(5); +bar(3) -> foo3(5); +bar(4) -> foo4(5); +bar(5) -> foo5(5); +bar(6) -> foo6(5); +bar(7) -> foo7(5). + +wrong_foo6() -> + b = foo6(a). + +%=============================================================================== + +-spec rec_arg(Arg) -> ok when + Arg :: {a, A} | {b, B}, + A :: a | {b, B}, + B :: b | {a, A}. + +rec_arg(X) -> get(X). + +c(aa) -> rec_arg({a, a}); +c(bb) -> rec_arg({b, b}); +c(abb) -> rec_arg({a, {b, b}}); +c(baa) -> rec_arg({b, {a, a}}); +c(abaa) -> rec_arg({a, {b, {a, a}}}); +c(babb) -> rec_arg({b, {a, {b, b}}}); +c(ababb) -> rec_arg({a, {b, {a, {b, b}}}}); +c(babaa) -> rec_arg({b, {a, {b, {a, a}}}}). + +w(ab) -> rec_arg({a, b}); +w(ba) -> rec_arg({b, a}); +w(aba) -> rec_arg({a, {b, a}}); +w(bab) -> rec_arg({b, {a, b}}); +w(abab) -> rec_arg({a, {b, {a, b}}}); +w(baba) -> rec_arg({b, {a, {b, a}}}); +w(ababa) -> rec_arg({a, {b, {a, {b, a}}}}); +w(babab) -> rec_arg({b, {a, {b, {a, b}}}}). + +%=============================================================================== + +-type dublo(X) :: {X, X}. + +-type weird(X,Y) :: {X, Y, X, X}. + +-spec forfun(dublo(Var)) -> ok when Var :: atom(). + +forfun(_) -> ok. + +-spec forfun2(weird(Var, Var)) -> ok when Var :: atom(). + +forfun2(_) -> ok. + +%=============================================================================== + +-spec shallow(X) -> {ok, X} | {ok, X, file:filename()} | err1 | err2. + +shallow(X) -> get(X). + +st(X) when is_atom(X) -> + case shallow(X) of + err1 -> ok; + err2 -> ok; + {ok, X} -> ok; + {ok, X, Res} -> + case Res of + 1 -> bad; + _Other -> ok + end; + alpha -> bad; + {ok, 42} -> bad; + 42 -> bad + end. + +%------------------------------------------------------------------------------- + +-spec deep(X) -> Ret when + Ret :: {ok, X} | Err, + Err :: err1 | err2. + +deep(X) -> get(X). + +dt(X) when is_atom(X) -> + case deep(X) of + err1 -> ok; + err2 -> ok; + {ok, X} -> ok; + alpha -> bad; + {ok, 42} -> bad; + 42 -> bad + end. + +%------------------------------------------------------------------------------- + +-type local_errors() :: err1 | err2. + +-spec deep2(X) -> Ret when + Ret :: {ok, X} | Err, + Err :: local_errors(). + +deep2(X) -> get(X). + +dt2(X) when is_atom(X) -> + case deep2(X) of + err1 -> ok; + err2 -> ok; + {ok, X} -> ok; + alpha -> bad; + {ok, 42} -> bad; + 42 -> bad + end. + +%------------------------------------------------------------------------------- + +-spec deep3(X) -> Ret when + Ret :: {ok, X, file:filename()} | Err, + Err :: local_errors(). + +deep3(X) -> get(X). + +dt3(X) when is_atom(X) -> + case deep3(X) of + err1 -> ok; + err2 -> ok; + {ok, X, Res} -> + case Res of + 1 -> bad; + _Other -> ok + end; + {ok, X} -> bad; + alpha -> bad; + {ok, 42} -> bad; + 42 -> bad + end. + +%=============================================================================== + +-spec flat_ets_new(Name, Options) -> atom() when + Name :: atom(), + Options :: [Option], + Option :: set + | ordered_set + | bag + | duplicate_bag + | public + | protected + | private + | named_table + | {keypos, integer()} + | {heir, pid(), term()} + | {heir, none} + | {write_concurrency, boolean()} + | {read_concurrency, boolean()} + | compressed. + +flat_ets_new(Name, Options) -> + get({Name, Options}). + +flat_ets_new_t() -> + flat_ets_new(12,[]), + flat_ets_new({a,b},[]), + flat_ets_new(name,[foo]), + flat_ets_new(name,{bag}), + flat_ets_new(name,bag), + ok. + +-type access() :: public | protected | private. +-type type() :: set | ordered_set | bag | duplicate_bag. + +-spec factored_ets_new(Name, Options) -> atom() when + Name :: atom(), + Options :: [Option], + Option :: Type | Access | named_table | {keypos,Pos} + | {heir, Pid :: pid(), HeirData} | {heir, none} | Tweaks, + Type :: type(), + Access :: access(), + Tweaks :: {write_concurrency, boolean()} + | {read_concurrency, boolean()} + | compressed, + Pos :: pos_integer(), + HeirData :: term(). + +factored_ets_new(Name, Options) -> + get({Name, Options}). + +factored_ets_new_t() -> + factored_ets_new(12,[]), + factored_ets_new({a,b},[]), + factored_ets_new(name,[foo]), + factored_ets_new(name,{bag}), + factored_ets_new(name,bag), + ok. diff --git a/lib/dialyzer/test/small_SUITE_data/src/deep_lc.erl b/lib/dialyzer/test/small_SUITE_data/src/deep_lc.erl new file mode 100644 index 0000000000..d9ca0817d9 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/deep_lc.erl @@ -0,0 +1,14 @@ +-module(deep_lc). + +-export([t/0]). + +%% This is compile/test/lc_SUITE:deeply_nested/1 +%% +%% Used to be _very_ slow. Unknown how slow, but more than 15 hours. + +t() -> + [[X1,X2,X3,X4,X5,X6,X7(),X8,X9,X10,X11,X12,X13,X14,X15,X16,X17,X18(),X19,X20] || + X1 <- [99],X2 <- [98],X3 <- [97],X4 <- [96],X5 <- [42],X6 <- [17], + X7 <- [fun() -> X5*X5 end],X8 <- [12],X9 <- [11],X10 <- [10], + X11 <- [9],X12 <- [8],X13 <- [7],X14 <- [6],X15 <- [5], + X16 <- [4],X17 <- [3],X18 <- [fun() -> X16+X17 end],X19 <- [2],X20 <- [1]]. diff --git a/lib/dialyzer/test/small_SUITE_data/src/port_info_test.erl b/lib/dialyzer/test/small_SUITE_data/src/port_info_test.erl index 2ee9a3a6e2..07f22256c9 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/port_info_test.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/port_info_test.erl @@ -3,7 +3,7 @@ %% and the quality of the warnings that Dialyzer spits out %% -module(port_info_test). --export([t1/1, t2/1, t3/1, t4/1, t5/2, buggy/1]). +-export([t1/1, t2/1, t3/1, t4/1, t5/2, t6/1, buggy/1]). %% The following errors are correctly caught, but the messages are a bit weird t1(X) when is_port(X) -> @@ -28,6 +28,10 @@ t5(X, Atom) when is_port(X) -> {gazonk, _} = erlang:port_info(X, Atom); t5(_, _) -> ok. +t6(X) when is_port(X) -> + {os_pid, "42"} = erlang:port_info(X, os_pid); +t6(_) -> ok. + %% The type system is not strong enough to catch the following errors buggy(X) when is_atom(X) -> {links, X} = erlang:port_info(foo, X). diff --git a/lib/diameter/autoconf/vxworks/sed.general b/lib/diameter/autoconf/vxworks/sed.general index 77b306aa0a..9199983e16 100644 --- a/lib/diameter/autoconf/vxworks/sed.general +++ b/lib/diameter/autoconf/vxworks/sed.general @@ -66,7 +66,6 @@ s|@HCLIBS@|| s|@ENABLE_ALLOC_TYPE_VARS@|| s|@TERMCAP_LIB@|| s|@ERTS_BUILD_SMP_EMU@|no| -s|@ERTS_BUILD_HYBRID_EMU@|no| s|@HAVE_VALGRIND@|no| s|@EXEEXT@|| s|@WITH_SCTP@|| diff --git a/lib/diameter/doc/src/Makefile b/lib/diameter/doc/src/Makefile index bc3e649e6b..cdf63e7fb6 100644 --- a/lib/diameter/doc/src/Makefile +++ b/lib/diameter/doc/src/Makefile @@ -162,18 +162,18 @@ include $(DIAMETER_TOP)/make/release_targets.mk endif release_docs_spec: $(LOCAL)docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man4 - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(HTMLDIR)/*.* $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN4_FILES) $(RELEASE_PATH)/man/man4 - [ -z "$(LOCAL)" ] || cp -r $(HTMLDIR)/js $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man4" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(HTMLDIR)/*.* "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DATA) $(MAN1_FILES) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN4_FILES) "$(RELEASE_PATH)/man/man4" + [ -z "$(LOCAL)" ] || cp -r $(HTMLDIR)/js "$(RELSYSDIR)/doc/html" echo $(LOCAL) release_spec: diff --git a/lib/diameter/src/Makefile b/lib/diameter/src/Makefile index dbfaa4e140..de2eca0279 100644 --- a/lib/diameter/src/Makefile +++ b/lib/diameter/src/Makefile @@ -195,27 +195,27 @@ endif release_spec: opt for d in bin ebin include src/dict; do \ - $(INSTALL_DIR) $(RELSYSDIR)/$$d; \ + $(INSTALL_DIR) "$(RELSYSDIR)/$$d"; \ done - $(INSTALL_SCRIPT) $(BINS:%=../bin/%) $(RELSYSDIR)/bin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_SCRIPT) $(BINS:%=../bin/%) "$(RELSYSDIR)/bin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(EXTERNAL_HRLS:%=../include/%) $(DICT_HRLS) \ - $(RELSYSDIR)/include - $(INSTALL_DATA) $(DICTS:%=dict/%.dia) $(RELSYSDIR)/src/dict + "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(DICTS:%=dict/%.dia) "$(RELSYSDIR)/src/dict" $(MAKE) $(TARGET_DIRS:%/=release_src_%) $(MAKE) $(EXAMPLE_DIRS:%/=release_examples_%) $(TARGET_DIRS:%/=release_src_%): release_src_%: - $(INSTALL_DIR) $(RELSYSDIR)/src/$* + $(INSTALL_DIR) "$(RELSYSDIR)/src/$*" $(INSTALL_DATA) $(filter $*/%, $(TARGET_MODULES:%=%.erl) \ $(INTERNAL_HRLS)) \ $(filter $*/%, compiler/$(DICT_YRL).yrl) \ - $(RELSYSDIR)/src/$* + "$(RELSYSDIR)/src/$*" $(EXAMPLE_DIRS:%/=release_examples_%): release_examples_%: - $(INSTALL_DIR) $(RELSYSDIR)/examples/$* + $(INSTALL_DIR) "$(RELSYSDIR)/examples/$*" $(INSTALL_DATA) $(patsubst %, ../examples/%, $(filter $*/%, $(EXAMPLES))) \ - $(RELSYSDIR)/examples/$* + "$(RELSYSDIR)/examples/$*" release_docs_spec: diff --git a/lib/diameter/test/Makefile b/lib/diameter/test/Makefile index ab5b45ff3d..1659330a91 100644 --- a/lib/diameter/test/Makefile +++ b/lib/diameter/test/Makefile @@ -141,7 +141,7 @@ log: # ---------------------------------------------------- /%: % force - sed -f release.sed $< > $(RELSYSDIR)$@ + sed -f release.sed $< > "$(RELSYSDIR)$@" ifeq ($(ERL_TOP),) include $(DIAMETER_TOP)/make/release_targets.mk @@ -152,17 +152,17 @@ endif release_spec release_docs_spec: release_tests_spec: - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(TEST_SPEC_FILE) \ $(COVER_SPEC_FILE) \ $(HRL_FILES) \ - $(RELSYSDIR) + "$(RELSYSDIR)" $(MAKE) $(DATA_DIRS:%/=release_data_%) $(MAKE) $(ERL_FILES:%=/%) $(DATA_DIRS:%/=release_data_%): release_data_%: - $(INSTALL_DIR) $(RELSYSDIR)/$* - $(INSTALL_DATA) $(filter $*/%, $(DATA)) $(RELSYSDIR)/$* + $(INSTALL_DIR) "$(RELSYSDIR)/$*" + $(INSTALL_DATA) $(filter $*/%, $(DATA)) "$(RELSYSDIR)/$*" force: diff --git a/lib/edoc/doc/src/Makefile b/lib/edoc/doc/src/Makefile index b933094464..1f92d36f12 100644 --- a/lib/edoc/doc/src/Makefile +++ b/lib/edoc/doc/src/Makefile @@ -124,13 +124,13 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/edoc/include/Makefile b/lib/edoc/include/Makefile index 5b2ad38c9d..cf2e051632 100644 --- a/lib/edoc/include/Makefile +++ b/lib/edoc/include/Makefile @@ -49,8 +49,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(INCLUDE_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(INCLUDE_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/edoc/priv/Makefile b/lib/edoc/priv/Makefile index 13225e6d1a..73c42c05eb 100644 --- a/lib/edoc/priv/Makefile +++ b/lib/edoc/priv/Makefile @@ -45,9 +45,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(PRIV_FILES) $(RELSYSDIR)/priv - $(INSTALL_SCRIPT) $(GEN_SCRIPT) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(PRIV_FILES) "$(RELSYSDIR)/priv" + $(INSTALL_SCRIPT) $(GEN_SCRIPT) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/edoc/src/Makefile b/lib/edoc/src/Makefile index fcb0b61292..72354ac711 100644 --- a/lib/edoc/src/Makefile +++ b/lib/edoc/src/Makefile @@ -85,10 +85,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(OBJECTS) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(SOURCES) $(HRL_FILES) $(YRL_FILE) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(OBJECTS) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(SOURCES) $(HRL_FILES) $(YRL_FILE) "$(RELSYSDIR)/src" release_docs_spec: diff --git a/lib/edoc/test/Makefile b/lib/edoc/test/Makefile index 2dbdb77eff..2033e003b3 100644 --- a/lib/edoc/test/Makefile +++ b/lib/edoc/test/Makefile @@ -57,10 +57,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) edoc.spec edoc.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) edoc.spec edoc.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/eldap/.gitignore b/lib/eldap/.gitignore index 5585418186..d3dd8228d5 100644 --- a/lib/eldap/.gitignore +++ b/lib/eldap/.gitignore @@ -1,4 +1,4 @@ *.beam *.asn1db -src/ELDAPv3.hrl -src/ELDAPv3.erl +ebin/ELDAPv3.hrl +ebin/ELDAPv3.erl diff --git a/lib/eldap/doc/src/Makefile b/lib/eldap/doc/src/Makefile index 4c827319b4..a4827793f4 100644 --- a/lib/eldap/doc/src/Makefile +++ b/lib/eldap/doc/src/Makefile @@ -99,16 +99,16 @@ clean clean_docs clean_tex: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 -# $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 -# $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" +# $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" +# $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/eldap/src/Makefile b/lib/eldap/src/Makefile index 4ddb8082d7..39a41d08e2 100644 --- a/lib/eldap/src/Makefile +++ b/lib/eldap/src/Makefile @@ -96,14 +96,14 @@ $(ASN1_HRL): ../asn1/$(ASN1_FILES) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/asn1 - $(INSTALL_DATA) ../asn1/$(ASN1_FILES) $(RELSYSDIR)/asn1 - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/asn1" + $(INSTALL_DATA) ../asn1/$(ASN1_FILES) "$(RELSYSDIR)/asn1" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/eldap/test/Makefile b/lib/eldap/test/Makefile index a17d4f56b2..3c5810eece 100644 --- a/lib/eldap/test/Makefile +++ b/lib/eldap/test/Makefile @@ -50,7 +50,7 @@ RELSYSDIR = $(RELEASE_PATH)/eldap_test # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += $(INCLUDES) +ERL_COMPILE_FLAGS += $(INCLUDES) -pa $(ERL_TOP)/lib/eldap/ebin EBIN = . @@ -75,9 +75,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) -# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" +# @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/erl_docgen/doc/src/Makefile b/lib/erl_docgen/doc/src/Makefile index ff50c12895..a254c4fb6d 100644 --- a/lib/erl_docgen/doc/src/Makefile +++ b/lib/erl_docgen/doc/src/Makefile @@ -124,13 +124,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/erl_docgen/doc/src/notes.xml b/lib/erl_docgen/doc/src/notes.xml index 23f64b876a..8ca11b1cf5 100644 --- a/lib/erl_docgen/doc/src/notes.xml +++ b/lib/erl_docgen/doc/src/notes.xml @@ -30,7 +30,60 @@ </header> <p>This document describes the changes made to the <em>erl_docgen</em> application.</p> - <section><title>Erl_Docgen 0.3</title> + <section><title>Erl_Docgen 0.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Some links in C libraries were not generated + correctly. This bug has been fixed. </p> + <p> + Own Id: OTP-9832</p> + </item> + <item> + <p> + Set `font-family: Courier, monospace' in OTP doc CSS</p> + <p> + left Courier as the primary original font and also added + monospace as secondary for people which in Linux does not + have it installed.</p> + <p> + Also adds minor cosmetic changes to the CSS. (Thanks to + Ricardo Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9918</p> + </item> + <item> + <p> + When generating from edoc it is now possible to use + ranges in specs and <img> tags in the description.</p> + <p> + Own Id: OTP-9970</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> Optimize and improve handling of multiple func:s. + </p> + <p> + Own Id: OTP-9877</p> + </item> + <item> + <p> The generation of the libraries' HTML documentation + has been optimized. </p> + <p> + Own Id: OTP-9893</p> + </item> + </list> + </section> + +</section> + +<section><title>Erl_Docgen 0.3</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/erl_docgen/priv/bin/Makefile b/lib/erl_docgen/priv/bin/Makefile index 95ad36216a..449cc6691c 100644 --- a/lib/erl_docgen/priv/bin/Makefile +++ b/lib/erl_docgen/priv/bin/Makefile @@ -64,8 +64,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(ESCRIPT_FILES) $(RELSYSDIR)/priv/bin + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_SCRIPT) $(ESCRIPT_FILES) "$(RELSYSDIR)/priv/bin" release_docs_spec: diff --git a/lib/erl_docgen/priv/css/Makefile b/lib/erl_docgen/priv/css/Makefile index 81124fb111..0faca019f3 100644 --- a/lib/erl_docgen/priv/css/Makefile +++ b/lib/erl_docgen/priv/css/Makefile @@ -64,13 +64,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/css - $(INSTALL_DATA) $(CSS_FILES) $(RELSYSDIR)/priv/css + $(INSTALL_DIR) "$(RELSYSDIR)/priv/css" + $(INSTALL_DATA) $(CSS_FILES) "$(RELSYSDIR)/priv/css" release_docs_spec: - $(INSTALL_DIR) $(RELEASE_PATH)/doc - $(INSTALL_DATA) $(CSS_FILES) ../nyi.html $(RELEASE_PATH)/doc + $(INSTALL_DIR) "$(RELEASE_PATH)/doc" + $(INSTALL_DATA) $(CSS_FILES) ../nyi.html "$(RELEASE_PATH)/doc" release_tests_spec: diff --git a/lib/erl_docgen/priv/dtd/Makefile b/lib/erl_docgen/priv/dtd/Makefile index 65c68fcca7..314374d34b 100644 --- a/lib/erl_docgen/priv/dtd/Makefile +++ b/lib/erl_docgen/priv/dtd/Makefile @@ -89,8 +89,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/dtd - $(INSTALL_DATA) $(DTD_FILES) $(ENT_FILES) $(RELSYSDIR)/priv/dtd + $(INSTALL_DIR) "$(RELSYSDIR)/priv/dtd" + $(INSTALL_DATA) $(DTD_FILES) $(ENT_FILES) "$(RELSYSDIR)/priv/dtd" release_docs_spec: diff --git a/lib/erl_docgen/priv/dtd_html_entities/Makefile b/lib/erl_docgen/priv/dtd_html_entities/Makefile index d57302bd1b..9cd3f38c4b 100644 --- a/lib/erl_docgen/priv/dtd_html_entities/Makefile +++ b/lib/erl_docgen/priv/dtd_html_entities/Makefile @@ -63,8 +63,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/dtd_html_entities - $(INSTALL_DATA) $(ENTITY_FILES) $(RELSYSDIR)/priv/dtd_html_entities + $(INSTALL_DIR) "$(RELSYSDIR)/priv/dtd_html_entities" + $(INSTALL_DATA) $(ENTITY_FILES) "$(RELSYSDIR)/priv/dtd_html_entities" release_docs_spec: diff --git a/lib/erl_docgen/priv/dtd_man_entities/Makefile b/lib/erl_docgen/priv/dtd_man_entities/Makefile index 5651d8bc29..b6f29af6b4 100644 --- a/lib/erl_docgen/priv/dtd_man_entities/Makefile +++ b/lib/erl_docgen/priv/dtd_man_entities/Makefile @@ -63,8 +63,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/dtd_man_entities - $(INSTALL_DATA) $(ENTITY_FILES) $(RELSYSDIR)/priv/dtd_man_entities + $(INSTALL_DIR) "$(RELSYSDIR)/priv/dtd_man_entities" + $(INSTALL_DATA) $(ENTITY_FILES) "$(RELSYSDIR)/priv/dtd_man_entities" release_docs_spec: diff --git a/lib/erl_docgen/priv/images/Makefile b/lib/erl_docgen/priv/images/Makefile index 8b858fefb3..389f9f98ae 100644 --- a/lib/erl_docgen/priv/images/Makefile +++ b/lib/erl_docgen/priv/images/Makefile @@ -66,13 +66,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/images - $(INSTALL_DATA) $(GIF_FILES) $(PNG_FILES) $(RELSYSDIR)/priv/images + $(INSTALL_DIR) "$(RELSYSDIR)/priv/images" + $(INSTALL_DATA) $(GIF_FILES) $(PNG_FILES) "$(RELSYSDIR)/priv/images" release_docs_spec: - $(INSTALL_DIR) $(RELEASE_PATH)/doc - $(INSTALL_DATA) $(PNG_FILES) $(RELEASE_PATH)/doc + $(INSTALL_DIR) "$(RELEASE_PATH)/doc" + $(INSTALL_DATA) $(PNG_FILES) "$(RELEASE_PATH)/doc" release_tests_spec: diff --git a/lib/erl_docgen/priv/js/flipmenu/Makefile b/lib/erl_docgen/priv/js/flipmenu/Makefile index 65c5c91f35..682d186608 100644 --- a/lib/erl_docgen/priv/js/flipmenu/Makefile +++ b/lib/erl_docgen/priv/js/flipmenu/Makefile @@ -68,13 +68,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/js/flipmenu - $(INSTALL_DATA) $(JS_FILES) $(GIF_FILES) $(RELSYSDIR)/priv/js/flipmenu + $(INSTALL_DIR) "$(RELSYSDIR)/priv/js/flipmenu" + $(INSTALL_DATA) $(JS_FILES) $(GIF_FILES) "$(RELSYSDIR)/priv/js/flipmenu" release_docs_spec: - $(INSTALL_DIR) $(RELEASE_PATH)/doc/js/flipmenu - $(INSTALL_DATA) $(JS_FILES) $(GIF_FILES) $(RELEASE_PATH)/doc/js/flipmenu + $(INSTALL_DIR) "$(RELEASE_PATH)/doc/js/flipmenu" + $(INSTALL_DATA) $(JS_FILES) $(GIF_FILES) "$(RELEASE_PATH)/doc/js/flipmenu" release_tests_spec: diff --git a/lib/erl_docgen/priv/xsl/Makefile b/lib/erl_docgen/priv/xsl/Makefile index 92a53b8c0b..ca7a4e8157 100644 --- a/lib/erl_docgen/priv/xsl/Makefile +++ b/lib/erl_docgen/priv/xsl/Makefile @@ -68,8 +68,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/xsl - $(INSTALL_DATA) $(XSL_FILES) $(RELSYSDIR)/priv/xsl + $(INSTALL_DIR) "$(RELSYSDIR)/priv/xsl" + $(INSTALL_DATA) $(XSL_FILES) "$(RELSYSDIR)/priv/xsl" release_docs_spec: diff --git a/lib/erl_docgen/priv/xsl/db_pdf.xsl b/lib/erl_docgen/priv/xsl/db_pdf.xsl index 4ed4fa14c4..bf17406d84 100644 --- a/lib/erl_docgen/priv/xsl/db_pdf.xsl +++ b/lib/erl_docgen/priv/xsl/db_pdf.xsl @@ -1564,7 +1564,7 @@ </xsl:variable> <fo:block xsl:use-attribute-sets="image"> - <fo:external-graphic content-width="60%" src="{@file}"/> + <fo:external-graphic content-width="scale-down-to-fit" inline-progression-dimension.maximum="100%" src="{@file}"/> <xsl:apply-templates> <xsl:with-param name="chapnum" select="$chapnum"/> diff --git a/lib/erl_docgen/src/Makefile b/lib/erl_docgen/src/Makefile index cbaf6e4627..4d8f43bfed 100644 --- a/lib/erl_docgen/src/Makefile +++ b/lib/erl_docgen/src/Makefile @@ -89,10 +89,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk 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 + $(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/vsn.mk b/lib/erl_docgen/vsn.mk index dbd7e017b0..bf10591f34 100644 --- a/lib/erl_docgen/vsn.mk +++ b/lib/erl_docgen/vsn.mk @@ -1,2 +1,2 @@ -ERL_DOCGEN_VSN = 0.3 +ERL_DOCGEN_VSN = 0.3.1 diff --git a/lib/erl_interface/doc/src/Makefile b/lib/erl_interface/doc/src/Makefile index e05b647cb2..2bad8976b5 100644 --- a/lib/erl_interface/doc/src/Makefile +++ b/lib/erl_interface/doc/src/Makefile @@ -113,16 +113,16 @@ clean clean_docs clean_tex: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 - $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DATA) $(MAN1_FILES) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml index 4cb9532880..48ac0be22d 100644 --- a/lib/erl_interface/doc/src/notes.xml +++ b/lib/erl_interface/doc/src/notes.xml @@ -30,6 +30,21 @@ </header> <p>This document describes the changes made to the Erl_interface application.</p> +<section><title>Erl_Interface 3.7.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Minor suppressions and fixes of compilation + warnings</p> + <p> + Own Id: OTP-10016</p> + </item> + </list> + </section> + +</section> + <section><title>Erl_Interface 3.7.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/erl_interface/src/Makefile.in b/lib/erl_interface/src/Makefile.in index d6b0ca1f16..661dbb68ac 100644 --- a/lib/erl_interface/src/Makefile.in +++ b/lib/erl_interface/src/Makefile.in @@ -843,32 +843,32 @@ EXTRA = \ $(TARGET)/eidefs.mk release: opt - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/lib - $(INSTALL_DIR) $(RELSYSDIR)/bin - $(INSTALL_DIR) $(RELSYSDIR)/src/auxdir - $(INSTALL_DIR) $(RELSYSDIR)/src/connect - $(INSTALL_DIR) $(RELSYSDIR)/src/decode - $(INSTALL_DIR) $(RELSYSDIR)/src/encode - $(INSTALL_DIR) $(RELSYSDIR)/src/epmd - $(INSTALL_DIR) $(RELSYSDIR)/src/legacy - $(INSTALL_DIR) $(RELSYSDIR)/src/misc - $(INSTALL_DIR) $(RELSYSDIR)/src/prog - $(INSTALL_DIR) $(RELSYSDIR)/src/registry - $(INSTALL_DATA) $(HEADERS) $(RELSYSDIR)/include - $(INSTALL_DATA) $(OBJ_TARGETS) $(RELSYSDIR)/lib + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/lib" + $(INSTALL_DIR) "$(RELSYSDIR)/bin" + $(INSTALL_DIR) "$(RELSYSDIR)/src/auxdir" + $(INSTALL_DIR) "$(RELSYSDIR)/src/connect" + $(INSTALL_DIR) "$(RELSYSDIR)/src/decode" + $(INSTALL_DIR) "$(RELSYSDIR)/src/encode" + $(INSTALL_DIR) "$(RELSYSDIR)/src/epmd" + $(INSTALL_DIR) "$(RELSYSDIR)/src/legacy" + $(INSTALL_DIR) "$(RELSYSDIR)/src/misc" + $(INSTALL_DIR) "$(RELSYSDIR)/src/prog" + $(INSTALL_DIR) "$(RELSYSDIR)/src/registry" + $(INSTALL_DATA) $(HEADERS) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(OBJ_TARGETS) "$(RELSYSDIR)/lib" ifneq ($(EXE_TARGETS),) - $(INSTALL_PROGRAM) $(EXE_TARGETS) $(RELSYSDIR)/bin -endif - $(INSTALL_DATA) $(EXTRA) $(RELSYSDIR)/src - $(INSTALL_DATA) connect/*.[ch] $(RELSYSDIR)/src/connect - $(INSTALL_DATA) decode/*.[ch] $(RELSYSDIR)/src/decode - $(INSTALL_DATA) encode/*.[ch] $(RELSYSDIR)/src/encode - $(INSTALL_DATA) epmd/*.[ch] $(RELSYSDIR)/src/epmd - $(INSTALL_DATA) misc/*.[ch] $(RELSYSDIR)/src/misc - $(INSTALL_DATA) registry/*.[ch] $(RELSYSDIR)/src/registry - $(INSTALL_DATA) legacy/*.[ch] $(RELSYSDIR)/src/legacy - $(INSTALL_DATA) prog/*.[ch] $(RELSYSDIR)/src/prog + $(INSTALL_PROGRAM) $(EXE_TARGETS) "$(RELSYSDIR)/bin" +endif + $(INSTALL_DATA) $(EXTRA) "$(RELSYSDIR)/src" + $(INSTALL_DATA) connect/*.[ch] "$(RELSYSDIR)/src/connect" + $(INSTALL_DATA) decode/*.[ch] "$(RELSYSDIR)/src/decode" + $(INSTALL_DATA) encode/*.[ch] "$(RELSYSDIR)/src/encode" + $(INSTALL_DATA) epmd/*.[ch] "$(RELSYSDIR)/src/epmd" + $(INSTALL_DATA) misc/*.[ch] "$(RELSYSDIR)/src/misc" + $(INSTALL_DATA) registry/*.[ch] "$(RELSYSDIR)/src/registry" + $(INSTALL_DATA) legacy/*.[ch] "$(RELSYSDIR)/src/legacy" + $(INSTALL_DATA) prog/*.[ch] "$(RELSYSDIR)/src/prog" release_docs: diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile index 4faf89c0d6..d11a138844 100644 --- a/lib/erl_interface/test/Makefile +++ b/lib/erl_interface/test/Makefile @@ -71,9 +71,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.src b/lib/erl_interface/test/all_SUITE_data/Makefile.src index 70652e47c5..39085def2d 100644 --- a/lib/erl_interface/test/all_SUITE_data/Makefile.src +++ b/lib/erl_interface/test/all_SUITE_data/Makefile.src @@ -32,7 +32,7 @@ all: $(ALL_OBJS) $(EI_COMMON_OBJS): gccifier@exe@ -@IFEQ@ (@erl_interface_cross_compile@, true) +@IFEQ@ (@cross@, yes) gccifier@exe@: $(CP) gccifier.sh gccifier@exe@ $(CHMOD) a+x gccifier@exe@ diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.c b/lib/erl_interface/test/all_SUITE_data/gccifier.c index 9f556fc4ed..a1019f9a72 100644 --- a/lib/erl_interface/test/all_SUITE_data/gccifier.c +++ b/lib/erl_interface/test/all_SUITE_data/gccifier.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2005-2009. All Rights Reserved. + * Copyright Ericsson AB 2004-2009. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -16,7 +16,6 @@ * * %CopyrightEnd% * - */ /* @@ -74,17 +73,23 @@ save_arg(args_t *args, char *arg1, ...) args->vec = (char **) (args->no ? realloc((void *) args->vec, (sizeof(char *) - *(args->no + ARGS_INCR + 1))) + *(args->no + ARGS_INCR + 2))) : malloc((sizeof(char *) - *(args->no + ARGS_INCR + 1)))); + *(args->no + ARGS_INCR + 2)))); if (!args->vec) enomem(); args->no += ARGS_INCR; } + if (carg == arg1) { + args->vec[args->ix++] = "\""; + args->chars++; + } args->vec[args->ix++] = carg; args->chars += strlen(carg); carg = va_arg(argp, char *); } + args->vec[args->ix++] = "\""; + args->chars++; args->vec[args->ix++] = " "; args->chars++; va_end(argp); @@ -232,6 +237,9 @@ main(int argc, char *argv[]) CHECK_FIRST_LINK_ARG; save_arg(&link_args, "-libpath:", arg, NULL); } + else if (strcmp("-link",arg) == 0) { + CHECK_FIRST_LINK_ARG; + } #endif /* #ifdef __WIN32__ */ else if (is_prefix("-l", &arg)) { CHECK_FIRST_LINK_ARG; diff --git a/lib/erl_interface/test/all_SUITE_data/init_tc.erl b/lib/erl_interface/test/all_SUITE_data/init_tc.erl index 7a599994fc..60c965eda3 100644 --- a/lib/erl_interface/test/all_SUITE_data/init_tc.erl +++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl @@ -48,8 +48,7 @@ run1(Name) -> generate(TcName, Cases) -> Hrl = TcName ++ "_cases.hrl", {ok, HrlFile} = file:open(Hrl, write), - {ok, Dir} = file:get_cwd(), - generate_hrl(Cases, HrlFile, {filename:join(Dir, TcName), 0}), + generate_hrl(Cases, HrlFile, {TcName, 0}), file:close(HrlFile), C = TcName ++ "_decl.c", {ok, CFile} = file:open(C, write), @@ -57,7 +56,7 @@ generate(TcName, Cases) -> file:close(CFile). generate_hrl([Case|Rest], File, {Name, Number}) -> - io:format(File, "-define(~s, {\"~s\", ~w}).~n", [Case, Name, Number]), + io:format(File, "-define(~s, {filename:join(proplists:get_value(data_dir,Config),\"~s\"), ~w}).~n", [Case, Name, Number]), generate_hrl(Rest, File, {Name, Number+1}); generate_hrl([], _, _) -> ok. diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl index 7ff8c08280..cc22cb7440 100644 --- a/lib/erl_interface/test/ei_tmo_SUITE.erl +++ b/lib/erl_interface/test/ei_tmo_SUITE.erl @@ -88,12 +88,12 @@ ei_recv_tmo(doc) -> ei_recv_tmo(suite) -> []; ei_recv_tmo(Config) when is_list(Config) -> - ?line do_one_recv(c_node_recv_tmo_1), - ?line do_one_recv_failure(c_node_recv_tmo_2), + ?line do_one_recv(Config,c_node_recv_tmo_1), + ?line do_one_recv_failure(Config,c_node_recv_tmo_2), ok. -do_one_recv(CNode) -> +do_one_recv(Config,CNode) -> ?line {_,Host} = split(node()), ?line P1 = runner:start(?recv_tmo), ?line runner:send_term(P1,{CNode, @@ -107,7 +107,7 @@ do_one_recv(CNode) -> ?line {term, Term1} = runner:get_term(P1, 10000), ?line runner:recv_eot(P1). -do_one_recv_failure(CNode) -> +do_one_recv_failure(Config,CNode) -> ?line P1 = runner:start(?recv_tmo), ?line runner:send_term(P1,{CNode, erlang:get_cookie(), @@ -128,14 +128,14 @@ ei_send_tmo(Config) when is_list(Config) -> %dbg:p(self()), VxSim = ?config(vxsim, Config), ?line register(ei_send_tmo_1,self()), - ?line do_one_send(self(),c_node_send_tmo_1), - ?line do_one_send(ei_send_tmo_1,c_node_send_tmo_2), - ?line do_one_send_failure(self(),cccc1,c_nod_send_tmo_3,VxSim), - ?line do_one_send_failure(ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim), + ?line do_one_send(Config,self(),c_node_send_tmo_1), + ?line do_one_send(Config,ei_send_tmo_1,c_node_send_tmo_2), + ?line do_one_send_failure(Config,self(),cccc1,c_nod_send_tmo_3,VxSim), + ?line do_one_send_failure(Config,ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim), ok. -do_one_send(From,CNode) -> +do_one_send(Config,From,CNode) -> ?line {_,Host} = split(node()), ?line P1 = runner:start(?send_tmo), ?line runner:send_term(P1,{CNode, @@ -155,7 +155,7 @@ do_one_send(From,CNode) -> ?line {term, 0} = runner:get_term(P1, 10000), ?line runner:recv_eot(P1). -do_one_send_failure(From,FakeName,CName,VxSim) -> +do_one_send_failure(Config,From,FakeName,CName,VxSim) -> ?line {_,Host} = split(node()), ?line OurName = join(FakeName,Host), ?line Node = join(CName,Host), diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl index e019fecca8..edbb17a8c1 100644 --- a/lib/erl_interface/test/erl_match_SUITE.erl +++ b/lib/erl_interface/test/erl_match_SUITE.erl @@ -29,7 +29,7 @@ bind/1, integers/1, floats/1, binaries/1, strings/1]). %% For interactive running of matcher. --export([start_matcher/0, erl_match/3]). +-export([start_matcher/1, erl_match/3]). %% This test suite tests the erl_match() function. @@ -57,7 +57,7 @@ end_per_group(_GroupName, Config) -> atoms(suite) -> []; atoms(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line eq(P, '', ''), ?line eq(P, a, a), @@ -74,7 +74,7 @@ atoms(Config) when is_list(Config) -> lists(suite) -> []; lists(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line eq(P, [], []), ?line ne(P, [], [a]), @@ -101,7 +101,7 @@ lists(Config) when is_list(Config) -> tuples(suite) -> []; tuples(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line ne(P, {}, {a, b}), ?line ne(P, {a, b}, {}), @@ -129,7 +129,7 @@ tuples(Config) when is_list(Config) -> references(suite) -> []; references(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line Ref1 = make_ref(), ?line Ref2 = make_ref(), @@ -144,7 +144,7 @@ references(Config) when is_list(Config) -> pids(suite) -> []; pids(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line Pid1 = c:pid(0,1,2), ?line Pid2 = c:pid(0,1,3), @@ -163,8 +163,8 @@ ports(Config) when is_list(Config) -> vxworks -> {skipped,"not on vxworks, pucko"}; _ -> - ?line P = start_matcher(), - ?line P2 = start_matcher(), + ?line P = start_matcher(Config), + ?line P2 = start_matcher(Config), ?line eq(P, P, P), ?line ne(P, P, P2), @@ -176,7 +176,7 @@ ports(Config) when is_list(Config) -> integers(suite) -> []; integers(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line I1 = 123, ?line I2 = 12345, ?line I3 = -123, @@ -195,7 +195,7 @@ integers(Config) when is_list(Config) -> floats(suite) -> []; floats(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line F1 = 3.1414, ?line F2 = 3.1415, ?line F3 = 3.1416, @@ -218,7 +218,7 @@ floats(Config) when is_list(Config) -> binaries(suite) -> []; binaries(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line Bin1 = term_to_binary({kalle, 146015, {kungsgatan, 23}}), ?line Bin2 = term_to_binary(sune), ?line Bin3 = list_to_binary("sune"), @@ -237,7 +237,7 @@ binaries(Config) when is_list(Config) -> strings(suite) -> []; strings(Config) when is_list(Config) -> - ?line P = start_matcher(), + ?line P = start_matcher(Config), ?line S1 = "string", ?line S2 = "streng", @@ -254,7 +254,7 @@ strings(Config) when is_list(Config) -> bind(suite) -> []; bind(Config) when is_list(Config) -> - ?line P = start_bind(), + ?line P = start_bind(Config), ?line S = "[X,Y,Z]", ?line L1 = [301,302,302], ?line L2 = [65,66,67], @@ -265,7 +265,7 @@ bind(Config) when is_list(Config) -> ?line runner:finish(P), ok. -start_bind() -> +start_bind(Config) -> runner:start(?erl_match_bind). bind_ok(Port, Bind, Term) -> @@ -287,7 +287,7 @@ erl_bind(Port, Pattern, Term) -> -start_matcher() -> +start_matcher(Config) -> runner:start(?erl_match_server). eq(Port, Pattern, Term) -> diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk index 2c402bba6c..0e249d2483 100644 --- a/lib/erl_interface/vsn.mk +++ b/lib/erl_interface/vsn.mk @@ -1 +1 @@ -EI_VSN = 3.7.6 +EI_VSN = 3.7.7 diff --git a/lib/et/doc/src/Makefile b/lib/et/doc/src/Makefile index 6bb8164e91..facd335449 100644 --- a/lib/et/doc/src/Makefile +++ b/lib/et/doc/src/Makefile @@ -97,14 +97,14 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/et/doc/src/et_intro.xml b/lib/et/doc/src/et_intro.xml index 0c5fb14d55..60da289721 100644 --- a/lib/et/doc/src/et_intro.xml +++ b/lib/et/doc/src/et_intro.xml @@ -40,8 +40,8 @@ ports or files.</p> <section> - <title>Scope and Purpose</title>' - + <title>Scope and Purpose</title> + <p>This manual describes the <c>Event Tracer (ET)</c> application, as a component of the Erlang/Open Telecom Platform development environment. It is assumed that the reader is familiar with the diff --git a/lib/et/doc/src/notes.xml b/lib/et/doc/src/notes.xml index acc6120fcd..42790e0cdf 100644 --- a/lib/et/doc/src/notes.xml +++ b/lib/et/doc/src/notes.xml @@ -36,6 +36,26 @@ one section in this document. The title of each section is the version number of <c>Event Tracer (ET)</c>.</p> +<section><title>ET 1.4.4.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + <section><title>ET 1.4.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/et/examples/Makefile b/lib/et/examples/Makefile index 67a6536fdf..190d5e2d6a 100644 --- a/lib/et/examples/Makefile +++ b/lib/et/examples/Makefile @@ -73,8 +73,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/et/src/Makefile b/lib/et/src/Makefile index bb6632ee91..7693571c5c 100644 --- a/lib/et/src/Makefile +++ b/lib/et/src/Makefile @@ -104,14 +104,14 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/et/test/Makefile b/lib/et/test/Makefile index e10a2a1587..7b4db7b0c3 100644 --- a/lib/et/test/Makefile +++ b/lib/et/test/Makefile @@ -70,12 +70,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) et.spec et.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_SCRIPT) ett $(RELSYSDIR) - $(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR) -# chmod -R u+w $(RELSYSDIR) -# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) et.spec et.cover $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_SCRIPT) ett "$(RELSYSDIR)" + $(INSTALL_DATA) $(INSTALL_PROGS) "$(RELSYSDIR)" +# chmod -R u+w "$(RELSYSDIR)" +# @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/et/vsn.mk b/lib/et/vsn.mk index 239a72ad73..090d43d52f 100644 --- a/lib/et/vsn.mk +++ b/lib/et/vsn.mk @@ -1 +1 @@ -ET_VSN = 1.4.4 +ET_VSN = 1.4.4.1 diff --git a/lib/eunit/doc/src/Makefile b/lib/eunit/doc/src/Makefile index 2cdc579275..cbcd4c1507 100644 --- a/lib/eunit/doc/src/Makefile +++ b/lib/eunit/doc/src/Makefile @@ -157,14 +157,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/eunit/examples/Makefile b/lib/eunit/examples/Makefile index 48ec2ebf2b..cfa0a7a645 100644 --- a/lib/eunit/examples/Makefile +++ b/lib/eunit/examples/Makefile @@ -49,8 +49,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(EXAMPLE_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/eunit/src/Makefile b/lib/eunit/src/Makefile index bec2fdbe0b..0a2e71cf7b 100644 --- a/lib/eunit/src/Makefile +++ b/lib/eunit/src/Makefile @@ -28,6 +28,9 @@ ERL_COMPILE_FLAGS += -pa $(EBIN) -I$(INCLUDE) +warn_unused_vars +nowarn_shadow_v PARSE_TRANSFORM = eunit_autoexport.erl +BEHAVIOUR_SOURCES= \ + eunit_listener.erl + SOURCES= \ eunit_striptests.erl \ eunit.erl \ @@ -40,13 +43,16 @@ SOURCES= \ eunit_data.erl \ eunit_tty.erl \ eunit_surefire.erl \ - eunit_listener.erl INCLUDE_FILES = eunit.hrl PARSE_TRANSFORM_BIN = $(PARSE_TRANSFORM:%.erl=$(EBIN)/%.$(EMULATOR)) -OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) +TARGET_FILES= $(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) + +BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) + +OBJECTS= $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) INCLUDE_DELIVERABLES = $(INCLUDE_FILES:%=$(INCLUDE)/%) @@ -62,6 +68,8 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE) # Targets # ---------------------------------------------------- +$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES) + debug opt: $(PARSE_TRANSFORM_BIN) $(OBJECTS) docs: @@ -107,12 +115,12 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(PARSE_TRANSFORM_BIN) $(OBJECTS) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(PARSE_TRANSFORM) $(SOURCES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(INCLUDE_DELIVERABLES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(PARSE_TRANSFORM_BIN) $(OBJECTS) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(PARSE_TRANSFORM) $(SOURCES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(INCLUDE_DELIVERABLES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/eunit/test/Makefile b/lib/eunit/test/Makefile index a2d276f619..1586dd8857 100644 --- a/lib/eunit/test/Makefile +++ b/lib/eunit/test/Makefile @@ -74,9 +74,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) eunit.spec $(EMAKEFILE) \ $(COVERFILE) $(ERL_FILES) \ - $(RELSYSDIR) + "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/gs/contribs/bonk/Makefile b/lib/gs/contribs/bonk/Makefile index be096824dd..dc92149784 100644 --- a/lib/gs/contribs/bonk/Makefile +++ b/lib/gs/contribs/bonk/Makefile @@ -94,14 +94,14 @@ $(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/bonk/bitmaps - $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) $(RELSYSDIR)/bonk/bitmaps - $(INSTALL_DIR) $(RELSYSDIR)/bonk/sounds - $(INSTALL_DATA) $(SOUNDS) $(RELSYSDIR)/bonk/sounds - $(INSTALL_DIR) $(RELSYSDIR)/bonk - $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) $(RELSYSDIR)/bonk + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/bonk/bitmaps" + $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) "$(RELSYSDIR)/bonk/bitmaps" + $(INSTALL_DIR) "$(RELSYSDIR)/bonk/sounds" + $(INSTALL_DATA) $(SOUNDS) "$(RELSYSDIR)/bonk/sounds" + $(INSTALL_DIR) "$(RELSYSDIR)/bonk" + $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/bonk" release_docs_spec: diff --git a/lib/gs/contribs/cols/Makefile b/lib/gs/contribs/cols/Makefile index 75ca75ffc0..4ce4204c92 100644 --- a/lib/gs/contribs/cols/Makefile +++ b/lib/gs/contribs/cols/Makefile @@ -91,12 +91,12 @@ $(EBIN)/help.gif: help.gif include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/cols/bitmaps - $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) $(RELSYSDIR)/cols/bitmaps - $(INSTALL_DIR) $(RELSYSDIR)/cols - $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) $(RELSYSDIR)/cols + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/cols/bitmaps" + $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) "$(RELSYSDIR)/cols/bitmaps" + $(INSTALL_DIR) "$(RELSYSDIR)/cols" + $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/cols" release_docs_spec: diff --git a/lib/gs/contribs/mandel/Makefile b/lib/gs/contribs/mandel/Makefile index 61a7a612e0..451ece2c8f 100644 --- a/lib/gs/contribs/mandel/Makefile +++ b/lib/gs/contribs/mandel/Makefile @@ -90,11 +90,11 @@ $(EBIN)/help.gif: help.gif include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/mandel/bitmaps - $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) $(RELSYSDIR)/mandel/bitmaps - $(INSTALL_DIR) $(RELSYSDIR)/mandel - $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) $(RELSYSDIR)/mandel + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/mandel/bitmaps" + $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) "$(RELSYSDIR)/mandel/bitmaps" + $(INSTALL_DIR) "$(RELSYSDIR)/mandel" + $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/mandel" release_docs_spec: diff --git a/lib/gs/contribs/othello/Makefile b/lib/gs/contribs/othello/Makefile index b81b35fb55..5f09f2ed13 100644 --- a/lib/gs/contribs/othello/Makefile +++ b/lib/gs/contribs/othello/Makefile @@ -89,12 +89,12 @@ $(EBIN)/$(TOOLNAME).tool: $(TOOLNAME).tool include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/othello - $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) $(RELSYSDIR)/othello - $(INSTALL_DIR) $(RELSYSDIR)/othello/priv - $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) $(RELSYSDIR)/othello/priv + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/othello" + $(INSTALL_DATA) $(ERL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/othello" + $(INSTALL_DIR) "$(RELSYSDIR)/othello/priv" + $(INSTALL_DATA) $(BITMAPS) $(TOOLBOX_FILES) "$(RELSYSDIR)/othello/priv" release_docs_spec: diff --git a/lib/gs/doc/src/Makefile b/lib/gs/doc/src/Makefile index 192dd67a52..14204c52fc 100644 --- a/lib/gs/doc/src/Makefile +++ b/lib/gs/doc/src/Makefile @@ -144,13 +144,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - (/bin/cp -rf $(HTMLDIR) $(RELSYSDIR)/doc) - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc") + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/gs/doc/src/notes.xml b/lib/gs/doc/src/notes.xml index cd63104346..d1b74ecfb1 100644 --- a/lib/gs/doc/src/notes.xml +++ b/lib/gs/doc/src/notes.xml @@ -30,7 +30,27 @@ </header> <p>This document describes the changes made to the GS application.</p> - <section><title>GS 1.5.15</title> + <section><title>GS 1.5.15.1</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + +<section><title>GS 1.5.15</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/gs/examples/Makefile b/lib/gs/examples/Makefile index 10b166b207..d214cd2256 100644 --- a/lib/gs/examples/Makefile +++ b/lib/gs/examples/Makefile @@ -87,9 +87,9 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" release_docs_spec: diff --git a/lib/gs/src/Makefile b/lib/gs/src/Makefile index 43b530295b..a9904161a4 100644 --- a/lib/gs/src/Makefile +++ b/lib/gs/src/Makefile @@ -107,13 +107,13 @@ $(GSTK_GENERIC_TARGET): gstk_generic.hrl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/src" $(INSTALL_DATA) $(APP_SRC) $(ERL_FILES) $(HRL_FILES) $(GEN_HRL_FILES) \ - $(GSTK_GENERIC) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/priv/bitmap - $(INSTALL_DATA) $(IMAGES) $(RELSYSDIR)/priv/bitmap + $(GSTK_GENERIC) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bitmap" + $(INSTALL_DATA) $(IMAGES) "$(RELSYSDIR)/priv/bitmap" release_docs_spec: diff --git a/lib/gs/src/gstk_generic.erl b/lib/gs/src/gstk_generic.erl index 10cb890013..9b0efd07c1 100644 --- a/lib/gs/src/gstk_generic.erl +++ b/lib/gs/src/gstk_generic.erl @@ -323,7 +323,7 @@ handle_external_opt_call([Opt|Options],Gstkid,TkW,DB,ExtraArg,ExtRes,S,P,C) -> end. handle_external_read(Res) -> - case Res of + _ = case Res of {bad_result,{Objtype,Reason,Option}} -> {error,{Objtype,Reason,Option}}; _ -> ok diff --git a/lib/gs/tcl/Makefile.in b/lib/gs/tcl/Makefile.in index dce34a4baa..0bccb60c7b 100644 --- a/lib/gs/tcl/Makefile.in +++ b/lib/gs/tcl/Makefile.in @@ -74,10 +74,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(TCL_FILES) $(EXTRA_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(TCL_FILES) $(EXTRA_FILES) "$(RELSYSDIR)/priv" ifneq ($(TCL_TAR),) - gzip -dc $(TCL_TAR) | (cd $(RELSYSDIR)/priv && tar -xf -) + gzip -dc $(TCL_TAR) | (cd "$(RELSYSDIR)/priv" && tar -xf -) endif release_docs_spec: diff --git a/lib/gs/vsn.mk b/lib/gs/vsn.mk index 41a2561809..48249cb3d0 100644 --- a/lib/gs/vsn.mk +++ b/lib/gs/vsn.mk @@ -1,2 +1,2 @@ -GS_VSN = 1.5.15 +GS_VSN = 1.5.15.1 diff --git a/lib/hipe/amd64/Makefile b/lib/hipe/amd64/Makefile index 15291e9bbe..50cd024d72 100644 --- a/lib/hipe/amd64/Makefile +++ b/lib/hipe/amd64/Makefile @@ -105,8 +105,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/arm/Makefile b/lib/hipe/arm/Makefile index a64f133679..651b82f1ed 100644 --- a/lib/hipe/arm/Makefile +++ b/lib/hipe/arm/Makefile @@ -106,8 +106,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/cerl/Makefile b/lib/hipe/cerl/Makefile index 14e68f5233..506e993ff4 100644 --- a/lib/hipe/cerl/Makefile +++ b/lib/hipe/cerl/Makefile @@ -42,7 +42,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN) # ---------------------------------------------------- # Target Specs # ---------------------------------------------------- -MODULES = cerl_cconv cerl_closurean cerl_hipeify cerl_hybrid_transform \ +MODULES = cerl_cconv cerl_closurean cerl_hipeify \ cerl_lib cerl_messagean cerl_pmatch cerl_prettypr cerl_to_icode \ cerl_typean erl_bif_types erl_types @@ -100,10 +100,10 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/cerl - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/cerl - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/cerl" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/cerl" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/cerl/cerl_hybrid_transform.erl b/lib/hipe/cerl/cerl_hybrid_transform.erl deleted file mode 100644 index b248b0ccd0..0000000000 --- a/lib/hipe/cerl/cerl_hybrid_transform.erl +++ /dev/null @@ -1,153 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% - --module(cerl_hybrid_transform). - -%% Use compile option `{core_transform, cerl_hybrid_transform}' to -%% insert this as a compilation pass. - --export([transform/2, core_transform/2]). - --spec core_transform(cerl:cerl(), [term()]) -> cerl:cerl(). - -core_transform(Code, Opts) -> - cerl:to_records(transform(cerl:from_records(Code), Opts)). - --spec transform(cerl:cerl(), [term()]) -> cerl:cerl(). - -transform(Code, _Opts) -> - Code0 = cerl_trees:map(fun unfold_literal/1, Code), - {Code1, _} = cerl_trees:label(Code0), - io:fwrite("Running hybrid heap analysis..."), - {T1,_} = statistics(runtime), - {Code2, _, Vars} = cerl_messagean:annotate(Code1), - {T2,_} = statistics(runtime), - io:fwrite("(~w ms), transform...", [T2 - T1]), - Code3 = rewrite(Code2, Vars), - io:fwrite("done.\n"), - cerl_trees:map(fun fold_literal/1, Code3). - -unfold_literal(T) -> - cerl:unfold_literal(T). - -fold_literal(T) -> - cerl:fold_literal(T). - -%% If escape-annotated: -%% {...} => hybrid:tuple([...]) -%% [H | T] => hybrid:cons(H, T) -%% -%% Wrapper for args to hybrid:cons/hybrid:tuple that may need copying: -%% hybrid:copy(A) - -rewrite(Node, Vars) -> - case cerl:type(Node) of - tuple -> - Es = rewrite_list(cerl:tuple_es(Node), Vars), - case is_escaping(Node) of - false -> - cerl:update_c_tuple(Node, Es); - true -> - Es1 = wrap(Es, Node, Vars), - cerl:update_c_call(Node, - cerl:abstract(hybrid), - cerl:abstract(tuple), - [cerl:make_list(Es1)]) -%%% cerl:update_c_call(Node, cerl:abstract(hybrid), -%%% cerl:abstract(tuple), Es1) - end; - cons -> - H = rewrite(cerl:cons_hd(Node), Vars), - T = rewrite(cerl:cons_tl(Node), Vars), - case is_escaping(Node) of - false -> - cerl:update_c_cons(Node, H, T); - true -> - Es = wrap([H, T], Node, Vars), - cerl:update_c_call(Node, - cerl:abstract(hybrid), - cerl:abstract(cons), - Es) - end; -%%% call -> -%%% M = rewrite(cerl:call_module(Node)), -%%% F = rewrite(cerl:call_name(Node)), -%%% As = rewrite_list(cerl:call_args(Node)), -%%% case cerl:is_c_atom(M) andalso cerl:is_c_atom(F) of -%%% true -> -%%% case {cerl:atom_val(M), cerl:atom_val(F), length(As)} of -%%% {erlang, '!', 2} -> -%%% cerl:update_c_call(Node, -%%% cerl:abstract(hipe_bifs), -%%% cerl:abstract(send), -%%% [cerl:make_list(As)]); -%%% _ -> -%%% cerl:update_c_call(Node, M, F, As) -%%% end; -%%% false -> -%%% cerl:update_c_call(Node, M, F, As) -%%% end; - clause -> - B = rewrite(cerl:clause_body(Node), Vars), - cerl:update_c_clause(Node, cerl:clause_pats(Node), - cerl:clause_guard(Node), B); - primop -> - case cerl:atom_val(cerl:primop_name(Node)) of - match_fail -> - Node; - _ -> - As = rewrite_list(cerl:primop_args(Node), Vars), - cerl:update_c_primop(Node, cerl:primop_name(Node), As) - end; - _T -> - case cerl:subtrees(Node) of - [] -> - Node; - Gs -> - cerl:update_tree(Node, [rewrite_list(Ns, Vars) - || Ns <- Gs]) - end - end. - -rewrite_list([N | Ns], Vars) -> - [rewrite(N, Vars) | rewrite_list(Ns, Vars)]; -rewrite_list([], _) -> - []. - -is_escaping(T) -> - lists:member(escapes, cerl:get_ann(T)). - -wrap(Es, Node, Vars) -> - L = cerl_trees:get_label(Node), - Xs = dict:fetch(L, Vars), - wrap(Es, Xs). - -wrap([E | Es], [{S, _} | Xs]) -> - case ordsets:is_element(unsafe, S) of -%% case cerl:type(E) =/= literal of - true -> - [cerl:c_call(cerl:abstract(hybrid), - cerl:abstract(copy), - [E]) - | wrap(Es, Xs)]; - false -> - [E | wrap(Es, Xs)] - end; -wrap([], _) -> - []. diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 0c2e846010..1ef73da1be 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -1186,6 +1186,7 @@ type(erlang, port_info, 2, Xs) -> ['links'] -> t_tuple([Item, t_list(t_pid())]); ['name'] -> t_tuple([Item, t_string()]); ['output'] -> t_tuple([Item, t_integer()]); + ['os_pid'] -> t_tuple([Item, t_sup(t_non_neg_integer(),t_atom('undefined'))]); ['registered_name'] -> t_tuple([Item, t_atom()]); List when is_list(List) -> t_tuple([t_sup([t_atom(A) || A <- List]), @@ -1268,7 +1269,6 @@ type(erlang, process_info, 2, Xs) -> ['links'] -> t_tuple([InfoItem, t_list(t_pid())]); ['memory'] -> t_tuple([InfoItem, t_non_neg_integer()]); - ['message_binary'] -> t_tuple([InfoItem, t_list()]); ['message_queue_len'] -> t_tuple([InfoItem, t_non_neg_integer()]); ['messages'] -> t_tuple([InfoItem, t_list()]); @@ -1593,14 +1593,10 @@ type(erlang, system_info, 1, Xs) -> t_tuple([t_atom('fullsweep_after'), t_non_neg_integer()]); ['garbage_collection'] -> t_list(); - ['global_heaps_size'] -> - t_non_neg_integer(); ['heap_sizes'] -> t_list(t_integer()); ['heap_type'] -> - t_sup([t_atom('private'), - t_atom('shared'), - t_atom('hybrid')]); + t_atom('private'); ['hipe_architecture'] -> t_atoms(['amd64', 'arm', 'powerpc', 'ppc64', 'undefined', 'ultrasparc', 'x86']); @@ -3789,7 +3785,7 @@ arg_types(erlang, port_info, 1) -> arg_types(erlang, port_info, 2) -> [t_sup(t_port(), t_atom()), t_atoms(['registered_name', 'id', 'connected', - 'links', 'name', 'input', 'output'])]; + 'links', 'name', 'input', 'output', 'os_pid'])]; arg_types(erlang, port_to_list, 1) -> [t_port()]; arg_types(erlang, ports, 0) -> @@ -4742,7 +4738,6 @@ t_pinfo_item() -> t_atom('last_calls'), t_atom('links'), t_atom('memory'), - t_atom('message_binary'), % for hybrid heap only t_atom('message_queue_len'), t_atom('messages'), t_atom('monitored_by'), diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index ceec31742e..1789fc79fa 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -2555,8 +2555,8 @@ t_subst_dict(?list(Contents, Termination, Size), Dict) -> ?nil -> ?list(NewContents, ?nil, Size); ?any -> ?list(NewContents, ?any, Size); Other -> - ?list(NewContents, NewTermination, _) = t_cons(NewContents, Other), - ?list(NewContents, NewTermination, Size) + ?list(NewContents2, NewTermination, _) = t_cons(NewContents, Other), + ?list(NewContents2, NewTermination, Size) end end; t_subst_dict(?function(Domain, Range), Dict) -> @@ -2597,8 +2597,8 @@ t_subst_aux(?list(Contents, Termination, Size), VarMap) -> ?nil -> ?list(NewContents, ?nil, Size); ?any -> ?list(NewContents, ?any, Size); Other -> - ?list(NewContents, NewTermination, _) = t_cons(NewContents, Other), - ?list(NewContents, NewTermination, Size) + ?list(NewContents2, NewTermination, _) = t_cons(NewContents, Other), + ?list(NewContents2, NewTermination, Size) end end; t_subst_aux(?function(Domain, Range), VarMap) -> @@ -3186,8 +3186,8 @@ t_abstract_records(?list(Contents, Termination, Size), RecDict) -> ?nil -> ?list(NewContents, ?nil, Size); ?any -> ?list(NewContents, ?any, Size); Other -> - ?list(NewContents, NewTermination, _) = t_cons(NewContents, Other), - ?list(NewContents, NewTermination, Size) + ?list(NewContents2, NewTermination, _) = t_cons(NewContents, Other), + ?list(NewContents2, NewTermination, Size) end end; t_abstract_records(?function(Domain, Range), RecDict) -> diff --git a/lib/hipe/doc/src/Makefile b/lib/hipe/doc/src/Makefile index a9cd583ff4..fbfd4ca327 100644 --- a/lib/hipe/doc/src/Makefile +++ b/lib/hipe/doc/src/Makefile @@ -106,12 +106,12 @@ realclean: clean include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" release_spec: diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 3f28cf9959..ed8cf0b8d3 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -30,6 +30,52 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.9.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + References to <c>is_constant/1</c> (which was removed in + the R12 release) has been removed from documentation and + code.</p> + <p> + Own Id: OTP-6454 Aux Id: seq10407 </p> + </item> + <item> + <p> + Fixed a discrepancy in compile_info</p> + <p> + The BEAM disassembler used the atom 'none' to signify the + absence of a compile_info chunk in a .beam file. This + clashed with the type declaration of the compile_info + field of a #beam_file{} record as containing a list. Now + [] signifies the absence of this chunk. This simplifies + the code and avoids a dialyzer warning.</p> + <p> + Own Id: OTP-9917</p> + </item> + <item> + <p> + Make dialyzer recognize the process_flag option sensitive + add missing specs to documentation (Thanks to Tobias + Schlager)</p> + <p> + Own Id: OTP-9923</p> + </item> + <item> + <p> + Remove hipe_ceach from hipe.app.src to fix + reltool-generated release startup. (Thanks to Tim + Stewart)</p> + <p> + Own Id: OTP-9939</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/flow/Makefile b/lib/hipe/flow/Makefile index 1a531fdfe5..75e156b542 100644 --- a/lib/hipe/flow/Makefile +++ b/lib/hipe/flow/Makefile @@ -100,10 +100,10 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/flow - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(INC_FILES) $(RELSYSDIR)/flow - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/flow" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(INC_FILES) "$(RELSYSDIR)/flow" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/icode/Makefile b/lib/hipe/icode/Makefile index 0d940d4b28..0f2d6db39b 100644 --- a/lib/hipe/icode/Makefile +++ b/lib/hipe/icode/Makefile @@ -118,10 +118,10 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/icode - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/icode - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/icode" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/icode" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/main/Makefile b/lib/hipe/main/Makefile index fc8923db6c..673431a175 100644 --- a/lib/hipe/main/Makefile +++ b/lib/hipe/main/Makefile @@ -115,10 +115,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DATA) ../vsn.mk $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/main - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/main - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DATA) ../vsn.mk "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/main" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/main" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src index d38b9ea7b1..7db4db8a57 100644 --- a/lib/hipe/main/hipe.app.src +++ b/lib/hipe/main/hipe.app.src @@ -24,7 +24,6 @@ {modules, [cerl_cconv, cerl_closurean, cerl_hipeify, - cerl_hybrid_transform, cerl_lib, cerl_messagean, cerl_pmatch, diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index c73db872ac..b2789978a4 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -482,12 +482,7 @@ compile(Name, File, Opts0) when is_atom(Name) -> compile_core(Name, Core0, File, Opts) -> Core = cerl:from_records(Core0), - Core1 = case (erlang:system_info(heap_type) =:= hybrid) - andalso proplists:get_bool(hybrid, Opts) of - true -> cerl_hybrid_transform:transform(Core, Opts); - false -> Core - end, - compile(Name, Core1, File, Opts). + compile(Name, Core, File, Opts). %% @spec compile(Name, Core, File, options()) -> %% {ok, {Target, Binary}} | {error, Reason} diff --git a/lib/hipe/misc/Makefile b/lib/hipe/misc/Makefile index 98a69d62c7..1204ab7c0b 100644 --- a/lib/hipe/misc/Makefile +++ b/lib/hipe/misc/Makefile @@ -100,10 +100,10 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/misc - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/misc - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/misc" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/misc" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/opt/Makefile b/lib/hipe/opt/Makefile index 426afd8052..a21c543574 100644 --- a/lib/hipe/opt/Makefile +++ b/lib/hipe/opt/Makefile @@ -97,8 +97,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/ppc/Makefile b/lib/hipe/ppc/Makefile index c4b0c3ba9d..8bd2a8226c 100644 --- a/lib/hipe/ppc/Makefile +++ b/lib/hipe/ppc/Makefile @@ -108,8 +108,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/regalloc/Makefile b/lib/hipe/regalloc/Makefile index d33f641640..d4be79ea85 100644 --- a/lib/hipe/regalloc/Makefile +++ b/lib/hipe/regalloc/Makefile @@ -112,8 +112,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/rtl/Makefile b/lib/hipe/rtl/Makefile index 30026831b7..426d1bd3ee 100644 --- a/lib/hipe/rtl/Makefile +++ b/lib/hipe/rtl/Makefile @@ -103,10 +103,10 @@ realclean: clean include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/rtl - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/rtl - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/rtl" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/rtl" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/sparc/Makefile b/lib/hipe/sparc/Makefile index e9e9d54e0c..eb40117691 100644 --- a/lib/hipe/sparc/Makefile +++ b/lib/hipe/sparc/Makefile @@ -108,8 +108,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile index f90d3c9f70..6761f11b01 100644 --- a/lib/hipe/tools/Makefile +++ b/lib/hipe/tools/Makefile @@ -96,8 +96,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/util/Makefile b/lib/hipe/util/Makefile index 2f17eee7f3..a5ee232057 100644 --- a/lib/hipe/util/Makefile +++ b/lib/hipe/util/Makefile @@ -103,10 +103,10 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/util - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/util - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/util" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/util" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index 347a0336cd..e296997466 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.9 +HIPE_VSN = 3.9.1 diff --git a/lib/hipe/x86/Makefile b/lib/hipe/x86/Makefile index f92e7eeec1..3602949944 100644 --- a/lib/hipe/x86/Makefile +++ b/lib/hipe/x86/Makefile @@ -116,8 +116,8 @@ $(DOCS)/%.html:%.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/ic/c_src/Makefile.in b/lib/ic/c_src/Makefile.in index 5e034c47c6..d8b8c85a8e 100644 --- a/lib/ic/c_src/Makefile.in +++ b/lib/ic/c_src/Makefile.in @@ -140,12 +140,12 @@ $(OBJDIR)/%.o: %.c include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/c_src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_DATA) ic.c ic_tmo.c $(RELSYSDIR)/c_src - $(INSTALL_DATA) $(IDL_FILES) $(H_FILES) $(RELSYSDIR)/include - $(INSTALL_DATA) $(LIBRARY) $(RELSYSDIR)/priv/lib + $(INSTALL_DIR) "$(RELSYSDIR)/c_src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DATA) ic.c ic_tmo.c "$(RELSYSDIR)/c_src" + $(INSTALL_DATA) $(IDL_FILES) $(H_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(LIBRARY) "$(RELSYSDIR)/priv/lib" release_docs_spec: diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile index 208f16e441..0ee242b234 100644 --- a/lib/ic/doc/src/Makefile +++ b/lib/ic/doc/src/Makefile @@ -220,12 +220,12 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - (/bin/cp -rf $(HTMLDIR) $(RELSYSDIR)/doc) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + (/bin/cp -rf $(HTMLDIR) "$(RELSYSDIR)/doc") + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml index 6329bf1fb5..eac932fc06 100644 --- a/lib/ic/doc/src/notes.xml +++ b/lib/ic/doc/src/notes.xml @@ -30,7 +30,23 @@ <file>notes.xml</file> </header> - <section><title>IC 4.2.29</title> + <section><title>IC 4.2.30</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Add generation of Erlang callback functions to generated + Erlang source code to avoid compiler warnings.</p> + <p> + Own Id: OTP-9998</p> + </item> + </list> + </section> + +</section> + +<section><title>IC 4.2.29</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/ic/examples/pre_post_condition/Makefile b/lib/ic/examples/pre_post_condition/Makefile index 8f85babb1a..8ae37394ed 100644 --- a/lib/ic/examples/pre_post_condition/Makefile +++ b/lib/ic/examples/pre_post_condition/Makefile @@ -124,8 +124,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/pre_post_condition - $(INSTALL_DATA) $(ERL_FILES) $(IDL_FILES) $(TXT_FILES) $(RELSYSDIR)/examples/pre_post_condition + $(INSTALL_DIR) "$(RELSYSDIR)/examples/pre_post_condition" + $(INSTALL_DATA) $(ERL_FILES) $(IDL_FILES) $(TXT_FILES) "$(RELSYSDIR)/examples/pre_post_condition" release_docs_spec: diff --git a/lib/ic/java_src/com/ericsson/otp/ic/Makefile b/lib/ic/java_src/com/ericsson/otp/ic/Makefile index f730749ccb..1b14d4430f 100644 --- a/lib/ic/java_src/com/ericsson/otp/ic/Makefile +++ b/lib/ic/java_src/com/ericsson/otp/ic/Makefile @@ -109,10 +109,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/java_src/com/ericsson/otp/ic - $(INSTALL_DATA) $(JAVA_FILES) $(RELSYSDIR)/java_src/com/ericsson/otp/ic - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/java_src/com/ericsson/otp/ic" + $(INSTALL_DATA) $(JAVA_FILES) "$(RELSYSDIR)/java_src/com/ericsson/otp/ic" + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/ic/src/Makefile b/lib/ic/src/Makefile index 5dac304e32..c830ebec95 100644 --- a/lib/ic/src/Makefile +++ b/lib/ic/src/Makefile @@ -196,23 +196,23 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DIR) $(RELSYSDIR)/examples/c-client - $(INSTALL_DATA) $(CCL_EX_FILES) $(RELSYSDIR)/examples/c-client - $(INSTALL_DIR) $(RELSYSDIR)/examples/c-server - $(INSTALL_DATA) $(CSRV_EX_FILES) $(RELSYSDIR)/examples/c-server - $(INSTALL_DIR) $(RELSYSDIR)/examples/erl-plain - $(INSTALL_DATA) $(EPL_EX_FILES) $(RELSYSDIR)/examples/erl-plain - $(INSTALL_DIR) $(RELSYSDIR)/examples/erl-genserv - $(INSTALL_DATA) $(ESRV_EX_FILES) $(RELSYSDIR)/examples/erl-genserv - $(INSTALL_DIR) $(RELSYSDIR)/examples/java-client-server - $(INSTALL_DATA) $(JAVA_EX_FILES) $(RELSYSDIR)/examples/java-client-server - $(INSTALL_DIR) $(RELSYSDIR)/examples/all-against-all - $(INSTALL_DATA) $(MIXED_EX_FILES) $(RELSYSDIR)/examples/all-against-all + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/c-client" + $(INSTALL_DATA) $(CCL_EX_FILES) "$(RELSYSDIR)/examples/c-client" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/c-server" + $(INSTALL_DATA) $(CSRV_EX_FILES) "$(RELSYSDIR)/examples/c-server" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/erl-plain" + $(INSTALL_DATA) $(EPL_EX_FILES) "$(RELSYSDIR)/examples/erl-plain" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/erl-genserv" + $(INSTALL_DATA) $(ESRV_EX_FILES) "$(RELSYSDIR)/examples/erl-genserv" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/java-client-server" + $(INSTALL_DATA) $(JAVA_EX_FILES) "$(RELSYSDIR)/examples/java-client-server" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/all-against-all" + $(INSTALL_DATA) $(MIXED_EX_FILES) "$(RELSYSDIR)/examples/all-against-all" release_docs_spec: diff --git a/lib/ic/src/ic.erl b/lib/ic/src/ic.erl index 50fad921c4..bc7ec8ba91 100644 --- a/lib/ic/src/ic.erl +++ b/lib/ic/src/ic.erl @@ -250,7 +250,7 @@ make_erl_options(Opts) -> Optimize = Opts#options.optimize, PreProc = lists:flatten( - lists:map(fun(D) -> io_lib:format("-I~s ", [ic_util:to_list(D)]) end, + lists:map(fun(D) -> io_lib:format("-I\"~s\" ", [ic_util:to_list(D)]) end, Includes1)++ lists:map( fun ({Name, Value}) -> diff --git a/lib/ic/src/ic_pp.erl b/lib/ic/src/ic_pp.erl index 8b53473caa..50eeeab48c 100644 --- a/lib/ic/src/ic_pp.erl +++ b/lib/ic/src/ic_pp.erl @@ -1894,23 +1894,37 @@ include_dir(Flags) when is_list(Flags)-> include_dir(_Flags) -> []. -include_dir(Flags,IncDir) -> +include_dir(Flags,IncDirs) -> case string:str(Flags,"-I") of 0 -> - lists:reverse(IncDir); + lists:reverse(IncDirs); X -> - Rem2 = string:sub_string(Flags, X+2), - Rem = string:strip(Rem2, left), - Y = string:str(Rem," "), - case string:str(Rem," ") of - 0 -> - lists:reverse([string:sub_string(Rem, Y+1)|IncDir]); - Y -> - include_dir(string:sub_string(Rem, Y+1), - [string:sub_string(Rem,1,Y-1)|IncDir]) - end + {NewDir, RemainingFlags} = + gobble_inc_dir(string:sub_string(Flags, X+2),nq,[]), + include_dir(RemainingFlags, [NewDir|IncDirs]) end. +% nq = not-quoted, q = quoted. +% Possible strange scenarios: +% /usr/test\ ing/ +% "/usr/test ing/" +% /usr/test\"ing/ +% "/usr/test\"ing/" +gobble_inc_dir([],nq,Acc) -> + % Only accept nq here, if we end up here in q mode the user has missed a " + {lists:reverse(Acc),[]}; +gobble_inc_dir([$\\,$"|R],Q,Acc) -> + gobble_inc_dir(R,Q,[$"|Acc]); +gobble_inc_dir([$"|R],nq,Acc) -> + gobble_inc_dir(R,q,Acc); +gobble_inc_dir([$"|R],q,Acc) -> + gobble_inc_dir(R,nq,Acc); +gobble_inc_dir([$\\,$ |R],nq,Acc) -> + gobble_inc_dir(R,nq,[$ |Acc]); +gobble_inc_dir([$ |R],nq,Acc) -> + {lists:reverse(Acc),R}; +gobble_inc_dir([C|R],Q,Acc) -> + gobble_inc_dir(R,Q,[C|Acc]). %%=============================================================== @@ -1954,7 +1968,6 @@ find_inc_file2(FileName, [D|Rem]) -> _ -> D++"/" end, - case catch file:read_file_info(Dir++FileName) of {ok, _} -> {ok, Dir++FileName}; diff --git a/lib/ic/test/Makefile b/lib/ic/test/Makefile index 1d90a1bc17..65003d703b 100644 --- a/lib/ic/test/Makefile +++ b/lib/ic/test/Makefile @@ -239,39 +239,39 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/ic_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/ic_register_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/ic_pragma_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/ic_pp_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/ic_be_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data - $(INSTALL_DIR) $(RELSYSDIR)/java_client_erl_server_SUITE_data + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/ic_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/ic_register_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/ic_pragma_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/ic_pp_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/ic_be_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/c_client_erl_server_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/c_client_erl_server_proto_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/erl_client_c_server_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/erl_client_c_server_proto_SUITE_data" + $(INSTALL_DIR) "$(RELSYSDIR)/java_client_erl_server_SUITE_data" $(INSTALL_DATA) $(IDL_FILES) ic.cover $(TEST_SPEC_FILE) $(ERL_FILES) \ - $(RELSYSDIR) - $(INSTALL_DATA) $(COMPILER_TEST_FILES) $(RELSYSDIR)/ic_SUITE_data + "$(RELSYSDIR)" + $(INSTALL_DATA) $(COMPILER_TEST_FILES) "$(RELSYSDIR)/ic_SUITE_data" $(INSTALL_DATA) $(COMPILER_TEST_FILES2) \ - $(RELSYSDIR)/ic_register_SUITE_data + "$(RELSYSDIR)/ic_register_SUITE_data" $(INSTALL_DATA) $(COMPILER_TEST_FILES3) \ - $(RELSYSDIR)/ic_pragma_SUITE_data + "$(RELSYSDIR)/ic_pragma_SUITE_data" $(INSTALL_DATA) $(COMPILER_TEST_FILES4) \ - $(RELSYSDIR)/ic_be_SUITE_data + "$(RELSYSDIR)/ic_be_SUITE_data" $(INSTALL_DATA) $(PREPROCESSOR_TEST_FILES) \ - $(RELSYSDIR)/ic_pp_SUITE_data + "$(RELSYSDIR)/ic_pp_SUITE_data" $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_TEST_FILES) \ - $(RELSYSDIR)/c_client_erl_server_SUITE_data + "$(RELSYSDIR)/c_client_erl_server_SUITE_data" $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TEST_FILES) \ - $(RELSYSDIR)/c_client_erl_server_proto_SUITE_data + "$(RELSYSDIR)/c_client_erl_server_proto_SUITE_data" $(INSTALL_DATA) $(C_CLIENT_ERL_SERVER_PROTO_TMO_TEST_FILES) \ - $(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data + "$(RELSYSDIR)/c_client_erl_server_proto_tmo_SUITE_data" $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_TEST_FILES) \ - $(RELSYSDIR)/erl_client_c_server_SUITE_data + "$(RELSYSDIR)/erl_client_c_server_SUITE_data" $(INSTALL_DATA) $(ERL_CLIENT_C_SERVER_PROTO_TEST_FILES) \ - $(RELSYSDIR)/erl_client_c_server_proto_SUITE_data - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) + "$(RELSYSDIR)/erl_client_c_server_proto_SUITE_data" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) $(JAVA_CLIENT_ERL_SERVER_TEST_FILES) \ - $(RELSYSDIR)/java_client_erl_server_SUITE_data + "$(RELSYSDIR)/java_client_erl_server_SUITE_data" diff --git a/lib/ic/test/java_client_erl_server_SUITE.erl b/lib/ic/test/java_client_erl_server_SUITE.erl index 407c3d2d44..d4523dc2ad 100644 --- a/lib/ic/test/java_client_erl_server_SUITE.erl +++ b/lib/ic/test/java_client_erl_server_SUITE.erl @@ -249,7 +249,7 @@ marshal_any_2(Config) when is_list(Config) -> java(Java, Dir, ClassAndArgs) -> - cmd(Java++" -classpath "++classpath(Dir)++" "++ClassAndArgs). + cmd(Java++" -classpath \""++classpath(Dir)++"\" "++ClassAndArgs). java(Java, Dir, Class, Args) -> java(Java, Dir, Class++" "++to_string(Args)). diff --git a/lib/inets/doc/src/Makefile b/lib/inets/doc/src/Makefile index b3a98fd6d5..1a8e1c7ca8 100644 --- a/lib/inets/doc/src/Makefile +++ b/lib/inets/doc/src/Makefile @@ -140,13 +140,13 @@ clean_man: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(HTMLDIR)/* "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/inets/examples/httpd_load_test/Makefile b/lib/inets/examples/httpd_load_test/Makefile index 1cc61ad8ae..de1b2a289f 100644 --- a/lib/inets/examples/httpd_load_test/Makefile +++ b/lib/inets/examples/httpd_load_test/Makefile @@ -34,7 +34,7 @@ VSN=$(INETS_VSN) # Release directory specification # ---------------------------------------------------- RELSYSDIR = $(RELEASE_PATH)/lib/inets-$(VSN) -EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples +EXAMPLE_RELSYSDIR = "$(RELSYSDIR)/examples" HDLT_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/httpd_load_test diff --git a/lib/inets/examples/server_root/Makefile b/lib/inets/examples/server_root/Makefile index d7a3231068..2230a7eafc 100644 --- a/lib/inets/examples/server_root/Makefile +++ b/lib/inets/examples/server_root/Makefile @@ -174,36 +174,36 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/auth - $(INSTALL_DATA) $(AUTH_FILES) $(RELSYSDIR)/examples/server_root/auth - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/cgi-bin - $(INSTALL_SCRIPT) $(CGI_FILES) $(RELSYSDIR)/examples/server_root/cgi-bin - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/conf - $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/examples/server_root/conf - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/open + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/auth" + $(INSTALL_DATA) $(AUTH_FILES) "$(RELSYSDIR)/examples/server_root/auth" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/cgi-bin" + $(INSTALL_SCRIPT) $(CGI_FILES) "$(RELSYSDIR)/examples/server_root/cgi-bin" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/conf" + $(INSTALL_DATA) $(CONF_FILES) "$(RELSYSDIR)/examples/server_root/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/htdocs/open" $(INSTALL_DATA) $(OPEN_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/open - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open + "$(RELSYSDIR)/examples/server_root/htdocs/open" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/htdocs/mnesia_open" $(INSTALL_DATA) $(MNESIA_OPEN_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_open - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs/misc + "$(RELSYSDIR)/examples/server_root/htdocs/mnesia_open" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/htdocs/misc" $(INSTALL_DATA) $(MISC_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/misc + "$(RELSYSDIR)/examples/server_root/htdocs/misc" $(INSTALL_DIR) \ - $(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret + "$(RELSYSDIR)/examples/server_root/htdocs/secret/top_secret" $(INSTALL_DIR) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret + "$(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret/top_secret" $(INSTALL_DATA) $(SECRET_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/secret + "$(RELSYSDIR)/examples/server_root/htdocs/secret" $(INSTALL_DATA) $(MNESIA_SECRET_FILES) \ - $(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/htdocs - $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/examples/server_root/htdocs - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/icons - $(INSTALL_DATA) $(ICON_FILES) $(RELSYSDIR)/examples/server_root/icons - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/ssl - $(INSTALL_DATA) $(SSL_FILES) $(RELSYSDIR)/examples/server_root/ssl - $(INSTALL_DIR) $(RELSYSDIR)/examples/server_root/logs + "$(RELSYSDIR)/examples/server_root/htdocs/mnesia_secret" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/htdocs" + $(INSTALL_DATA) $(HTDOCS_FILES) "$(RELSYSDIR)/examples/server_root/htdocs" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/icons" + $(INSTALL_DATA) $(ICON_FILES) "$(RELSYSDIR)/examples/server_root/icons" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/ssl" + $(INSTALL_DATA) $(SSL_FILES) "$(RELSYSDIR)/examples/server_root/ssl" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/server_root/logs" release_docs_spec: diff --git a/lib/inets/priv/Makefile b/lib/inets/priv/Makefile index 85da409e55..4dc521f618 100644 --- a/lib/inets/priv/Makefile +++ b/lib/inets/priv/Makefile @@ -57,8 +57,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(EXECUTABLES) $(RELSYSDIR)/priv/bin + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_SCRIPT) $(EXECUTABLES) "$(RELSYSDIR)/priv/bin" release_docs_spec: diff --git a/lib/inets/src/ftp/Makefile b/lib/inets/src/ftp/Makefile index 19b93870df..426286f254 100644 --- a/lib/inets/src/ftp/Makefile +++ b/lib/inets/src/ftp/Makefile @@ -88,11 +88,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/ftp - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/ftp - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/ftp" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/ftp" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/http_client/Makefile b/lib/inets/src/http_client/Makefile index d490e59929..850c790bd1 100644 --- a/lib/inets/src/http_client/Makefile +++ b/lib/inets/src/http_client/Makefile @@ -89,11 +89,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/http_client - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_client - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/http_client" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/http_client" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/http_lib/Makefile b/lib/inets/src/http_lib/Makefile index aaf3cfb995..3ec6ce7436 100644 --- a/lib/inets/src/http_lib/Makefile +++ b/lib/inets/src/http_lib/Makefile @@ -87,11 +87,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/http_lib - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_lib - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/http_lib" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/http_lib" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/http_server/Makefile b/lib/inets/src/http_server/Makefile index 60bb0d2527..67555d5f1c 100644 --- a/lib/inets/src/http_server/Makefile +++ b/lib/inets/src/http_server/Makefile @@ -123,11 +123,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/http_server - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/http_server - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/http_server" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/http_server" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/inets_app/Makefile b/lib/inets/src/inets_app/Makefile index 6da6a1d79f..b8d923edd8 100644 --- a/lib/inets/src/inets_app/Makefile +++ b/lib/inets/src/inets_app/Makefile @@ -111,13 +111,13 @@ $(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/inets_app - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/inets_app - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/inets_app" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/inets_app" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/src/tftp/Makefile b/lib/inets/src/tftp/Makefile index 759b70c8e4..a9df8d0319 100644 --- a/lib/inets/src/tftp/Makefile +++ b/lib/inets/src/tftp/Makefile @@ -39,8 +39,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN) # ---------------------------------------------------- # Target Specs # ---------------------------------------------------- +BEHAVIOUR_MODULES= \ + tftp + MODULES = \ - tftp \ tftp_binary \ tftp_engine \ tftp_file \ @@ -50,10 +52,13 @@ MODULES = \ HRL_FILES = tftp.hrl -ERL_FILES = $(MODULES:%=%.erl) +ERL_FILES= \ + $(MODULES:%=%.erl) \ + $(BEHAVIOUR_MODULES:%=%.erl) TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR)) # ---------------------------------------------------- # FLAGS @@ -72,10 +77,12 @@ ERL_COMPILE_FLAGS += \ # Targets # ---------------------------------------------------- +$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES) + debug opt: $(TARGET_FILES) clean: - rm -f $(TARGET_FILES) + rm -f $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES) rm -f core docs: @@ -86,11 +93,11 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/tftp - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src/tftp - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/tftp" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src/tftp" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(BEHAVIOUR_TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index 87ca60e4b3..7befa82272 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -234,7 +234,7 @@ endif # Release directory specification # ---------------------------------------------------- -RELTESTSYSDIR = $(RELEASE_PATH)/inets_test +RELTESTSYSDIR = "$(RELEASE_PATH)/inets_test" RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin @@ -284,9 +284,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/test - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/test - $(INSTALL_DATA) $(INETS_FILES) $(RELSYSDIR)/test + $(INSTALL_DIR) "$(RELSYSDIR)/test" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/test" + $(INSTALL_DATA) $(INETS_FILES) "$(RELSYSDIR)/test" @for d in $(DATADIRS); do \ echo "installing data dir $$d"; \ if test -f $$d/TAR.exclude; then \ @@ -299,9 +299,9 @@ release_spec: opt 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 -); \ + tar cfX - $$d/TAR.exclude2 $$d | (cd "$(RELSYSDIR)/test"; tar xf -); \ else \ - tar cf - $$d | (cd $(RELSYSDIR)/test; tar xf -); \ + tar cf - $$d | (cd "$(RELSYSDIR)/test"; tar xf -); \ fi; \ done @@ -330,8 +330,8 @@ info: @echo "INETS_SPECS = $(INETS_SPECS)" @echo "INETS_FILES = $(INETS_FILES)" @echo "" - @echo "RELEASE_PATH = $(RELEASE_PATH)" - @echo "RELSYSDIR = $(RELSYSDIR)" + @echo "RELEASE_PATH = "$(RELEASE_PATH)"" + @echo "RELSYSDIR = "$(RELSYSDIR)"" @echo "RELTESTSYSDIR = $(RELTESTSYSDIR)" @echo "RELTESTSYSALLDATADIR = $(RELTESTSYSALLDATADIR)" @echo "RELTESTSYSBINDIR = $(RELTESTSYSBINDIR)" diff --git a/lib/inviso/doc/src/Makefile b/lib/inviso/doc/src/Makefile index 1b184ed78b..f00b10f29c 100644 --- a/lib/inviso/doc/src/Makefile +++ b/lib/inviso/doc/src/Makefile @@ -106,14 +106,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/inviso/src/Makefile b/lib/inviso/src/Makefile index 1f2f8b1aff..292a2bec99 100644 --- a/lib/inviso/src/Makefile +++ b/lib/inviso/src/Makefile @@ -87,12 +87,12 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src -# $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" +# $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/inviso/test/Makefile b/lib/inviso/test/Makefile index c1df29d631..2650faa392 100644 --- a/lib/inviso/test/Makefile +++ b/lib/inviso/test/Makefile @@ -51,10 +51,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) inviso.spec inviso.cover $(ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) inviso.spec inviso.cover $(ERL_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/jinterface/doc/src/Makefile b/lib/jinterface/doc/src/Makefile index acd5307dee..858c97f187 100644 --- a/lib/jinterface/doc/src/Makefile +++ b/lib/jinterface/doc/src/Makefile @@ -160,17 +160,17 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DIR) $(RELSYSDIR)/doc/html/java/$(JAVA_PKG_PATH) - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - (/bin/cp -rf ../html $(RELSYSDIR)/doc) + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html/java/$(JAVA_PKG_PATH)" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + (/bin/cp -rf ../html "$(RELSYSDIR)/doc") # $(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \ -# $(RELSYSDIR)/doc/html -# $(INSTALL_DATA) $(JAVA_EXTRA_FILES) $(RELSYSDIR)/doc/html/java -# $(INSTALL_DATA) $(TOP_HTML_FILES) $(RELSYSDIR)/doc +# "$(RELSYSDIR)/doc/html" +# $(INSTALL_DATA) $(JAVA_EXTRA_FILES) "$(RELSYSDIR)/doc/html/java" +# $(INSTALL_DATA) $(TOP_HTML_FILES) "$(RELSYSDIR)/doc" release_spec: diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml index bf94077114..420e121389 100644 --- a/lib/jinterface/doc/src/notes.xml +++ b/lib/jinterface/doc/src/notes.xml @@ -30,6 +30,39 @@ </header> <p>This document describes the changes made to the Jinterface application.</p> +<section><title>Jinterface 1.5.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Correct spelling of registered (Thanks to Richard + Carlsson)</p> + <p> + Own Id: OTP-9925</p> + </item> + <item> + <p> + Java 1.5 has a bug where detecting codepoint offsets in + strings that are created by String.substring() gives + wrong results. The new implementation uses a different + method, avoinding the issue. (Thanks to Vlad Dumitrescu)</p> + <p> + Own Id: OTP-9927</p> + </item> + <item> + <p> + Improve error message when creating a too long + OtpErlangAtom. Also print the value that we tried to use + for the atom. (Thanks to Vlad Dumitrescu)</p> + <p> + Own Id: OTP-9928</p> + </item> + </list> + </section> + +</section> + <section><title>Jinterface 1.5.5</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile index 365798e68a..ec817aa39b 100644 --- a/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile +++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/Makefile @@ -66,7 +66,7 @@ JARFLAGS=-cvf JAVA_OPTIONS = ifeq ($(TESTROOT),) -RELEASE_PATH=$(ERL_TOP)/release/$(TARGET) +RELEASE_PATH="$(ERL_TOP)/release/$(TARGET)" else RELEASE_PATH=$(TESTROOT) endif @@ -96,13 +96,13 @@ docs: # include $(ERL_TOP)/make/otp_release_targets.mk release release_docs release_tests release_html: - $(MAKE) $(MFLAGS) RELEASE_PATH=$(RELEASE_PATH) $(TARGET_MAKEFILE) $@_spec + $(MAKE) $(MFLAGS) RELEASE_PATH="$(RELEASE_PATH)" $(TARGET_MAKEFILE) $@_spec release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/java_src/com/ericsson/otp/erlang - $(INSTALL_DATA) $(JAVA_SRC) $(RELSYSDIR)/java_src/com/ericsson/otp/erlang - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang" + $(INSTALL_DATA) $(JAVA_SRC) "$(RELSYSDIR)/java_src/com/ericsson/otp/erlang" + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(JAVA_DEST_ROOT)$(JARFILE) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/jinterface/test/Makefile b/lib/jinterface/test/Makefile index a85d0e7411..b70521c08d 100644 --- a/lib/jinterface/test/Makefile +++ b/lib/jinterface/test/Makefile @@ -80,6 +80,6 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_FILE) $(ERL_FILES) $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_FILE) $(ERL_FILES) "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk index 9d8229e9fa..15423e5658 100644 --- a/lib/jinterface/vsn.mk +++ b/lib/jinterface/vsn.mk @@ -1 +1 @@ -JINTERFACE_VSN = 1.5.5 +JINTERFACE_VSN = 1.5.6 diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile index 214e994889..78e5f7bc26 100644 --- a/lib/kernel/doc/src/Makefile +++ b/lib/kernel/doc/src/Makefile @@ -155,18 +155,18 @@ $(SPECDIR)/specs_zlib_stub.xml: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man4 - $(INSTALL_DATA) $(MAN4_FILES) $(RELEASE_PATH)/man/man4 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man4" + $(INSTALL_DATA) $(MAN4_FILES) "$(RELEASE_PATH)/man/man4" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/kernel/doc/src/gen_sctp.xml b/lib/kernel/doc/src/gen_sctp.xml index 579b7f1f74..e327a4f907 100644 --- a/lib/kernel/doc/src/gen_sctp.xml +++ b/lib/kernel/doc/src/gen_sctp.xml @@ -123,7 +123,7 @@ <p>Completely closes the socket and all associations on it. The unsent data is flushed as in <c>eof/2</c>. The <c>close/1</c> call is blocking or otherwise depending of the value of - the <seealso marker="#option-linger">linger</seealso> socket + the <seealso marker="inet#option-linger">linger</seealso> socket <seealso marker="#options">option</seealso>. If <c>close</c> does not linger or linger timeout expires, the call returns and the data is flushed in the background.</p> @@ -309,8 +309,8 @@ <seealso marker="#option-active">passive</seealso> mode, with <anno>SockType</anno> <c>seqpacket</c>, and with reasonably large - <seealso marker="#option-sndbuf">kernel</seealso> and driver - <seealso marker="#option-buffer">buffers.</seealso></p> + <seealso marker="inet#option-sndbuf">kernel</seealso> and driver + <seealso marker="inet#option-buffer">buffers.</seealso></p> </desc> </func> <func> @@ -530,19 +530,8 @@ SCTP data interleaved with other inter-process messages.</p> </item> </list> - <marker id="option-buffer"></marker> </item> - <tag><c>{buffer, integer()}</c></tag> - <item> - <p>Determines the size of the user-level software buffer used by - the SCTP driver. Not to be confused with <c>sndbuf</c> - and <c>recbuf</c> options which correspond to - the kernel socket buffers. It is recommended - to have <c>val(buffer) >= max(val(sndbuf),val(recbuf))</c>. - In fact, the <c>val(buffer)</c> is automatically set to - the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p> - </item> - <tag><c>{tos, integer()}</c></tag> + <tag><c>{tos, integer()}</c></tag> <item> <p>Sets the Type-Of-Service field on the IP datagrams being sent, to the given value, which effectively determines a prioritization @@ -567,19 +556,8 @@ <c>{IP,Port}</c> of the socket can be re-used immediately: no waiting in the CLOSE_WAIT state is performed (may be required for high-throughput servers).</p> - <marker id="option-linger"></marker> - </item> - <tag><c>{linger, {true|false, integer()}</c></tag> - <item> - <p>Determines the timeout in seconds for flushing unsent data in the - <c>gen_sctp:close/1</c> socket call. If the 1st component of the value - tuple is <c>false</c>, the 2nd one is ignored, which means that - <c>gen_sctp:close/1</c> returns immediately not waiting - for data to be flushed. Otherwise, the 2nd component is - the flushing time-out in seconds.</p> - <marker id="option-sndbuf"></marker> </item> - <tag><c>{sndbuf, integer()}</c></tag> + <tag><c>{sndbuf, integer()}</c></tag> <item> <p>The size, in bytes, of the *kernel* send buffer for this socket. Sending errors would occur for datagrams larger than @@ -593,6 +571,15 @@ <c>val(sndbuf)</c>. Setting this option also adjusts the size of the driver buffer (see <c>buffer</c> above).</p> </item> + + <tag><c>{sctp_module, module()}</c></tag> + <item> <p> + Override which callback module is used. Defaults to + <c>inet_sctp</c> for IPv4 and <c>inet6_sctp</c> for IPv6. + </p> + </item> + + <tag><c>{sctp_rtoinfo, #sctp_rtoinfo{}}</c></tag> <item> <pre> #sctp_rtoinfo{ diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml index cf97607af1..11a0843c10 100644 --- a/lib/kernel/doc/src/gen_tcp.xml +++ b/lib/kernel/doc/src/gen_tcp.xml @@ -96,37 +96,47 @@ do_recv(Sock, Bs) -> can be either a hostname, or an IP address.</p> <p>The available options are:</p> <taglist> - <tag><c>list</c></tag> - <item> - <p>Received <c>Packet</c> is delivered as a list.</p> - </item> - <tag><c>binary</c></tag> - <item> - <p>Received <c>Packet</c> is delivered as a binary.</p> - </item> - <tag><c>{ip, ip_address()}</c></tag> + <tag><c>{ip, ip_address()}</c></tag> <item> <p>If the host has several network interfaces, this option specifies which one to use.</p> </item> - <tag><c>{port, Port}</c></tag> + + <tag><c>{ifaddr, ip_address()}</c></tag> <item> - <p>Specify which local port number to use.</p> - </item> + <p>Same as <c>{ip, ip_address()}</c>. If the host has several network interfaces, this option + specifies which one to use.</p> + </item> + <tag><c>{fd, integer() >= 0}</c></tag> <item> <p>If a socket has somehow been connected without using <c>gen_tcp</c>, use this option to pass the file descriptor for it.</p> </item> - <tag><c>inet6</c></tag> + + <tag><c>inet</c></tag> <item> + <p>Set up the socket for IPv4.</p> + </item> + + <tag><c>inet6</c></tag> + <item> <p>Set up the socket for IPv6.</p> </item> - <tag><c>inet</c></tag> + + <tag><c>{port, Port}</c></tag> <item> - <p>Set up the socket for IPv4.</p> + <p>Specify which local port number to use.</p> </item> + + <tag><c>{tcp_module, module()}</c></tag> + <item> <p> + Override which callback module is used. Defaults to + <c>inet_tcp</c> for IPv4 and <c>inet6_tcp</c> for IPv6. + </p> + </item> + <tag><c>Opt</c></tag> <item> <p>See @@ -197,6 +207,13 @@ do_recv(Sock, Bs) -> <c>gen_tcp</c>, use this option to pass the file descriptor for it.</p> </item> + + <tag><c>{ifaddr, ip_address()}</c></tag> + <item> + <p>Same as <c>{ip, ip_address()}</c>. If the host has several network interfaces, this option + specifies which one to use.</p> + </item> + <tag><c>inet6</c></tag> <item> <p>Set up the socket for IPv6.</p> @@ -205,6 +222,14 @@ do_recv(Sock, Bs) -> <item> <p>Set up the socket for IPv4.</p> </item> + + <tag><c>{tcp_module, module()}</c></tag> + <item> <p> + Override which callback module is used. Defaults to + <c>inet_tcp</c> for IPv4 and <c>inet6_tcp</c> for IPv6. + </p> + </item> + <tag><c>Opt</c></tag> <item> <p>See @@ -299,7 +324,7 @@ do_recv(Sock, Bs) -> <c><anno>Socket</anno></c>. The controlling process is the process which receives messages from the socket. If called by any other process than the current controlling process, - <c>{error, eperm}</c> is returned.</p> + <c>{error, not_owner}</c> is returned.</p> </desc> </func> <func> diff --git a/lib/kernel/doc/src/gen_udp.xml b/lib/kernel/doc/src/gen_udp.xml index daa9b7d887..726dc30546 100644 --- a/lib/kernel/doc/src/gen_udp.xml +++ b/lib/kernel/doc/src/gen_udp.xml @@ -72,6 +72,14 @@ <p>If the host has several network interfaces, this option specifies which one to use.</p> </item> + + <tag><c>{ifaddr, ip_address()}</c></tag> + <item> + <p>Same as <c>{ip, ip_address()}</c>. If the host has several network interfaces, this option + specifies which one to use.</p> + </item> + + <tag><c>{fd, integer() >= 0}</c></tag> <item> <p>If a socket has somehow been opened without using @@ -86,6 +94,51 @@ <item> <p>Set up the socket for IPv4.</p> </item> + + <tag><c>{udp_module, module()}</c></tag> + <item> <p> + Override which callback module is used. Defaults to + <c>inet_udp</c> for IPv4 and <c>inet6_udp</c> for IPv6. + </p> + </item> + + <tag><c>{multicast_if, Address}</c></tag> + <item> + <p>Set the local device for a multicast socket.</p> + </item> + + <tag><c>{multicast_loop, true | false}</c></tag> + <item> + <p> + When <c>true</c> sent multicast packets will be looped back to the local + sockets. + </p> + </item> + + <tag><c>{multicast_ttl, Integer}</c></tag> + <item> + <p> + The <c>multicast_ttl</c> option changes the time-to-live (TTL) for + outgoing multicast datagrams in order to control the scope of the + multicasts. + </p> + <p> + Datagrams with a TTL of 1 are not forwarded beyond the local + network. + <br />Default: 1 + </p> + </item> + + <tag><c>{add_membership, {MultiAddress, InterfaceAddress}}</c></tag> + <item> + <p>Join a multicast group. </p> + </item> + + <tag><c>{drop_membership, {MultiAddress, InterfaceAddress}}</c></tag> + <item> + <p>Leave multicast group.</p> + </item> + <tag><c>Opt</c></tag> <item> <p>See @@ -136,7 +189,9 @@ <desc> <p>Assigns a new controlling process <c><anno>Pid</anno></c> to <c><anno>Socket</anno></c>. The controlling process is the process which - receives messages from the socket.</p> + receives messages from the socket. If called by any other + process than the current controlling process, + <c>{error, not_owner}</c> is returned.</p> </desc> </func> <func> diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index bf6c4cfb1a..096ddfd847 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -445,10 +445,34 @@ fe80::204:acff:fe17:bf38 flow control; the other side will not be able send faster than the receiver can read.</p> </item> + + <tag><c>{bit8, clear | set | on | off}</c></tag> + <item> + <p> + Scans every byte in received data-packets and checks if the 8 bit + is set in any of them. Information is retrieved with + <c>inet:getopts/2</c>. + <note>Deprecated! Will be removed in Erlang/OTP R16.</note> + </p> + </item> + <tag><c>{broadcast, Boolean}</c>(UDP sockets)</tag> <item> <p>Enable/disable permission to send broadcasts.</p> + <marker id="option-buffer"></marker> </item> + + <tag><c>{buffer, Size}</c></tag> + <item> + <p>Determines the size of the user-level software buffer used by + the driver. Not to be confused with <c>sndbuf</c> + and <c>recbuf</c> options which correspond to + the kernel socket buffers. It is recommended + to have <c>val(buffer) >= max(val(sndbuf),val(recbuf))</c>. + In fact, the <c>val(buffer)</c> is automatically set to + the above maximum when <c>sndbuf</c> or <c>recbuf</c> values are set.</p> + </item> + <tag><c>{delay_send, Boolean}</c></tag> <item> <p>Normally, when an Erlang process sends to a socket, @@ -463,10 +487,19 @@ fe80::204:acff:fe17:bf38 real property of the socket. Needless to say it is an implementation specific option. Default is <c>false</c>.</p> </item> + + <tag><c>{deliver, port | term}</c></tag> + <item> <p> When <c>{active, true}</c> delivers data on the forms + <c>port</c> : <c>{S, {data, [H1,..Hsz | Data]}}</c> or + <c>term</c> : <c>{tcp, S, [H1..Hsz | Data]}</c>. + </p> + </item> + <tag><c>{dontroute, Boolean}</c></tag> <item> <p>Enable/disable routing bypass for outgoing messages.</p> </item> + <tag><c>{exit_on_close, Boolean}</c></tag> <item> <p>By default this option is set to <c>true</c>.</p> @@ -476,6 +509,7 @@ fe80::204:acff:fe17:bf38 <seealso marker="gen_tcp#shutdown/2">gen_tcp:shutdown/2</seealso> to shutdown the write side.</p> </item> + <tag><c>{header, Size}</c></tag> <item> <p>This option is only meaningful if the <c>binary</c> @@ -487,6 +521,15 @@ fe80::204:acff:fe17:bf38 example <c>Size == 2</c>, the data received will match <c>[Byte1,Byte2|Binary]</c>.</p> </item> + + <tag><c>{high_watermark, Size}</c></tag> + <item> <p> + Sender is forced busy if sent and enqueued data + reaches the highwater mark. + <br /> Default: 8192 kB. + </p> + </item> + <tag><c>{keepalive, Boolean}</c>(TCP/IP sockets)</tag> <item> <p>Enables/disables periodic transmission on a connected @@ -494,7 +537,43 @@ fe80::204:acff:fe17:bf38 the other end does not respond, the connection is considered broken and an error message will be sent to the controlling process. Default disabled.</p> + <marker id="option-linger"></marker> </item> + + <tag><c>{linger, {true|false, Seconds}}</c></tag> + <item> + <p>Determines the timeout in seconds for flushing unsent data in the + <c>close/1</c> socket call. If the 1st component of the value + tuple is <c>false</c>, the 2nd one is ignored, which means that + <c>close/1</c> returns immediately not waiting + for data to be flushed. Otherwise, the 2nd component is + the flushing time-out in seconds.</p> + </item> + + <tag><c>{low_watermark, Size}</c></tag> + <item> <p> + If the port has reached its <c>high_watermark</c> it will + force busy onto senders. When the port data queue reaches the + <c>low_watermark</c> callers are no longer forced busy. + <br /> Default: 4096 kB. + </p> + </item> + + <tag><c>{mode, Mode :: binary | list}</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as defined by Mode.</p> + </item> + + <tag><c>list</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a list.</p> + </item> + + <tag><c>binary</c></tag> + <item> + <p>Received <c>Packet</c> is delivered as a binary.</p> + </item> + <tag><c>{nodelay, Boolean}</c>(TCP/IP sockets)</tag> <item> <p>If <c>Boolean == true</c>, the <c>TCP_NODELAY</c> option @@ -578,6 +657,16 @@ fe80::204:acff:fe17:bf38 indicated length are accepted and not considered invalid due to internal buffer limitations.</p> </item> + + <tag><c>{priority, Priority}</c></tag> + <item> <p>Set the protocol-defined priority for all packets to be sent + on this socket.</p> + </item> + + <tag><c>{raw, Protocol, OptionNum, ValueBin}</c></tag> + <item> <p>See below.</p> + </item> + <tag><c>{read_packets, Integer}</c>(UDP sockets)</tag> <item> <p>Sets the max number of UDP packets to read without @@ -589,7 +678,7 @@ fe80::204:acff:fe17:bf38 high the system can become unresponsive due to UDP packet flooding.</p> </item> - <tag><c>{recbuf, Integer}</c></tag> + <tag><c>{recbuf, Size}</c></tag> <item> <p>Gives the size of the receive buffer to use for the socket.</p> @@ -618,9 +707,10 @@ fe80::204:acff:fe17:bf38 returns <c>{error,timeout}</c>. The recommended setting is <c>true</c> which will automatically close the socket. Default is <c>false</c> due to backward compatibility.</p> + <marker id="option-sndbuf"></marker> </item> - <tag><c>{sndbuf, Integer}</c></tag> + <tag><c>{sndbuf, Size}</c></tag> <item> <p>Gives the size of the send buffer to use for the socket.</p> </item> @@ -639,6 +729,7 @@ fe80::204:acff:fe17:bf38 not implemented. Use with caution.</p> </item> </taglist> + <p>In addition to the options mentioned above, <em>raw</em> option specifications can be used. The raw options are specified as a tuple of arity four, beginning with the tag diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml index 9121186631..94624bf512 100644 --- a/lib/kernel/doc/src/notes.xml +++ b/lib/kernel/doc/src/notes.xml @@ -30,6 +30,133 @@ </header> <p>This document describes the changes made to the Kernel application.</p> +<section><title>Kernel 2.15.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Driver output has been corrected so output of large + binaries (> 4 GiB) now does not silently fail or crash + the emulator, but either outputs the binary or fails the + call. This means that writing a binary > 4 Gib to file + now works but on e.g 64-bit Windows (that has + scatter/gather I/O buffer segment lengths of 32 bits) + fails. The behaviour may change in the future to always + write the binary, in parts if necessary.</p> + <p> + Own Id: OTP-9820 Aux Id: OTP-9795 </p> + </item> + <item> + <p> + erts: minor fix for unnecessary condition erts: change + SENDFILE_CHUNK_SIZE from signed to unsigned (Thanks to + jovi zhang)</p> + <p> + Own Id: OTP-9872</p> + </item> + <item> + <p> Two contracts in <c>gen_sctp</c> have been corrected. + </p> + <p> + Own Id: OTP-9874</p> + </item> + <item> + <p>If a process calls a module with an running on_load + handler, the process is supposed to be suspended. But if + the module with the on_load handler was loading used + <c>code:load_binary/3</c>, the call would instead fail + with an <c>undef</c> exception.</p> + <p> + Own Id: OTP-9875</p> + </item> + <item> + <p> + File name and error reason is now returned if creation of + a cookie fails. (Thanks to Magnus Henoch)</p> + <p> + Own Id: OTP-9954</p> + </item> + <item> + <p> + Fix port leak in <c>zlib</c> when passing invalid data to + <c>compress,uncompress,zip,unzip,gzip,gunzip</c>.</p> + <p> + Own Id: OTP-9981</p> + </item> + <item> + <p> + Various typographical errors corrected in documentation + for the global, error_logger, etop, lists, ets and + supervisor modules and in the c_portdriver and kernel_app + documentation. (Thanks to Ricardo Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9987</p> + </item> + <item> + <p> Fix returned error from gen_tcp:accept/1,2 when + running out of ports + <p> + The {error, enfile} return value is badly misleading and + confusing for this case, since the Posix ENFILE errno + value has a well-defined meaning that has nothing to do + with Erlang ports. The fix changes the return value to + {error, system_limit}, which is consistent with e.g. + various file(3) functions. inet:format_error/1 has also + been updated to support system_limit in the same manner + as file:format_error/1. (Thanks to Per Hedeland)</p></p> + <p> + Own Id: OTP-9990</p> + </item> + <item> + <p><c>erts_debug:size/1</c> has been corrected to take + sharing in the environment of funs into account. For funs + it used to always give the same result as + <c>erts_debug:flat_size/1</c>.</p> + <p> + Own Id: OTP-9991</p> + </item> + <item> + <p> + In some cases when the process doing file:sendfile + crashes while sending the file the efile_drv code would + not clean up after itself correctly. This has now been + fixed.</p> + <p> + Own Id: OTP-9993</p> + </item> + <item> + <p> + On BSD based platforms file:sendfile would sometime go + into an infinite loop when sending big files. This has + now been fixed.</p> + <p> + Own Id: OTP-9994</p> + </item> + <item> + <p>While <c>disk_log</c> eagerly collects logged terms + for better performance, collecting too much data may + choke the system and cause huge binaries to be + written.</p> + <p>The problem was addressed in OTP-9764, but the + situation was not improved in all cases.</p> + <p>(Thanks to Richard Carlsson.)</p> + <p> + Own Id: OTP-9999 Aux Id: OTP-9764 </p> + </item> + <item> + <p> + The documentation of .app files incorrectly said that the + default value for the <c>mod</c> parameter is + <c>undefined</c>. This is now corrected to <c>[]</c>.</p> + <p> + Own Id: OTP-10002</p> + </item> + </list> + </section> + +</section> + <section><title>Kernel 2.15</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/kernel/examples/Makefile b/lib/kernel/examples/Makefile index fb27f8d438..21dfd0ec0e 100644 --- a/lib/kernel/examples/Makefile +++ b/lib/kernel/examples/Makefile @@ -47,8 +47,8 @@ RELSYSDIR = $(RELEASE_PATH)/lib/kernel-$(KERNEL_VSN)/examples EXAMPLES = uds_dist release_spec: - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" tar cf - $(EXAMPLES) | \ - (cd $(RELSYSDIR); tar xf - ; chmod -R ug+w $(EXAMPLES) ) + (cd "$(RELSYSDIR)"; tar xf - ; chmod -R ug+w $(EXAMPLES) ) release_docs_spec: diff --git a/lib/kernel/src/Makefile b/lib/kernel/src/Makefile index 54f21eb2b8..a39864d6b7 100644 --- a/lib/kernel/src/Makefile +++ b/lib/kernel/src/Makefile @@ -198,13 +198,13 @@ $(EBIN)/erl_epmd.beam: $(ESRC)/erl_epmd.erl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/kernel/src/disk_log.erl b/lib/kernel/src/disk_log.erl index f5f972c112..5b1efcd395 100644 --- a/lib/kernel/src/disk_log.erl +++ b/lib/kernel/src/disk_log.erl @@ -282,7 +282,8 @@ change_notify(Log, Pid, NewNotify) -> -spec change_header(Log, Header) -> 'ok' | {'error', Reason} when Log :: log(), - Header :: {head, dlog_head_opt()} | {head_func, mfa()}, + Header :: {head, dlog_head_opt()} + | {head_func, MFA :: {atom(), atom(), list()}}, Reason :: no_such_log | nonode | {read_only_mode, Log} | {blocked_log, Log} | {badarg, head}. change_header(Log, NewHead) -> @@ -336,7 +337,9 @@ format_error(Error) -> ok | {blocked, QueueLogRecords :: boolean()}} | {node, Node :: node()} | {distributed, Dist :: local | [node()]} - | {head, Head :: none | {head, term()} | mfa()} + | {head, Head :: none + | {head, term()} + | (MFA :: {atom(), atom(), list()})} | {no_written_items, NoWrittenItems ::non_neg_integer()} | {full, Full :: boolean} | {no_current_bytes, non_neg_integer()} diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl index 259967650f..242a25a7a6 100644 --- a/lib/kernel/src/disk_log.hrl +++ b/lib/kernel/src/disk_log.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -74,7 +74,7 @@ | {distributed, Nodes :: [node()]} | {notify, boolean()} | {head, Head :: dlog_head_opt()} - | {head_func, mfa()} + | {head_func, MFA :: {atom(), atom(), list()}} | {mode, Mode :: dlog_mode()}. -type dlog_options() :: [dlog_option()]. -type dlog_repair() :: 'truncate' | boolean(). diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl index d8033ee192..cdb984c333 100644 --- a/lib/kernel/src/file.erl +++ b/lib/kernel/src/file.erl @@ -1258,7 +1258,7 @@ sendfile_fallback_int(File, Sock, Bytes, ChunkSize, BytesSent) when Bytes > BytesSent; Bytes == 0 -> Size = if Bytes == 0 -> ChunkSize; - (Bytes - BytesSent + ChunkSize) > 0 -> + (Bytes - BytesSent) < ChunkSize -> Bytes - BytesSent; true -> ChunkSize diff --git a/lib/kernel/src/gen_sctp.erl b/lib/kernel/src/gen_sctp.erl index d8954f0cf7..8fa963ec78 100644 --- a/lib/kernel/src/gen_sctp.erl +++ b/lib/kernel/src/gen_sctp.erl @@ -425,9 +425,10 @@ error_string(X) -> erlang:error(badarg, [X]). --spec controlling_process(Socket, Pid) -> ok when +-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when Socket :: sctp_socket(), - Pid :: pid(). + Pid :: pid(), + Reason :: closed | not_owner | inet:posix(). controlling_process(S, Pid) when is_port(S), is_pid(Pid) -> inet:udp_controlling_process(S, Pid); diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index ef6bfdf7f4..e6dfdadb03 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -31,7 +31,6 @@ -type option() :: {active, true | false | once} | - {bit8, clear | set | on | off} | {buffer, non_neg_integer()} | {delay_send, boolean()} | {deliver, port | term} | @@ -61,7 +60,6 @@ {tos, non_neg_integer()}. -type option_name() :: active | - bit8 | buffer | delay_send | deliver | diff --git a/lib/kernel/src/gen_udp.erl b/lib/kernel/src/gen_udp.erl index 8688799ae9..914854c65c 100644 --- a/lib/kernel/src/gen_udp.erl +++ b/lib/kernel/src/gen_udp.erl @@ -185,9 +185,10 @@ connect(S, Address, Port) when is_port(S) -> Error end. --spec controlling_process(Socket, Pid) -> ok when +-spec controlling_process(Socket, Pid) -> ok | {error, Reason} when Socket :: socket(), - Pid :: pid(). + Pid :: pid(), + Reason :: closed | not_owner | inet:posix(). controlling_process(S, NewOwner) -> inet:udp_controlling_process(S, NewOwner). diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index abaf4486dc..0bb5444dbb 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -1246,6 +1246,8 @@ udp_close(S) when is_port(S) -> %% Set controlling process for TCP socket. tcp_controlling_process(S, NewOwner) when is_port(S), is_pid(NewOwner) -> case erlang:port_info(S, connected) of + {connected, NewOwner} -> + ok; {connected, Pid} when Pid =/= self() -> {error, not_owner}; undefined -> @@ -1297,6 +1299,8 @@ tcp_sync_input(S, Owner, Flag) -> %% Set controlling process for UDP or SCTP socket. udp_controlling_process(S, NewOwner) when is_port(S), is_pid(NewOwner) -> case erlang:port_info(S, connected) of + {connected, NewOwner} -> + ok; {connected, Pid} when Pid =/= self() -> {error, not_owner}; _ -> diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile index 5dcaad3f5e..7bb3e3a365 100644 --- a/lib/kernel/test/Makefile +++ b/lib/kernel/test/Makefile @@ -140,12 +140,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(APP_FILES) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(APP_FILES) "$(RELSYSDIR)" $(INSTALL_DATA) kernel.spec $(EMAKEFILE)\ - $(COVERFILE) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(COVERFILE) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/kernel/test/bif_SUITE.erl b/lib/kernel/test/bif_SUITE.erl index 6276270d20..a2826f34df 100644 --- a/lib/kernel/test/bif_SUITE.erl +++ b/lib/kernel/test/bif_SUITE.erl @@ -260,23 +260,15 @@ spawn_opt2(Config) when is_list(Config) -> ?line P1 = spawn_opt(fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> - [{fullsweep_after, 0},{min_heap_size, 1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after, 0},{min_heap_size, 1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), ?line check_proc_vals(true, max, 0, 1000, PV1) end, ?line P2 = spawn_opt(fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -295,13 +287,8 @@ spawn_opt3(Config) when is_list(Config) -> fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -309,10 +296,7 @@ spawn_opt3(Config) when is_list(Config) -> end, ?line P2 = spawn_opt(Node, fun() -> Parent ! {self(), fetch_proc_vals(self())} end, - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -333,13 +317,8 @@ spawn_opt4(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -350,10 +329,7 @@ spawn_opt4(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -374,13 +350,8 @@ spawn_opt5(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> - [{fullsweep_after,0}, {min_heap_size,1000}]; - shared -> - [] - end - ++ [link, {priority, max}]), + [{fullsweep_after,0}, {min_heap_size,1000}, + link, {priority, max}]), ?line receive {P1, PV1} -> ?line Node = node(P1), @@ -392,10 +363,7 @@ spawn_opt5(Config) when is_list(Config) -> [fun() -> Parent ! {self(), fetch_proc_vals(self())} end], - case heap_type() of - separate -> [{min_heap_size, 10}]; - shared -> [] - end), + [{min_heap_size, 10}]), ?line receive {P2, PV2} -> ?line Node = node(P2), @@ -532,34 +500,19 @@ spawn_failures(Config) when is_list(Config) -> check_proc_vals(Link, Priority, FullsweepAfter, MinHeapSize, {Ls, P, FA, HS}) -> ?line Link = lists:member(self(), Ls), ?line Priority = P, - ?line case heap_type() of - separate -> - ?line FullsweepAfter = FA, - ?line true = (HS >= MinHeapSize); - shared -> - ?line ok - end, + FullsweepAfter = FA, + true = (HS >= MinHeapSize), ?line ok. fetch_proc_vals(Pid) -> ?line PI = process_info(Pid), ?line {value,{links, Ls}} = lists:keysearch(links, 1, PI), ?line {value,{priority,P}} = lists:keysearch(priority, 1, PI), - ?line {FA, HS} - = case heap_type() of - separate -> - ?line {value, - {garbage_collection, - Gs}} = lists:keysearch(garbage_collection, 1, PI), - ?line {value, - {fullsweep_after, - Fa}} = lists:keysearch(fullsweep_after, 1, Gs), - ?line {value, - {heap_size,Hs}} = lists:keysearch(heap_size, 1, PI), - ?line {Fa, Hs}; - shared -> - {undefined, undefined} - end, + {value,{garbage_collection,Gs}} = + lists:keysearch(garbage_collection, 1, PI), + {value,{fullsweep_after,FA}} = + lists:keysearch(fullsweep_after, 1, Gs), + {value,{heap_size,HS}} = lists:keysearch(heap_size, 1, PI), ?line {Ls, P, FA, HS}. % This testcase should probably be moved somewhere else @@ -650,12 +603,3 @@ stop_node(Node) -> run_fun(Fun) -> Fun(). - -heap_type() -> - case catch erlang:system_info(heap_type) of - shared -> shared; - unified -> shared; - _ -> separate - end. - - diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl index 2c59351600..3e8bdaf1ff 100644 --- a/lib/kernel/test/code_SUITE.erl +++ b/lib/kernel/test/code_SUITE.erl @@ -501,7 +501,7 @@ sticky_dir(doc) -> ["Test that a module with the same name as a module in ", "a sticky directory cannot be loaded."]; sticky_dir(Config) when is_list(Config) -> MyDir=filename:dirname(code:which(?MODULE)), - ?line {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa "++MyDir}]), + ?line {ok, Node}=?t:start_node(sticky_dir, slave,[{args, "-pa \""++MyDir++"\""}]), File=filename:join([?config(data_dir, Config), "calendar"]), ?line Ret=rpc:call(Node, ?MODULE, sticky_compiler, [File]), case Ret of @@ -822,7 +822,7 @@ load_cached(Config) when is_list(Config) -> ?line WD = filename:dirname(code:which(?MODULE)), ?line {ok,Node} = ?t:start_node(code_cache_node, peer, [{args, - "-pa " ++ WD}, + "-pa \"" ++ WD ++ "\""}, {erl, [this]}]), CCTabCreated = fun(Tab) -> case ets:info(Tab, name) of @@ -907,7 +907,7 @@ add_and_rehash(Config) when is_list(Config) -> ?line WD = filename:dirname(code:which(?MODULE)), ?line {ok,Node} = ?t:start_node(code_cache_node, peer, [{args, - "-pa " ++ WD}, + "-pa \"" ++ WD ++ "\""}, {erl, [this]}]), CCTabCreated = fun(Tab) -> case ets:info(Tab, name) of diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl index ad987fe7a7..0c3f5c3514 100644 --- a/lib/kernel/test/disk_log_SUITE.erl +++ b/lib/kernel/test/disk_log_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -90,7 +90,7 @@ evil/1, - otp_6278/1]). + otp_6278/1, otp_10131/1]). -export([head_fun/1, hf/0, lserv/1, measure/0, init_m/1, xx/0, head_exit/0, slow_header/1]). @@ -124,7 +124,7 @@ [halt_int, wrap_int, halt_ext, wrap_ext, read_mode, head, notif, new_idx_vsn, reopen, block, unblock, open, close, error, chunk, truncate, many_users, info, change_size, - change_attribute, distribution, evil, otp_6278]). + change_attribute, distribution, evil, otp_6278, otp_10131]). %% The following two lists should be mutually exclusive. To skip a case %% on VxWorks altogether, use the kernel.spec.vxworks file instead. @@ -153,7 +153,7 @@ all() -> {group, open}, {group, close}, {group, error}, chunk, truncate, many_users, {group, info}, {group, change_size}, change_attribute, - {group, distribution}, evil, otp_6278]. + {group, distribution}, evil, otp_6278, otp_10131]. groups() -> [{halt_int, [], [halt_int_inf, {group, halt_int_sz}]}, @@ -4915,6 +4915,22 @@ otp_6278(Conf) when is_list(Conf) -> end, ?line error_logger:delete_report_handler(?MODULE). +otp_10131(suite) -> []; +otp_10131(doc) -> ["OTP-10131. head_func type."]; +otp_10131(Conf) when is_list(Conf) -> + Dir = ?privdir(Conf), + Log = otp_10131, + File = filename:join(Dir, lists:concat([Log, ".LOG"])), + HeadFunc = {?MODULE, head_fun, [{ok,"head"}]}, + {ok, Log} = disk_log:open([{name,Log},{file,File}, + {head_func, HeadFunc}]), + HeadFunc = info(Log, head, undef), + HeadFunc2 = {?MODULE, head_fun, [{ok,"head2"}]}, + ok = disk_log:change_header(Log, {head_func, HeadFunc2}), + HeadFunc2 = info(Log, head, undef), + ok = disk_log:close(Log), + ok. + mark(FileName, What) -> {ok,Fd} = file:open(FileName, [raw, binary, read, write]), {ok,_} = file:position(Fd, 4), diff --git a/lib/kernel/test/gen_tcp_misc_SUITE.erl b/lib/kernel/test/gen_tcp_misc_SUITE.erl index c74a258af9..1592399996 100644 --- a/lib/kernel/test/gen_tcp_misc_SUITE.erl +++ b/lib/kernel/test/gen_tcp_misc_SUITE.erl @@ -24,7 +24,8 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, - controlling_process/1, no_accept/1, close_with_pending_output/1, + controlling_process/1, controlling_process_self/1, + no_accept/1, close_with_pending_output/1, data_before_close/1, iter_max_socks/1, get_status/1, passive_sockets/1, accept_closed_by_other_process/1, init_per_testcase/2, end_per_testcase/2, @@ -58,7 +59,7 @@ end_per_testcase(_Func, Config) -> suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [controlling_process, no_accept, + [controlling_process, controlling_process_self, no_accept, close_with_pending_output, data_before_close, iter_max_socks, passive_sockets, accept_closed_by_other_process, otp_3924, closed_socket, @@ -307,6 +308,32 @@ not_owner(S) -> ok end. +controlling_process_self(doc) -> + ["Open a listen port and assign the controlling process to " + "it self, then exit and make sure the port is closed properly."]; +controlling_process_self(Config) when is_list(Config) -> + S = self(), + process_flag(trap_exit,true), + spawn_link(fun() -> + {ok,Sock} = gen_tcp:listen(0,[]), + S ! {socket, Sock}, + ok = gen_tcp:controlling_process(Sock,self()), + S ! done + end), + receive + done -> + receive + {socket,Sock} -> + process_flag(trap_exit,false), + %% Make sure the port is invalid after process crash + {error,einval} = inet:port(Sock) + end; + Msg when element(1,Msg) /= socket -> + process_flag(trap_exit,false), + exit({unknown_msg,Msg}) + end. + + no_accept(doc) -> ["Open a listen port and connect to it, then close the listen port ", "without doing any accept. The connected socket should receive ", @@ -2044,7 +2071,7 @@ send_timeout_active(Config) when is_list(Config) -> ?line {error,timeout} = Loop(fun() -> receive - {tcp, Sock, _Data} -> + {tcp, _Sock, _Data} -> inet:setopts(A, [{active, once}]), Res = gen_tcp:send(A,lists:duplicate(1000, $a)), %erlang:display(Res), @@ -2536,7 +2563,7 @@ otp_8102_do(LSocket, PortNum, {Bin,PType}) -> otp_9389(doc) -> ["Verify packet_size handles long HTTP header lines"]; otp_9389(suite) -> []; otp_9389(Config) when is_list(Config) -> - ?line {ok, LS} = gen_tcp:listen(0, []), + ?line {ok, LS} = gen_tcp:listen(0, [{active,false}]), ?line {ok, {_, PortNum}} = inet:sockname(LS), io:format("Listening on ~w with port number ~p\n", [LS, PortNum]), OrigLinkHdr = "/" ++ string:chars($S, 8192), diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl index b39fadd65f..e3fa4642b7 100644 --- a/lib/kernel/test/init_SUITE.erl +++ b/lib/kernel/test/init_SUITE.erl @@ -608,7 +608,7 @@ boot2(Config) when is_list(Config) -> %% Absolute boot file name Boot = filename:join([code:root_dir(), "bin", "start_sasl"]), - Args = args() ++ " -boot " ++ Boot, + Args = args() ++ " -boot \"" ++ Boot++"\"", ?line {ok, Node} = start_node(init_test, Args), ?line stop_node(Node), @@ -618,7 +618,7 @@ boot2(Config) when is_list(Config) -> %% converted to backslashes. Win_boot = lists:map(fun($/) -> $\\; (C) -> C end, Boot), - Args2 = args() ++ " -boot " ++ Win_boot, + Args2 = args() ++ " -boot \"" ++ Win_boot ++ "\"", ?line {ok, Node2} = start_node(init_test, Args2), ?line stop_node(Node2); _ -> diff --git a/lib/kernel/test/interactive_shell_SUITE.erl b/lib/kernel/test/interactive_shell_SUITE.erl index b2308dd321..96e45cc23f 100644 --- a/lib/kernel/test/interactive_shell_SUITE.erl +++ b/lib/kernel/test/interactive_shell_SUITE.erl @@ -251,7 +251,7 @@ rtnode(Commands,Nodename,ErlPrefix) -> ?line {skip, Reason2}; Tempdir -> ?line SPid = - start_runerl_node(RunErl,ErlPrefix++Erl, + start_runerl_node(RunErl,ErlPrefix++"\\\""++Erl++"\\\"", Tempdir,Nodename), ?line CPid = start_toerl_server(ToErl,Tempdir), ?line erase(getline_skipped), @@ -487,7 +487,7 @@ start_runerl_node(RunErl,Erl,Tempdir,Nodename) -> " -setcookie "++atom_to_list(erlang:get_cookie()) end, spawn(fun() -> - os:cmd(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++ + os:cmd("\""++RunErl++"\" "++Tempdir++"/ "++Tempdir++" \""++ Erl++XArg++"\"") end). @@ -518,7 +518,7 @@ try_to_erl(Command, N) -> end. toerl_server(Parent,ToErl,Tempdir) -> - Port = try_to_erl(ToErl++" "++Tempdir++"/ 2>/dev/null",8), + Port = try_to_erl("\""++ToErl++"\" "++Tempdir++"/ 2>/dev/null",8), case Port of P when is_port(P) -> Parent ! {self(),started}; diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk index 76d3003ff4..c494f8a864 100644 --- a/lib/kernel/vsn.mk +++ b/lib/kernel/vsn.mk @@ -1 +1 @@ -KERNEL_VSN = 2.15.1 +KERNEL_VSN = 2.15.2 diff --git a/lib/megaco/Makefile b/lib/megaco/Makefile index 9dc84c122c..fc8f408b0a 100644 --- a/lib/megaco/Makefile +++ b/lib/megaco/Makefile @@ -49,11 +49,14 @@ VSN=$(MEGACO_VSN) DIR_NAME = megaco_src-$(VSN)$(PRE_VSN) +nullstring := +space := $(nullstring) # a space at the end + ifndef APP_RELEASE_DIR ifndef TESTROOT APP_RELEASE_DIR = /tmp else - APP_RELEASE_DIR = $(TESTROOT) + APP_RELEASE_DIR = $(subst $(space),\ ,$(TESTROOT)) endif endif @@ -151,7 +154,7 @@ version: # Application install (of a app built from source) targets # ---------------------------------------------------- app_install: - $(MAKE) TESTROOT=$(APP_INSTALL_DIR) release + $(MAKE) TESTROOT="$(APP_INSTALL_DIR)" release # ---------------------------------------------------- @@ -185,20 +188,20 @@ TAR.exclude2: Makefile TAR.exclude (cd ..; find megaco -name '.cmake.state' >> megaco/TAR.exclude2) $(APP_DIR): tar_exclude - mkdir -p $(APP_DIR); \ + mkdir -p "$(subst $(space),\ ,$@)"; \ (cd ..; tar cfX - megaco/TAR.exclude2 megaco) | \ - (cd $(APP_DIR); tar xf -); \ - mv $(APP_DIR)/megaco/* $(APP_DIR)/; \ - mkdir $(APP_DIR)/autoconf; \ - cp autoconf/config.guess $(APP_DIR)/autoconf/; \ - cp autoconf/config.sub $(APP_DIR)/autoconf/; \ - cp autoconf/install-sh $(APP_DIR)/autoconf/; \ - rmdir $(APP_DIR)/megaco + (cd "$(subst $(space),\ ,$@)"; tar xf -); \ + mv "$(subst $(space),\ ,$@)"/megaco/* "$(subst $(space),\ ,$@)"/; \ + mkdir $(subst $(space),\ ,$@)/autoconf; \ + cp autoconf/config.guess "$(subst $(space),\ ,$@)"/autoconf/; \ + cp autoconf/config.sub "$(subst $(space),\ ,$@)"/autoconf/; \ + cp autoconf/install-sh "$(subst $(space),\ ,$@)"/autoconf/; \ + rmdir "$(subst $(space),\ ,$@)"/megaco tar: $(APP_TAR_FILE) $(APP_TAR_FILE): $(APP_DIR) - (cd $(APP_RELEASE_DIR); gtar zcf $(APP_TAR_FILE) $(DIR_NAME)) + (cd "$(APP_RELEASE_DIR)"; gtar zcf "$(subst $(space),\ ,$@)" $(DIR_NAME)) dialyzer_plt: $(DIA_PLT) diff --git a/lib/megaco/doc/src/Makefile b/lib/megaco/doc/src/Makefile index 137f0315d8..493304523e 100644 --- a/lib/megaco/doc/src/Makefile +++ b/lib/megaco/doc/src/Makefile @@ -164,16 +164,16 @@ info: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELSYSDIR)/doc/standard - $(INSTALL_DATA) $(STANDARDS) $(RELSYSDIR)/doc/standard + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/standard" + $(INSTALL_DATA) $(STANDARDS) "$(RELSYSDIR)/doc/standard" release_spec: diff --git a/lib/megaco/examples/meas/Makefile.in b/lib/megaco/examples/meas/Makefile.in index 6af7ef6c65..607d81d440 100644 --- a/lib/megaco/examples/meas/Makefile.in +++ b/lib/megaco/examples/meas/Makefile.in @@ -131,12 +131,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(EXAMPLE_RELSYSDIR) - $(INSTALL_DIR) $(MEAS_RELSYSDIR) - $(INSTALL_DATA) $(MESSAGE_PACKAGES) $(MEAS_RELSYSDIR) - $(INSTALL_DATA) $(SCRIPT_SKELETONS) $(MEAS_RELSYSDIR) - $(INSTALL_DATA) $(TARGET_FILES) $(MEAS_RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(MEAS_RELSYSDIR) + $(INSTALL_DIR) "$(EXAMPLE_RELSYSDIR)" + $(INSTALL_DIR) "$(MEAS_RELSYSDIR)" + $(INSTALL_DATA) $(MESSAGE_PACKAGES) "$(MEAS_RELSYSDIR)" + $(INSTALL_DATA) $(SCRIPT_SKELETONS) "$(MEAS_RELSYSDIR)" + $(INSTALL_DATA) $(TARGET_FILES) "$(MEAS_RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) "$(MEAS_RELSYSDIR)" release_docs_spec: diff --git a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl index ca8016d65f..9af88d9f50 100644 --- a/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl +++ b/lib/megaco/examples/meas/megaco_codec_mstone_lib.erl @@ -100,7 +100,6 @@ display_system_info() -> OtpRel = otp_release(), SysVer = system_version(), SysHT = heap_type(), - SysGHSz = global_heaps_size(), SysSMP = smp_support(), SysNumSched = schedulers(), SysProcLimit = process_limit(), @@ -113,7 +112,6 @@ display_system_info() -> io:format("OTP release: ~s~n", [OtpRel]), io:format("System version: ~s~n", [SysVer]), io:format("Heap type: ~s~n", [SysHT]), - io:format("Global heap size: ~s~n", [SysGHSz]), io:format("Thread support: ~s~n", [SysThreads]), io:format("Thread pool size: ~s~n", [SysTPSz]), io:format("Process limit: ~s~n", [SysProcLimit]), @@ -137,9 +135,6 @@ system_version() -> heap_type() -> system_info(heap_type, any). -global_heaps_size() -> - system_info(global_heaps_size, any). - smp_support() -> system_info(smp_support, any). diff --git a/lib/megaco/examples/simple/Makefile b/lib/megaco/examples/simple/Makefile index f91d1d886f..261acbb479 100644 --- a/lib/megaco/examples/simple/Makefile +++ b/lib/megaco/examples/simple/Makefile @@ -139,9 +139,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DIR) $(RELSYSDIR)/examples/simple - $(INSTALL_DATA) $(ERL_FILES) $(TARGET_FILES) $(RELSYSDIR)/examples/simple + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/simple" + $(INSTALL_DATA) $(ERL_FILES) $(TARGET_FILES) "$(RELSYSDIR)/examples/simple" release_docs_spec: diff --git a/lib/megaco/src/app/Makefile b/lib/megaco/src/app/Makefile index 01dfb9b860..a7b458845d 100644 --- a/lib/megaco/src/app/Makefile +++ b/lib/megaco/src/app/Makefile @@ -108,14 +108,14 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/app - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/app - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/app" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/app" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/megaco/src/binary/Makefile b/lib/megaco/src/binary/Makefile index d594f34f43..77b06c81d3 100644 --- a/lib/megaco/src/binary/Makefile +++ b/lib/megaco/src/binary/Makefile @@ -194,11 +194,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/binary - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(ASN1_FILES) $(RELSYSDIR)/src/binary + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/binary" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(ASN1_FILES) "$(RELSYSDIR)/src/binary" release_docs_spec: diff --git a/lib/megaco/src/engine/Makefile b/lib/megaco/src/engine/Makefile index 3943f4b957..ae2fadb3fc 100644 --- a/lib/megaco/src/engine/Makefile +++ b/lib/megaco/src/engine/Makefile @@ -42,9 +42,14 @@ RELSYSDIR = $(RELEASE_PATH)/lib/megaco-$(VSN) include modules.mk -ERL_FILES = $(MODULES:%=%.erl) +ERL_FILES = \ + $(MODULES:%=%.erl) \ + $(BEHAVIOUR_MODULES:%=%.erl) -TARGET_FILES = \ +BEHAVIOUR_TARGET_FILES= \ + $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR)) + +TARGET_FILES = \ $(MODULES:%=$(EBIN)/%.$(EMULATOR)) @@ -65,19 +70,23 @@ ERL_COMPILE_FLAGS += \ # ---------------------------------------------------- # Targets # ---------------------------------------------------- + +$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES) + debug: @${MAKE} TYPE=debug opt opt: $(TARGET_FILES) clean: - rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) rm -f errs core *~ docs: info: @echo "MODULES = $(MODULES)" + @echo "BEHAVIOUR_MODULES = $(BEHAVIOUR_MODULES)" @echo "" @@ -88,12 +97,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/engine - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/engine - $(INSTALL_DIR) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/engine" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/engine" + $(INSTALL_DIR) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/megaco/src/engine/modules.mk b/lib/megaco/src/engine/modules.mk index 4bc57cd63e..6e2f9246f0 100644 --- a/lib/megaco/src/engine/modules.mk +++ b/lib/megaco/src/engine/modules.mk @@ -23,7 +23,6 @@ BEHAVIOUR_MODULES = \ megaco_transport MODULES = \ - $(BEHAVIOUR_MODULES) \ megaco_config_misc \ megaco_config \ megaco_digit_map \ diff --git a/lib/megaco/src/flex/Makefile.in b/lib/megaco/src/flex/Makefile.in index 7d82644246..976ecaa4f7 100644 --- a/lib/megaco/src/flex/Makefile.in +++ b/lib/megaco/src/flex/Makefile.in @@ -271,16 +271,16 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/flex - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/flex - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/flex" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/flex" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" ifeq ($(ENABLE_MEGACO_FLEX_SCANNER),true) - $(INSTALL_DATA) $(FLEX_FILES) $(C_TARGETS) $(RELSYSDIR)/src/flex - $(INSTALL_PROGRAM) $(SOLIBS) $(RELSYSDIR)/priv/lib + $(INSTALL_DATA) $(FLEX_FILES) $(C_TARGETS) "$(RELSYSDIR)/src/flex" + $(INSTALL_PROGRAM) $(SOLIBS) "$(RELSYSDIR)/priv/lib" endif diff --git a/lib/megaco/src/tcp/Makefile b/lib/megaco/src/tcp/Makefile index 0bd4b7c4ee..efc76bb2c5 100644 --- a/lib/megaco/src/tcp/Makefile +++ b/lib/megaco/src/tcp/Makefile @@ -89,11 +89,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/tcp - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/tcp + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/tcp" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/tcp" release_docs_spec: diff --git a/lib/megaco/src/text/Makefile b/lib/megaco/src/text/Makefile index b2e8e762dd..2c7703cd33 100644 --- a/lib/megaco/src/text/Makefile +++ b/lib/megaco/src/text/Makefile @@ -130,11 +130,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(BEAM_TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/text - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_YRL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/text + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(BEAM_TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/text" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_YRL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/text" release_docs_spec: diff --git a/lib/megaco/src/udp/Makefile b/lib/megaco/src/udp/Makefile index 64b6478c2c..db9bb72d82 100644 --- a/lib/megaco/src/udp/Makefile +++ b/lib/megaco/src/udp/Makefile @@ -89,11 +89,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/udp - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/udp + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/udp" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/udp" release_docs_spec: diff --git a/lib/megaco/test/Makefile b/lib/megaco/test/Makefile index 88f6f06e73..b1bca10ca8 100644 --- a/lib/megaco/test/Makefile +++ b/lib/megaco/test/Makefile @@ -748,11 +748,11 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(RELTEST_FILES) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(RELTEST_FILES) "$(RELSYSDIR)" # $(INSTALL_DATA) $(TEST_SPEC_FILE) $(COVER_SPEC_FILE) \ # $(HRL_FILES) $(ERL_FILES) \ -# $(RELSYSDIR) +# "$(RELSYSDIR)" # - chmod -R u+w $(RELSYSDIR) + chmod -R u+w "$(RELSYSDIR)" diff --git a/lib/mnesia/doc/src/Makefile b/lib/mnesia/doc/src/Makefile index 1ac5760510..173e43ac1f 100644 --- a/lib/mnesia/doc/src/Makefile +++ b/lib/mnesia/doc/src/Makefile @@ -142,13 +142,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml index a300fcc12d..612ccb5ee8 100644 --- a/lib/mnesia/doc/src/notes.xml +++ b/lib/mnesia/doc/src/notes.xml @@ -38,7 +38,37 @@ thus constitutes one section in this document. The title of each section is the version number of Mnesia.</p> - <section><title>Mnesia 4.6</title> + <section><title>Mnesia 4.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Returns the same value for + mnesia_loader:disc_load_table/2 as + mnesia_loader:net_load_table/4 if a table copy can not be + found. (Thanks to Uwe Dauernheim)</p> + <p> + Own Id: OTP-10015</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Improved table lock algorithm.</p> + <p> + Own Id: OTP-9890</p> + </item> + </list> + </section> + +</section> + +<section><title>Mnesia 4.6</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/mnesia/examples/Makefile b/lib/mnesia/examples/Makefile index ff00ee76a5..5379761c64 100644 --- a/lib/mnesia/examples/Makefile +++ b/lib/mnesia/examples/Makefile @@ -78,9 +78,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) $(RELSYSDIR)/examples - $(INSTALL_DIR) $(RELSYSDIR)/examples/bench + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) "$(RELSYSDIR)/examples" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/bench" (cd bench; $(INSTALL_DATA) \ Makefile \ README \ @@ -96,8 +96,8 @@ release_spec: opt bench.config5 \ bench.config6 \ bench.config7 \ - $(RELSYSDIR)/examples/bench) - (cd bench; $(INSTALL_SCRIPT) bench.sh $(RELSYSDIR)/examples/bench) + "$(RELSYSDIR)/examples/bench") + (cd bench; $(INSTALL_SCRIPT) bench.sh "$(RELSYSDIR)/examples/bench") release_docs_spec: diff --git a/lib/mnesia/include/Makefile b/lib/mnesia/include/Makefile index f9b7d72abe..20f62b5460 100644 --- a/lib/mnesia/include/Makefile +++ b/lib/mnesia/include/Makefile @@ -54,8 +54,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(INCLUDE_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(INCLUDE_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/mnesia/src/Makefile b/lib/mnesia/src/Makefile index 1c8ec54605..1432eabc37 100644 --- a/lib/mnesia/src/Makefile +++ b/lib/mnesia/src/Makefile @@ -132,10 +132,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/mnesia/test/Makefile b/lib/mnesia/test/Makefile index ae4c9626c7..0451da697d 100644 --- a/lib/mnesia/test/Makefile +++ b/lib/mnesia/test/Makefile @@ -52,24 +52,29 @@ MODULES= \ mnesia_cost \ mnesia_dbn_meters -MnesiaExamplesDir := ../examples +DocExamplesDir := ../doc/src/ -ExampleModules = \ +DocExampleModules = \ company \ company_o \ - bup \ - mnesia_meter \ - mnesia_tpcb -ExamplesHrl = \ + bup + +DocExamplesHrl = \ company.hrl \ company_o.hrl -ERL_FILES= $(MODULES:%=%.erl) $(ExampleModules:%=$(MnesiaExamplesDir)/%.erl) +ExamplesDir := ../examples/ + +ExampleModules = \ + mnesia_meter \ + mnesia_tpcb -HRL_FILES= mnesia_test_lib.hrl $(ExamplesHrl:%=$(MnesiaExamplesDir)/%) +ERL_FILES= $(MODULES:%=%.erl) $(DocExampleModules:%=$(DocExamplesDir)/%.erl) $(ExampleModules:%=$(ExamplesDir)/%.erl) + +HRL_FILES= mnesia_test_lib.hrl $(DocExamplesHrl:%=$(DocExamplesDir)/%) TARGET_FILES= \ - $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ExampleModules:%=$(EBIN)/%.$(EMULATOR)) + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(DocExampleModules:%=$(EBIN)/%.$(EMULATOR)) $(ExampleModules:%=$(EBIN)/%.$(EMULATOR)) INSTALL_PROGS= $(TARGET_FILES) @@ -91,7 +96,10 @@ EBIN = . tests debug opt: $(TARGET_FILES) -$(EBIN)/%.beam: $(MnesiaExamplesDir)/%.erl +$(EBIN)/%.beam: $(DocExamplesDir)/%.erl + $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(EBIN) $< + +$(EBIN)/%.beam: $(ExamplesDir)/%.erl $(ERLC) -bbeam $(ERL_COMPILE_FLAGS) -o$(EBIN) $< clean: @@ -108,11 +116,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) mnesia.spec mnesia.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_SCRIPT) mt $(INSTALL_PROGS) $(RELSYSDIR) -# chmod -R u+w $(RELSYSDIR) -# @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) mnesia.spec mnesia.cover $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_SCRIPT) mt $(INSTALL_PROGS) "$(RELSYSDIR)" +# chmod -R u+w "$(RELSYSDIR)" +# @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/mnesia/test/mnesia_consistency_test.erl b/lib/mnesia/test/mnesia_consistency_test.erl index f38e13f3a2..bb21723e27 100644 --- a/lib/mnesia/test/mnesia_consistency_test.erl +++ b/lib/mnesia/test/mnesia_consistency_test.erl @@ -100,7 +100,7 @@ groups() -> {group, updates_during_checkpoint_iteration}, {group, load_table_with_activated_checkpoint}, {group, - add_table_copy_to_table_with_activated_checkpoint}]}, + add_table_copy_to_table_checkpoint}]}, {updates_during_checkpoint_activation, [], [updates_during_checkpoint_activation_2_ram, updates_during_checkpoint_activation_2_disc, @@ -116,10 +116,10 @@ groups() -> [load_table_with_activated_checkpoint_ram, load_table_with_activated_checkpoint_disc, load_table_with_activated_checkpoint_disc_only]}, - {add_table_copy_to_table_with_activated_checkpoint, [], - [add_table_copy_to_table_with_activated_checkpoint_ram, - add_table_copy_to_table_with_activated_checkpoint_disc, - add_table_copy_to_table_with_activated_checkpoint_disc_only]}, + {add_table_copy_to_table_checkpoint, [], + [add_table_copy_to_table_checkpoint_ram, + add_table_copy_to_table_checkpoint_disc, + add_table_copy_to_table_checkpoint_disc_only]}, {backup_consistency, [], [{group, interupted_install_fallback}, {group, interupted_uninstall_fallback}, @@ -952,16 +952,16 @@ view(Source, Mod) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -add_table_copy_to_table_with_activated_checkpoint_ram(suite) -> []; -add_table_copy_to_table_with_activated_checkpoint_ram(Config) when is_list(Config) -> +add_table_copy_to_table_checkpoint_ram(suite) -> []; +add_table_copy_to_table_checkpoint_ram(Config) when is_list(Config) -> add_table_copy_to_table_with_activated_checkpoint(ram_copies, Config). -add_table_copy_to_table_with_activated_checkpoint_disc(suite) -> []; -add_table_copy_to_table_with_activated_checkpoint_disc(Config) when is_list(Config) -> +add_table_copy_to_table_checkpoint_disc(suite) -> []; +add_table_copy_to_table_checkpoint_disc(Config) when is_list(Config) -> add_table_copy_to_table_with_activated_checkpoint(disc_copies, Config). -add_table_copy_to_table_with_activated_checkpoint_disc_only(suite) -> []; -add_table_copy_to_table_with_activated_checkpoint_disc_only(Config) when is_list(Config) -> +add_table_copy_to_table_checkpoint_disc_only(suite) -> []; +add_table_copy_to_table_checkpoint_disc_only(Config) when is_list(Config) -> add_table_copy_to_table_with_activated_checkpoint(disc_only_copies, Config). add_table_copy_to_table_with_activated_checkpoint(Type,Config) -> diff --git a/lib/mnesia/vsn.mk b/lib/mnesia/vsn.mk index 080548acac..da292cbb43 100644 --- a/lib/mnesia/vsn.mk +++ b/lib/mnesia/vsn.mk @@ -1 +1 @@ -MNESIA_VSN = 4.6 +MNESIA_VSN = 4.7 diff --git a/lib/observer/doc/src/Makefile b/lib/observer/doc/src/Makefile index cd9f9466ca..0f564d3299 100644 --- a/lib/observer/doc/src/Makefile +++ b/lib/observer/doc/src/Makefile @@ -133,16 +133,16 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/observer/src/Makefile b/lib/observer/src/Makefile index 91a4c656ad..7135a6abd5 100644 --- a/lib/observer/src/Makefile +++ b/lib/observer/src/Makefile @@ -129,20 +129,20 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_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 - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(EXECUTABLES) $(RELSYSDIR)/priv/bin - $(INSTALL_DIR) $(RELSYSDIR)/priv/crashdump_viewer - $(INSTALL_DATA) $(WEBTOOLFILES) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(GIF_FILES) $(RELSYSDIR)/priv/crashdump_viewer + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_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" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_SCRIPT) $(EXECUTABLES) "$(RELSYSDIR)/priv/bin" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/crashdump_viewer" + $(INSTALL_DATA) $(WEBTOOLFILES) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(GIF_FILES) "$(RELSYSDIR)/priv/crashdump_viewer" release_docs_spec: diff --git a/lib/observer/src/crashdump_viewer_html.erl b/lib/observer/src/crashdump_viewer_html.erl index 24a80b1916..3151b83bfb 100644 --- a/lib/observer/src/crashdump_viewer_html.erl +++ b/lib/observer/src/crashdump_viewer_html.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2011. All Rights Reserved. +%% Copyright Ericsson AB 2003-2012. 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 @@ -1394,7 +1394,7 @@ timers_table(Timer) -> td("ALIGN=right",Time)]). loaded_mods_table(#loaded_mod{mod=Mod,current_size=CS,old_size=OS}) -> - tr([td(href(["loaded_mod_details?mod=",Mod],Mod)), + tr([td(href(["loaded_mod_details?mod=",http_uri:encode(Mod)],Mod)), td("ALIGN=right",CS), td("ALIGN=right",OS)]). diff --git a/lib/observer/src/observer_app_wx.erl b/lib/observer/src/observer_app_wx.erl index 7eac2b8fab..f9be11e05a 100644 --- a/lib/observer/src/observer_app_wx.erl +++ b/lib/observer/src/observer_app_wx.erl @@ -147,11 +147,11 @@ setup_scrollbar({CW, CH}, AppWin, #app{dim={W0,H0}}) -> H = max(H0,CH), PPC = 20, if W0 =< CW, H0 =< CH -> - wxScrolledWindow:setScrollbars(AppWin, W, H, 1, 1); + wxScrolledWindow:setScrollbars(AppWin, W, H, 0, 0); H0 =< CH -> - wxScrolledWindow:setScrollbars(AppWin, PPC, H, W div PPC+1, 1); + wxScrolledWindow:setScrollbars(AppWin, PPC, H, W div PPC+1, 0); W0 =< CW -> - wxScrolledWindow:setScrollbars(AppWin, W, PPC, 1, H div PPC+1); + wxScrolledWindow:setScrollbars(AppWin, W, PPC, 0, H div PPC+1); true -> wxScrolledWindow:setScrollbars(AppWin, PPC, PPC, W div PPC+1, H div PPC+1) end; @@ -204,7 +204,7 @@ handle_event(#wx{id=?ID_PROC_MSG, event=#wxCommand{type=command_menu_selected}}, handle_event(#wx{id=?ID_PROC_KILL, event=#wxCommand{type=command_menu_selected}}, State = #state{panel=Panel, sel={#box{s1=#str{pid=Pid}},_}}) -> - case observer_lib:user_term(Panel, "Enter Exit Reason", "") of + case observer_lib:user_term(Panel, "Enter Exit Reason", "kill") of cancel -> ok; {ok, Term} -> exit(Pid, Term); {error, Error} -> observer_lib:display_info_dialog(Error) @@ -267,24 +267,17 @@ handle_call(Event, From, _State) -> handle_cast(Event, _State) -> error({unhandled_cast, Event}). %%%%%%%%%% -handle_info({active, Node}, State = #state{parent=Parent, current=Curr, appmon=Appmon}) -> +handle_info({active, Node}, State = #state{parent=Parent, current=Curr}) -> create_menus(Parent, []), {ok, Pid} = appmon_info:start_link(Node, self(), []), - case Appmon of - undefined -> ok; - Pid -> ok; - _ -> %% Deregister me as client (and stop appmon if last) - exit(Appmon, normal) - end, appmon_info:app_ctrl(Pid, Node, true, []), (Curr =/= undefined) andalso appmon_info:app(Pid, Curr, true, []), {noreply, State#state{appmon=Pid}}; - -handle_info(not_active, State = #state{appmon=AppMon, current=Prev}) -> +handle_info(not_active, State = #state{appmon=AppMon}) -> appmon_info:app_ctrl(AppMon, node(AppMon), false, []), - (Prev =/= undefined) andalso appmon_info:app(AppMon, Prev, false, []), - {noreply, State}; - + lists:member(node(AppMon), nodes()) andalso exit(AppMon, normal), + observer_wx:set_status(""), + {noreply, State#state{appmon=undefined}}; handle_info({delivery, Pid, app_ctrl, _, Apps0}, State = #state{appmon=Pid, apps_w=LBox, current=Curr0}) -> Apps = [atom_to_list(App) || {_, App, {_, _, _}} <- Apps0], @@ -341,6 +334,7 @@ handle_mouse_click(Node = {#box{s1=#str{pid=Pid}},_}, Type, right_down -> popup_menu(Panel); _ -> ok end, + observer_wx:set_status(io_lib:format("Pid: ~p", [Pid])), wxWindow:refresh(AppWin), State#state{sel=Node}; handle_mouse_click(_, _, State = #state{sel=undefined}) -> @@ -349,6 +343,7 @@ handle_mouse_click(_, right_down, State=#state{panel=Panel}) -> popup_menu(Panel), State; handle_mouse_click(_, _, State=#state{app_w=AppWin}) -> + observer_wx:set_status(""), wxWindow:refresh(AppWin), State#state{sel=undefined}. @@ -376,10 +371,11 @@ popup_menu(Panel) -> wxMenu:append(Menu, ?ID_TRACE_NAME, "Trace named process"), wxMenu:append(Menu, ?ID_TRACE_TREE_PIDS, "Trace process tree"), wxMenu:append(Menu, ?ID_TRACE_TREE_NAMES, "Trace named process tree"), + wxMenu:append(Menu, ?ID_PROC_MSG, "Send Msg"), + wxMenu:append(Menu, ?ID_PROC_KILL, "Kill process"), wxWindow:popupMenu(Panel, Menu), wxMenu:destroy(Menu). - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% locate_node(X, _Y, [{Box=#box{x=BX}, _Chs}|_Rest]) when X < BX -> diff --git a/lib/observer/src/observer_pro_wx.erl b/lib/observer/src/observer_pro_wx.erl index 7578215ff9..e2f3ddb02b 100644 --- a/lib/observer/src/observer_pro_wx.erl +++ b/lib/observer/src/observer_pro_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2012. 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 @@ -191,13 +191,20 @@ dump_to_file(Parent, FileName, Holder) -> start_procinfo(undefined, _Frame, Opened) -> Opened; start_procinfo(Pid, Frame, Opened) -> - case lists:member(Pid, Opened) of - true -> - Opened; - false -> - observer_procinfo:start(Pid, Frame, self()), - [Pid | Opened] + %% This code doesn't work until we collect which windows have been + %% closed maybe it should moved to observer_wx.erl + %% and add a global menu which remembers windows. + %% case lists:keyfind(Pid, 1, Opened) of + %% false -> + case observer_procinfo:start(Pid, Frame, self()) of + {error, _} -> Opened; + PI -> [{Pid, PI} | Opened] end. + %%; + %% {_, PI} -> + %% wxFrame:raise(PI), + %% Opened + %% end. call(Holder, What) -> Ref = erlang:monitor(process, Holder), diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl index ec08d3aff1..13e41cfe33 100644 --- a/lib/observer/src/observer_procinfo.erl +++ b/lib/observer/src/observer_procinfo.erl @@ -49,7 +49,8 @@ init([Pid, ParentFrame, Parent]) -> try Title=case observer_wx:try_rpc(node(Pid), erlang, process_info, [Pid, registered_name]) of [] -> io_lib:format("~p",[Pid]); - {registered_name, Registered} -> atom_to_list(Registered) + {registered_name, Registered} -> io_lib:format("~p (~p)",[Registered, Pid]); + undefined -> throw(process_undefined) end, Frame=wxFrame:new(ParentFrame, ?wxID_ANY, [atom_to_list(node(Pid)), $:, Title], [{style, ?wxDEFAULT_FRAME_STYLE}, {size, {850,600}}]), @@ -75,7 +76,10 @@ init([Pid, ParentFrame, Parent]) -> }} catch error:{badrpc, _} -> observer_wx:return_to_localnode(ParentFrame, node(Pid)), - {stop, badrpc, #state{parent=Parent, pid=Pid}} + {stop, badrpc}; + process_undefined -> + observer_lib:display_info_dialog("No such alive process"), + {stop, normal} end. init_panel(Notebook, Str, Pid, Fun) -> @@ -94,8 +98,11 @@ handle_event(#wx{event=#wxClose{type=close_window}}, State) -> handle_event(#wx{id=?wxID_CLOSE, event=#wxCommand{type=command_menu_selected}}, State) -> {stop, normal, State}; -handle_event(#wx{id=?REFRESH}, #state{pages=Pages}=State) -> - [(W#worker.callback)() || W <- Pages], +handle_event(#wx{id=?REFRESH}, #state{frame=Frame, pid=Pid, pages=Pages}=State) -> + try [(W#worker.callback)() || W <- Pages] + catch process_undefined -> + wxFrame:setTitle(Frame, io_lib:format("*DEAD* ~p",[Pid])) + end, {noreply, State}; handle_event(Event, _State) -> @@ -162,7 +169,8 @@ init_message_page(Parent, Pid) -> false -> wxTextCtrl:writeText(Text, Messages) end; - _ -> ok + _ -> + throw(process_undefined) end end, Update(), @@ -178,7 +186,8 @@ init_dict_page(Parent, Pid) -> Last = wxTextCtrl:getLastPosition(Text), wxTextCtrl:remove(Text, 0, Last), wxTextCtrl:writeText(Text, Dict); - _ -> ok + _ -> + throw(process_undefined) end end, Update(), @@ -216,7 +225,8 @@ init_stack_page(Parent, Pid) -> wxListCtrl:setItem(LCtrl, Row, 1, FileLine), Row+1 end, 0, RawBt); - _ -> ok + _ -> + throw(process_undefined) end end, Resize = fun(#wx{event=#wxSize{size={W,_}}},Ev) -> @@ -266,7 +276,7 @@ process_info_fields(Pid) -> RawInfo when is_list(RawInfo) -> observer_lib:fill_info(Struct, RawInfo); _ -> - ok + throw(process_undefined) end. item_list() -> diff --git a/lib/observer/src/observer_traceoptions_wx.erl b/lib/observer/src/observer_traceoptions_wx.erl index 6a634e06f0..e27f565abc 100644 --- a/lib/observer/src/observer_traceoptions_wx.erl +++ b/lib/observer/src/observer_traceoptions_wx.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011. All Rights Reserved. +%% Copyright Ericsson AB 2011-2012. 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 @@ -167,8 +167,10 @@ module_selector(Parent, Node) -> function_selector(Parent, Node, Module) -> Functions = observer_wx:try_rpc(Node, Module, module_info, [functions]), - Choices = lists:sort([{Name, Arity} || {Name, Arity} <- Functions, - not(erl_internal:guard_bif(Name, Arity))]), + Externals = observer_wx:try_rpc(Node, Module, module_info, [exports]), + + Choices = lists:usort([{Name, Arity} || {Name, Arity} <- Externals ++ Functions, + not(erl_internal:guard_bif(Name, Arity))]), ParsedChoices = parse_function_names(Choices), case check_selector(Parent, ParsedChoices) of [] -> [{Module, '_', '_'}]; diff --git a/lib/observer/src/observer_tv_table.erl b/lib/observer/src/observer_tv_table.erl index f432173f57..3930f9ee26 100644 --- a/lib/observer/src/observer_tv_table.erl +++ b/lib/observer/src/observer_tv_table.erl @@ -453,7 +453,7 @@ get_attr(Table, Item) -> Ref = erlang:monitor(process, Table), Table ! {get_attr, self(), Item}, receive - {'DOWN', Ref, _, _, _} -> ""; + {'DOWN', Ref, _, _, _} -> wx:null(); {Table, Res} -> erlang:demonitor(Ref), Res diff --git a/lib/observer/src/observer_wx.erl b/lib/observer/src/observer_wx.erl index e2b256d768..ce3f48a05d 100644 --- a/lib/observer/src/observer_wx.erl +++ b/lib/observer/src/observer_wx.erl @@ -20,7 +20,7 @@ -behaviour(wx_object). -export([start/0]). --export([create_menus/2, get_attrib/1, get_tracer/0, +-export([create_menus/2, get_attrib/1, get_tracer/0, set_status/1, create_txt_dialog/4, try_rpc/4, return_to_localnode/2]). -export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3, @@ -58,7 +58,8 @@ perf_panel, active_tab, node, - nodes + nodes, + prev_node="" }). start() -> @@ -73,6 +74,9 @@ create_menus(Object, Menus) when is_list(Menus) -> get_attrib(What) -> wx_object:call(observer, {get_attrib, What}). +set_status(What) -> + wx_object:cast(observer, {status_bar, What}). + get_tracer() -> wx_object:call(observer, get_tracer). @@ -258,20 +262,21 @@ handle_event(#wx{id = ?ID_CONNECT, event = #wxCommand{type = command_menu_select handle_event(#wx{id = ?ID_PING, event = #wxCommand{type = command_menu_selected}}, #state{frame = Frame} = State) -> UpdState = case create_connect_dialog(ping, State) of - cancel -> State; + cancel -> State; {value, Value} when is_list(Value) -> try Node = list_to_atom(Value), case net_adm:ping(Node) of pang -> create_txt_dialog(Frame, "Connect failed", "Pang", ?wxICON_EXCLAMATION), - State; + State#state{prev_node=Value}; pong -> - change_node_view(Node, State) + State1 = change_node_view(Node, State), + State1#state{prev_node=Value} end catch _:_ -> create_txt_dialog(Frame, "Connect failed", "Pang", ?wxICON_EXCLAMATION), - State + State#state{prev_node=Value} end end, {noreply, UpdState}; @@ -288,6 +293,10 @@ handle_event(Event, State) -> Pid ! Event, {noreply, State}. +handle_cast({status_bar, Msg}, State=#state{status_bar=SB}) -> + wxStatusBar:setStatusText(SB, Msg), + {noreply, State}; + handle_cast(_Cast, State) -> {noreply, State}. @@ -439,8 +448,8 @@ pid2panel(Pid, #state{pro_panel=Pro, sys_panel=Sys, end. -create_connect_dialog(ping, #state{frame = Frame}) -> - Dialog = wxTextEntryDialog:new(Frame, "Connect to node"), +create_connect_dialog(ping, #state{frame = Frame, prev_node=Prev}) -> + Dialog = wxTextEntryDialog:new(Frame, "Connect to node", [{value, Prev}]), case wxDialog:showModal(Dialog) of ?wxID_OK -> Value = wxTextEntryDialog:getValue(Dialog), @@ -560,7 +569,16 @@ remove_menu_items([], _MB) -> ok. get_nodes() -> - Nodes = [node()| nodes()], + Nodes0 = case erlang:is_alive() of + false -> []; + true -> + case net_adm:names() of + {error, _} -> nodes(); + {ok, Names} -> + epmd_nodes(Names) ++ nodes() + end + end, + Nodes = lists:usort(Nodes0), {_, Menues} = lists:foldl(fun(Node, {Id, Acc}) when Id < ?LAST_NODES_MENU_ID -> {Id + 1, [#create_menu{id=Id + ?FIRST_NODES_MENU_ID, @@ -568,6 +586,10 @@ get_nodes() -> end, {1, []}, Nodes), {Nodes, lists:reverse(Menues)}. +epmd_nodes(Names) -> + [_, Host] = string:tokens(atom_to_list(node()),"@"), + [list_to_atom(Name ++ [$@|Host]) || {Name, _} <- Names]. + update_node_list(State = #state{menubar=MenuBar}) -> {Nodes, NodesMenuItems} = get_nodes(), NodeMenuId = wxMenuBar:findMenu(MenuBar, "Nodes"), diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile index bf99f07081..9df0591da5 100644 --- a/lib/observer/test/Makefile +++ b/lib/observer/test/Makefile @@ -82,11 +82,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) observer.spec $(EMAKEFILE) \ $(COVERFILE) $(ERL_FILES) \ - $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl index 5bbce9d076..6f882d0be9 100644 --- a/lib/observer/test/crashdump_viewer_SUITE.erl +++ b/lib/observer/test/crashdump_viewer_SUITE.erl @@ -414,6 +414,10 @@ special(Port,File) -> _ -> ok end; + ".strangemodname" -> + AllMods = contents(Port,"loaded_modules"), + open_all_modules(Port,AllMods), + ok; %%! No longer needed - all atoms are shown on one page!! %% ".250atoms" -> %% Html1 = contents(Port,"atoms"), @@ -496,6 +500,26 @@ expand_binary_link(Html) -> expand_binary_link(T) end. +open_all_modules(Port,Modules) -> + case get_first_module(Modules) of + {Module,Rest} -> + ModuleDetails = contents(Port,"loaded_mod_details?mod=" ++ Module), + ModTitle = http_uri:decode(Module), + ModTitle = title(ModuleDetails), + open_all_modules(Port,Rest); + false -> + ok + end. + +get_first_module([]) -> + false; +get_first_module(Html) -> + case Html of + "<TD><A HREF=\"loaded_mod_details?mod=" ++ Rest -> + {string:sub_word(Rest,1,$"),Rest}; + [_H|T] -> + get_first_module(T) + end. %% next_link(Html) -> %% case Html of @@ -565,7 +589,7 @@ create_dumps(DataDir,[Rel|Rels],Acc) -> Fun = fun() -> do_create_dumps(DataDir,Rel) end, Pa = filename:dirname(code:which(?MODULE)), {SlAllocDumps,Dumps,DosDump} = - ?t:run_on_shielded_node(Fun, compat_rel(Rel) ++ "-pa " ++ Pa), + ?t:run_on_shielded_node(Fun, compat_rel(Rel) ++ "-pa \"" ++ Pa ++ "\""), create_dumps(DataDir,Rels,SlAllocDumps ++ Dumps ++ Acc ++ DosDump); create_dumps(_DataDir,[],Acc) -> Acc. @@ -590,7 +614,8 @@ do_create_dumps(DataDir,Rel) -> case Rel of current -> CD3 = dump_with_args(DataDir,Rel,"instr","+Mim true"), - {SlAllocDumps, [CD1,CD2,CD3], DosDump}; + CD4 = dump_with_strange_module_name(DataDir,Rel,"strangemodname"), + {SlAllocDumps, [CD1,CD2,CD3,CD4], DosDump}; _ -> {SlAllocDumps, [CD1,CD2], DosDump} end. @@ -600,7 +625,7 @@ do_create_dumps(DataDir,Rel) -> %% not connected node, and with monitors and links between nodes. full_dist_dump(DataDir,Rel) -> Opt = rel_opt(Rel), - Pz = "-pz " ++ filename:dirname(code:which(?MODULE)), + Pz = "-pz \"" ++ filename:dirname(code:which(?MODULE)) ++ "\"", PzOpt = [{args,Pz}], {ok,N1} = ?t:start_node(n1,peer,Opt ++ PzOpt), {ok,N2} = ?t:start_node(n2,peer,Opt ++ PzOpt), @@ -648,7 +673,22 @@ dump_with_args(DataDir,Rel,DumpName,Args) -> ?t:stop_node(n1), CD. +%% This dump is added to test OTP-10090 - regarding URL encoding of +%% module names in the module detail link. +dump_with_strange_module_name(DataDir,Rel,DumpName) -> + Opt = rel_opt(Rel), + {ok,N1} = ?t:start_node(n1,peer,Opt), + Mod = '<mod ule#with?strange%name>', + File = atom_to_list(Mod) ++ ".erl", + Forms = [{attribute,1,file,{File,1}}, + {attribute,1,module,Mod}, + {eof,4}], + {ok,Mod,Bin} = rpc:call(N1,compile,forms,[Forms,[binary]]), + {module,Mod} = rpc:call(N1,code,load_binary,[Mod,File,Bin]), + CD = dump(N1,DataDir,Rel,DumpName), + ?t:stop_node(n1), + CD. dump(Node,DataDir,Rel,DumpName) -> rpc:call(Node,erlang,halt,[DumpName]), diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk index fa104ede01..4eb10ae4e8 100644 --- a/lib/observer/vsn.mk +++ b/lib/observer/vsn.mk @@ -1 +1 @@ -OBSERVER_VSN = 1.0 +OBSERVER_VSN = 1.1 diff --git a/lib/odbc/c_src/Makefile.in b/lib/odbc/c_src/Makefile.in index 3a96a53ef8..5b37b352fb 100644 --- a/lib/odbc/c_src/Makefile.in +++ b/lib/odbc/c_src/Makefile.in @@ -128,12 +128,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt ifdef EXE_TARGET - $(INSTALL_DIR) $(RELSYSDIR)/c_src - $(INSTALL_DATA) $(C_FILES) $(H_FILES) $(RELSYSDIR)/c_src - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_DIR) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(EXE_TARGET) $(RELSYSDIR)/priv/bin + $(INSTALL_DIR) "$(RELSYSDIR)/c_src" + $(INSTALL_DATA) $(C_FILES) $(H_FILES) "$(RELSYSDIR)/c_src" + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/obj" + $(INSTALL_PROGRAM) $(EXE_TARGET) "$(RELSYSDIR)/priv/bin" endif release_docs_spec: diff --git a/lib/odbc/doc/src/Makefile b/lib/odbc/doc/src/Makefile index 0d456085f3..cd9bca0a55 100644 --- a/lib/odbc/doc/src/Makefile +++ b/lib/odbc/doc/src/Makefile @@ -125,13 +125,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/odbc/src/Makefile b/lib/odbc/src/Makefile index b48dd768c8..7ca82d784b 100644 --- a/lib/odbc/src/Makefile +++ b/lib/odbc/src/Makefile @@ -108,13 +108,13 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXT_HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \ - $(RELSYSDIR)/ebin + "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/odbc/src/odbc.erl b/lib/odbc/src/odbc.erl index 36afd1abcf..9f7b06dcf1 100644 --- a/lib/odbc/src/odbc.erl +++ b/lib/odbc/src/odbc.erl @@ -451,7 +451,7 @@ init(Args) -> %% Start the port program (a c program) that utilizes the odbc driver case os:find_executable(?SERVERPROG, ?SERVERDIR) of FileName when is_list(FileName)-> - Port = open_port({spawn, FileName}, + Port = open_port({spawn, "\""++FileName++"\""}, [{packet, ?LENGTH_INDICATOR_SIZE}, binary, exit_status]), State = #state{listen_sockets = diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile index bc6449242e..84551f0eb1 100644 --- a/lib/odbc/test/Makefile +++ b/lib/odbc/test/Makefile @@ -101,8 +101,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/orber/COSS/CosNaming/Makefile b/lib/orber/COSS/CosNaming/Makefile index 064447f148..a61fcd08a6 100644 --- a/lib/orber/COSS/CosNaming/Makefile +++ b/lib/orber/COSS/CosNaming/Makefile @@ -141,11 +141,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/COSS/CosNaming - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(IDL_FILE) $(RELSYSDIR)/COSS/CosNaming - $(INSTALL_DATA) $(GEN_FILES) $(RELSYSDIR)/COSS/CosNaming + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/COSS/CosNaming" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(IDL_FILE) "$(RELSYSDIR)/COSS/CosNaming" + $(INSTALL_DATA) $(GEN_FILES) "$(RELSYSDIR)/COSS/CosNaming" release_docs_spec: diff --git a/lib/orber/c_src/Makefile.in b/lib/orber/c_src/Makefile.in index 56f0d57545..5953d41ff3 100644 --- a/lib/orber/c_src/Makefile.in +++ b/lib/orber/c_src/Makefile.in @@ -89,23 +89,23 @@ include $(ERL_TOP)/make/otp_release_targets.mk ifeq ($(findstring win32,$(TARGET)),win32) release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/src - $(INSTALL_DIR) $(RELSYSDIR)/priv/include - $(INSTALL_PROGRAM) $(CC_FILES) $(RELSYSDIR)/priv/src - $(INSTALL_PROGRAM) $(HH_FILES) $(RELSYSDIR)/priv/include + $(INSTALL_DIR) "$(RELSYSDIR)/priv/src" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/include" + $(INSTALL_PROGRAM) $(CC_FILES) "$(RELSYSDIR)/priv/src" + $(INSTALL_PROGRAM) $(HH_FILES) "$(RELSYSDIR)/priv/include" else ifeq ($(findstring vxworks,$(TARGET)),vxworks) release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/priv/src - $(INSTALL_DIR) $(RELSYSDIR)/priv/include - $(INSTALL_PROGRAM) $(CC_FILES) $(RELSYSDIR)/priv/src - $(INSTALL_PROGRAM) $(HH_FILES) $(RELSYSDIR)/priv/include + $(INSTALL_DIR) "$(RELSYSDIR)/priv/src" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/include" + $(INSTALL_PROGRAM) $(CC_FILES) "$(RELSYSDIR)/priv/src" + $(INSTALL_PROGRAM) $(HH_FILES) "$(RELSYSDIR)/priv/include" else release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/src - $(INSTALL_DIR) $(RELSYSDIR)/priv/include - $(INSTALL_DATA) $(CC_FILES) $(RELSYSDIR)/priv/src - $(INSTALL_DATA) $(HH_FILES) $(RELSYSDIR)/priv/include + $(INSTALL_DIR) "$(RELSYSDIR)/priv/src" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/include" + $(INSTALL_DATA) $(CC_FILES) "$(RELSYSDIR)/priv/src" + $(INSTALL_DATA) $(HH_FILES) "$(RELSYSDIR)/priv/include" endif endif diff --git a/lib/orber/doc/src/Makefile b/lib/orber/doc/src/Makefile index 68fbe3dce0..c429c1d80b 100644 --- a/lib/orber/doc/src/Makefile +++ b/lib/orber/doc/src/Makefile @@ -164,13 +164,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml index 35ee5e35dd..72cd808d20 100644 --- a/lib/orber/doc/src/notes.xml +++ b/lib/orber/doc/src/notes.xml @@ -32,7 +32,29 @@ <file>notes.xml</file> </header> - <section><title>Orber 3.6.23</title> + <section><title>Orber 3.6.24</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix number of arguments in orber dbg printout</p> + <p> + Own Id: OTP-9887</p> + </item> + <item> + <p> The descriptions of <c>ssl_server_options</c> and + <c>ssl_client_options</c> are corrected.<br/> Seq. Id: + seq12018 </p> + <p> + Own Id: OTP-9966 Aux Id: OTP-9773 </p> + </item> + </list> + </section> + +</section> + +<section><title>Orber 3.6.23</title> <section><title>Fixed Bugs and Malfunctions</title> <list> diff --git a/lib/orber/examples/Stack/Makefile b/lib/orber/examples/Stack/Makefile index b985f348fa..b03d7c3b86 100644 --- a/lib/orber/examples/Stack/Makefile +++ b/lib/orber/examples/Stack/Makefile @@ -118,8 +118,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/Stack - $(INSTALL_DATA) $(ERL_FILES) $(JAVA_FILES) $(CPP_FILES) $(IDL_FILES) $(RELSYSDIR)/examples/Stack + $(INSTALL_DIR) "$(RELSYSDIR)/examples/Stack" + $(INSTALL_DATA) $(ERL_FILES) $(JAVA_FILES) $(CPP_FILES) $(IDL_FILES) "$(RELSYSDIR)/examples/Stack" release_docs_spec: diff --git a/lib/orber/java_src/Orber/Makefile b/lib/orber/java_src/Orber/Makefile index 49da975a8b..4e52ed3635 100644 --- a/lib/orber/java_src/Orber/Makefile +++ b/lib/orber/java_src/Orber/Makefile @@ -63,8 +63,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/java_src/Orber - $(INSTALL_DATA) $(JAVA_FILES) $(RELSYSDIR)/java_src/Orber + $(INSTALL_DIR) "$(RELSYSDIR)/java_src/Orber" + $(INSTALL_DATA) $(JAVA_FILES) "$(RELSYSDIR)/java_src/Orber" release_docs_spec: diff --git a/lib/orber/priv/Makefile b/lib/orber/priv/Makefile index af82177466..7957f7bbf0 100644 --- a/lib/orber/priv/Makefile +++ b/lib/orber/priv/Makefile @@ -58,8 +58,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(HELP_FILES) $(HTML_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(HELP_FILES) $(HTML_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/orber/src/Makefile b/lib/orber/src/Makefile index d2e98686da..a57d6d948b 100644 --- a/lib/orber/src/Makefile +++ b/lib/orber/src/Makefile @@ -254,12 +254,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(GEN_HRL_FILES_LOC) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(GEN_HRL_FILES_EXT) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(GEN_HRL_FILES_LOC) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXTERNAL_HRL_FILES) $(GEN_HRL_FILES_EXT) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/orber/test/Makefile b/lib/orber/test/Makefile index d4be009af3..8eef1934a4 100644 --- a/lib/orber/test/Makefile +++ b/lib/orber/test/Makefile @@ -209,12 +209,12 @@ release_spec: release_docs_spec: release_tests_spec: tests - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(IDL_FILES) $(TEST_SPEC_FILE) $(COVER_FILE) \ - $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_TARGET_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - $(INSTALL_DIR) $(RELSYSDIR)/$(IDLOUTDIR) + $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_TARGET_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELSYSDIR)/$(IDLOUTDIR)" $(INSTALL_DATA) $(GEN_TARGET_FILES) $(GEN_FILES) \ - $(RELSYSDIR)/$(IDLOUTDIR) + "$(RELSYSDIR)/$(IDLOUTDIR)" diff --git a/lib/orber/test/orber_test_lib.erl b/lib/orber/test/orber_test_lib.erl index 0ddde49cd6..2bfa1ef871 100644 --- a/lib/orber/test/orber_test_lib.erl +++ b/lib/orber/test/orber_test_lib.erl @@ -282,6 +282,7 @@ starter(Host, Name, Args) -> vxworks -> test_server:start_node(Name, slave, [{args,Args}]); _ -> + io:format("slave:start_link(~p,~p,~p).~n",[Host,Name,Args]), slave:start_link(Host, Name, Args) end. @@ -403,8 +404,8 @@ create_paths() -> filename:join(Path, "idl_output") ++ " -pa " ++ filename:join(Path, "all_SUITE_data") ++ - " -pa " ++ - filename:dirname(code:which(orber)). + " -pa \"" ++ + filename:dirname(code:which(orber))++"\"". %%------------------------------------------------------------ %% function : destroy_node diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index 0eac1e1410..f891440600 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -1,3 +1,3 @@ -ORBER_VSN = 3.6.23 +ORBER_VSN = 3.6.24 diff --git a/lib/os_mon/c_src/Makefile.in b/lib/os_mon/c_src/Makefile.in index bac0413ece..45dc01e993 100644 --- a/lib/os_mon/c_src/Makefile.in +++ b/lib/os_mon/c_src/Makefile.in @@ -131,10 +131,10 @@ ifeq ($(findstring vxworks_simso,$(TARGET)),vxworks_simso) release_spec: else release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(C_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_PROGRAM) $(TARGET_FILES) $(RELSYSDIR)/priv/bin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(C_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_PROGRAM) $(TARGET_FILES) "$(RELSYSDIR)/priv/bin" endif release_docs_spec: diff --git a/lib/os_mon/doc/src/Makefile b/lib/os_mon/doc/src/Makefile index c9765749c9..aa8fb4b60c 100644 --- a/lib/os_mon/doc/src/Makefile +++ b/lib/os_mon/doc/src/Makefile @@ -109,16 +109,16 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/os_mon/doc/src/notes.xml b/lib/os_mon/doc/src/notes.xml index b459e31fa5..6674d7b722 100644 --- a/lib/os_mon/doc/src/notes.xml +++ b/lib/os_mon/doc/src/notes.xml @@ -30,6 +30,25 @@ </header> <p>This document describes the changes made to the OS_Mon application.</p> +<section><title>Os_Mon 2.2.9</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix segmentation fault in memsup</p> + <p> + when /proc/meminfo does not include information about + buffers/cache (for instance inside OpenVZ container) + (Thanks to Anton Vorobev)</p> + <p> + Own Id: OTP-9913</p> + </item> + </list> + </section> + +</section> + <section><title>Os_Mon 2.2.8</title> <section><title>Improvements and New Features</title> diff --git a/lib/os_mon/mibs/Makefile b/lib/os_mon/mibs/Makefile index 655190edf4..a6d8ab5042 100644 --- a/lib/os_mon/mibs/Makefile +++ b/lib/os_mon/mibs/Makefile @@ -88,13 +88,13 @@ $(SNMP_BIN_TARGET_DIR)/OTP-OS-MON-MIB.bin: \ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/mibs - $(INSTALL_DIR) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DATA) $(MIB_FILES) $(FUNCS_FILES) $(RELSYSDIR)/mibs - $(INSTALL_DATA) $(V1_MIB_FILES) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_TARGETS) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/priv/mibs - $(INSTALL_DATA) $(BIN_TARGETS) $(RELSYSDIR)/priv/mibs + $(INSTALL_DIR) "$(RELSYSDIR)/mibs" + $(INSTALL_DIR) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DATA) $(MIB_FILES) $(FUNCS_FILES) "$(RELSYSDIR)/mibs" + $(INSTALL_DATA) $(V1_MIB_FILES) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_TARGETS) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/mibs" + $(INSTALL_DATA) $(BIN_TARGETS) "$(RELSYSDIR)/priv/mibs" release_docs_spec: diff --git a/lib/os_mon/src/Makefile b/lib/os_mon/src/Makefile index 9a75446a89..a8ad26f6a1 100644 --- a/lib/os_mon/src/Makefile +++ b/lib/os_mon/src/Makefile @@ -94,11 +94,11 @@ $(EBIN)/memsup.$(EMULATOR): $(MEMSUP_HRL) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/os_mon/src/disksup.erl b/lib/os_mon/src/disksup.erl index 308cd1b7fa..c7abb7a386 100644 --- a/lib/os_mon/src/disksup.erl +++ b/lib/os_mon/src/disksup.erl @@ -43,24 +43,24 @@ start_link() -> gen_server:start_link({local, disksup}, disksup, [], []). get_disk_data() -> - os_mon:call(disksup, get_disk_data). + os_mon:call(disksup, get_disk_data, infinity). get_check_interval() -> - os_mon:call(disksup, get_check_interval). + os_mon:call(disksup, get_check_interval, infinity). set_check_interval(Minutes) -> case param_type(disk_space_check_interval, Minutes) of true -> - os_mon:call(disksup, {set_check_interval, Minutes}); + os_mon:call(disksup, {set_check_interval, Minutes}, infinity); false -> erlang:error(badarg) end. get_almost_full_threshold() -> - os_mon:call(disksup, get_almost_full_threshold). + os_mon:call(disksup, get_almost_full_threshold, infinity). set_almost_full_threshold(Float) -> case param_type(disk_almost_full_threshold, Float) of true -> - os_mon:call(disksup, {set_almost_full_threshold, Float}); + os_mon:call(disksup, {set_almost_full_threshold, Float}, infinity); false -> erlang:error(badarg) end. diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl index 5ef240f128..54771b4703 100644 --- a/lib/os_mon/src/memsup.erl +++ b/lib/os_mon/src/memsup.erl @@ -112,7 +112,7 @@ get_helper_timeout() -> set_helper_timeout(Seconds) -> case param_type(memsup_helper_timeout, Seconds) of true -> - os_mon:call(memsup, {set_helper_timeout, Seconds}); + os_mon:call(memsup, {set_helper_timeout, Seconds}, infinity); false -> erlang:error(badarg) end. diff --git a/lib/os_mon/src/os_mon.erl b/lib/os_mon/src/os_mon.erl index 3098c38808..2b6cd7c498 100644 --- a/lib/os_mon/src/os_mon.erl +++ b/lib/os_mon/src/os_mon.erl @@ -85,13 +85,13 @@ open_port(Name, Opts) -> %% Check os_mon*/priv/bin/Name case filelib:is_regular(ReleasedPath) of true -> - erlang:open_port({spawn, ReleasedPath}, Opts); + erlang:open_port({spawn, "\""++ReleasedPath++"\""}, Opts); false -> %% Use os_mon*/priv/bin/Arch/Name ArchPath = filename:join( [PrivDir,"bin",erlang:system_info(system_architecture),Name]), - erlang:open_port({spawn, ArchPath}, Opts) + erlang:open_port({spawn, "\""++ArchPath++"\""}, Opts) end. diff --git a/lib/os_mon/test/Makefile b/lib/os_mon/test/Makefile index a240640f92..954cfef7fb 100644 --- a/lib/os_mon/test/Makefile +++ b/lib/os_mon/test/Makefile @@ -84,9 +84,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) os_mon.spec os_mon.cover $(EMAKEFILE) $(SOURCE) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) os_mon.spec os_mon.cover $(EMAKEFILE) $(SOURCE) "$(RELSYSDIR)" -## tar chf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) +## tar chf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/os_mon/vsn.mk b/lib/os_mon/vsn.mk index 89dfa59dd9..b92bdf3c1a 100644 --- a/lib/os_mon/vsn.mk +++ b/lib/os_mon/vsn.mk @@ -1 +1 @@ -OS_MON_VSN = 2.2.8 +OS_MON_VSN = 2.2.9 diff --git a/lib/otp_mibs/doc/src/Makefile b/lib/otp_mibs/doc/src/Makefile index bd2810034b..16a5bb39b4 100644 --- a/lib/otp_mibs/doc/src/Makefile +++ b/lib/otp_mibs/doc/src/Makefile @@ -102,14 +102,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/otp_mibs/mibs/Makefile b/lib/otp_mibs/mibs/Makefile index 5e59824d3f..7ef8480b3e 100644 --- a/lib/otp_mibs/mibs/Makefile +++ b/lib/otp_mibs/mibs/Makefile @@ -76,13 +76,13 @@ v1/%.mib.v1: %.mib include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/mibs - $(INSTALL_DIR) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DATA) $(MIB_FILES) $(FUNCS_FILES) $(RELSYSDIR)/mibs - $(INSTALL_DATA) $(V1_MIB_FILES) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_TARGETS) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/priv/mibs - $(INSTALL_DATA) $(BIN_TARGETS) $(RELSYSDIR)/priv/mibs + $(INSTALL_DIR) "$(RELSYSDIR)/mibs" + $(INSTALL_DIR) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DATA) $(MIB_FILES) $(FUNCS_FILES) "$(RELSYSDIR)/mibs" + $(INSTALL_DATA) $(V1_MIB_FILES) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_TARGETS) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/mibs" + $(INSTALL_DATA) $(BIN_TARGETS) "$(RELSYSDIR)/priv/mibs" release_docs_spec: diff --git a/lib/otp_mibs/src/Makefile b/lib/otp_mibs/src/Makefile index 833a439adb..c9c40fec3a 100644 --- a/lib/otp_mibs/src/Makefile +++ b/lib/otp_mibs/src/Makefile @@ -95,10 +95,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk 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) $(TARGETS) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGETS) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/parsetools/doc/src/Makefile b/lib/parsetools/doc/src/Makefile index 6e693e0cf0..464ea66af0 100644 --- a/lib/parsetools/doc/src/Makefile +++ b/lib/parsetools/doc/src/Makefile @@ -105,14 +105,14 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/parsetools/src/Makefile b/lib/parsetools/src/Makefile index 89e079e411..e228ee88ef 100644 --- a/lib/parsetools/src/Makefile +++ b/lib/parsetools/src/Makefile @@ -89,12 +89,12 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk 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 - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/parsetools/test/Makefile b/lib/parsetools/test/Makefile index 624c4e6975..430386bfe5 100644 --- a/lib/parsetools/test/Makefile +++ b/lib/parsetools/test/Makefile @@ -70,9 +70,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) parsetools.spec parsetools.cover $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - # @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) parsetools.spec parsetools.cover $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + # @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/percept/doc/src/Makefile b/lib/percept/doc/src/Makefile index f0d43c5a01..e749103783 100644 --- a/lib/percept/doc/src/Makefile +++ b/lib/percept/doc/src/Makefile @@ -175,15 +175,15 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTML_EXAMPLE_FILES) $(HTML_STYLESHEET_FILES) \ $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/percept/priv/Makefile b/lib/percept/priv/Makefile index 7c37ccd98b..4d7942c49c 100644 --- a/lib/percept/priv/Makefile +++ b/lib/percept/priv/Makefile @@ -77,20 +77,20 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt # Finished - $(INSTALL_DIR) $(RELSYSDIR)/priv/logs - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root/htdocs - $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/priv/server_root/htdocs - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root/conf - $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/priv/server_root/conf - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root/scripts - $(INSTALL_DATA) $(SCRIPT_FILES) $(RELSYSDIR)/priv/server_root/scripts - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root/css - $(INSTALL_DATA) $(CSS_FILES) $(RELSYSDIR)/priv/server_root/css - $(INSTALL_DIR) $(RELSYSDIR)/priv/server_root/images - $(INSTALL_DATA) $(IMAGE_FILES) $(RELSYSDIR)/priv/server_root/images - $(INSTALL_DIR) $(RELSYSDIR)/priv/fonts - $(INSTALL_DATA) $(FONT_FILES) $(RELSYSDIR)/priv/fonts + $(INSTALL_DIR) "$(RELSYSDIR)/priv/logs" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/htdocs" + $(INSTALL_DATA) $(HTDOCS_FILES) "$(RELSYSDIR)/priv/server_root/htdocs" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/conf" + $(INSTALL_DATA) $(CONF_FILES) "$(RELSYSDIR)/priv/server_root/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/scripts" + $(INSTALL_DATA) $(SCRIPT_FILES) "$(RELSYSDIR)/priv/server_root/scripts" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/css" + $(INSTALL_DATA) $(CSS_FILES) "$(RELSYSDIR)/priv/server_root/css" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/server_root/images" + $(INSTALL_DATA) $(IMAGE_FILES) "$(RELSYSDIR)/priv/server_root/images" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/fonts" + $(INSTALL_DATA) $(FONT_FILES) "$(RELSYSDIR)/priv/fonts" release_docs_spec: diff --git a/lib/percept/src/Makefile b/lib/percept/src/Makefile index 5dfc72575a..4b9a10cdb8 100644 --- a/lib/percept/src/Makefile +++ b/lib/percept/src/Makefile @@ -93,12 +93,12 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src -# $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" +# $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/percept/test/Makefile b/lib/percept/test/Makefile index d927386d1c..ee70966b01 100644 --- a/lib/percept/test/Makefile +++ b/lib/percept/test/Makefile @@ -81,10 +81,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) percept.spec percept.cover $(EMAKEFILE) $(SOURCE) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) percept.spec percept.cover $(EMAKEFILE) $(SOURCE) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/pman/doc/src/Makefile b/lib/pman/doc/src/Makefile index 4e116cb23e..ec759091ab 100644 --- a/lib/pman/doc/src/Makefile +++ b/lib/pman/doc/src/Makefile @@ -103,14 +103,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/pman/doc/src/notes.xml b/lib/pman/doc/src/notes.xml index 82cb35af00..778f960004 100644 --- a/lib/pman/doc/src/notes.xml +++ b/lib/pman/doc/src/notes.xml @@ -30,6 +30,26 @@ </header> <p>This document describes the changes made to the Pman application.</p> +<section><title>Pman 2.7.1.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + <section><title>Pman 2.7.1.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/pman/priv/Makefile b/lib/pman/priv/Makefile index 43f9d45d94..a89278fd3a 100644 --- a/lib/pman/priv/Makefile +++ b/lib/pman/priv/Makefile @@ -50,8 +50,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(TOOLBAR_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(TOOLBAR_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/pman/src/Makefile b/lib/pman/src/Makefile index e573e57220..2cd1c64c49 100644 --- a/lib/pman/src/Makefile +++ b/lib/pman/src/Makefile @@ -103,10 +103,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(TOOLBOX_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(TARGET_TOOLBOX_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(TOOLBOX_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(TARGET_TOOLBOX_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/pman/vsn.mk b/lib/pman/vsn.mk index a62a9d7c89..13dce1a7a5 100644 --- a/lib/pman/vsn.mk +++ b/lib/pman/vsn.mk @@ -1 +1 @@ -PMAN_VSN = 2.7.1.1 +PMAN_VSN = 2.7.1.2 diff --git a/lib/public_key/asn1/Makefile b/lib/public_key/asn1/Makefile index 943d97bdb8..d48f48a5d5 100644 --- a/lib/public_key/asn1/Makefile +++ b/lib/public_key/asn1/Makefile @@ -91,13 +91,13 @@ $(INCLUDE)/%.hrl: %.hrl include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/asn1 + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/asn1" $(INSTALL_DATA) $(ASN_ASNS) $(ASN_ERLS) $(ASN_HRLS) $(ASN_CONFIGS) \ - $(GEN_ERLS) $(RELSYSDIR)/asn1 - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(GEN_ERLS) "$(RELSYSDIR)/asn1" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile index 9616a96195..928aa62c1b 100644 --- a/lib/public_key/doc/src/Makefile +++ b/lib/public_key/doc/src/Makefile @@ -114,14 +114,14 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: info: diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml index c9a5561e3f..4d3a9856eb 100644 --- a/lib/public_key/doc/src/notes.xml +++ b/lib/public_key/doc/src/notes.xml @@ -34,6 +34,35 @@ <file>notes.xml</file> </header> +<section><title>Public_Key 0.15</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Changed ssh implementation to use the public_key + application for all public key handling. This is also a + first step for enabling a callback API for supplying + public keys and handling keys protected with password + phrases. </p> + <p> + Additionally the test suites where improved so that they + do not copy the users keys to test server directories as + this is a security liability. Also ipv6 and file access + issues found in the process has been fixed.</p> + <p> + This change also solves OTP-7677 and OTP-7235</p> + <p> + This changes also involves some updates to public_keys + ssh-functions.</p> + <p> + Own Id: OTP-9911</p> + </item> + </list> + </section> + +</section> + <section><title>Public_Key 0.14</title> <section><title>Improvements and New Features</title> diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile index 062c495a65..8a72da477f 100644 --- a/lib/public_key/src/Makefile +++ b/lib/public_key/src/Makefile @@ -102,11 +102,11 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 2e2a6cd296..9f1a0b3af5 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -241,15 +241,15 @@ pkix_encode(Asn1Type, Term0, otp) when is_atom(Asn1Type) -> decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). -decrypt_private(CipherText, - #'RSAPrivateKey'{modulus = N,publicExponent = E, - privateExponent = D}, - Options) when is_binary(CipherText), - is_list(Options) -> +decrypt_private(CipherText, + #'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D} = Key, + Options) + when is_binary(CipherText), + is_integer(N), is_integer(E), is_integer(D), + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_decrypt(CipherText, - [crypto:mpint(E), crypto:mpint(N), - crypto:mpint(D)], Padding). + crypto:rsa_private_decrypt(CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- -spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> @@ -307,14 +307,29 @@ encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, encrypt_private(PlainText, Key) -> encrypt_private(PlainText, Key, []). -encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, - publicExponent = E, - privateExponent = D}, - Options) when is_binary(PlainText), is_list(Options) -> +encrypt_private(PlainText, + #'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D} = Key, + Options) + when is_binary(PlainText), + is_integer(N), is_integer(E), is_integer(D), + is_list(Options) -> Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:rsa_private_encrypt(PlainText, [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)], Padding). + crypto:rsa_private_encrypt(PlainText, format_rsa_private_key(Key), Padding). + + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D, + prime1 = P1, prime2 = P2, + exponent1 = E1, exponent2 = E2, + coefficient = C}) + when is_integer(P1), is_integer(P2), + is_integer(E1), is_integer(E2), is_integer(C) -> + [crypto:mpint(K) || K <- [E, N, D, P1, P2, E1, E2, C]]; + +format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E, + privateExponent = D}) -> + [crypto:mpint(K) || K <- [E, N, D]]. %%-------------------------------------------------------------------- -spec sign(PlainTextOrDigest :: binary(), rsa_digest_type() | dss_digest_type(), @@ -323,15 +338,13 @@ encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, %% %% Description: Create digital signature. %%-------------------------------------------------------------------- -sign(PlainText, DigestType, #'RSAPrivateKey'{modulus = N, publicExponent = E, - privateExponent = D}) +sign(PlainText, DigestType, + #'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D} = Key) when is_binary(PlainText), - (DigestType == md5 orelse - DigestType == sha) -> - - crypto:rsa_sign(DigestType, sized_binary(PlainText), [crypto:mpint(E), - crypto:mpint(N), - crypto:mpint(D)]); + (DigestType == md5 orelse DigestType == sha), + is_integer(N), is_integer(E), is_integer(D) -> + crypto:rsa_sign(DigestType, sized_binary(PlainText), + format_rsa_private_key(Key)); sign(Digest, none, #'DSAPrivateKey'{p = P, q = Q, g = G, x = X}) when is_binary(Digest)-> diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile index b7f91981a5..41d77f103b 100644 --- a/lib/public_key/test/Makefile +++ b/lib/public_key/test/Makefile @@ -21,7 +21,7 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk -INCLUDES= -I. -I ../include +INCLUDES= -I. -I ../include -pa $(ERL_TOP)/lib/public_key/ebin # ---------------------------------------------------- # Target Specs @@ -78,11 +78,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/reltool/doc/src/Makefile b/lib/reltool/doc/src/Makefile index 8bc1488f77..0b85b7e02c 100644 --- a/lib/reltool/doc/src/Makefile +++ b/lib/reltool/doc/src/Makefile @@ -97,13 +97,13 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(HTMLDIR)/* $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(HTMLDIR)/* "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index cf2cf7f7bc..0aae128c2b 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -37,7 +37,149 @@ thus constitutes one section in this document. The title of each section is the version number of Reltool.</p> - <section><title>Reltool 0.5.7.1</title> + <section><title>Reltool 0.6</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Miscellaneous corrections: <list> <item> Start of reltool + GUI would sometimes crash with a badmatch in + reltool_sys_win:do_init. This has been corrected. </item> + <item> Minor corrections of documentation and type + specifications of app() and mod() are done. </item> + <item> If a module name is duplicated in an app file + reltool would return an error. This is now changed to a + warning. </item> <item> Reltool would earlier not + necessarily keep the order of applications as listed in + the rel specification in the configuration. This has been + corrected. </item> <item> Reltool would earlier set the + default for included applications to an empty list if it + was not set in the rel specification in the + configuration. This was correct according to + sasl/systools documentation, but not according to + sasl/systools implementation. We decided to change the + documentation and reltool to use the value of + included_applications from the .app file as default + instead of the empty list, since this seems more + intuitive and since systools always has done the same. + </item> <item> The value of included applications in the + rel specification in the configuration did not overwrite + included_applications in the .app file if it was set to + an empty list. This has been corrected. </item> <item> + Reltool would earlier add load instructions in the + script/boot files for ALL modules in the ebin directory + of an application even if mod_cond was set to app + (include only modules listed in the .app file). This has + been corrected. </item> <item> Reltool would earlier add + start instructions in the script/boot file for included + applications. This has been corrected - included + applications shall only be loaded since the including + application is responsible for starting them. </item> + <item> Status bar now indicates that reltool is working + (Processing libraries...) for all configuration changes, + and when generating target system. </item> <item> Title + of dependecies column in app and mod window is changed + from "Modules used by others" to "Modules using this". + </item> </list></p> + <p> + Own Id: OTP-9792</p> + </item> + <item> + <p> + Configuration changes via the GUI had a few bugs related + to error handling, rollback and undo. A major re-write of + the reltool_server has been done in order to align the + way reltool_server updates and uses its state and tables + for all different kinds of configuration change. </p> + <p> + All configuration changes (except undo) now cause a + re-read of the file system, meaning that if something has + changed in the file system it will be reflected in the + result of the configuration change.</p> + <p> + When loading a new configuration file via the GUI, the + old configuration is now completely scratched, and only + the new is valid.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9794</p> + </item> + <item> + <p> + Some bug fixes related to the handling of escripts: + <list> <item> Reltool could not handle escripts with + inlined applications. This has been corrected. Inlined + applications will be visible in the GUI, but not possible + to include/exclude separately. </item> <item> Loading a + config which contains an escript via the GUI menu did not + produce the same result as when using the same + configuration at reltool start. Paths, version and label + could differ. This has been corrected. </item> <item> + Loading config with same escript (source) twice caused + reltool to add same module twice. This has been + corrected. </item> <item> Loading config with same + escript (inlined beam) twice caused reltool to fail + saying module is included by two different applications. + This has been corrected. </item> <item> Loading config + which in addition to an existing escript also adds + another escript, for which the name sorts before the + existing one, would cause reltool to fail saying + "Application name clash". This has been corrected. + </item> </list></p> + <p> + Own Id: OTP-9968</p> + </item> + <item> + <p> + Reltool would sometimes generate a .app file containing + <c>{start_phases,undefined}</c>, which would cause an + exception in systools at parse time. This has been + corrected so reltool now omits the <c>start_phases</c> + entry if the value is <c>undefined</c>. (Thanks to Juan + Jose Comellas)</p> + <p> + In order to align with reltool, sasl will also omit + <c>start_phases</c> entries with value <c>undefined</c> + in .script files.</p> + <p> + Own Id: OTP-10003</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A warning list is added to the sys window of the reltool + GUI. This list will continuously show all warnings + produced by the current configuration.</p> + <p> + Own Id: OTP-9967</p> + </item> + <item> + <p> + As a way of specifying one specific version of an + application, the following configuration parameter is + added on application level:</p> + <p> + {lib_dir,Dir}, Dir = string()</p> + <p> + This can be useful if the parent directory of the + application directory is not suitable to use as a lib dir + on system level.</p> + <p> + Own Id: OTP-9977</p> + </item> + </list> + </section> + +</section> + +<section><title>Reltool 0.5.7.1</title> <section><title>Improvements and New Features</title> <list> diff --git a/lib/reltool/examples/Makefile b/lib/reltool/examples/Makefile index dacfd4e7d4..afc47e1d12 100644 --- a/lib/reltool/examples/Makefile +++ b/lib/reltool/examples/Makefile @@ -72,8 +72,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) $(DATA_FILES) $(HRL_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile index 4e6a112b7e..4730b4acff 100644 --- a/lib/reltool/src/Makefile +++ b/lib/reltool/src/Makefile @@ -97,11 +97,11 @@ $(TARGET_FILES): $(HRL_FILES) $(INTERNAL_HRL_FILES) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/reltool/test/Makefile b/lib/reltool/test/Makefile index d8a7adb837..52cdef44da 100644 --- a/lib/reltool/test/Makefile +++ b/lib/reltool/test/Makefile @@ -49,7 +49,7 @@ RELSYSDIR = $(RELEASE_PATH)/reltool_test # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -#ERL_COMPILE_FLAGS += +ERL_COMPILE_FLAGS += -pa $(ERL_TOP)/lib/reltool/ebin/ EBIN = . @@ -73,12 +73,12 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) reltool.spec reltool.cover $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) $(RELSYSDIR) - $(INSTALL_DATA) $(INSTALL_PROGS) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) reltool.spec reltool.cover $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_SCRIPT) rtt $(INSTALL_PROGS) "$(RELSYSDIR)" + $(INSTALL_DATA) $(INSTALL_PROGS) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk index 3869284ee7..3811d897c7 100644 --- a/lib/reltool/vsn.mk +++ b/lib/reltool/vsn.mk @@ -1 +1 @@ -RELTOOL_VSN = 0.5.7.1 +RELTOOL_VSN = 0.6 diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in index cbbcfa2d56..754e6ccd78 100644 --- a/lib/runtime_tools/c_src/Makefile.in +++ b/lib/runtime_tools/c_src/Makefile.in @@ -193,10 +193,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/obj - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_PROGRAM) $(DYNTRACE_OBJS) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(NIF_LIB) $(SOLIBS) $(RELSYSDIR)/priv/lib + $(INSTALL_DIR) "$(RELSYSDIR)/priv/obj" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/lib" + $(INSTALL_PROGRAM) $(DYNTRACE_OBJS) "$(RELSYSDIR)/priv/obj" + $(INSTALL_PROGRAM) $(NIF_LIB) $(SOLIBS) "$(RELSYSDIR)/priv/lib" release_docs_spec: diff --git a/lib/runtime_tools/doc/src/Makefile b/lib/runtime_tools/doc/src/Makefile index c67f7bd1f6..d240b287c3 100644 --- a/lib/runtime_tools/doc/src/Makefile +++ b/lib/runtime_tools/doc/src/Makefile @@ -108,16 +108,16 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml index ccf11bf0fe..2d4a206e1c 100644 --- a/lib/runtime_tools/doc/src/notes.xml +++ b/lib/runtime_tools/doc/src/notes.xml @@ -31,6 +31,28 @@ <p>This document describes the changes made to the Runtime_Tools application.</p> +<section><title>Runtime_Tools 1.8.8</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + The DTrace source patch from Scott Lystig Fritchie is + integrated in the source tree. Using an emulator with + dtrace probe is still not supported for production use, + but may be a valuable debugging tool. Configure with + --with-dynamic-trace=dtrace (or + --with-dynamic-trace=systemtap) to create a build with + dtrace probes enabled. See runtime_tools for + documentation and examples.</p> + <p> + Own Id: OTP-10017</p> + </item> + </list> + </section> + +</section> + <section><title>Runtime_Tools 1.8.7</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile index cb302b79c2..810e3e8741 100644 --- a/lib/runtime_tools/src/Makefile +++ b/lib/runtime_tools/src/Makefile @@ -99,14 +99,14 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(EXAMPLE_FILES) "$(RELSYSDIR)/examples" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/runtime_tools/test/Makefile b/lib/runtime_tools/test/Makefile index 3e50ba02ca..4979b9c7b1 100644 --- a/lib/runtime_tools/test/Makefile +++ b/lib/runtime_tools/test/Makefile @@ -57,10 +57,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) runtime_tools.spec runtime_tools.cover $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(EMAKEFILE) runtime_tools.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) runtime_tools.spec runtime_tools.cover $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) runtime_tools.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk index 3fbc1b3379..c9b5cc1a41 100644 --- a/lib/runtime_tools/vsn.mk +++ b/lib/runtime_tools/vsn.mk @@ -1 +1 @@ -RUNTIME_TOOLS_VSN = 1.8.7 +RUNTIME_TOOLS_VSN = 1.8.8 diff --git a/lib/sasl/doc/src/Makefile b/lib/sasl/doc/src/Makefile index eb880ccb78..b0ec671adc 100644 --- a/lib/sasl/doc/src/Makefile +++ b/lib/sasl/doc/src/Makefile @@ -116,18 +116,18 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man4 - $(INSTALL_DATA) $(MAN4_FILES) $(RELEASE_PATH)/man/man4 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man4" + $(INSTALL_DATA) $(MAN4_FILES) "$(RELEASE_PATH)/man/man4" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml index 2f22a8ec43..e4a2c98db7 100644 --- a/lib/sasl/doc/src/notes.xml +++ b/lib/sasl/doc/src/notes.xml @@ -30,6 +30,102 @@ </header> <p>This document describes the changes made to the SASL application.</p> +<section><title>SASL 2.2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + If sys.config existed, but was not readable or parseable, + this would not be detected until after the upgrade and at + the next node restart. The possibility for this to happen + is now reduced by adding a check to systools:make_tar + which fails the creation of the tar file if sys.config or + relup does not have reasonable contents. Note that there + are no detailed checks, only parsing and erlang term + format check.</p> + <p> + Own Id: OTP-9539</p> + </item> + <item> + <p> + systools:make_script would allow {kernel,Vsn,load} in the + .rel file, causing a .boot file which only loaded kernel + and did not start it. This has been corrected. Only start + type 'permanent', which is the default, is now allowed + for kernel and stdlib.</p> + <p> + Own Id: OTP-9652</p> + </item> + <item> + <p> + release_handler:remove_release/1 now handles symlinked + files properly</p> + <p> + Own Id: OTP-9864</p> + </item> + <item> + <p> + If stdlib was stated with a start type different from + <c>permanent</c> in a .rel file, systools would + incorrectly say that sasl had faulty start type. This has + been corrected.</p> + <p> + Own Id: OTP-9888</p> + </item> + <item> + <p> + Sasl documentation earlier said that the InclApps + parameters in a .rel file defaults to the empty list. + This is not correct. It defaults to the same value as + specified in the .app file. This has been corrected.</p> + <p> + Own Id: OTP-9980</p> + </item> + <item> + <p> + Applications that are listed in + <c>{applications,Apps}</c> in the .app file were not + sorted correctly by <c>systools:make_script/1,2</c>. They + got the reverse order of how they were listed in the .app + file. This is corrected so they are now sorted + (internally between each other) in the same order as they + are listed in the .rel file (i.e. the order they are + listed in the .app file does no longer matter).</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9984</p> + </item> + <item> + <p> + Documentation of .appup files now also states that + <c>UpFromVsn</c> and <c>DownToVsn</c> can be specified as + regular expressions in order to avoid duplicated upgrade + instructions.</p> + <p> + Own Id: OTP-10001</p> + </item> + <item> + <p> + Reltool would sometimes generate a .app file containing + <c>{start_phases,undefined}</c>, which would cause an + exception in systools at parse time. This has been + corrected so reltool now omits the <c>start_phases</c> + entry if the value is <c>undefined</c>. (Thanks to Juan + Jose Comellas)</p> + <p> + In order to align with reltool, sasl will also omit + <c>start_phases</c> entries with value <c>undefined</c> + in .script files.</p> + <p> + Own Id: OTP-10003</p> + </item> + </list> + </section> + +</section> + <section><title>SASL 2.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/sasl/examples/src/Makefile b/lib/sasl/examples/src/Makefile index 9cf0d4c25d..47c8626205 100644 --- a/lib/sasl/examples/src/Makefile +++ b/lib/sasl/examples/src/Makefile @@ -63,10 +63,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/src - $(INSTALL_DIR) $(RELSYSDIR)/examples/ebin - (cd ..; tar cf - src ebin | (cd $(RELSYSDIR)/examples; tar xf -)) - chmod -R ug+w $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples/src" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/ebin" + (cd ..; tar cf - src ebin | (cd "$(RELSYSDIR)/examples"; tar xf -)) + chmod -R ug+w "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/sasl/src/Makefile b/lib/sasl/src/Makefile index 9a5d1e42d9..cae8146ebc 100644 --- a/lib/sasl/src/Makefile +++ b/lib/sasl/src/Makefile @@ -91,10 +91,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/sasl/test/Makefile b/lib/sasl/test/Makefile index 91a8c42484..bb3f82f411 100644 --- a/lib/sasl/test/Makefile +++ b/lib/sasl/test/Makefile @@ -85,10 +85,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) sasl.spec sasl.cover $(EMAKEFILE) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cfh - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) sasl.spec sasl.cover $(EMAKEFILE) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cfh - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk index 23694f1399..6e9e2c9ff8 100644 --- a/lib/sasl/vsn.mk +++ b/lib/sasl/vsn.mk @@ -1 +1 @@ -SASL_VSN = 2.2 +SASL_VSN = 2.2.1 diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile index 8645886590..6c58ae994a 100644 --- a/lib/snmp/doc/src/Makefile +++ b/lib/snmp/doc/src/Makefile @@ -170,20 +170,20 @@ $(MAN1DIR)/snmpc.1: snmpc_cmd.xml include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 - $(INSTALL_DATA) $(MAN1DIR)/* $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6DIR)/* $(RELEASE_PATH)/man/man6 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man7 - $(INSTALL_DATA) $(MAN7DIR)/* $(RELEASE_PATH)/man/man7 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DATA) $(MAN1DIR)/* "$(RELEASE_PATH)/man/man1" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6DIR)/* "$(RELEASE_PATH)/man/man6" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man7" + $(INSTALL_DATA) $(MAN7DIR)/* "$(RELEASE_PATH)/man/man7" release_spec: diff --git a/lib/snmp/examples/ex1/Makefile b/lib/snmp/examples/ex1/Makefile index 1a55ba0470..996b686e0e 100644 --- a/lib/snmp/examples/ex1/Makefile +++ b/lib/snmp/examples/ex1/Makefile @@ -46,7 +46,7 @@ ERL_COMPILE_FLAGS += -I../include \ # Release directory specification # ---------------------------------------------------- RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN) -EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples +EXAMPLE_RELSYSDIR = "$(RELSYSDIR)/examples" EX1_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/ex1 # ---------------------------------------------------- diff --git a/lib/snmp/examples/ex2/Makefile b/lib/snmp/examples/ex2/Makefile index 7fbd7f530b..090b9274d4 100644 --- a/lib/snmp/examples/ex2/Makefile +++ b/lib/snmp/examples/ex2/Makefile @@ -47,7 +47,7 @@ ERL_COMPILE_FLAGS += -I../include \ # Release directory specification # ---------------------------------------------------- RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN) -EXAMPLE_RELSYSDIR = $(RELSYSDIR)/examples +EXAMPLE_RELSYSDIR = "$(RELSYSDIR)/examples" EX2_RELSYSDIR = $(EXAMPLE_RELSYSDIR)/ex2 # ---------------------------------------------------- diff --git a/lib/snmp/mibs/Makefile.in b/lib/snmp/mibs/Makefile.in index 993a67c6f2..c74c0b2ac4 100644 --- a/lib/snmp/mibs/Makefile.in +++ b/lib/snmp/mibs/Makefile.in @@ -211,7 +211,7 @@ info: @echo "" @echo "SNMP_VSN = $(SNMP_VSN)" @echo "VSN = $(VSN)" - @echo "RELSYSDIR = $(RELSYSDIR)" + @echo "RELSYSDIR = "$(RELSYSDIR)"" v1/%.mib.v1: %.mib $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 -o $@ $< @@ -223,17 +223,17 @@ v1/%.mib.v1: %.mib $(ERL_TOP)/lib/snmp/bin/snmp-v2tov1 include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/mibs - $(INSTALL_DIR) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DATA) $(MIB_FILES) $(RELSYSDIR)/mibs - $(INSTALL_DATA) $(STD_v2_MIB_FILES) $(RELSYSDIR)/mibs - $(INSTALL_DATA) $(FUNCS_FILES) $(RELSYSDIR)/mibs - $(INSTALL_DATA) $(STD_v1_MIB_FILES) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DATA) $(V1_MIB_FILES) $(RELSYSDIR)/mibs/v1 - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/priv/mibs - $(INSTALL_DATA) $(BIN_TARGETS) $(RELSYSDIR)/priv/mibs + $(INSTALL_DIR) "$(RELSYSDIR)/mibs" + $(INSTALL_DIR) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DATA) $(MIB_FILES) "$(RELSYSDIR)/mibs" + $(INSTALL_DATA) $(STD_v2_MIB_FILES) "$(RELSYSDIR)/mibs" + $(INSTALL_DATA) $(FUNCS_FILES) "$(RELSYSDIR)/mibs" + $(INSTALL_DATA) $(STD_v1_MIB_FILES) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DATA) $(V1_MIB_FILES) "$(RELSYSDIR)/mibs/v1" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/mibs" + $(INSTALL_DATA) $(BIN_TARGETS) "$(RELSYSDIR)/priv/mibs" release_docs_spec: diff --git a/lib/snmp/priv/conf/agent/Makefile b/lib/snmp/priv/conf/agent/Makefile index ee3a915c2b..c7921bacc2 100644 --- a/lib/snmp/priv/conf/agent/Makefile +++ b/lib/snmp/priv/conf/agent/Makefile @@ -55,9 +55,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/conf - $(INSTALL_DIR) $(RELSYSDIR)/priv/conf/agent - $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/priv/conf/agent + $(INSTALL_DIR) "$(RELSYSDIR)/priv/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/conf/agent" + $(INSTALL_DATA) $(CONF_FILES) "$(RELSYSDIR)/priv/conf/agent" release_docs_spec: diff --git a/lib/snmp/priv/conf/manager/Makefile b/lib/snmp/priv/conf/manager/Makefile index 16355f0ff3..ba5a74c3fe 100644 --- a/lib/snmp/priv/conf/manager/Makefile +++ b/lib/snmp/priv/conf/manager/Makefile @@ -55,9 +55,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/conf - $(INSTALL_DIR) $(RELSYSDIR)/priv/conf/manager - $(INSTALL_DATA) $(CONF_FILES) $(RELSYSDIR)/priv/conf/manager + $(INSTALL_DIR) "$(RELSYSDIR)/priv/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/conf/manager" + $(INSTALL_DATA) $(CONF_FILES) "$(RELSYSDIR)/priv/conf/manager" release_docs_spec: diff --git a/lib/snmp/src/agent/Makefile b/lib/snmp/src/agent/Makefile index a67fe4d17c..9a982edf91 100644 --- a/lib/snmp/src/agent/Makefile +++ b/lib/snmp/src/agent/Makefile @@ -128,14 +128,14 @@ info: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/agent - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src/agent - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/agent" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src/agent" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \ - $(RELSYSDIR)/ebin -# $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include + "$(RELSYSDIR)/ebin" +# $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(EXT_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/snmp/src/app/Makefile b/lib/snmp/src/app/Makefile index d89eb4e723..7a16d42c30 100644 --- a/lib/snmp/src/app/Makefile +++ b/lib/snmp/src/app/Makefile @@ -127,14 +127,14 @@ $(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/app - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src/app - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/app" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src/app" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \ - $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include + "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXT_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile index 627af6f185..9658ee0005 100644 --- a/lib/snmp/src/compile/Makefile +++ b/lib/snmp/src/compile/Makefile @@ -120,13 +120,13 @@ $(GENERATED_PARSER): $(PARSER_SRC) include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/compiler - $(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(EBIN_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/bin - $(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/compiler" + $(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src/compiler" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(EBIN_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/bin" + $(INSTALL_SCRIPT) $(ESCRIPT_BIN) "$(RELSYSDIR)/bin" release_docs_spec: diff --git a/lib/snmp/src/manager/Makefile b/lib/snmp/src/manager/Makefile index c1d5703300..1f30669f02 100644 --- a/lib/snmp/src/manager/Makefile +++ b/lib/snmp/src/manager/Makefile @@ -111,13 +111,13 @@ info: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/manager - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src/manager - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin -# $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/manager" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src/manager" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" +# $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(EXT_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/snmp/src/misc/Makefile b/lib/snmp/src/misc/Makefile index 48d76bdbed..c6a5064d89 100644 --- a/lib/snmp/src/misc/Makefile +++ b/lib/snmp/src/misc/Makefile @@ -109,13 +109,13 @@ info: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/misc - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src/misc - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin -# $(INSTALL_DIR) $(RELSYSDIR)/include -# $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/misc" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src/misc" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" +# $(INSTALL_DIR) "$(RELSYSDIR)/include" +# $(INSTALL_DATA) $(EXT_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile index 40a294f783..546d46a002 100644 --- a/lib/snmp/test/Makefile +++ b/lib/snmp/test/Makefile @@ -79,7 +79,7 @@ COVER_SPEC_FILE = snmp.cover # ---------------------------------------------------- # Release directory specification # ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/snmp_test +RELSYSDIR = $(RELEASE_PATH)/snmp_test # ---------------------------------------------------- @@ -235,10 +235,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(RELTEST_FILES) $(COVER_SPEC_FILE) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - tar cf - snmp_test_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(RELTEST_FILES) $(COVER_SPEC_FILE) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + tar cf - snmp_test_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: @@ -254,7 +254,7 @@ info: @echo "" @echo "ERL_COMPILE_FLAGS = $(ERL_COMPILE_FLAGS)" @echo "" - @echo "RELSYSDIR = $(RELSYSDIR)" + @echo "RELSYSDIR = "$(RELSYSDIR)"" @echo "" @echo "SOURCE = $(SOURCE)" @echo "" diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile index 125dcf8775..38782a3b00 100644 --- a/lib/ssh/doc/src/Makefile +++ b/lib/ssh/doc/src/Makefile @@ -109,13 +109,13 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml index c6c634212f..a85cada732 100644 --- a/lib/ssh/doc/src/notes.xml +++ b/lib/ssh/doc/src/notes.xml @@ -29,6 +29,108 @@ <file>notes.xml</file> </header> +<section><title>Ssh 2.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + All keys in authorized_keys are considerd, wrongly only + the first one was before.</p> + <p> + Own Id: OTP-7235</p> + </item> + <item> + <p> + ssh daemon now properly handles ras host keys, in + previous versions only dsa host keys sufficed to set up a + connection.</p> + <p> + Own Id: OTP-7677</p> + </item> + <item> + <p> + ssh:shell/3 and ssh:connect/3 does not hang anymore if + connection negotiation fails</p> + <p> + Own Id: OTP-8111</p> + </item> + <item> + <p> + Improve check so that we will not try to read ssh packet + length indicator if not sure we have enough data.</p> + <p> + Own Id: OTP-8380</p> + </item> + <item> + <p> + Do not try to use user interaction when it is disabled.</p> + <p> + Own Id: OTP-9466 Aux Id: seq11886 </p> + </item> + <item> + <p> + Improved error handling of internal errors i the ssh + connection handling process</p> + <p> + Own Id: OTP-9905</p> + </item> + <item> + <p> + sftp daemon generates file handles correct</p> + <p> + Own Id: OTP-9948</p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Document supported algorithms</p> + <p> + Own Id: OTP-8109</p> + </item> + <item> + <p> + Graceful handling of premature close from an sftp client.</p> + <p> + Own Id: OTP-9391 Aux Id: seq11838 </p> + </item> + <item> + <p> + Changed ssh implementation to use the public_key + application for all public key handling. This is also a + first step for enabling a callback API for supplying + public keys and handling keys protected with password + phrases. </p> + <p> + Additionally the test suites where improved so that they + do not copy the users keys to test server directories as + this is a security liability. Also ipv6 and file access + issues found in the process has been fixed.</p> + <p> + This change also solves OTP-7677 and OTP-7235</p> + <p> + This changes also involves some updates to public_keys + ssh-functions.</p> + <p> + Own Id: OTP-9911</p> + </item> + <item> + <p> + Added options for the ssh client to support user keys + files that are password protected.</p> + <p> + Own Id: OTP-10036 Aux Id: OTP-6400, Seq10595 </p> + </item> + </list> + </section> + +</section> + <section><title>Ssh 2.0.9</title> <section><title>Improvements and New Features</title> diff --git a/lib/ssh/examples/Makefile b/lib/ssh/examples/Makefile index 5f17542fb8..84c7edac8c 100644 --- a/lib/ssh/examples/Makefile +++ b/lib/ssh/examples/Makefile @@ -69,8 +69,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/ssh/src/Makefile b/lib/ssh/src/Makefile index 1734ae4df4..b8eecd3fa2 100644 --- a/lib/ssh/src/Makefile +++ b/lib/ssh/src/Makefile @@ -38,15 +38,17 @@ RELSYSDIR = $(RELEASE_PATH)/lib/ssh-$(VSN) # Behaviour (api) modules are first so they are compiled when # the compiler reaches a callback module using them. -MODULES= \ +BEHAVIOUR_MODULES= \ ssh_sftpd_file_api \ - ssh_key_api \ + ssh_channel \ + ssh_key_api + +MODULES= \ ssh \ ssh_sup \ sshc_sup \ sshd_sup \ ssh_connection_sup \ - ssh_channel \ ssh_connection \ ssh_connection_handler \ ssh_connection_manager \ @@ -73,11 +75,14 @@ MODULES= \ PUBLIC_HRL_FILES= ssh.hrl ssh_userauth.hrl ssh_xfer.hrl -ERL_FILES= $(MODULES:%=%.erl) +ERL_FILES= \ + $(MODULES:%=%.erl) \ + $(BEHAVIOUR_MODULES:%=%.erl) -ALL_MODULES= $(MODULES) -TARGET_FILES= $(ALL_MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) +TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR)) APP_FILE= ssh.app APPUP_FILE= ssh.appup @@ -93,29 +98,29 @@ INTERNAL_HRL_FILES = ssh_auth.hrl ssh_connect.hrl ssh_transport.hrl # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += -pa$(EBIN)\ - -pz $(ERL_TOP)/lib/public_key/ebin +EXTRA_ERLC_FLAGS = +warn_unused_vars +ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ + -pz $(EBIN) \ + -pz $(ERL_TOP)/lib/public_key/ebin \ + $(EXTRA_ERLC_FLAGS) + + # ---------------------------------------------------- # Targets # ---------------------------------------------------- -debug opt: $(TARGET_FILES) +$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES) -debug: ERLC_FLAGS += -Ddebug +debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: - rm -f $(TARGET_FILES) + rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) rm -f errs core *~ -$(TARGET_FILES): ssh.hrl - -# $(EBIN)/ssh_sftpd_file.$(EMULATOR): ERLC_FLAGS += -pa$(EBIN) -# $(EBIN)/ssh_sftpd_file.$(EMULATOR): $(EBIN)/ssh_sftpd_file_api.$(EMULATOR) - -$(APP_TARGET): $(APP_SRC) ../vsn.mk +$(APP_TARGET): $(APP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ -$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ @@ -127,12 +132,13 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(PUBLIC_HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) $(APP_TARGET) \ + $(APPUP_TARGET) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(PUBLIC_HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl index 39c7fe329e..f4a40c81a4 100644 --- a/lib/ssh/src/ssh.erl +++ b/lib/ssh/src/ssh.erl @@ -346,8 +346,9 @@ handle_option([{role, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{compression, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); -handle_option([{allow_user_interaction, _} = Opt | Rest], SocketOptions, SshOptions) -> - handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +%%Backwards compatibility +handle_option([{allow_user_interaction, Value} | Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option({user_interaction, Value}) | SshOptions]); handle_option([{infofun, _} = Opt | Rest],SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{connectfun, _} = Opt | Rest], SocketOptions, SshOptions) -> @@ -366,6 +367,8 @@ handle_option([{ssh_cli, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([{shell, _} = Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); +handle_option([{exec, _} = Opt | Rest], SocketOptions, SshOptions) -> + handle_option(Rest, SocketOptions, [handle_ssh_option(Opt) | SshOptions]); handle_option([Opt | Rest], SocketOptions, SshOptions) -> handle_option(Rest, [handle_inet_option(Opt) | SocketOptions], SshOptions). @@ -401,8 +404,9 @@ handle_ssh_option({key_cb, Value} = Opt) when is_atom(Value) -> Opt; handle_ssh_option({compression, Value} = Opt) when is_atom(Value) -> Opt; -handle_ssh_option({allow_user_interaction, Value} = Opt) when Value == true; - Value == false -> +handle_ssh_option({exec, {Module, Function, _}} = Opt) when is_atom(Module), + is_atom(Function) -> + Opt; handle_ssh_option({infofun, Value} = Opt) when is_function(Value) -> Opt; @@ -412,11 +416,12 @@ handle_ssh_option({disconnectfun , Value} = Opt) when is_function(Value) -> Opt; handle_ssh_option({failfun, Value} = Opt) when is_function(Value) -> Opt; -handle_ssh_option({ip_v6_disabled, Value} = Opt) when is_function(Value) -> +handle_ssh_option({ip_v6_disabled, Value} = Opt) when Value == true; + Value == false -> Opt; handle_ssh_option({transport, {Protocol, Cb, ClosTag}} = Opt) when is_atom(Protocol), - is_atom(Cb), - is_atom(ClosTag) -> + is_atom(Cb), + is_atom(ClosTag) -> Opt; handle_ssh_option({subsystems, Value} = Opt) when is_list(Value) -> Opt; @@ -495,4 +500,3 @@ verify_data(Data, Signature, Algorithm) when is_binary(Data), is_binary(Signatur Error -> Error end. - diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl index 1a4517c689..aa452a8e09 100644 --- a/lib/ssh/src/ssh_auth.erl +++ b/lib/ssh/src/ssh_auth.erl @@ -71,7 +71,7 @@ password_msg([#ssh{opts = Opts, io_cb = IoCb, ssh_bits:install_messages(userauth_passwd_messages()), Password = case proplists:get_value(password, Opts) of undefined -> - user_interaction(Opts, IoCb); + user_interaction(IoCb); PW -> PW end, @@ -89,13 +89,10 @@ password_msg([#ssh{opts = Opts, io_cb = IoCb, Ssh) end. -user_interaction(Opts, IoCb) -> - case proplists:get_value(allow_user_interaction, Opts, true) of - true -> - IoCb:read_password("ssh password: "); - false -> - not_ok - end. +user_interaction(ssh_no_io) -> + not_ok; +user_interaction(IoCb) -> + IoCb:read_password("ssh password: "). %% See RFC 4256 for info on keyboard-interactive @@ -124,8 +121,7 @@ init_userauth_request_msg(#ssh{opts = Opts} = Ssh) -> FirstAlg = algorithm(proplists:get_value(public_key_alg, Opts, ?PREFERRED_PK_ALG)), SecondAlg = other_alg(FirstAlg), - AllowUserInt = proplists:get_value(allow_user_interaction, Opts, - true), + AllowUserInt = proplists:get_value(user_interaction, Opts, true), Prefs = method_preference(FirstAlg, SecondAlg, AllowUserInt), ssh_transport:ssh_packet(Msg, Ssh#ssh{user = User, userauth_preference = Prefs, diff --git a/lib/ssh/src/ssh_channel.erl b/lib/ssh/src/ssh_channel.erl index 7b600ed8b2..1938858420 100644 --- a/lib/ssh/src/ssh_channel.erl +++ b/lib/ssh/src/ssh_channel.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -215,7 +215,7 @@ handle_info({ssh_cm, ConnectionManager, {closed, ChannelId}}, close_sent = false} = State) -> %% To be on the safe side, i.e. the manager has already been terminated. (catch ssh_connection:close(ConnectionManager, ChannelId)), - {stop, normal, State}; + {stop, normal, State#state{close_sent = true}}; handle_info({ssh_cm, _, _} = Msg, #state{cm = ConnectionManager, channel_cb = Module, diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index 46f0c7e688..c46f799b6d 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -720,12 +720,17 @@ handle_msg(#ssh_msg_channel_request{request_type = "env"}, handle_msg(#ssh_msg_channel_request{recipient_channel = ChannelId, request_type = _Other, - want_reply = WantReply}, Connection, + want_reply = WantReply}, #connection{channel_cache = Cache} = Connection, ConnectionPid, _) -> if WantReply == true -> - FailMsg = channel_failure_msg(ChannelId), - {{replies, [{connection_reply, ConnectionPid, FailMsg}]}, - Connection}; + case ssh_channel:cache_lookup(Cache, ChannelId) of + #channel{remote_id = RemoteId} -> + FailMsg = channel_failure_msg(RemoteId), + {{replies, [{connection_reply, ConnectionPid, FailMsg}]}, + Connection}; + undefined -> %% Chanel has been closed + {noreply, Connection} + end; true -> {noreply, Connection} end; diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl index e993f597a5..e53cd4f4f7 100644 --- a/lib/ssh/src/ssh_connection_manager.erl +++ b/lib/ssh/src/ssh_connection_manager.erl @@ -267,7 +267,7 @@ handle_call({ssh_msg, Pid, Msg}, From, disconnect_fun(Reason, SSHOpts), {stop, {shutdown, normal}, State#state{connection_state = Connection}} catch - _:Reason -> + _:Error -> {disconnect, Reason, {{replies, Replies}, Connection}} = ssh_connection:handle_msg( #ssh_msg_disconnect{code = ?SSH_DISCONNECT_BY_APPLICATION, @@ -277,7 +277,7 @@ handle_call({ssh_msg, Pid, Msg}, From, lists:foreach(fun send_msg/1, Replies), SSHOpts = proplists:get_value(ssh_opts, Opts), disconnect_fun(Reason, SSHOpts), - {stop, {shutdown, Reason}, State#state{connection_state = Connection}} + {stop, {shutdown, Error}, State#state{connection_state = Connection}} end; handle_call({global_request, Pid, _, _, _} = Request, From, @@ -384,9 +384,10 @@ handle_call({close, ChannelId}, _, #state{connection = Pid, connection_state = #connection{channel_cache = Cache}} = State) -> case ssh_channel:cache_lookup(Cache, ChannelId) of - #channel{remote_id = Id} -> + #channel{remote_id = Id} = Channel -> send_msg({connection_reply, Pid, ssh_connection:channel_close_msg(Id)}), + ssh_channel:cache_update(Cache, Channel#channel{sent_close = true}), {reply, ok, State}; undefined -> {reply, ok, State} @@ -585,7 +586,7 @@ call(Pid, Msg, Timeout) -> catch exit:{timeout, _} -> {error, timeout}; - exit:{normal} -> + exit:{normal, _} -> {error, channel_closed}; exit:{{shutdown, _}, _} -> {error, channel_closed}; diff --git a/lib/ssh/test/Makefile b/lib/ssh/test/Makefile index 145d5d2ad6..25072688ad 100644 --- a/lib/ssh/test/Makefile +++ b/lib/ssh/test/Makefile @@ -110,11 +110,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) ssh.spec ssh.cover $(RELSYSDIR) - $(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) ssh.spec ssh.cover "$(RELSYSDIR)" + $(INSTALL_DATA) $(HRL_FILES_NEEDED_IN_TEST) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/ssh/test/ssh_basic_SUITE.erl b/lib/ssh/test/ssh_basic_SUITE.erl index d66214d415..c5019425cd 100644 --- a/lib/ssh/test/ssh_basic_SUITE.erl +++ b/lib/ssh/test/ssh_basic_SUITE.erl @@ -183,7 +183,29 @@ app_test(doc) -> app_test(Config) when is_list(Config) -> ?t:app_test(ssh), ok. +%%-------------------------------------------------------------------- +misc_ssh_options(doc) -> + ["Test that we can set some misc options not tested elsewhere, " + "some options not yet present are not decided if we should support or " + "if they need thier own test case."]; +misc_ssh_options(suite) -> + []; +misc_ssh_options(Config) when is_list(Config) -> + SystemDir = filename:join(?config(priv_dir, Config), system), + UserDir = ?config(priv_dir, Config), + + CMiscOpt0 = [{connecect_timeout, 1000}, {ip_v6_disable, false}, {user_dir, UserDir}], + CMiscOpt1 = [{connecect_timeout, infinity}, {ip_v6_disable, true}, {user_dir, UserDir}], + SMiscOpt0 = [{ip_v6_disable, false}, {user_dir, UserDir}, {system_dir, SystemDir}], + SMiscOpt1 = [{ip_v6_disable, true}, {user_dir, UserDir}, {system_dir, SystemDir}], + + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + basic_test([{client_opts, CMiscOpt0 ++ ClientOpts}, {server_opts, SMiscOpt0 ++ ServerOpts}]), + basic_test([{client_opts, CMiscOpt1 ++ ClientOpts}, {server_opts, SMiscOpt1 ++ ServerOpts}]). +%%-------------------------------------------------------------------- exec(doc) -> ["Test api function ssh_connection:exec"]; @@ -500,13 +522,14 @@ internal_error(Config) when is_list(Config) -> SystemDir = filename:join(?config(priv_dir, Config), system), UserDir = ?config(priv_dir, Config), - {_Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, + {Pid, Host, Port} = ssh_test_lib:daemon([{system_dir, SystemDir}, {user_dir, UserDir}, {failfun, fun ssh_test_lib:failfun/2}]), {error,"Internal error"} = ssh:connect(Host, Port, [{silently_accept_hosts, true}, {user_dir, UserDir}, - {user_interaction, false}]). + {user_interaction, false}]), + ssh:stop_daemon(Pid). %%-------------------------------------------------------------------- close(doc) -> @@ -539,3 +562,12 @@ close(Config) when is_list(Config) -> %%-------------------------------------------------------------------- %% Internal functions %%-------------------------------------------------------------------- + +basic_test(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {Pid, Host, Port} = ssh_test_lib:daemon(ServerOpts), + {ok, CM} = ssh:connect(Host, Port, ClientOpts), + ok = ssh:close(CM), + ssh:stop_daemon(Pid). diff --git a/lib/ssl/doc/src/Makefile b/lib/ssl/doc/src/Makefile index 5d808d6727..8736913c72 100644 --- a/lib/ssl/doc/src/Makefile +++ b/lib/ssl/doc/src/Makefile @@ -117,15 +117,15 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index 1e1fe0d119..a4da939d3e 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -30,7 +30,53 @@ </header> <p>This document describes the changes made to the SSL application.</p> - <section><title>SSL 5.0</title> + <section><title>SSL 5.0.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Robustness and improvement to distribution over SSL</p> + <p> + Fix a bug where ssl_tls_dist_proxy would crash at caller + timeout. Fix a bug where a timeout from the SSL layer + would block the distribution indefinately. Run the proxy + exclusively on the loopback interface. (Thanks to Paul + Guyot)</p> + <p> + Own Id: OTP-9915</p> + </item> + <item> + <p> + Fix setup loop of SSL TLS dist proxy</p> + <p> + Fix potential leak of processes waiting indefinately for + data from closed sockets during socket setup phase. + (Thanks to Paul Guyot)</p> + <p> + Own Id: OTP-9916</p> + </item> + <item> + <p> + Correct spelling of registered (Thanks to Richard + Carlsson)</p> + <p> + Own Id: OTP-9925</p> + </item> + <item> + <p> + Added TLS PRF function to the SSL API for generation of + additional key material from a TLS session. (Thanks to + Andreas Schultz)</p> + <p> + Own Id: OTP-10024</p> + </item> + </list> + </section> + +</section> + +<section><title>SSL 5.0</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 e019654685..28bf82b406 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -193,13 +193,13 @@ </item> <tag>{depth, integer()}</tag> - <item>Specifies the maximum - verification depth, i.e. how far in a chain of certificates the - verification process can proceed before the verification is - considered to fail. Peer certificate = 0, CA certificate = 1, - higher level CA certificate = 2, etc. The value 2 thus means - that a chain can at most contain peer cert, CA cert, next CA - cert, and an additional CA cert. The default value is 1. + <item> + The depth is the maximum number of non-self-issued + intermediate certificates that may follow the peer certificate + in a valid certification path. So if depth is 0 the PEER must + be signed by the trusted ROOT-CA directly, if 1 the path can + be PEER, CA, ROOT-CA, if it is 2 PEER, CA, CA, ROOT-CA and so + on. The default value is 1. </item> <tag>{verify_fun, {Verifyfun :: fun(), InitialUserState :: term()}}</tag> diff --git a/lib/ssl/examples/certs/Makefile b/lib/ssl/examples/certs/Makefile index a4f067ade6..549f11d709 100644 --- a/lib/ssl/examples/certs/Makefile +++ b/lib/ssl/examples/certs/Makefile @@ -54,8 +54,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/certs + $(INSTALL_DIR) "$(RELSYSDIR)/examples/certs" tar cf - etc | \ - (cd $(RELSYSDIR)/examples/certs; tar xf -) - chmod -R ug+rw $(RELSYSDIR)/examples + (cd "$(RELSYSDIR)/examples/certs"; tar xf -) + chmod -R ug+rw "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/ssl/examples/src/Makefile b/lib/ssl/examples/src/Makefile index c5f31b689c..420634c97e 100644 --- a/lib/ssl/examples/src/Makefile +++ b/lib/ssl/examples/src/Makefile @@ -63,10 +63,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples/src - $(INSTALL_DIR) $(RELSYSDIR)/examples/ebin - (cd ..; tar cf - src ebin | (cd $(RELSYSDIR)/examples; tar xf -)) - chmod -R ug+w $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples/src" + $(INSTALL_DIR) "$(RELSYSDIR)/examples/ebin" + (cd ..; tar cf - src ebin | (cd "$(RELSYSDIR)/examples"; tar xf -)) + chmod -R ug+w "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/ssl/src/Makefile b/lib/ssl/src/Makefile index dc69b53b28..a08444b8dd 100644 --- a/lib/ssl/src/Makefile +++ b/lib/ssl/src/Makefile @@ -37,6 +37,9 @@ RELSYSDIR = $(RELEASE_PATH)/lib/ssl-$(VSN) # Common Macros # ---------------------------------------------------- +BEHAVIOUR_MODULES= \ + ssl_session_cache_api + MODULES= \ ssl \ ssl_alert \ @@ -53,7 +56,6 @@ MODULES= \ ssl_handshake \ ssl_manager \ ssl_session \ - ssl_session_cache_api \ ssl_session_cache \ ssl_record \ ssl_ssl2 \ @@ -66,10 +68,15 @@ INTERNAL_HRL_FILES = \ ssl_alert.hrl ssl_cipher.hrl ssl_handshake.hrl ssl_internal.hrl \ ssl_record.hrl -ERL_FILES= $(MODULES:%=%.erl) +ERL_FILES= \ + $(MODULES:%=%.erl) \ + $(BEHAVIOUR_MODULES:%=%.erl) + TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +BEHAVIOUR_TARGET_FILES= $(BEHAVIOUR_MODULES:%=$(EBIN)/%.$(EMULATOR)) + APP_FILE= ssl.app APPUP_FILE= ssl.appup @@ -83,6 +90,7 @@ APPUP_TARGET= $(EBIN)/$(APPUP_FILE) # ---------------------------------------------------- EXTRA_ERLC_FLAGS = +warn_unused_vars ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ + -pz $(EBIN) \ -pz $(ERL_TOP)/lib/public_key/ebin \ $(EXTRA_ERLC_FLAGS) -DVSN=\"$(VSN)\" @@ -91,6 +99,8 @@ ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/kernel/src \ # Targets # ---------------------------------------------------- +$(TARGET_FILES): $(BEHAVIOUR_TARGET_FILES) + debug opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) clean: @@ -105,23 +115,18 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk docs: + # ---------------------------------------------------- # Release Target # ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) \ - $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(BEHAVIOUR_TARGET_FILES) $(TARGET_FILES) $(APP_TARGET) \ + $(APPUP_TARGET) "$(RELSYSDIR)/ebin" release_docs_spec: - - - - - - diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index 0bcdffbeff..5e3ced144a 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -30,7 +30,7 @@ controlling_process/2, listen/2, pid/1, peername/1, peercert/1, recv/2, recv/3, send/2, getopts/2, setopts/2, sockname/1, versions/0, session_info/1, format_error/1, - renegotiate/1, prf/5]). + renegotiate/1, prf/5, clear_pem_cache/0]). -deprecated({pid, 1, next_major_release}). @@ -431,6 +431,15 @@ prf(#sslsocket{pid = Pid, fd = new_ssl}, Secret, Label, Seed, WantedLength) -> ssl_connection:prf(Pid, Secret, Label, Seed, WantedLength). + +%%-------------------------------------------------------------------- +-spec clear_pem_cache() -> ok. +%% +%% Description: Clear the PEM cache +%%-------------------------------------------------------------------- +clear_pem_cache() -> + ssl_manager:clear_pem_cache(). + %%--------------------------------------------------------------- -spec format_error({error, term()}) -> list(). %% @@ -532,7 +541,7 @@ handle_options(Opts0, _Role) -> throw({error, {eoptions, {verify, Value}}}) end, - CertFile = handle_option(certfile, Opts, ""), + CertFile = handle_option(certfile, Opts, <<>>), SSLOptions = #ssl_options{ versions = handle_option(versions, Opts, []), @@ -619,8 +628,12 @@ validate_option(depth, Value) when is_integer(Value), validate_option(cert, Value) when Value == undefined; is_binary(Value) -> Value; -validate_option(certfile, Value) when Value == undefined; is_list(Value) -> +validate_option(certfile, undefined = Value) -> Value; +validate_option(certfile, Value) when is_binary(Value) -> + Value; +validate_option(certfile, Value) when is_list(Value) -> + list_to_binary(Value); validate_option(key, undefined) -> undefined; @@ -631,8 +644,13 @@ validate_option(key, {KeyType, Value}) when is_binary(Value), KeyType == 'DSAPrivateKey'; KeyType == 'PrivateKeyInfo' -> {KeyType, Value}; -validate_option(keyfile, Value) when is_list(Value) -> + +validate_option(keyfile, undefined) -> + <<>>; +validate_option(keyfile, Value) when is_binary(Value) -> Value; +validate_option(keyfile, Value) when is_list(Value), Value =/= "" -> + list_to_binary(Value); validate_option(password, Value) when is_list(Value) -> Value; @@ -642,16 +660,20 @@ validate_option(cacerts, Value) when Value == undefined; %% certfile must be present in some cases otherwhise it can be set %% to the empty string. validate_option(cacertfile, undefined) -> - ""; -validate_option(cacertfile, Value) when is_list(Value), Value =/= "" -> + <<>>; +validate_option(cacertfile, Value) when is_binary(Value) -> Value; +validate_option(cacertfile, Value) when is_list(Value), Value =/= ""-> + list_to_binary(Value); validate_option(dh, Value) when Value == undefined; is_binary(Value) -> Value; validate_option(dhfile, undefined = Value) -> Value; -validate_option(dhfile, Value) when is_list(Value), Value =/= "" -> +validate_option(dhfile, Value) when is_binary(Value) -> Value; +validate_option(dhfile, Value) when is_list(Value), Value =/= "" -> + list_to_binary(Value); validate_option(ciphers, Value) when is_list(Value) -> Version = ssl_record:highest_protocol_version([]), try cipher_suites(Version, Value) diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl index cb2473576a..01ddf056c9 100644 --- a/lib/ssl/src/ssl_certificate_db.erl +++ b/lib/ssl/src/ssl_certificate_db.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. 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,12 +24,13 @@ -module(ssl_certificate_db). -include("ssl_internal.hrl"). -include_lib("public_key/include/public_key.hrl"). +-include_lib("kernel/include/file.hrl"). -export([create/0, remove/1, add_trusted_certs/3, - remove_trusted_certs/2, lookup_trusted_cert/4, foldl/3, - lookup_cached_certs/2, cache_pem_file/4, uncache_pem_file/2, lookup/2]). - --type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}. + remove_trusted_certs/2, insert/3, remove/2, clear/1, db_size/1, + ref_count/3, lookup_trusted_cert/4, foldl/3, + lookup_cached_pem/2, cache_pem_file/2, cache_pem_file/3, + lookup/2]). %%==================================================================== %% Internal application API @@ -43,9 +44,14 @@ %% the process that called create may call the other functions. %%-------------------------------------------------------------------- create() -> - [ets:new(ssl_otp_certificate_db, [set, protected]), - ets:new(ssl_file_to_ref, [set, protected]), - ets:new(ssl_pid_to_file, [bag, private])]. + [%% Let connection process delete trusted certs + %% that can only belong to one connection. (Supplied directly + %% on DER format to ssl:connect/listen.) + ets:new(ssl_otp_cacertificate_db, [set, public]), + %% Let connection processes call ref_count/3 directly + ets:new(ssl_otp_ca_file_ref, [set, public]), + ets:new(ssl_otp_pem_cache, [set, protected]) + ]. %%-------------------------------------------------------------------- -spec remove([db_handle()]) -> term(). @@ -53,7 +59,9 @@ create() -> %% Description: Removes database db %%-------------------------------------------------------------------- remove(Dbs) -> - lists:foreach(fun(Db) -> true = ets:delete(Db) end, Dbs). + lists:foreach(fun(Db) -> + true = ets:delete(Db) + end, Dbs). %%-------------------------------------------------------------------- -spec lookup_trusted_cert(db_handle(), certdb_ref(), serialnumber(), issuer()) -> @@ -72,11 +80,14 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) -> {ok, Certs} end. -lookup_cached_certs(DbHandle, File) -> - ets:lookup(DbHandle, {file, File}). +lookup_cached_pem([_, _, PemChache], MD5) -> + lookup_cached_pem(PemChache, MD5); +lookup_cached_pem(PemChache, MD5) -> + lookup(MD5, PemChache). %%-------------------------------------------------------------------- --spec add_trusted_certs(pid(), string() | {der, list()}, [db_handle()]) -> {ok, [db_handle()]}. +-spec add_trusted_certs(pid(), {erlang:timestamp(), string()} | + {der, list()}, [db_handle()]) -> {ok, [db_handle()]}. %% %% Description: Adds the trusted certificates from file <File> to the %% runtime database. Returns Ref that should be handed to lookup_trusted_cert @@ -86,82 +97,55 @@ add_trusted_certs(_Pid, {der, DerList}, [CerDb, _,_]) -> NewRef = make_ref(), add_certs_from_der(DerList, NewRef, CerDb), {ok, NewRef}; -add_trusted_certs(Pid, File, [CertsDb, FileToRefDb, PidToFileDb]) -> - Ref = case lookup(File, FileToRefDb) of - undefined -> - NewRef = make_ref(), - add_certs_from_file(File, NewRef, CertsDb), - insert(File, NewRef, 1, FileToRefDb), - NewRef; - [OldRef] -> - ref_count(File,FileToRefDb,1), - OldRef - end, - insert(Pid, File, PidToFileDb), - {ok, Ref}. + +add_trusted_certs(_Pid, File, [CertsDb, RefDb, PemChache] = Db) -> + MD5 = crypto:md5(File), + case lookup_cached_pem(Db, MD5) of + [{_Content, Ref}] -> + ref_count(Ref, RefDb, 1), + {ok, Ref}; + [Content] -> + Ref = make_ref(), + insert(Ref, [], 1, RefDb), + insert(MD5, {Content, Ref}, PemChache), + add_certs_from_pem(Content, Ref, CertsDb), + {ok, Ref}; + undefined -> + new_trusted_cert_entry({MD5, File}, Db) + end. %%-------------------------------------------------------------------- --spec cache_pem_file(pid(), string(), time(), [db_handle()]) -> term(). +-spec cache_pem_file(string(), [db_handle()]) -> term(). +-spec cache_pem_file(reference(), string(), [db_handle()]) -> term(). %% %% Description: Cache file as binary in DB %%-------------------------------------------------------------------- -cache_pem_file(Pid, File, Time, [CertsDb, _FileToRefDb, PidToFileDb]) -> - {ok, PemBin} = file:read_file(File), +cache_pem_file({MD5, File}, [_CertsDb, _RefDb, PemChache]) -> + {ok, PemBin} = file:read_file(File), Content = public_key:pem_decode(PemBin), - insert({file, File}, {Time, Content}, CertsDb), - insert(Pid, File, PidToFileDb), + insert(MD5, Content, PemChache), {ok, Content}. -%-------------------------------------------------------------------- --spec uncache_pem_file(string(), [db_handle()]) -> no_return(). -%% -%% Description: If a cached file is no longer valid (changed on disk) -%% we must terminate the connections using the old file content, and -%% when those processes are finish the cache will be cleaned. It is -%% a rare but possible case a new ssl client/server is started with -%% a filename with the same name as previously started client/server -%% but with different content. -%% -------------------------------------------------------------------- -uncache_pem_file(File, [_CertsDb, _FileToRefDb, PidToFileDb]) -> - Pids = select(PidToFileDb, [{{'$1', File},[],['$$']}]), - lists:foreach(fun([Pid]) -> - exit(Pid, shutdown) - end, Pids). - -%%-------------------------------------------------------------------- --spec remove_trusted_certs(pid(), [db_handle()]) -> term(). - -%% -%% Description: Removes trusted certs originating from -%% the file associated to Pid from the runtime database. -%%-------------------------------------------------------------------- -remove_trusted_certs(Pid, [CertsDb, FileToRefDb, PidToFileDb]) -> - Files = lookup(Pid, PidToFileDb), - delete(Pid, PidToFileDb), - Clear = fun(File) -> - delete({file,File}, CertsDb), - try - 0 = ref_count(File, FileToRefDb, -1), - case lookup(File, FileToRefDb) of - [Ref] when is_reference(Ref) -> - remove_certs(Ref, CertsDb); - _ -> ok - end, - delete(File, FileToRefDb) - catch _:_ -> - ok - end - end, - case Files of - undefined -> ok; - _ -> - [Clear(File) || File <- Files], - ok - end. +cache_pem_file(Ref, {MD5, File}, [_CertsDb, _RefDb, PemChache]) -> + {ok, PemBin} = file:read_file(File), + Content = public_key:pem_decode(PemBin), + insert(MD5, {Content, Ref}, PemChache), + {ok, Content}. + +remove_trusted_certs(Ref, CertsDb) -> + remove_certs(Ref, CertsDb). + +%%-------------------------------------------------------------------- +-spec remove(term(), db_handle()) -> term(). +%% +%% Description: Removes an element in a <Db>. +%%-------------------------------------------------------------------- +remove(Key, Db) -> + _ = ets:delete(Db, Key). %%-------------------------------------------------------------------- -spec lookup(term(), db_handle()) -> term() | undefined. %% -%% Description: Looks up an element in a certificat <Db>. +%% Description: Looks up an element in a <Db>. %%-------------------------------------------------------------------- lookup(Key, Db) -> case ets:lookup(Db, Key) of @@ -184,25 +168,47 @@ lookup(Key, Db) -> %%-------------------------------------------------------------------- foldl(Fun, Acc0, Cache) -> ets:foldl(Fun, Acc0, Cache). - + %%-------------------------------------------------------------------- -%%% Internal functions +-spec ref_count(term(), db_handle(), integer()) -> integer(). +%% +%% Description: Updates a reference counter in a <Db>. +%%-------------------------------------------------------------------- +ref_count(Key, Db, N) -> + ets:update_counter(Db,Key,N). + +%%-------------------------------------------------------------------- +-spec clear(db_handle()) -> term(). +%% +%% Description: Clears the cache +%%-------------------------------------------------------------------- +clear(Db) -> + ets:delete_all_objects(Db). + +%%-------------------------------------------------------------------- +-spec db_size(db_handle()) -> integer(). +%% +%% Description: Returns the size of the db +%%-------------------------------------------------------------------- +db_size(Db) -> + ets:info(Db, size). + +%%-------------------------------------------------------------------- +%%-spec insert(Key::term(), Data::term(), Db::db_handle()) -> no_return(). +%% +%% Description: Inserts data into <Db> %%-------------------------------------------------------------------- insert(Key, Data, Db) -> true = ets:insert(Db, {Key, Data}). +%%-------------------------------------------------------------------- +%%% Internal functions +%%-------------------------------------------------------------------- +insert(Key, [], Count, Db) -> + true = ets:insert(Db, {Key, Count}); insert(Key, Data, Count, Db) -> true = ets:insert(Db, {Key, Count, Data}). -ref_count(Key, Db,N) -> - ets:update_counter(Db,Key,N). - -delete(Key, Db) -> - _ = ets:delete(Db, Key). - -select(Db, MatchSpec)-> - ets:select(Db, MatchSpec). - remove_certs(Ref, CertsDb) -> ets:match_delete(CertsDb, {{Ref, '_', '_'}, '_'}). @@ -210,10 +216,8 @@ add_certs_from_der(DerList, Ref, CertsDb) -> Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, [Add(Cert) || Cert <- DerList]. -add_certs_from_file(File, Ref, CertsDb) -> +add_certs_from_pem(PemEntries, Ref, CertsDb) -> Add = fun(Cert) -> add_certs(Cert, Ref, CertsDb) end, - {ok, PemBin} = file:read_file(File), - PemEntries = public_key:pem_decode(PemBin), [Add(Cert) || {'Certificate', Cert, not_encrypted} <- PemEntries]. add_certs(Cert, Ref, CertsDb) -> @@ -229,3 +233,10 @@ add_certs(Cert, Ref, CertsDb) -> "it could not be correctly decoded.~n", []), error_logger:info_report(Report) end. + +new_trusted_cert_entry(FileRef, [CertsDb, RefDb, _] = Db) -> + Ref = make_ref(), + insert(Ref, [], 1, RefDb), + {ok, Content} = cache_pem_file(Ref, FileRef, Db), + add_certs_from_pem(Content, Ref, CertsDb), + {ok, Ref}. diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 6c06baff98..c57930e821 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -47,8 +47,8 @@ -export([start_link/7]). %% gen_fsm callbacks --export([init/1, hello/2, certify/2, cipher/2, connection/2, - abbreviated/2, handle_event/3, +-export([init/1, hello/2, certify/2, cipher/2, + abbreviated/2, connection/2, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -record(state, { @@ -83,13 +83,13 @@ diffie_hellman_params, % PKIX: #'DHParameter'{} relevant for server side diffie_hellman_keys, % {PublicKey, PrivateKey} premaster_secret, % - cert_db_ref, % ets_table() - from, % term(), where to reply + file_ref_db, % ets() + cert_db_ref, % ref() bytes_to_read, % integer(), # bytes to read in passive mode user_data_buffer, % binary() log_alert, % boolean() renegotiation, % {boolean(), From | internal | peer} - recv_from, % + start_or_recv_from, % "gen_fsm From" send_queue, % queue() terminated = false, % allow_renegotiate = true @@ -297,39 +297,30 @@ prf(ConnectionPid, Secret, Label, Seed, WantedLength) -> %% does not return until Module:init/1 has returned. %%-------------------------------------------------------------------- start_link(Role, Host, Port, Socket, Options, User, CbInfo) -> - gen_fsm:start_link(?MODULE, [Role, Host, Port, Socket, Options, - User, CbInfo], []). + {ok, proc_lib:spawn_link(?MODULE, init, [[Role, Host, Port, Socket, Options, User, CbInfo]])}. -%%==================================================================== -%% gen_fsm callbacks -%%==================================================================== -%%-------------------------------------------------------------------- -%% Description:Whenever a gen_fsm is started using gen_fsm:start/[3,4] or -%% gen_fsm:start_link/3,4, this function is called by the new process to -%% initialize. -%%-------------------------------------------------------------------- -init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, - User, CbInfo]) -> +init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, User, CbInfo]) -> State0 = initial_state(Role, Host, Port, Socket, Options, User, CbInfo), Hashes0 = ssl_handshake:init_hashes(), TimeStamp = calendar:datetime_to_gregorian_seconds({date(), time()}), try ssl_init(SSLOpts0, Role) of - {ok, Ref, CertDbHandle, CacheHandle, OwnCert, Key, DHParams} -> + {ok, Ref, CertDbHandle, FileRefHandle, CacheHandle, OwnCert, Key, DHParams} -> Session = State0#state.session, State = State0#state{tls_handshake_hashes = Hashes0, session = Session#session{own_certificate = OwnCert, time_stamp = TimeStamp}, + file_ref_db = FileRefHandle, cert_db_ref = Ref, cert_db = CertDbHandle, session_cache = CacheHandle, private_key = Key, diffie_hellman_params = DHParams}, - {ok, hello, State, get_timeout(State)} - catch + gen_fsm:enter_loop(?MODULE, [], hello, State, get_timeout(State)) + catch throw:Error -> - {stop, Error} + gen_fsm:enter_loop(?MODULE, [], error, {Error,State0}, get_timeout(State0)) end. - + %%-------------------------------------------------------------------- %% Description:There should be one instance of this function for each %% possible state name. Whenever a gen_fsm receives an event sent @@ -337,6 +328,7 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, %% same name as the current state name StateName is called to handle %% the event. It is also called if a timeout occurs. %% + %%-------------------------------------------------------------------- -spec hello(start | #hello_request{} | #client_hello{} | #server_hello{} | term(), #state{}) -> gen_fsm_state_return(). @@ -344,23 +336,23 @@ init([Role, Host, Port, Socket, {SSLOpts0, _} = Options, hello(start, #state{host = Host, port = Port, role = client, ssl_options = SslOpts, session = #session{own_certificate = Cert} = Session0, + session_cache = Cache, session_cache_cb = CacheCb, transport_cb = Transport, socket = Socket, - connection_states = ConnectionStates, + connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}} = State0) -> - Hello = ssl_handshake:client_hello(Host, Port, - ConnectionStates, - SslOpts, Renegotiation, Cert), + Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts, + Cache, CacheCb, Renegotiation, Cert), Version = Hello#client_hello.client_version, Hashes0 = ssl_handshake:init_hashes(), - {BinMsg, CS2, Hashes1} = - encode_handshake(Hello, Version, ConnectionStates, Hashes0), + {BinMsg, ConnectionStates, Hashes} = + encode_handshake(Hello, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), - State1 = State0#state{connection_states = CS2, - negotiated_version = Version, %% Requested version + State1 = State0#state{connection_states = ConnectionStates, + negotiated_version = Version, %% Requested version at this point session = Session0#session{session_id = Hello#client_hello.session_id}, - tls_handshake_hashes = Hashes1}, + tls_handshake_hashes = Hashes}, {Record, State} = next_record(State1), next_state(hello, hello, Record, State); @@ -394,7 +386,8 @@ hello(#server_hello{cipher_suite = CipherSuite, case ssl_session:is_new(OldId, NewId) of true -> - handle_new_session(NewId, CipherSuite, Compression, State); + handle_new_session(NewId, CipherSuite, Compression, + State#state{connection_states = ConnectionStates}); false -> handle_resumed_session(NewId, State#state{connection_states = ConnectionStates}) end; @@ -552,8 +545,8 @@ certify(#server_hello_done{}, role = client} = State0) -> case ssl_handshake:master_secret(Version, Session, ConnectionStates0, client) of - {MasterSecret, ConnectionStates1} -> - State = State0#state{connection_states = ConnectionStates1}, + {MasterSecret, ConnectionStates} -> + State = State0#state{connection_states = ConnectionStates}, client_certify_and_key_exchange(State); #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State0), @@ -569,10 +562,10 @@ certify(#server_hello_done{}, role = client} = State0) -> case ssl_handshake:master_secret(Version, PremasterSecret, ConnectionStates0, client) of - {MasterSecret, ConnectionStates1} -> + {MasterSecret, ConnectionStates} -> Session = Session0#session{master_secret = MasterSecret}, - State = State0#state{connection_states = ConnectionStates1, - session = Session}, + State = State0#state{connection_states = ConnectionStates, + session = Session}, client_certify_and_key_exchange(State); #alert{} = Alert -> handle_own_alert(Alert, Version, certify, State0), @@ -691,22 +684,24 @@ cipher(Msg, State) -> %%-------------------------------------------------------------------- connection(#hello_request{}, #state{host = Host, port = Port, socket = Socket, - session = #session{own_certificate = Cert}, + session = #session{own_certificate = Cert} = Session0, + session_cache = Cache, session_cache_cb = CacheCb, ssl_options = SslOpts, negotiated_version = Version, transport_cb = Transport, connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}, tls_handshake_hashes = Hashes0} = State0) -> - Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, - SslOpts, Renegotiation, Cert), + Hello = ssl_handshake:client_hello(Host, Port, ConnectionStates0, SslOpts, + Cache, CacheCb, Renegotiation, Cert), - {BinMsg, ConnectionStates1, Hashes1} = + {BinMsg, ConnectionStates, Hashes} = encode_handshake(Hello, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), {Record, State} = next_record(State0#state{connection_states = - ConnectionStates1, - tls_handshake_hashes = Hashes1}), + ConnectionStates, + session = Session0#session{session_id = Hello#client_hello.session_id}, + tls_handshake_hashes = Hashes}), next_state(connection, hello, Record, State); connection(#client_hello{} = Hello, #state{role = server, allow_renegotiate = true} = State) -> %% Mitigate Computational DoS attack @@ -732,6 +727,7 @@ connection(timeout, State) -> connection(Msg, State) -> handle_unexpected_message(Msg, connection, State). + %%-------------------------------------------------------------------- %% Description: Whenever a gen_fsm receives an event sent using %% gen_fsm:send_all_state_event/2, this function is called to handle @@ -761,8 +757,8 @@ handle_sync_event({application_data, Data}, From, StateName, State#state{send_queue = queue:in({From, Data}, Queue)}, get_timeout(State)}; -handle_sync_event(start, From, hello, State) -> - hello(start, State#state{from = From}); +handle_sync_event(start, StartFrom, hello, State) -> + hello(start, State#state{start_or_recv_from = StartFrom}); %% The two clauses below could happen if a server upgrades a socket in %% active mode. Note that in this case we are lucky that @@ -774,8 +770,10 @@ handle_sync_event(start, From, hello, State) -> %% they upgrade a active socket. handle_sync_event(start, _, connection, State) -> {reply, connected, connection, State, get_timeout(State)}; -handle_sync_event(start, From, StateName, State) -> - {next_state, StateName, State#state{from = From}, get_timeout(State)}; +handle_sync_event(start, _From, error, {Error, State = #state{}}) -> + {stop, {shutdown, Error}, {error, Error}, State}; +handle_sync_event(start, StartFrom, StateName, State) -> + {next_state, StateName, State#state{start_or_recv_from = StartFrom}, get_timeout(State)}; handle_sync_event(close, _, StateName, State) -> %% Run terminate before returning @@ -806,13 +804,13 @@ handle_sync_event({shutdown, How0}, _, StateName, {stop, normal, Error, State} end; -handle_sync_event({recv, N}, From, connection = StateName, State0) -> - passive_receive(State0#state{bytes_to_read = N, recv_from = From}, StateName); +handle_sync_event({recv, N}, RecvFrom, connection = StateName, State0) -> + passive_receive(State0#state{bytes_to_read = N, start_or_recv_from = RecvFrom}, StateName); %% Doing renegotiate wait with handling request until renegotiate is %% finished. Will be handled by next_state_is_connection/2. -handle_sync_event({recv, N}, From, StateName, State) -> - {next_state, StateName, State#state{bytes_to_read = N, recv_from = From}, +handle_sync_event({recv, N}, RecvFrom, StateName, State) -> + {next_state, StateName, State#state{bytes_to_read = N, start_or_recv_from = RecvFrom}, get_timeout(State)}; handle_sync_event({new_user, User}, _From, StateName, @@ -963,9 +961,9 @@ handle_info({CloseTag, Socket}, StateName, {stop, normal, State}; handle_info({ErrorTag, Socket, econnaborted}, StateName, - #state{socket = Socket, from = User, role = Role, + #state{socket = Socket, start_or_recv_from = StartFrom, role = Role, error_tag = ErrorTag} = State) when StateName =/= connection -> - alert_user(User, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role), + alert_user(StartFrom, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role), {stop, normal, State}; handle_info({ErrorTag, Socket, Reason}, StateName, #state{socket = Socket, @@ -1002,16 +1000,19 @@ terminate(Reason, connection, #state{negotiated_version = Version, connection_states = ConnectionStates, transport_cb = Transport, socket = Socket, send_queue = SendQueue, - renegotiation = Renegotiate}) -> + renegotiation = Renegotiate} = State) -> + handle_trusted_certs_db(State), notify_senders(SendQueue), notify_renegotiater(Renegotiate), BinAlert = terminate_alert(Reason, Version, ConnectionStates), Transport:send(Socket, BinAlert), workaround_transport_delivery_problems(Socket, Transport, Reason), Transport:close(Socket); + terminate(Reason, _StateName, #state{transport_cb = Transport, socket = Socket, send_queue = SendQueue, - renegotiation = Renegotiate}) -> + renegotiation = Renegotiate} = State) -> + handle_trusted_certs_db(State), notify_senders(SendQueue), notify_renegotiater(Renegotiate), workaround_transport_delivery_problems(Socket, Transport, Reason), @@ -1059,12 +1060,12 @@ ssl_init(SslOpts, Role) -> init_manager_name(SslOpts#ssl_options.erl_dist), - {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert} = init_certificates(SslOpts, Role), + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, OwnCert} = init_certificates(SslOpts, Role), PrivateKey = - init_private_key(CertDbHandle, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile, + init_private_key(PemCacheHandle, SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile, SslOpts#ssl_options.password, Role), - DHParams = init_diffie_hellman(CertDbHandle, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role), - {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert, PrivateKey, DHParams}. + DHParams = init_diffie_hellman(PemCacheHandle, SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role), + {ok, CertDbRef, CertDbHandle, FileRefHandle, CacheHandle, OwnCert, PrivateKey, DHParams}. init_manager_name(false) -> put(ssl_manager, ssl_manager); @@ -1075,7 +1076,7 @@ init_certificates(#ssl_options{cacerts = CaCerts, cacertfile = CACertFile, certfile = CertFile, cert = Cert}, Role) -> - {ok, CertDbRef, CertDbHandle, CacheHandle} = + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle} = try Certs = case CaCerts of undefined -> @@ -1083,38 +1084,38 @@ init_certificates(#ssl_options{cacerts = CaCerts, _ -> {der, CaCerts} end, - {ok, _, _, _} = ssl_manager:connection_init(Certs, Role) + {ok, _, _, _, _, _} = ssl_manager:connection_init(Certs, Role) catch Error:Reason -> handle_file_error(?LINE, Error, Reason, CACertFile, ecacertfile, erlang:get_stacktrace()) end, - init_certificates(Cert, CertDbRef, CertDbHandle, CacheHandle, CertFile, Role). + init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CertFile, Role). -init_certificates(undefined, CertDbRef, CertDbHandle, CacheHandle, "", _) -> - {ok, CertDbRef, CertDbHandle, CacheHandle, undefined}; +init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, <<>>, _) -> + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, undefined}; -init_certificates(undefined, CertDbRef, CertDbHandle, CacheHandle, CertFile, client) -> +init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, CertFile, client) -> try - [OwnCert] = ssl_certificate:file_to_certificats(CertFile, CertDbHandle), - {ok, CertDbRef, CertDbHandle, CacheHandle, OwnCert} + [OwnCert] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle), + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, OwnCert} catch _Error:_Reason -> - {ok, CertDbRef, CertDbHandle, CacheHandle, undefined} + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheHandle, undefined} end; -init_certificates(undefined, CertDbRef, CertDbHandle, CacheRef, CertFile, server) -> +init_certificates(undefined, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, CertFile, server) -> try - [OwnCert] = ssl_certificate:file_to_certificats(CertFile, CertDbHandle), - {ok, CertDbRef, CertDbHandle, CacheRef, OwnCert} + [OwnCert] = ssl_certificate:file_to_certificats(CertFile, PemCacheHandle), + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, OwnCert} catch Error:Reason -> handle_file_error(?LINE, Error, Reason, CertFile, ecertfile, erlang:get_stacktrace()) end; -init_certificates(Cert, CertDbRef, CertDbHandle, CacheRef, _, _) -> - {ok, CertDbRef, CertDbHandle, CacheRef, Cert}. +init_certificates(Cert, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, _, _) -> + {ok, CertDbRef, CertDbHandle, FileRefHandle, PemCacheHandle, CacheRef, Cert}. -init_private_key(_, undefined, "", _Password, _Client) -> +init_private_key(_, undefined, <<>>, _Password, _Client) -> undefined; init_private_key(DbHandle, undefined, KeyFile, Password, _) -> try @@ -1225,11 +1226,11 @@ certify_client(#state{client_certificate_requested = true, role = client, socket = Socket, tls_handshake_hashes = Hashes0} = State) -> Certificate = ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, client), - {BinCert, ConnectionStates1, Hashes1} = + {BinCert, ConnectionStates, Hashes} = encode_handshake(Certificate, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinCert), - State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}; + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}; certify_client(#state{client_certificate_requested = false} = State) -> State. @@ -1246,12 +1247,12 @@ verify_client_cert(#state{client_certificate_requested = true, role = client, case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret, Version, PrivateKey, Hashes0) of #certificate_verify{} = Verified -> - {BinVerified, ConnectionStates1, Hashes1} = + {BinVerified, ConnectionStates, Hashes} = encode_handshake(Verified, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinVerified), - State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}; + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}; ignore -> State; #alert{} = Alert -> @@ -1261,7 +1262,7 @@ verify_client_cert(#state{client_certificate_requested = false} = State) -> State. do_server_hello(Type, #state{negotiated_version = Version, - session = #session{session_id = SessId} = Session, + session = #session{session_id = SessId}, connection_states = ConnectionStates0, renegotiation = {Renegotiation, _}} = State0) when is_atom(Type) -> @@ -1269,29 +1270,13 @@ do_server_hello(Type, #state{negotiated_version = Version, ServerHello = ssl_handshake:server_hello(SessId, Version, ConnectionStates0, Renegotiation), - State1 = server_hello(ServerHello, State0), + State = server_hello(ServerHello, State0), case Type of new -> - new_server_hello(ServerHello, State1); + new_server_hello(ServerHello, State); resumed -> - ConnectionStates1 = State1#state.connection_states, - case ssl_handshake:master_secret(Version, Session, - ConnectionStates1, server) of - {_, ConnectionStates2} -> - State2 = State1#state{connection_states=ConnectionStates2, - session = Session}, - {ConnectionStates, Hashes} = - finalize_handshake(State2, abbreviated), - State3 = State2#state{connection_states = - ConnectionStates, - tls_handshake_hashes = Hashes}, - {Record, State} = next_record(State3), - next_state(hello, abbreviated, Record, State); - #alert{} = Alert -> - handle_own_alert(Alert, Version, hello, State1), - {stop, normal, State1} - end + resumed_server_hello(State) end. new_server_hello(#server_hello{cipher_suite = CipherSuite, @@ -1314,6 +1299,27 @@ new_server_hello(#server_hello{cipher_suite = CipherSuite, {stop, normal, State0} end. +resumed_server_hello(#state{session = Session, + connection_states = ConnectionStates0, + negotiated_version = Version} = State0) -> + + case ssl_handshake:master_secret(Version, Session, + ConnectionStates0, server) of + {_, ConnectionStates1} -> + State1 = State0#state{connection_states = ConnectionStates1, + session = Session}, + {ConnectionStates, Hashes} = + finalize_handshake(State1, abbreviated), + State2 = State1#state{connection_states = + ConnectionStates, + tls_handshake_hashes = Hashes}, + {Record, State} = next_record(State2), + next_state(hello, abbreviated, Record, State); + #alert{} = Alert -> + handle_own_alert(Alert, Version, hello, State0), + {stop, normal, State0} + end. + handle_new_session(NewId, CipherSuite, Compression, #state{session = Session0} = State0) -> Session = Session0#session{session_id = NewId, cipher_suite = CipherSuite, @@ -1329,10 +1335,10 @@ handle_resumed_session(SessId, #state{connection_states = ConnectionStates0, Session = CacheCb:lookup(Cache, {{Host, Port}, SessId}), case ssl_handshake:master_secret(Version, Session, ConnectionStates0, client) of - {_, ConnectionStates1} -> + {_, ConnectionStates} -> {Record, State} = next_record(State0#state{ - connection_states = ConnectionStates1, + connection_states = ConnectionStates, session = Session}), next_state(hello, abbreviated, Record, State); #alert{} = Alert -> @@ -1385,16 +1391,16 @@ server_hello(ServerHello, #state{transport_cb = Transport, server_hello_done(#state{transport_cb = Transport, socket = Socket, negotiated_version = Version, - connection_states = ConnectionStates, - tls_handshake_hashes = Hashes} = State) -> + connection_states = ConnectionStates0, + tls_handshake_hashes = Hashes0} = State) -> HelloDone = ssl_handshake:server_hello_done(), - {BinHelloDone, NewConnectionStates, NewHashes} = - encode_handshake(HelloDone, Version, ConnectionStates, Hashes), + {BinHelloDone, ConnectionStates, Hashes} = + encode_handshake(HelloDone, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinHelloDone), - State#state{connection_states = NewConnectionStates, - tls_handshake_hashes = NewHashes}. + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}. certify_server(#state{key_algorithm = dh_anon} = State) -> State; @@ -1402,18 +1408,18 @@ certify_server(#state{key_algorithm = dh_anon} = State) -> certify_server(#state{transport_cb = Transport, socket = Socket, negotiated_version = Version, - connection_states = ConnectionStates, - tls_handshake_hashes = Hashes, + connection_states = ConnectionStates0, + tls_handshake_hashes = Hashes0, cert_db = CertDbHandle, cert_db_ref = CertDbRef, session = #session{own_certificate = OwnCert}} = State) -> case ssl_handshake:certificate(OwnCert, CertDbHandle, CertDbRef, server) of CertMsg = #certificate{} -> - {BinCertMsg, NewConnectionStates, NewHashes} = - encode_handshake(CertMsg, Version, ConnectionStates, Hashes), + {BinCertMsg, ConnectionStates, Hashes} = + encode_handshake(CertMsg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinCertMsg), - State#state{connection_states = NewConnectionStates, - tls_handshake_hashes = NewHashes + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes }; Alert = #alert{} -> throw(Alert) @@ -1443,12 +1449,12 @@ key_exchange(#state{role = server, key_algorithm = Algo, Algo, ClientRandom, ServerRandom, PrivateKey}), - {BinMsg, ConnectionStates, Hashes1} = + {BinMsg, ConnectionStates, Hashes} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), State#state{connection_states = ConnectionStates, diffie_hellman_keys = Keys, - tls_handshake_hashes = Hashes1}; + tls_handshake_hashes = Hashes}; key_exchange(#state{role = client, connection_states = ConnectionStates0, @@ -1459,11 +1465,11 @@ key_exchange(#state{role = client, socket = Socket, transport_cb = Transport, tls_handshake_hashes = Hashes0} = State) -> Msg = rsa_key_exchange(PremasterSecret, PublicKeyInfo), - {BinMsg, ConnectionStates1, Hashes1} = + {BinMsg, ConnectionStates, Hashes} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), - State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}; + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}; key_exchange(#state{role = client, connection_states = ConnectionStates0, key_algorithm = Algorithm, @@ -1475,11 +1481,11 @@ key_exchange(#state{role = client, Algorithm == dhe_rsa; Algorithm == dh_anon -> Msg = ssl_handshake:key_exchange(client, {dh, DhPubKey}), - {BinMsg, ConnectionStates1, Hashes1} = + {BinMsg, ConnectionStates, Hashes} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), - State#state{connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}. + State#state{connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}. rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _}) when Algorithm == ?rsaEncryption; @@ -1501,12 +1507,12 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer}, socket = Socket, transport_cb = Transport} = State) -> Msg = ssl_handshake:certificate_request(ConnectionStates0, CertDbHandle, CertDbRef), - {BinMsg, ConnectionStates1, Hashes1} = + {BinMsg, ConnectionStates, Hashes} = encode_handshake(Msg, Version, ConnectionStates0, Hashes0), Transport:send(Socket, BinMsg), State#state{client_certificate_requested = true, - connection_states = ConnectionStates1, - tls_handshake_hashes = Hashes1}; + connection_states = ConnectionStates, + tls_handshake_hashes = Hashes}; request_client_cert(#state{ssl_options = #ssl_options{verify = verify_none}} = State) -> State. @@ -1697,7 +1703,7 @@ passive_receive(State0 = #state{user_data_buffer = Buffer}, StateName) -> read_application_data(Data, #state{user_application = {_Mon, Pid}, socket_options = SOpts, bytes_to_read = BytesToRead, - recv_from = From, + start_or_recv_from = RecvFrom, user_data_buffer = Buffer0} = State0) -> Buffer1 = if Buffer0 =:= <<>> -> Data; @@ -1706,9 +1712,9 @@ read_application_data(Data, #state{user_application = {_Mon, Pid}, end, case get_data(SOpts, BytesToRead, Buffer1) of {ok, ClientData, Buffer} -> % Send data - SocketOpt = deliver_app_data(SOpts, ClientData, Pid, From), + SocketOpt = deliver_app_data(SOpts, ClientData, Pid, RecvFrom), State = State0#state{user_data_buffer = Buffer, - recv_from = undefined, + start_or_recv_from = undefined, bytes_to_read = 0, socket_options = SocketOpt }, @@ -1723,7 +1729,7 @@ read_application_data(Data, #state{user_application = {_Mon, Pid}, {more, Buffer} -> % no reply, we need more data next_record(State0#state{user_data_buffer = Buffer}); {error,_Reason} -> %% Invalid packet in packet mode - deliver_packet_error(SOpts, Buffer1, Pid, From), + deliver_packet_error(SOpts, Buffer1, Pid, RecvFrom), {stop, normal, State0} end. @@ -1843,8 +1849,9 @@ format_reply(binary, _, N, Data) when N > 0 -> % Header mode format_reply(binary, _, _, Data) -> Data; format_reply(list, Packet, _, Data) - when Packet == http; Packet == {http, headers}; Packet == http_bin; Packet == {http_bin, headers}; Packet == httph; - Packet == httph_bin-> + when Packet == http; Packet == {http, headers}; + Packet == http_bin; Packet == {http_bin, headers}; + Packet == httph; Packet == httph_bin -> Data; format_reply(list, _,_, Data) -> binary_to_list(Data). @@ -2008,9 +2015,9 @@ next_state_connection(StateName, #state{send_queue = Queue0, %% premaster_secret and public_key_info (only needed during handshake) %% to reduce memory foot print of a connection. next_state_is_connection(_, State = - #state{recv_from = From, + #state{start_or_recv_from = RecvFrom, socket_options = - #socket_options{active = false}}) when From =/= undefined -> + #socket_options{active = false}}) when RecvFrom =/= undefined -> passive_receive(State#state{premaster_secret = undefined, public_key_info = undefined, tls_handshake_hashes = {<<>>, <<>>}}, connection); @@ -2073,7 +2080,7 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User, log_alert = true, session_cache_cb = SessionCacheCb, renegotiation = {false, first}, - recv_from = undefined, + start_or_recv_from = undefined, send_queue = queue:new() }. @@ -2177,7 +2184,7 @@ handle_alerts([Alert | Alerts], {next_state, StateName, State, _Timeout}) -> handle_alerts(Alerts, handle_alert(Alert, StateName, State)). handle_alert(#alert{level = ?FATAL} = Alert, StateName, - #state{from = From, host = Host, port = Port, session = Session, + #state{start_or_recv_from = From, host = Host, port = Port, session = Session, user_application = {_Mon, Pid}, log_alert = Log, role = Role, socket_options = Opts} = State) -> invalidate_session(Role, Host, Port, Session), @@ -2259,13 +2266,13 @@ handle_own_alert(Alert, Version, StateName, ok end. -handle_normal_shutdown(Alert, _, #state{from = User, role = Role, renegotiation = {false, first}}) -> - alert_user(User, Alert, Role); +handle_normal_shutdown(Alert, _, #state{start_or_recv_from = StartFrom, role = Role, renegotiation = {false, first}}) -> + alert_user(StartFrom, Alert, Role); handle_normal_shutdown(Alert, StateName, #state{socket_options = Opts, user_application = {_Mon, Pid}, - from = User, role = Role}) -> - alert_user(StateName, Opts, Pid, User, Alert, Role). + start_or_recv_from = RecvFrom, role = Role}) -> + alert_user(StateName, Opts, Pid, RecvFrom, Alert, Role). handle_unexpected_message(Msg, Info, #state{negotiated_version = Version} = State) -> Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE), @@ -2291,9 +2298,9 @@ ack_connection(#state{renegotiation = {true, From}} = State) -> gen_fsm:reply(From, ok), State#state{renegotiation = undefined}; ack_connection(#state{renegotiation = {false, first}, - from = From} = State) when From =/= undefined -> - gen_fsm:reply(From, connected), - State#state{renegotiation = undefined}; + start_or_recv_from = StartFrom} = State) when StartFrom =/= undefined -> + gen_fsm:reply(StartFrom, connected), + State#state{renegotiation = undefined, start_or_recv_from = undefined}; ack_connection(State) -> State. @@ -2359,7 +2366,29 @@ linux_workaround_transport_delivery_problems(#alert{level = ?FATAL}, Socket) -> linux_workaround_transport_delivery_problems(_, _) -> ok. -get_timeout(#state{ssl_options=#ssl_options{hibernate_after=undefined}}) -> +get_timeout(#state{ssl_options=#ssl_options{hibernate_after = undefined}}) -> infinity; -get_timeout(#state{ssl_options=#ssl_options{hibernate_after=HibernateAfter}}) -> +get_timeout(#state{ssl_options=#ssl_options{hibernate_after = HibernateAfter}}) -> HibernateAfter. + +handle_trusted_certs_db(#state{ssl_options = #ssl_options{cacertfile = <<>>}}) -> + %% No trusted certs specified + ok; +handle_trusted_certs_db(#state{cert_db_ref = Ref, + cert_db = CertDb, + ssl_options = #ssl_options{cacertfile = undefined}}) -> + %% Certs provided as DER directly can not be shared + %% with other connections and it is safe to delete them when the connection ends. + ssl_certificate_db:remove_trusted_certs(Ref, CertDb); +handle_trusted_certs_db(#state{file_ref_db = undefined}) -> + %% Something went wrong early (typically cacertfile does not exist) so there is nothing to handle + ok; +handle_trusted_certs_db(#state{cert_db_ref = Ref, + file_ref_db = RefDb, + ssl_options = #ssl_options{cacertfile = File}}) -> + case ssl_certificate_db:ref_count(Ref, RefDb, -1) of + 0 -> + ssl_manager:clean_cert_db(Ref, File); + _ -> + ok + end. diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index 2e0a3de182..06d45966c1 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -30,7 +30,7 @@ -include("ssl_internal.hrl"). -include_lib("public_key/include/public_key.hrl"). --export([master_secret/4, client_hello/6, server_hello/4, hello/4, +-export([master_secret/4, client_hello/8, server_hello/4, hello/4, hello_request/0, certify/7, certificate/4, client_certificate_verify/5, certificate_verify/5, certificate_request/3, key_exchange/2, server_key_exchange_hash/2, @@ -51,14 +51,17 @@ %%==================================================================== %%-------------------------------------------------------------------- -spec client_hello(host(), inet:port_number(), #connection_states{}, - #ssl_options{}, boolean(), der_cert()) -> #client_hello{}. + #ssl_options{}, integer(), atom(), boolean(), der_cert()) -> + #client_hello{}. %% %% Description: Creates a client hello message. %%-------------------------------------------------------------------- -client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, - ciphers = UserSuites} - = SslOpts, Renegotiation, OwnCert) -> - +client_hello(Host, Port, ConnectionStates, + #ssl_options{versions = Versions, + ciphers = UserSuites + } = SslOpts, + Cache, CacheCb, Renegotiation, OwnCert) -> + Fun = fun(Version) -> ssl_record:protocol_version(Version) end, @@ -67,15 +70,15 @@ client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions, SecParams = Pending#connection_state.security_parameters, Ciphers = available_suites(UserSuites, Version), - Id = ssl_manager:client_session_id(Host, Port, SslOpts, OwnCert), + Id = ssl_session:client_id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), - #client_hello{session_id = Id, + #client_hello{session_id = Id, client_version = Version, cipher_suites = cipher_suites(Ciphers, Renegotiation), compression_methods = ssl_record:compressions(), random = SecParams#security_parameters.client_random, - renegotiation_info = - renegotiation_info(client, ConnectionStates, Renegotiation) + renegotiation_info = + renegotiation_info(client, ConnectionStates, Renegotiation) }. %%-------------------------------------------------------------------- @@ -584,24 +587,23 @@ path_validation_alert({bad_cert, unknown_ca}) -> path_validation_alert(_) -> ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE). -select_session(Hello, Port, Session, Version, +select_session(Hello, Port, Session, Version, #ssl_options{ciphers = UserSuites} = SslOpts, Cache, CacheCb, Cert) -> SuggestedSessionId = Hello#client_hello.session_id, - SessionId = ssl_manager:server_session_id(Port, SuggestedSessionId, - SslOpts, Cert), - - Suites = available_suites(Cert, UserSuites, Version), - case ssl_session:is_new(SuggestedSessionId, SessionId) of - true -> - CipherSuite = - select_cipher_suite(Hello#client_hello.cipher_suites, Suites), + {SessionId, Resumed} = ssl_session:server_id(Port, SuggestedSessionId, + SslOpts, Cert, + Cache, CacheCb), + Suites = available_suites(Cert, UserSuites, Version), + case Resumed of + undefined -> + CipherSuite = select_cipher_suite(Hello#client_hello.cipher_suites, Suites), Compressions = Hello#client_hello.compression_methods, Compression = select_compression(Compressions), {new, Session#session{session_id = SessionId, cipher_suite = CipherSuite, compression_method = Compression}}; - false -> - {resumed, CacheCb:lookup(Cache, {Port, SessionId})} + _ -> + {resumed, Resumed} end. available_suites(UserSuites, Version) -> diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl index 6389ff03f5..3e947af2c9 100644 --- a/lib/ssl/src/ssl_manager.erl +++ b/lib/ssl/src/ssl_manager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. 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 @@ -30,9 +30,9 @@ -export([start_link/1, start_link_dist/1, connection_init/2, cache_pem_file/2, lookup_trusted_cert/4, - client_session_id/4, server_session_id/4, + new_session_id/1, clean_cert_db/2, register_session/2, register_session/3, invalidate_session/2, - invalidate_session/3]). + invalidate_session/3, clear_pem_cache/0]). % Spawn export -export([init_session_validator/1]). @@ -56,9 +56,12 @@ -define('24H_in_msec', 8640000). -define('24H_in_sec', 8640). +-define(GEN_UNIQUE_ID_MAX_TRIES, 10). -define(SESSION_VALIDATION_INTERVAL, 60000). --define(CERTIFICATE_CACHE_CLEANUP, 30000). +-define(CLEAR_PEM_CACHE, 120000). -define(CLEAN_SESSION_DB, 60000). +-define(CLEAN_CERT_DB, 500). +-define(NOT_TO_BIG, 10). %%==================================================================== %% API @@ -82,26 +85,46 @@ start_link_dist(Opts) -> gen_server:start_link({local, ssl_manager_dist}, ?MODULE, [ssl_manager_dist, Opts], []). %%-------------------------------------------------------------------- --spec connection_init(string()| {der, list()}, client | server) -> +-spec connection_init(binary()| {der, list()}, client | server) -> {ok, certdb_ref(), db_handle(), db_handle()}. %% %% Description: Do necessary initializations for a new connection. %%-------------------------------------------------------------------- +connection_init({der, _} = Trustedcerts, Role) -> + call({connection_init, Trustedcerts, Role}); + +connection_init(<<>> = Trustedcerts, Role) -> + call({connection_init, Trustedcerts, Role}); + connection_init(Trustedcerts, Role) -> call({connection_init, Trustedcerts, Role}). + %%-------------------------------------------------------------------- --spec cache_pem_file(string(), term()) -> {ok, term()} | {error, reason()}. +-spec cache_pem_file(binary(), term()) -> {ok, term()} | {error, reason()}. %% %% Description: Cach a pem file and return its content. %%-------------------------------------------------------------------- cache_pem_file(File, DbHandle) -> - try file:read_file_info(File) of - {ok, #file_info{mtime = LastWrite}} -> - cache_pem_file(File, LastWrite, DbHandle) - catch - _:Reason -> - {error, Reason} + MD5 = crypto:md5(File), + case ssl_certificate_db:lookup_cached_pem(DbHandle, MD5) of + [{Content,_}] -> + {ok, Content}; + [Content] -> + {ok, Content}; + undefined -> + call({cache_pem, {MD5, File}}) end. + +%%-------------------------------------------------------------------- +-spec clear_pem_cache() -> ok. +%% +%% Description: Clear the PEM cache +%%-------------------------------------------------------------------- +clear_pem_cache() -> + %% Not supported for distribution at the moement, should it be? + put(ssl_manager, ssl_manager), + call(unconditionally_clear_pem_cache). + %%-------------------------------------------------------------------- -spec lookup_trusted_cert(term(), reference(), serialnumber(), issuer()) -> undefined | @@ -114,22 +137,15 @@ lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer) -> ssl_certificate_db:lookup_trusted_cert(DbHandle, Ref, SerialNumber, Issuer). %%-------------------------------------------------------------------- --spec client_session_id(host(), inet:port_number(), #ssl_options{}, - der_cert() | undefined) -> session_id(). +-spec new_session_id(integer()) -> session_id(). %% -%% Description: Select a session id for the client. +%% Description: Creates a session id for the server. %%-------------------------------------------------------------------- -client_session_id(Host, Port, SslOpts, OwnCert) -> - call({client_session_id, Host, Port, SslOpts, OwnCert}). +new_session_id(Port) -> + call({new_session_id, Port}). -%%-------------------------------------------------------------------- --spec server_session_id(host(), inet:port_number(), #ssl_options{}, - der_cert()) -> session_id(). -%% -%% Description: Select a session id for the server. -%%-------------------------------------------------------------------- -server_session_id(Port, SuggestedSessionId, SslOpts, OwnCert) -> - call({server_session_id, Port, SuggestedSessionId, SslOpts, OwnCert}). +clean_cert_db(Ref, File) -> + erlang:send_after(?CLEAN_CERT_DB, self(), {clean_cert_db, Ref, File}). %%-------------------------------------------------------------------- -spec register_session(inet:port_number(), #session{}) -> ok. @@ -177,6 +193,7 @@ init([Name, Opts]) -> SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])), Timer = erlang:send_after(SessionLifeTime * 1000, self(), validate_sessions), + erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache), {ok, #state{certificate_db = CertDb, session_cache = SessionCache, session_cache_cb = CacheCb, @@ -194,55 +211,44 @@ init([Name, Opts]) -> %% %% Description: Handling call messages %%-------------------------------------------------------------------- -handle_call({{connection_init, "", _Role}, Pid}, _From, - #state{certificate_db = [CertDb |_], +handle_call({{connection_init, <<>>, _Role}, _Pid}, _From, + #state{certificate_db = [CertDb, FileRefDb, PemChace], session_cache = Cache} = State) -> - erlang:monitor(process, Pid), - Result = {ok, make_ref(),CertDb, Cache}, + Result = {ok, make_ref(),CertDb, FileRefDb, PemChace, Cache}, {reply, Result, State}; handle_call({{connection_init, Trustedcerts, _Role}, Pid}, _From, - #state{certificate_db = [CertDb|_] =Db, + #state{certificate_db = [CertDb, FileRefDb, PemChace] = Db, session_cache = Cache} = State) -> - erlang:monitor(process, Pid), Result = try {ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, Trustedcerts, Db), - {ok, Ref, CertDb, Cache} + {ok, Ref, CertDb, FileRefDb, PemChace, Cache} catch _:Reason -> {error, Reason} end, {reply, Result, State}; -handle_call({{client_session_id, Host, Port, SslOpts, OwnCert}, _}, _, - #state{session_cache = Cache, - session_cache_cb = CacheCb} = State) -> - Id = ssl_session:id({Host, Port, SslOpts}, Cache, CacheCb, OwnCert), - {reply, Id, State}; - -handle_call({{server_session_id, Port, SuggestedSessionId, SslOpts, OwnCert}, _}, +handle_call({{new_session_id,Port}, _}, _, #state{session_cache_cb = CacheCb, - session_cache = Cache, - session_lifetime = LifeTime} = State) -> - Id = ssl_session:id(Port, SuggestedSessionId, SslOpts, - Cache, CacheCb, LifeTime, OwnCert), + session_cache = Cache} = State) -> + Id = new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb), {reply, Id, State}; -handle_call({{cache_pem, File, LastWrite}, Pid}, _, + +handle_call({{cache_pem, File}, _Pid}, _, #state{certificate_db = Db} = State) -> - try ssl_certificate_db:cache_pem_file(Pid, File, LastWrite, Db) of + try ssl_certificate_db:cache_pem_file(File, Db) of Result -> {reply, Result, State} catch _:Reason -> {reply, {error, Reason}, State} end; -handle_call({{recache_pem, File, LastWrite}, Pid}, From, - #state{certificate_db = Db} = State) -> - ssl_certificate_db:uncache_pem_file(File, Db), - cast({recache_pem, File, LastWrite, Pid, From}), - {noreply, State}. +handle_call({unconditionally_clear_pem_cache, _},_, #state{certificate_db = [_,_,PemChace]} = State) -> + ssl_certificate_db:clear(PemChace), + {reply, ok, State}. %%-------------------------------------------------------------------- -spec handle_cast(msg(), #state{}) -> {noreply, #state{}}. @@ -278,22 +284,7 @@ handle_cast({invalidate_session, Host, Port, handle_cast({invalidate_session, Port, #session{session_id = ID} = Session}, #state{session_cache = Cache, session_cache_cb = CacheCb} = State) -> - invalidate_session(Cache, CacheCb, {Port, ID}, Session, State); - -handle_cast({recache_pem, File, LastWrite, Pid, From}, - #state{certificate_db = [_, FileToRefDb, _]} = State0) -> - case ssl_certificate_db:lookup(File, FileToRefDb) of - undefined -> - {reply, Msg, State} = - handle_call({{cache_pem, File, LastWrite}, Pid}, From, State0), - gen_server:reply(From, Msg), - {noreply, State}; - _ -> %% Send message to self letting cleanup messages be handled - %% first so that no reference to the old version of file - %% exists when we cache the new one. - cast({recache_pem, File, LastWrite, Pid, From}), - {noreply, State0} - end. + invalidate_session(Cache, CacheCb, {Port, ID}, Session, State). %%-------------------------------------------------------------------- -spec handle_info(msg(), #state{}) -> {noreply, #state{}}. @@ -318,23 +309,38 @@ handle_info({delayed_clean_session, Key}, #state{session_cache = Cache, CacheCb:delete(Cache, Key), {noreply, State}; -handle_info({'EXIT', _, _}, State) -> - %% Session validator died!! Do we need to take any action? - %% maybe error log +handle_info(clear_pem_cache, #state{certificate_db = [_,_,PemChace]} = State) -> + case ssl_certificate_db:db_size(PemChace) of + N when N < ?NOT_TO_BIG -> + ok; + _ -> + ssl_certificate_db:clear(PemChace) + end, + erlang:send_after(?CLEAR_PEM_CACHE, self(), clear_pem_cache), {noreply, State}; -handle_info({'DOWN', _Ref, _Type, _Pid, ecacertfile}, State) -> - {noreply, State}; -handle_info({'DOWN', _Ref, _Type, Pid, shutdown}, State) -> - handle_info({remove_trusted_certs, Pid}, State); -handle_info({'DOWN', _Ref, _Type, Pid, _Reason}, State) -> - erlang:send_after(?CERTIFICATE_CACHE_CLEANUP, self(), - {remove_trusted_certs, Pid}), +handle_info({clean_cert_db, Ref, File}, + #state{certificate_db = [CertDb,RefDb, PemCache]} = State) -> + case ssl_certificate_db:ref_count(Ref, RefDb, 0) of + 0 -> + MD5 = crypto:md5(File), + case ssl_certificate_db:lookup_cached_pem(MD5, PemCache) of + [{Content, Ref}] -> + ssl_certificate_db:insert(MD5, Content, PemCache); + undefined -> + ok + end, + ssl_certificate_db:remove(Ref, RefDb), + ssl_certificate_db:remove_trusted_certs(Ref, CertDb); + _ -> + ok + end, {noreply, State}; -handle_info({remove_trusted_certs, Pid}, - #state{certificate_db = Db} = State) -> - ssl_certificate_db:remove_trusted_certs(Pid, Db), + +handle_info({'EXIT', _, _}, State) -> + %% Session validator died!! Do we need to take any action? + %% maybe error log {noreply, State}; handle_info(_Info, State) -> @@ -406,19 +412,6 @@ session_validation({{Port, _}, Session}, LifeTime) -> validate_session(Port, Session, LifeTime), LifeTime. -cache_pem_file(File, LastWrite, DbHandle) -> - case ssl_certificate_db:lookup_cached_certs(DbHandle,File) of - [{_, {Mtime, Content}}] -> - case LastWrite of - Mtime -> - {ok, Content}; - _ -> - call({recache_pem, File, LastWrite}) - end; - [] -> - call({cache_pem, File, LastWrite}) - end. - delay_time() -> case application:get_env(ssl, session_delay_cleanup_time) of {ok, Time} when is_integer(Time) -> @@ -448,3 +441,28 @@ last_delay_timer({{_,_},_}, TRef, {LastServer, _}) -> {LastServer, TRef}; last_delay_timer({_,_}, TRef, {_, LastClient}) -> {TRef, LastClient}. + +%% If we can not generate a not allready in use session ID in +%% ?GEN_UNIQUE_ID_MAX_TRIES we make the new session uncacheable The +%% value of ?GEN_UNIQUE_ID_MAX_TRIES is stolen from open SSL which +%% states : "If we can not find a session id in +%% ?GEN_UNIQUE_ID_MAX_TRIES either the RAND code is broken or someone +%% is trying to open roughly very close to 2^128 (or 2^256) SSL +%% sessions to our server" +new_id(_, 0, _, _) -> + <<>>; +new_id(Port, Tries, Cache, CacheCb) -> + Id = crypto:rand_bytes(?NUM_OF_SESSION_ID_BYTES), + case CacheCb:lookup(Cache, {Port, Id}) of + undefined -> + Now = calendar:datetime_to_gregorian_seconds({date(), time()}), + %% New sessions can not be set to resumable + %% until handshake is compleate and the + %% other session values are set. + CacheCb:update(Cache, {Port, Id}, #session{session_id = Id, + is_resumable = false, + time_stamp = Now}), + Id; + _ -> + new_id(Port, Tries - 1, Cache, CacheCb) + end. diff --git a/lib/ssl/src/ssl_session.erl b/lib/ssl/src/ssl_session.erl index df5d7e0146..2ad422fc03 100644 --- a/lib/ssl/src/ssl_session.erl +++ b/lib/ssl/src/ssl_session.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2012. 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,9 +28,9 @@ -include("ssl_internal.hrl"). %% Internal application API --export([is_new/2, id/4, id/7, valid_session/2]). +-export([is_new/2, client_id/4, server_id/6, valid_session/2]). --define(GEN_UNIQUE_ID_MAX_TRIES, 10). +-define('24H_in_sec', 8640). -type seconds() :: integer(). @@ -48,13 +48,13 @@ is_new(_ClientSuggestion, _ServerDecision) -> true. %%-------------------------------------------------------------------- --spec id({host(), inet:port_number(), #ssl_options{}}, db_handle(), atom(), +-spec client_id({host(), inet:port_number(), #ssl_options{}}, db_handle(), atom(), undefined | binary()) -> binary(). %% -%% Description: Should be called by the client side to get an id +%% Description: Should be called by the client side to get an id %% for the client hello message. %%-------------------------------------------------------------------- -id(ClientInfo, Cache, CacheCb, OwnCert) -> +client_id(ClientInfo, Cache, CacheCb, OwnCert) -> case select_session(ClientInfo, Cache, CacheCb, OwnCert) of no_session -> <<>>; @@ -62,27 +62,6 @@ id(ClientInfo, Cache, CacheCb, OwnCert) -> SessionId end. -%%-------------------------------------------------------------------- --spec id(inet:port_number(), binary(), #ssl_options{}, db_handle(), - atom(), seconds(), binary()) -> binary(). -%% -%% Description: Should be called by the server side to get an id -%% for the server hello message. -%%-------------------------------------------------------------------- -id(Port, <<>>, _, Cache, CacheCb, _, _) -> - new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb); - -id(Port, SuggestedSessionId, #ssl_options{reuse_sessions = ReuseEnabled, - reuse_session = ReuseFun}, - Cache, CacheCb, SecondLifeTime, OwnCert) -> - case is_resumable(SuggestedSessionId, Port, ReuseEnabled, - ReuseFun, Cache, CacheCb, SecondLifeTime, OwnCert) of - true -> - SuggestedSessionId; - false -> - new_id(Port, ?GEN_UNIQUE_ID_MAX_TRIES, Cache, CacheCb) - end. -%%-------------------------------------------------------------------- -spec valid_session(#session{}, seconds()) -> boolean(). %% %% Description: Check that the session has not expired @@ -91,57 +70,51 @@ valid_session(#session{time_stamp = TimeStamp}, LifeTime) -> Now = calendar:datetime_to_gregorian_seconds({date(), time()}), Now - TimeStamp < LifeTime. +server_id(Port, <<>>, _SslOpts, _Cert, _, _) -> + {ssl_manager:new_session_id(Port), undefined}; +server_id(Port, SuggestedId, + #ssl_options{reuse_sessions = ReuseEnabled, + reuse_session = ReuseFun}, + Cert, Cache, CacheCb) -> + LifeTime = case application:get_env(ssl, session_lifetime) of + {ok, Time} when is_integer(Time) -> Time; + _ -> ?'24H_in_sec' + end, + case is_resumable(SuggestedId, Port, ReuseEnabled,ReuseFun, + Cache, CacheCb, LifeTime, Cert) + of + {true, Resumed} -> + {SuggestedId, Resumed}; + {false, undefined} -> + {ssl_manager:new_session_id(Port), undefined} + end. + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +select_session({_, _, #ssl_options{reuse_sessions=false}}, _Cache, _CacheCb, _OwnCert) -> + no_session; select_session({HostIP, Port, SslOpts}, Cache, CacheCb, OwnCert) -> Sessions = CacheCb:select_session(Cache, {HostIP, Port}), select_session(Sessions, SslOpts, OwnCert). select_session([], _, _) -> no_session; - -select_session(Sessions, #ssl_options{ciphers = Ciphers, - reuse_sessions = ReuseSession}, OwnCert) -> - IsResumable = - fun(Session) -> - ReuseSession andalso resumable(Session#session.is_resumable) andalso - lists:member(Session#session.cipher_suite, Ciphers) - andalso (OwnCert == Session#session.own_certificate) +select_session(Sessions, #ssl_options{ciphers = Ciphers}, OwnCert) -> + IsNotResumable = + fun([_Id, Session]) -> + not (resumable(Session#session.is_resumable) andalso + lists:member(Session#session.cipher_suite, Ciphers) + andalso (OwnCert == Session#session.own_certificate)) end, - case [Id || [Id, Session] <- Sessions, IsResumable(Session)] of - [] -> - no_session; - List -> - hd(List) - end. - -%% If we can not generate a not allready in use session ID in -%% ?GEN_UNIQUE_ID_MAX_TRIES we make the new session uncacheable The -%% value of ?GEN_UNIQUE_ID_MAX_TRIES is stolen from open SSL which -%% states : "If we can not find a session id in -%% ?GEN_UNIQUE_ID_MAX_TRIES either the RAND code is broken or someone -%% is trying to open roughly very close to 2^128 (or 2^256) SSL -%% sessions to our server" -new_id(_, 0, _, _) -> - <<>>; -new_id(Port, Tries, Cache, CacheCb) -> - Id = crypto:rand_bytes(?NUM_OF_SESSION_ID_BYTES), - case CacheCb:lookup(Cache, {Port, Id}) of - undefined -> - Now = calendar:datetime_to_gregorian_seconds({date(), time()}), - %% New sessions can not be set to resumable - %% until handshake is compleate and the - %% other session values are set. - CacheCb:update(Cache, {Port, Id}, #session{session_id = Id, - is_resumable = false, - time_stamp = Now}), - Id; - _ -> - new_id(Port, Tries - 1, Cache, CacheCb) + case lists:dropwhile(IsNotResumable, Sessions) of + [] -> no_session; + [[Id, _]|_] -> Id end. -is_resumable(SuggestedSessionId, Port, ReuseEnabled, ReuseFun, Cache, +is_resumable(_, _, false, _, _, _, _, _) -> + {false, undefined}; +is_resumable(SuggestedSessionId, Port, true, ReuseFun, Cache, CacheCb, SecondLifeTime, OwnCert) -> case CacheCb:lookup(Cache, {Port, SuggestedSessionId}) of #session{cipher_suite = CipherSuite, @@ -149,14 +122,17 @@ is_resumable(SuggestedSessionId, Port, ReuseEnabled, ReuseFun, Cache, compression_method = Compression, is_resumable = IsResumable, peer_certificate = PeerCert} = Session -> - ReuseEnabled - andalso resumable(IsResumable) + case resumable(IsResumable) andalso (OwnCert == SessionOwnCert) - andalso valid_session(Session, SecondLifeTime) - andalso ReuseFun(SuggestedSessionId, PeerCert, - Compression, CipherSuite); + andalso valid_session(Session, SecondLifeTime) + andalso ReuseFun(SuggestedSessionId, PeerCert, + Compression, CipherSuite) + of + true -> {true, Session}; + false -> {false, undefined} + end; undefined -> - false + {false, undefined} end. resumable(new) -> diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl index f9bbf905e1..5c6ee3c54c 100644 --- a/lib/ssl/src/ssl_session_cache.erl +++ b/lib/ssl/src/ssl_session_cache.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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,7 +32,7 @@ %% Description: Return table reference. Called by ssl_manager process. %%-------------------------------------------------------------------- init(_) -> - ets:new(cache_name(), [set, protected]). + ets:new(cache_name(), [ordered_set, protected]). %%-------------------------------------------------------------------- %% Description: Handles cache table at termination of ssl manager. diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile index 6b1da63d08..a0f54c0359 100644 --- a/lib/ssl/test/Makefile +++ b/lib/ssl/test/Makefile @@ -120,11 +120,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) $(RELSYSDIR) - $(INSTALL_DATA) ssl.spec ssl.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) "$(RELSYSDIR)" + $(INSTALL_DATA) ssl.spec ssl.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 590ecf33ca..5a52917d6c 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -50,6 +50,7 @@ %%-------------------------------------------------------------------- init_per_suite(Config0) -> Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2), + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), @@ -261,7 +262,8 @@ all() -> no_reuses_session_server_restart_new_cert_file, reuseaddr, hibernate, connect_twice, renegotiate_dos_mitigate_active, renegotiate_dos_mitigate_passive, - tcp_error_propagation_in_active_mode, rizzo, no_rizzo_rc4 + tcp_error_propagation_in_active_mode, rizzo, no_rizzo_rc4, + recv_error_handling ]. groups() -> @@ -3649,6 +3651,8 @@ no_reuses_session_server_restart_new_cert_file(Config) when is_list(Config) -> ssl_test_lib:close(Server), ssl_test_lib:close(Client0), + ssl:clear_pem_cache(), + NewServerOpts = new_config(PrivDir, DsaServerOpts), Server1 = @@ -3872,16 +3876,16 @@ tcp_error_propagation_in_active_mode(Config) when is_list(Config) -> {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, - {from, self()}, - {mfa, {ssl_test_lib, no_result, []}}, - {options, ServerOpts}]), + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, ServerOpts}]), Port = ssl_test_lib:inet_port(Server), {Client, #sslsocket{pid=Pid} = SslSocket} = ssl_test_lib:start_client([return_socket, - {node, ClientNode}, {port, Port}, - {host, Hostname}, - {from, self()}, - {mfa, {?MODULE, receive_msg, []}}, - {options, ClientOpts}]), + {node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {?MODULE, receive_msg, []}}, + {options, ClientOpts}]), {status, _, _, StatusInfo} = sys:get_status(Pid), [_, _,_, _, Prop] = StatusInfo, @@ -3892,6 +3896,32 @@ tcp_error_propagation_in_active_mode(Config) when is_list(Config) -> Pid ! {tcp_error, Socket, etimedout}, ssl_test_lib:check_result(Client, {ssl_closed, SslSocket}). + + +%%-------------------------------------------------------------------- + +recv_error_handling(doc) -> + ["Special case of call error handling"]; +recv_error_handling(Config) when is_list(Config) -> + ClientOpts = ?config(client_opts, Config), + ServerOpts = ?config(server_opts, Config), + + {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), + Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, + {from, self()}, + {mfa, {?MODULE, recv_close, []}}, + {options, [{active, false} | ServerOpts]}]), + Port = ssl_test_lib:inet_port(Server), + {Client, #sslsocket{pid=Pid} = SslSocket} = ssl_test_lib:start_client([return_socket, + {node, ClientNode}, {port, Port}, + {host, Hostname}, + {from, self()}, + {mfa, {ssl_test_lib, no_result, []}}, + {options, ClientOpts}]), + ssl:close(SslSocket), + ssl_test_lib:check_result(Server, ok). + + %%-------------------------------------------------------------------- rizzo(doc) -> ["Test that there is a 1/n-1-split for non RC4 in 'TLS < 1.1' as it is @@ -3903,7 +3933,7 @@ rizzo(Config) when is_list(Config) -> {?MODULE, send_recv_result_active_rizzo, []}), run_send_recv_rizzo(Ciphers, Config, tlsv1, {?MODULE, send_recv_result_active_rizzo, []}). - +%%-------------------------------------------------------------------- no_rizzo_rc4(doc) -> ["Test that there is no 1/n-1-split for RC4 as it is not vunrable to Rizzo/Dungon attack"]; @@ -3914,6 +3944,7 @@ no_rizzo_rc4(Config) when is_list(Config) -> run_send_recv_rizzo(Ciphers, Config, tlsv1, {?MODULE, send_recv_result_active_no_rizzo, []}). +%%-------------------------------------------------------------------- run_send_recv_rizzo(Ciphers, Config, Version, Mfa) -> Result = lists:map(fun(Cipher) -> rizzo_test(Cipher, Config, Version, Mfa) end, @@ -3967,6 +3998,15 @@ send_recv_result(Socket) -> {ok,"Hello world"} = ssl:recv(Socket, 11), ok. +recv_close(Socket) -> + {error, closed} = ssl:recv(Socket, 11), + receive + {_,{error,closed}} -> + error_extra_close_sent_to_user_process + after 500 -> + ok + end. + send_recv_result_active(Socket) -> ssl:send(Socket, "Hello world"), receive diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl index 12d92c8ca1..818f7f1897 100644 --- a/lib/ssl/test/ssl_dist_SUITE.erl +++ b/lib/ssl/test/ssl_dist_SUITE.erl @@ -369,7 +369,7 @@ mk_node_cmdline(ListenPort, Name, Args) -> _ -> "-name " end, {ok, Pwd} = file:get_cwd(), - Prog ++ " " + "\"" ++ Prog ++ "\" " ++ Static ++ " " ++ NameSw ++ " " ++ Name ++ " " ++ "-pa " ++ Pa ++ " " @@ -729,7 +729,7 @@ add_ssl_opts_config(Config) -> [{ssl_opts, "-boot " ++ Script} | Config] catch _:_ -> - [{ssl_opts, "-pa " ++ filename:dirname(code:which(ssl))} + [{ssl_opts, "-pa \"" ++ filename:dirname(code:which(ssl))++"\""} | add_comment_config( "Bootscript wasn't used since the test wasn't run on an " "installed OTP system.", diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl index 4b74f57a60..593b1fda5e 100644 --- a/lib/ssl/test/ssl_packet_SUITE.erl +++ b/lib/ssl/test/ssl_packet_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2008-2011. All Rights Reserved. +%% Copyright Ericsson AB 2008-2012. 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 @@ -53,6 +53,7 @@ %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config) -> + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl index 24e86b3913..02b5516e35 100644 --- a/lib/ssl/test/ssl_payload_SUITE.erl +++ b/lib/ssl/test/ssl_payload_SUITE.erl @@ -37,6 +37,7 @@ %% variable, but should NOT alter/remove any existing entries. %%-------------------------------------------------------------------- init_per_suite(Config) -> + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), diff --git a/lib/ssl/test/ssl_session_cache_SUITE.erl b/lib/ssl/test/ssl_session_cache_SUITE.erl index 491aa893c2..6d758ecb01 100644 --- a/lib/ssl/test/ssl_session_cache_SUITE.erl +++ b/lib/ssl/test/ssl_session_cache_SUITE.erl @@ -49,6 +49,7 @@ %%-------------------------------------------------------------------- init_per_suite(Config0) -> Dog = ssl_test_lib:timetrap(?LONG_TIMEOUT *2), + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl index 01fca1f166..f593c1c552 100644 --- a/lib/ssl/test/ssl_to_openssl_SUITE.erl +++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl @@ -50,6 +50,7 @@ init_per_suite(Config0) -> false -> {skip, "Openssl not found"}; _ -> + catch crypto:stop(), try crypto:start() of ok -> application:start(public_key), @@ -112,6 +113,9 @@ special_init(TestCase, Config) special_init(ssl2_erlang_server_openssl_client, Config) -> check_sane_openssl_sslv2(Config); +special_init(ciphers_dsa_signed_certs, Config) -> + check_sane_openssl_dsa(Config); + special_init(_, Config) -> Config. @@ -600,7 +604,7 @@ erlang_server_openssl_client_no_wrap_sequence_number(Config) when is_list(Config {from, self()}, {mfa, {ssl_test_lib, trigger_renegotiate, [[Data, N+2]]}}, - {options, [{renegotiate_at, N} | ServerOpts]}]), + {options, [{renegotiate_at, N}, {reuse_sessions, false} | ServerOpts]}]), Port = ssl_test_lib:inet_port(Server), Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++ @@ -1440,14 +1444,24 @@ check_sane_openssl_renegotaite(Config) -> {skip, "Known renegotiation bug in OppenSSL"}; "OpenSSL 0.9.7" ++ _ -> {skip, "Known renegotiation bug in OppenSSL"}; + "OpenSSL 1.0.1c" ++ _ -> + {skip, "Known renegotiation bug in OppenSSL"}; _ -> Config end. check_sane_openssl_sslv2(Config) -> case os:cmd("openssl version") of - "OpenSSL 1.0.0" ++ _ -> + "OpenSSL 1." ++ _ -> {skip, "sslv2 by default turned of in 1.*"}; _ -> Config end. + +check_sane_openssl_dsa(Config) -> + case os:cmd("openssl version") of + "OpenSSL 1.0.1" ++ _ -> + {skip, "known dsa bug in openssl"}; + _ -> + Config + end. diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile index 6c92756ae7..c3138c4d9f 100644 --- a/lib/stdlib/doc/src/Makefile +++ b/lib/stdlib/doc/src/Makefile @@ -173,15 +173,15 @@ $(SPECDIR)/specs_erl_id_trans.xml: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml index 42a26ee44a..4834426d5c 100644 --- a/lib/stdlib/doc/src/notes.xml +++ b/lib/stdlib/doc/src/notes.xml @@ -30,6 +30,171 @@ </header> <p>This document describes the changes made to the STDLIB application.</p> +<section><title>STDLIB 1.18.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + References to <c>is_constant/1</c> (which was removed in + the R12 release) has been removed from documentation and + code.</p> + <p> + Own Id: OTP-6454 Aux Id: seq10407 </p> + </item> + <item> + <p> + Leave control back to gen_server during supervisor's + restart loop</p> + <p> + When an attempt to restart a child failed, supervisor + would earlier keep the execution flow and try to restart + the child over and over again until it either succeeded + or the restart frequency limit was reached. If none of + these happened, supervisor would hang forever in this + loop.</p> + <p> + This commit adds a timer of 0 ms where the control is + left back to the gen_server which implements the + supervisor. This way any incoming request to the + supervisor will be handled - which could help breaking + the infinite loop - e.g. shutdown request for the + supervisor or for the problematic child.</p> + <p> + This introduces some incompatibilities in stdlib due to + new return values from supervisor: <list> + <item>restart_child/2 can now return + {error,restarting}</item> <item>delete_child/2 can now + return {error,restarting}</item> <item>which_children/1 + returns a list of {Id,Child,Type,Mods}, where Child, in + addition to the old pid() or 'undefined', now also can be + 'restarting'.</item> </list></p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9549</p> + </item> + <item> + <p> + If a temporary child's start function returned 'ignore', + then the supervisor would keep it's child specification. + This has been corrected. Child specifications for + non-existing temporary children shall never be kept.</p> + <p> + Own Id: OTP-9782 Aux Id: seq11964 </p> + </item> + <item> + <p> Use universal time as base in error logger + <p> + Previous conversion used the deprecated + calendar:local_time_to_universal_time/1 </p></p> + <p> + Own Id: OTP-9854</p> + </item> + <item> + <p>Calling a guard test (such as is_list/1) from the + top-level in a guard, would cause a compiler crash if + there was a local definition with the same name. + Corrected to reject the program with an error + message.</p> + <p> + Own Id: OTP-9866</p> + </item> + <item> + <p> + Fix the type spec from the doc of binary:part/3 (Thanks + to Ricardo Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9920</p> + </item> + <item> + <p> + Correct spelling of registered (Thanks to Richard + Carlsson)</p> + <p> + Own Id: OTP-9925</p> + </item> + <item> + <p> + Put gb_trees documentation into alphabetical order + (Thanks to Aidan Hobson Sayers)</p> + <p> + Own Id: OTP-9929</p> + </item> + <item> + <p> + Fix bug in ETS with <c>compressed</c> option and + insertion of term containing large integers (>2G) on + 64-bit machines. Seen to cause emulator crash. (Thanks to + Diego Llarrull for excellent bug report)</p> + <p> + Own Id: OTP-9932</p> + </item> + <item> + <p> + Add plugin support for alternative name lookup This patch + introduces a new way of locating a behaviour instance: + {via, Module, Name}. (Thanks to Ulf Wiger)</p> + <p> + Own Id: OTP-9945</p> + </item> + <item> + <p> The function <c>digraph_utils:condensation/1</c> used + to create a digraph containing loops contradicting the + documentation which states that the created digraph is + free of cycles. This bug has been fixed. (Thanks to + Kostis Sagonas for finding the bug.) </p> + <p> + Own Id: OTP-9953</p> + </item> + <item> + <p> When an escript ends now all printout to standard + output and standard error gets out on the terminal. This + bug has been corrected by changing the behaviour of + erlang:halt/0,1, which should fix the same problem for + other escript-like applications, i.e that data stored in + the output port driver buffers got lost when printing on + a TTY and exiting through erlang:halt/0,1. </p> + <p> The BIF:s erlang:halt/0,1 has gotten improved + semantics and there is a new BIF erlang:halt/2 to + accomplish something like the old semantics. See the + documentation. </p> + <p> Now erlang:halt/0 and erlang:halt/1 with an integer + argument will close all ports and allow all pending async + threads operations to finish before exiting the emulator. + Previously erlang:halt/0 and erlang:halt(0) would just + wait for pending async threads operations but not close + ports. And erlang:halt/1 with a non-zero integer argument + would not even wait for pending async threads operations. + </p> + <p> To roughly the old behaviour, to not wait for ports + and async threads operations when you exit the emulator, + you use erlang:halt/2 with an integer first argument and + an option list containing {flush,false} as the second + argument. Note that now is flushing not dependant of the + exit code, and you can not only flush async threads + operations which we deemed as a strange behaviour anyway. + </p> + <p>Also, erlang:halt/1,2 has gotten a new feature: If the + first argument is the atom 'abort' the emulator is + aborted producing a core dump, if the operating system so + allows. </p> + <p> + Own Id: OTP-9985</p> + </item> + <item> + <p> + Add escript win32 alternative invocation. escript can now + be started as both "escript.exe" and "escript" (Thanks to + Pierre Rouleau)</p> + <p> + Own Id: OTP-9997</p> + </item> + </list> + </section> + +</section> + <section><title>STDLIB 1.18</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/stdlib/examples/Makefile b/lib/stdlib/examples/Makefile index 25c88d1de3..198aceb3a9 100644 --- a/lib/stdlib/examples/Makefile +++ b/lib/stdlib/examples/Makefile @@ -47,6 +47,6 @@ RELSYSDIR = $(RELEASE_PATH)/lib/stdlib-$(STDLIB_VSN)/examples EXAMPLES = erl_id_trans.erl release_spec: - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(EXAMPLES) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EXAMPLES) "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile index 90e239b00f..8bdaae57fd 100644 --- a/lib/stdlib/src/Makefile +++ b/lib/stdlib/src/Makefile @@ -198,13 +198,13 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) erl_parse.yrl $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) erl_parse.yrl "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index d532cea187..b098d4cb91 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -264,6 +264,9 @@ ensure_dir(F) -> case do_is_dir(Dir, file) of true -> ok; + false when Dir =:= F -> + %% Protect against infinite loop + {error,einval}; false -> ensure_dir(Dir), case file:make_dir(Dir) of diff --git a/lib/stdlib/src/lib.erl b/lib/stdlib/src/lib.erl index 314fd60903..cf4b87d7eb 100644 --- a/lib/stdlib/src/lib.erl +++ b/lib/stdlib/src/lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. 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 @@ -209,7 +209,7 @@ explain_reason(badarg, error, [], _PF, _S) -> explain_reason({badarg,V}, error=Cl, [], PF, S) -> % orelse, andalso format_value(V, <<"bad argument: ">>, Cl, PF, S); explain_reason(badarith, error, [], _PF, _S) -> - <<"bad argument in an arithmetic expression">>; + <<"an error occurred when evaluating an arithmetic expression">>; explain_reason({badarity,{Fun,As}}, error, [], _PF, _S) when is_function(Fun) -> %% Only the arity is displayed, not the arguments As. diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile index 4de6ea3ee7..29b8e28d3a 100644 --- a/lib/stdlib/test/Makefile +++ b/lib/stdlib/test/Makefile @@ -135,10 +135,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) stdlib.spec $(EMAKEFILE) \ - $(ERL_FILES) $(COVERFILE) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(ERL_FILES) $(COVERFILE) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl index 9f95df062b..7ed1ee742a 100644 --- a/lib/stdlib/test/escript_SUITE.erl +++ b/lib/stdlib/test/escript_SUITE.erl @@ -62,7 +62,7 @@ end_per_group(_GroupName, Config) -> Config. init_per_testcase(_Case, Config) -> - ?line Dog = ?t:timetrap(?t:minutes(1)), + ?line Dog = ?t:timetrap(?t:minutes(2)), [{watchdog,Dog}|Config]. end_per_testcase(_Case, Config) -> diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl index 954d19a46f..297c4ec1c9 100644 --- a/lib/stdlib/test/ets_SUITE.erl +++ b/lib/stdlib/test/ets_SUITE.erl @@ -715,30 +715,17 @@ adjust_xmem([T1,T2,T3,T4], {A0,B0,C0,D0} = _Mem0) -> 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,{ets:info(T1,stats),ets:info(T2,stats),ets:info(T3,stats),ets:info(T4,stats)}}. - 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. t_whitebox(doc) -> ["Diverse whitebox testes"]; diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl index 9bed20f771..661d57c85b 100644 --- a/lib/stdlib/test/io_proto_SUITE.erl +++ b/lib/stdlib/test/io_proto_SUITE.erl @@ -137,7 +137,7 @@ unicode_prompt(Config) when is_list(Config) -> {putline, "io:get_line('')."}, {putline, "hej"}, {getline, "<<\"hej\\n\">>"} - ],[],[],"-pa "++ PA), + ],[],[],"-pa \""++ PA++"\""), %% And one with oldshell ?line rtnode([{putline,""}, {putline, "2."}, @@ -153,7 +153,7 @@ unicode_prompt(Config) when is_list(Config) -> {putline, "io:get_line('')."}, {putline, "hej"}, {getline_re, ".*<<\"hej\\\\n\">>"} - ],[],[],"-oldshell -pa "++PA), + ],[],[],"-oldshell -pa \""++PA++"\""), ok. @@ -732,7 +732,7 @@ bc_with_r12_1(Config) -> PA = filename:dirname(code:which(?MODULE)), Name1 = io_proto_r12_1, ?line N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()), - ?line ?t:start_node(Name1, peer, [{args, "-pz "++PA},{erl,[{release,"r12b"}]}]), + ?line ?t:start_node(Name1, peer, [{args, "-pz \""++PA++"\""},{erl,[{release,"r12b"}]}]), DataDir = ?config(data_dir,Config), %PrivDir = ?config(priv_dir,Config), FileName1 = filename:join([DataDir,"testdata_latin1.dat"]), @@ -908,7 +908,7 @@ bc_with_r12_gl_1(_Config,Machine) -> PA = filename:dirname(code:which(?MODULE)), Name1 = io_proto_r12_gl_1, ?line N1 = list_to_atom(atom_to_list(Name1) ++ "@" ++ hostname()), - ?line ?t:start_node(Name1, peer, [{args, "-pz "++PA},{erl,[{release,"r12b"}]}]), + ?line ?t:start_node(Name1, peer, [{args, "-pz \""++PA++"\""},{erl,[{release,"r12b"}]}]), TestDataLine1 = [229,228,246], TestDataLine1BinUtf = unicode:characters_to_binary(TestDataLine1), TestDataLine1BinLatin = list_to_binary(TestDataLine1), @@ -1290,7 +1290,7 @@ eof_on_pipe(Config) when is_list(Config) -> end end, CommandLine1 = EchoLine ++ - Erl++" -noshell -eval " + "\""++Erl++"\" -noshell -eval " "'io:format(\"~p\",[io:get_line(\"\")])," "io:format(\"~p\",[io:get_line(\"\")])," "io:format(\"~p\",[io:get_line(\"\")]).' -run init stop", @@ -1301,7 +1301,7 @@ eof_on_pipe(Config) when is_list(Config) -> exit({unexpected1,Other1}) end, CommandLine2 = EchoLine ++ - Erl++" -noshell -eval " + "\""++Erl++"\" -noshell -eval " "'io:setopts([binary]),io:format(\"~p\",[io:get_line(\"\")])," "io:format(\"~p\",[io:get_line(\"\")])," "io:format(\"~p\",[io:get_line(\"\")]).' -run init stop", @@ -1340,7 +1340,8 @@ rtnode(Commands,Nodename,ErlPrefix,Extra) -> ?line {skip, Reason2}; Tempdir -> ?line SPid = - start_runerl_node(RunErl,ErlPrefix++Erl, + start_runerl_node(RunErl,ErlPrefix++ + "\\\""++Erl++"\\\"", Tempdir,Nodename, Extra), ?line CPid = start_toerl_server(ToErl,Tempdir), ?line erase(getline_skipped), @@ -1607,10 +1608,10 @@ start_runerl_node(RunErl,Erl,Tempdir,Nodename,Extra) -> " "++Extra end, spawn(fun() -> - ?dbg(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++ - Erl++XArg++XXArg++"\""), - os:cmd(RunErl++" "++Tempdir++"/ "++Tempdir++" \""++ - Erl++XArg++XXArg++"\"") + ?dbg("\""++RunErl++"\" "++Tempdir++"/ "++Tempdir++ + " \""++Erl++XArg++XXArg++"\""), + os:cmd("\""++RunErl++"\" "++Tempdir++"/ "++Tempdir++ + " \""++Erl++XArg++XXArg++"\"") end). start_toerl_server(ToErl,Tempdir) -> @@ -1640,7 +1641,7 @@ try_to_erl(Command, N) -> end. toerl_server(Parent,ToErl,Tempdir) -> - Port = try_to_erl(ToErl++" "++Tempdir++"/ 2>/dev/null",8), + Port = try_to_erl("\""++ToErl++"\" "++Tempdir++"/ 2>/dev/null",8), case Port of P when is_port(P) -> Parent ! {self(),started}; diff --git a/lib/stdlib/test/shell_SUITE.erl b/lib/stdlib/test/shell_SUITE.erl index 5be14767fa..4b83e42ee0 100644 --- a/lib/stdlib/test/shell_SUITE.erl +++ b/lib/stdlib/test/shell_SUITE.erl @@ -153,7 +153,7 @@ start_restricted_from_shell(Config) when is_list(Config) -> comm_err(<<"begin init:stop() end.">>), ?line "exception exit: restricted shell does not allow init:stop()" = comm_err(<<"begin F = fun() -> init:stop() end, F() end.">>), - ?line "exception error: bad argument in an arithmetic expression" = + ?line "exception error: an error occurred when evaluating an arithmetic expression" = comm_err(<<"begin +a end.">>), ?line "exception exit: restricted shell does not allow a + b" = comm_err(<<"begin a+b end.">>), @@ -2359,7 +2359,7 @@ otp_6554(Config) when is_list(Config) -> comm_err(<<"fun(X) -> not X end(a).">>), ?line "exception error: bad argument: a" = comm_err(<<"fun(A, B) -> A orelse B end(a, b).">>), - ?line "exception error: bad argument in an arithmetic expression" = + ?line "exception error: an error occurred when evaluating an arithmetic expression" = comm_err(<<"math:sqrt(2)/round(math:sqrt(0)).">>), ?line "exception error: interpreted function with arity 1 called with no arguments" = comm_err(<<"fun(V) -> V end().">>), @@ -2478,9 +2478,9 @@ otp_6554(Config) when is_list(Config) -> " receive {'EXIT', Pid, {{nocatch,foo},_}} -> ok end " "end.">>), - ?line "exception error: bad argument in an arithmetic expression" = + ?line "exception error: an error occurred when evaluating an arithmetic expression" = comm_err(<<"begin catch_exception(true), 1/0 end.">>), - ?line "exception error: bad argument in an arithmetic expression" = + ?line "exception error: an error occurred when evaluating an arithmetic expression" = comm_err(<<"begin catch_exception(false), 1/0 end.">>), ?line "exception error: no function clause matching call to catch_exception/1" = comm_err(<<"catch_exception(1).">>), @@ -2637,7 +2637,7 @@ otp_8393(Config) when is_list(Config) -> prompt_err(<<"shell:prompt_func('> ').">>), ?line _ = shell:prompt_func(default), - ?line "exception error: bad argument in an arithmetic expression"++_ = + ?line "exception error: an error occurred when evaluating an arithmetic expression"++_ = prompt_err(<<"shell:prompt_func({shell_SUITE,prompt4}).">>), ?line _ = shell:prompt_func(default), @@ -2710,7 +2710,7 @@ prompt3(L) -> integer_to_list(N). prompt4(_L) -> - erlang:apply({erlang,'/'}, [1,0]). + erlang:apply(fun erlang:'/'/2, [1,0]). prompt5(_L) -> [1050,1072,1082,1074,1086,32,1077,32,85,110,105,99,111,100,101,32,63]. diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk index 694d39ce9c..3df7495ec4 100644 --- a/lib/stdlib/vsn.mk +++ b/lib/stdlib/vsn.mk @@ -1 +1 @@ -STDLIB_VSN = 1.18.1 +STDLIB_VSN = 1.18.2 diff --git a/lib/syntax_tools/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile index 291b3e3047..d1c6989bd9 100644 --- a/lib/syntax_tools/doc/src/Makefile +++ b/lib/syntax_tools/doc/src/Makefile @@ -125,13 +125,13 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index b9ac587043..434a3e721e 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -31,6 +31,21 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> +<section><title>Syntax_Tools 1.6.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Minor suppressions and fixes of compilation + warnings</p> + <p> + Own Id: OTP-10016</p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 1.6.7.2</title> <section><title>Improvements and New Features</title> diff --git a/lib/syntax_tools/examples/Makefile b/lib/syntax_tools/examples/Makefile index 7cfe9185c2..2724b0899b 100644 --- a/lib/syntax_tools/examples/Makefile +++ b/lib/syntax_tools/examples/Makefile @@ -49,8 +49,8 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(EXAMPLE_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile index bac138e95a..dca5e78be9 100644 --- a/lib/syntax_tools/src/Makefile +++ b/lib/syntax_tools/src/Makefile @@ -80,10 +80,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(OBJECTS) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(SOURCES) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(OBJECTS) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(SOURCES) "$(RELSYSDIR)/src" release_docs_spec: diff --git a/lib/syntax_tools/test/Makefile b/lib/syntax_tools/test/Makefile index 3e31bdbd50..d4733b9a42 100644 --- a/lib/syntax_tools/test/Makefile +++ b/lib/syntax_tools/test/Makefile @@ -57,9 +57,9 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) syntax_tools.spec syntax_tools.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) syntax_tools.spec syntax_tools.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 962492befd..2b9a08e192 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 1.6.7.2 +SYNTAX_TOOLS_VSN = 1.6.8 diff --git a/lib/test_server/doc/src/Makefile b/lib/test_server/doc/src/Makefile index b32f3d3c59..3ce549f0e1 100644 --- a/lib/test_server/doc/src/Makefile +++ b/lib/test_server/doc/src/Makefile @@ -119,16 +119,16 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 - $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man6" + $(INSTALL_DATA) $(MAN6_FILES) "$(RELEASE_PATH)/man/man6" release_spec: diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml index d90ad2c4ed..3701066e56 100644 --- a/lib/test_server/doc/src/notes.xml +++ b/lib/test_server/doc/src/notes.xml @@ -32,6 +32,155 @@ <file>notes.xml</file> </header> +<section><title>Test_Server 3.5.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + After a test case timeout or abortion, the + end_per_testcase function executes on a new dedicated + process. The group leader for this process should be set + to the IO server for the test case, which was not done + properly. The result of this error was that no warnings + about end_per_testcase failing or timing out were ever + printed in the test case log. Also, help functions such + as e.g. test_server:stop_node/1, attempting to + synchronize with the IO server, would hang. The fault has + been corrected.</p> + <p> + Own Id: OTP-9666</p> + </item> + <item> + <p> + A deadlock situation could occur if Common Test is + forwarding error_handler printouts to Test Server at the + same time a new test case is starting. This error has + been fixed.</p> + <p> + Own Id: OTP-9894</p> + </item> + <item> + <p> + When a test case was killed because of a timetrap + timeout, the current location (suite, case and line) was + not printed correctly in the log files. This has been + corrected.</p> + <p> + Own Id: OTP-9930 Aux Id: seq12002 </p> + </item> + <item> + <p> + Test Server and Common Test would add new error handlers + with each test run and fail to remove previously added + ones. In the case of Test Server, this would only happen + if SASL was not running on the test node. This has been + fixed.</p> + <p> + Own Id: OTP-9941 Aux Id: seq12009 </p> + </item> + <item> + <p> + If a test case process was terminated due to an exit + signal from a linked process, Test Server failed to + report the correct name of the suite and case to the + framework. This has been corrected.</p> + <p> + Own Id: OTP-9958 Aux Id: OTP-9855 </p> + </item> + </list> + </section> + + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + A new optional feature has been introduced that enables + Common Test to generate priv_dir directory names that are + unique for each test case or config function. The name of + the option/flag is 'create_priv_dir' and it can be set to + value 'auto_per_run' (which is the default, existing, + behaviour), or 'auto_per_tc' or 'manual_per_tc'. If + 'auto_per_tc' is used, Test Server creates a dedicated + priv_dir automatically for each test case (which can be + very expensive in case of many and/or repeated cases). If + 'manual_per_tc' is used, the user needs to create the + priv_dir explicitly by calling the new function + ct:make_priv_dir/0.</p> + <p> + Own Id: OTP-9659 Aux Id: seq11930 </p> + </item> + <item> + <p> + A column for test case group name has been added to the + suite overview HTML log file.</p> + <p> + Own Id: OTP-9730 Aux Id: seq11952 </p> + </item> + <item> + <p> + It is now possible to use the post_end_per_testcase CT + hook function to print a comment for a test case in the + overview log file, even if the test case gets killed by a + timetrap or unknown exit signal, or if the + end_per_testcase function times out.</p> + <p> + Own Id: OTP-9855 Aux Id: seq11979 </p> + </item> + <item> + <p> + Common Test will now print error information (with a time + stamp) in the test case log file immediately when a test + case fails. This makes it easier to see when, in time, + the fault actually occured, and aid the job of locating + relevant trace and debug printouts in the log.</p> + <p> + Own Id: OTP-9904 Aux Id: seq11985, OTP-9900 </p> + </item> + <item> + <p> + Test Server has been modified to check the SASL + errlog_type parameter when receiving an error logger + event, so that it doesn't print reports of type that the + user has disabled.</p> + <p> + Own Id: OTP-9955 Aux Id: seq12013 </p> + </item> + <item> + <p> + If an application cannot be found by ts it is + automatically skipped when testing.</p> + <p> + Own Id: OTP-9971</p> + </item> + <item> + <p> + By specifying a user defined function ({M,F,A} or fun) as + timetrap value, either by means of an info function or by + calling ct:timetrap/1, it is now possible to set a + timetrap that will be triggered when the user function + returns.</p> + <p> + Own Id: OTP-9988 Aux Id: OTP-9501, seq11894 </p> + </item> + <item> + <p> + If the optional configuration functions init_per_suite/1 + and end_per_suite/1 are not implemented in the test + suite, local Common Test versions of these functions are + called instead, and will be displayed in the overview log + file. Any printouts made by the pre- or + post_init_per_suite and pre- or post_end_per_suite hook + functions are saved in the log files for these functions.</p> + <p> + Own Id: OTP-9992</p> + </item> + </list> + </section> + +</section> + <section><title>Test_Server 3.5</title> <section><title>Improvements and New Features</title> diff --git a/lib/test_server/src/Makefile b/lib/test_server/src/Makefile index 4bc51873c2..a75855eaab 100644 --- a/lib/test_server/src/Makefile +++ b/lib/test_server/src/Makefile @@ -124,22 +124,22 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(INTERNAL_HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_tests_spec: opt - $(INSTALL_DIR) $(RELEASE_PATH)/test_server + $(INSTALL_DIR) "$(RELEASE_PATH)/test_server" $(INSTALL_DATA) $(ERL_FILES) $(TS_ERL_FILES) \ $(HRL_FILES) $(INTERNAL_HRL_FILES) $(TS_HRL_FILES) \ $(TS_TARGET_FILES) \ $(AUTOCONF_FILES) $(C_FILES) $(COVER_FILES) $(CONFIG) \ - $(RELEASE_PATH)/test_server - $(INSTALL_SCRIPT) $(PROGRAMS) $(RELEASE_PATH)/test_server + "$(RELEASE_PATH)/test_server" + $(INSTALL_SCRIPT) $(PROGRAMS) "$(RELEASE_PATH)/test_server" release_docs_spec: diff --git a/lib/test_server/src/configure.in b/lib/test_server/src/configure.in index 097853bcfc..77bc993ccd 100644 --- a/lib/test_server/src/configure.in +++ b/lib/test_server/src/configure.in @@ -108,7 +108,7 @@ AC_CHECK_HEADER(poll.h, AC_DEFINE(HAVE_POLL_H)) # for the system. AC_MSG_CHECKING([system version (for dynamic loading)]) -system=`uname -s`-`uname -r` +system=`./config.sub $host` AC_MSG_RESULT($system) # Step 2: check for existence of -ldl library. This is needed because @@ -119,10 +119,9 @@ AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no) # Step 3: set configuration options based on system name and version. SHLIB_LDLIBS= - fullSrcDir=`cd $srcdir; pwd` case $system in - Linux*) + *-linux-*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" if test "$have_dl" = yes; then @@ -136,7 +135,7 @@ case $system in fi SHLIB_EXTRACT_ALL="" ;; - NetBSD-*|FreeBSD-*|OpenBSD-*|DragonFly*) + *-netbsd*|*-freebsd*|*-openbsd*|*-dragonfly*) # Not available on all versions: check for include file. AC_CHECK_HEADER(dlfcn.h, [ SHLIB_CFLAGS="-fpic" @@ -153,28 +152,21 @@ case $system in ]) SHLIB_EXTRACT_ALL="" ;; - SunOS-4*) - SHLIB_CFLAGS="-PIC" - SHLIB_LD="ld" - SHLIB_LDFLAGS="$LDFLAGS" - SHLIB_SUFFIX=".so" - SHLIB_EXTRACT_ALL="" - ;; - SunOS-5*|UNIX_SV-4.2*) + *-solaris2*|*-sysv4*) SHLIB_CFLAGS="-KPIC" SHLIB_LD="/usr/ccs/bin/ld" SHLIB_LDFLAGS="$LDFLAGS -G -z text" SHLIB_SUFFIX=".so" SHLIB_EXTRACT_ALL="-z allextract" ;; - Darwin*) + *darwin*) SHLIB_CFLAGS="-fno-common" SHLIB_LD="cc" SHLIB_LDFLAGS="$LDFLAGS -bundle -flat_namespace -undefined suppress" SHLIB_SUFFIX=".so" SHLIB_EXTRACT_ALL="" ;; - OSF1*) + *osf1*) SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld" SHLIB_LDFLAGS="$LDFLAGS -shared" @@ -206,19 +198,19 @@ esac if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then case $system in - AIX-*) + *-aix) ;; - BSD/OS*) + *-bsd*) ;; - IRIX*) + *-irix) ;; - NetBSD-*|FreeBSD-*|OpenBSD-*) + *-netbsd|*-freebsd|*-openbsd) ;; - RISCos-*) + *-riscos) ;; - ULTRIX-4.*) + *ultrix4.*) ;; - Darwin*) + *darwin*) ;; *) SHLIB_CFLAGS="-fPIC" diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl index e8498a43f2..6358efa764 100644 --- a/lib/test_server/src/test_server_node.erl +++ b/lib/test_server/src/test_server_node.erl @@ -407,7 +407,7 @@ start_node_peer(SlaveName, OptList, From, TI) -> % Support for erl_crash_dump files.. CrashFile = filename:join([TI#target_info.test_server_dir, "erl_crash_dump."++cast_to_list(SlaveName)]), - CrashArgs = lists:concat([" -env ERL_CRASH_DUMP ",CrashFile," "]), + CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]), FailOnError = start_node_get_option_value(fail_on_error, OptList, true), Pa = TI#target_info.test_server_dir, Prog0 = start_node_get_option_value(erl, OptList, default), @@ -420,7 +420,7 @@ start_node_peer(SlaveName, OptList, From, TI) -> Cmd = lists:concat([Prog, " -detached ", TI#target_info.naming, " ", SlaveName, - " -pa ", Pa, + " -pa \"", Pa,"\"", NodeStarted, CrashArgs, " ", Args]), @@ -472,9 +472,9 @@ start_node_slave(SlaveName, OptList, From, TI) -> CrashFile = filename:join([TI#target_info.test_server_dir, "erl_crash_dump."++cast_to_list(SlaveName)]), - CrashArgs = lists:concat([" -env ERL_CRASH_DUMP ",CrashFile," "]), + CrashArgs = lists:concat([" -env ERL_CRASH_DUMP \"",CrashFile,"\" "]), Pa = TI#target_info.test_server_dir, - Args = lists:concat([" -pa ", Pa, " ", SuppliedArgs, CrashArgs]), + Args = lists:concat([" -pa \"", Pa, "\" ", SuppliedArgs, CrashArgs]), Prog0 = start_node_get_option_value(erl, OptList, default), Prog = pick_erl_program(Prog0), diff --git a/lib/test_server/src/ts.erl b/lib/test_server/src/ts.erl index cb06264adb..4899f38d2b 100644 --- a/lib/test_server/src/ts.erl +++ b/lib/test_server/src/ts.erl @@ -27,9 +27,10 @@ -export([run/0, run/1, run/2, run/3, run/4, clean/0, clean/1, tests/0, tests/1, - install/0, install/1, install/2, index/0, + install/0, install/1, index/0, estone/0, estone/1, cross_cover_analyse/1, + compile_testcases/0, compile_testcases/1, help/0]). -export([i/0, l/1, r/0, r/1, r/2, r/3]). @@ -88,35 +89,25 @@ -define( install_help, [ - " ts:install() - Install TS for local target with no Options.\n" - " ts:install([Options])\n", - " - Install TS for local target with Options\n" - " ts:install({Architecture, Target_name})\n", - " - Install TS for a remote target architecture.\n", - " and target network name (e.g. {vxworks_cpu32, sauron}).\n", - " ts:install({Architecture, Target_name}, [Options])\n", - " - Install TS as above, and with Options.\n", + " ts:install() - Install TS with no Options.\n" + " ts:install([Options]) - Install TS with Options\n" "\n", "Installation options supported:\n", " {longnames, true} - Use fully qualified hostnames\n", - " {hosts, [HostList]}\n" - " - Use theese hosts for distributed testing.\n" " {verbose, Level} - Sets verbosity level for TS output (0,1,2), 0 is\n" " quiet(default).\n" - " {slavetargets, SlaveTarges}\n" - " - Available hosts for starting slave nodes for\n" - " platforms which cannot have more than one erlang\n" - " node per host.\n" - " {crossroot, TargetErlRoot}\n" - " - Erlang root directory on target host\n" - " Mandatory for remote targets\n" - " {master, {MasterHost, MasterCookie}}\n" - " - Master host and cookie for targets which are\n" - " started as slave nodes.\n" - " erl_boot_server must be started on master before\n" - " test is run.\n" - " Optional, default is controller host and then\n" - " erl_boot_server is started autmatically\n" + " {crossroot, ErlTop}\n" + " - Erlang root directory on build host, ~n" + " normally same value as $ERL_TOP\n" + " {crossenv, [{Key,Val}]}\n" + " - Environmentals used by test configure on build host\n" + " {crossflags, FlagsString}\n" + " - Flags used by test configure on build host\n" + " {xcomp, XCompFile}\n" + " - The xcomp file to use for cross compiling the~n" + " testcases. Using this option will override any~n" + " cross* configurations given to ts. Note that you~n" + " have to have a correct ERL_TOP as well.~n" ]). help() -> @@ -183,26 +174,24 @@ help(installed) -> " cover_details. Analyses modules specified in\n" " cross.cover.\n" " Level can be 'overview' or 'details'.\n", + " ts:compile_testcases()~n" + " ts:compile_testcases(Apps)~n" + " - Compile all testcases for usage in a cross ~n" + " compile environment." " \n" "Installation (already done):\n" ], show_help([H,?install_help]). show_help(H) -> - io:put_chars(lists:flatten(H)). + io:format(lists:flatten(H)). %% Installs tests. install() -> ts_install:install(install_local,[]). -install({Architecture, Target_name}) -> - ts_install:install({ts_lib:maybe_atom_to_list(Architecture), - ts_lib:maybe_atom_to_list(Target_name)}, []); install(Options) when is_list(Options) -> ts_install:install(install_local,Options). -install({Architecture, Target_name}, Options) when is_list(Options)-> - ts_install:install({ts_lib:maybe_atom_to_list(Architecture), - ts_lib:maybe_atom_to_list(Target_name)}, Options). %% Updates the local index page. @@ -728,3 +717,23 @@ cover_type(cover_details) -> details. do_load(Mod) -> code:purge(Mod), code:load_file(Mod). + + +compile_testcases() -> + compile_datadirs("../*/*_data"). + +compile_testcases(App) when is_atom(App) -> + compile_testcases([App]); +compile_testcases([App | T]) -> + compile_datadirs(io_lib:format("../~s_test/*_data", [App])), + compile_testcases(T); +compile_testcases([]) -> + ok. + +compile_datadirs(DataDirs) -> + {ok,Variables} = file:consult("variables"), + + lists:foreach(fun(Dir) -> + ts_lib:make_non_erlang(Dir, Variables) + end, + filelib:wildcard(DataDirs)). diff --git a/lib/test_server/src/ts.hrl b/lib/test_server/src/ts.hrl index 885a726c54..db804d23a1 100644 --- a/lib/test_server/src/ts.hrl +++ b/lib/test_server/src/ts.hrl @@ -28,6 +28,7 @@ -define(run_summary, "suite.summary"). -define(cover_total,"total_cover.log"). -define(variables, "variables"). +-define(cross_variables, "variables-cross"). -define(LF, [10]). % Newline in VxWorks script -define(CHAR_PER_LINE, 60). % Characters per VxWorks script building line -define(CROSS_COOKIE, "cross"). % cookie used when cross platform testing diff --git a/lib/test_server/src/ts_autoconf_win32.erl b/lib/test_server/src/ts_autoconf_win32.erl index 9103542fd2..258040b39e 100644 --- a/lib/test_server/src/ts_autoconf_win32.erl +++ b/lib/test_server/src/ts_autoconf_win32.erl @@ -67,6 +67,7 @@ system_type(Vars) -> {5,1,_} -> "Windows XP"; {5,2,_} -> "Windows 2003"; {6,0,_} -> "Windows Vista"; + {6,1,_} -> "Windows 7"; {_,_,_} -> "Windows NCC-1701-D" end; {win32, windows} -> diff --git a/lib/test_server/src/ts_erl_config.erl b/lib/test_server/src/ts_erl_config.erl index 5585e8ccd3..45d88016a4 100644 --- a/lib/test_server/src/ts_erl_config.erl +++ b/lib/test_server/src/ts_erl_config.erl @@ -128,15 +128,15 @@ erts_lib(Vars,OsType) -> ErtsLibInternal} end, [{erts_lib_include, - filename:nativename(ErtsLibInclude)}, + quote(filename:nativename(ErtsLibInclude))}, {erts_lib_include_generated, - filename:nativename(ErtsLibIncludeGenerated)}, + quote(filename:nativename(ErtsLibIncludeGenerated))}, {erts_lib_include_internal, - filename:nativename(ErtsLibIncludeInternal)}, + quote(filename:nativename(ErtsLibIncludeInternal))}, {erts_lib_include_internal_generated, - filename:nativename(ErtsLibIncludeInternalGenerated)}, - {erts_lib_path, filename:nativename(ErtsLibPath)}, - {erts_lib_internal_path, filename:nativename(ErtsLibInternalPath)}, + quote(filename:nativename(ErtsLibIncludeInternalGenerated))}, + {erts_lib_path, quote(filename:nativename(ErtsLibPath))}, + {erts_lib_internal_path, quote(filename:nativename(ErtsLibInternalPath))}, {erts_lib_multi_threaded, erts_lib_name(multi_threaded, OsType)}, {erts_lib_single_threaded, erts_lib_name(single_threaded, OsType)} | Vars]. @@ -145,13 +145,13 @@ erl_include(Vars) -> Include = case erl_root(Vars) of {installed, Root} -> - filename:join([Root, "usr", "include"]); + quote(filename:join([Root, "usr", "include"])); {srctree, Root, Target} -> - filename:join([Root, "erts", "emulator", "beam"]) - ++ " -I" ++ filename:join([Root, "erts", "emulator"]) + quote(filename:join([Root, "erts", "emulator", "beam"])) + ++ " -I" ++ quote(filename:join([Root, "erts", "emulator"])) ++ system_include(Root, Vars) - ++ " -I" ++ filename:join([Root, "erts", "include"]) - ++ " -I" ++ filename:join([Root, "erts", "include", Target]) + ++ " -I" ++ quote(filename:join([Root, "erts", "include"])) + ++ " -I" ++ quote(filename:join([Root, "erts", "include", Target])) end, [{erl_include, filename:nativename(Include)}|Vars]. @@ -163,7 +163,7 @@ system_include(Root, Vars) -> "VxWorks" -> "sys.vxworks"; _ -> "sys/unix" end, - " -I" ++ filename:nativename(filename:join([Root, "erts", "emulator", SysDir])). + " -I" ++ quote(filename:nativename(filename:join([Root, "erts", "emulator", SysDir]))). erl_interface(Vars,OsType) -> {Incl, {LibPath, MkIncl}} = @@ -220,20 +220,16 @@ erl_interface(Vars,OsType) -> _ -> "" % VxWorks end, - CrossCompile = case OsType of - vxworks -> "true"; - _ -> "false" - end, - [{erl_interface_libpath, filename:nativename(LibPath)}, + [{erl_interface_libpath, quote(filename:nativename(LibPath))}, {erl_interface_sock_libs, sock_libraries(OsType)}, {erl_interface_lib, Lib}, {erl_interface_eilib, Lib1}, {erl_interface_lib_drv, LibDrv}, {erl_interface_eilib_drv, Lib1Drv}, {erl_interface_threadlib, ThreadLib}, - {erl_interface_include, filename:nativename(Incl)}, - {erl_interface_mk_include, filename:nativename(MkIncl)}, - {erl_interface_cross_compile, CrossCompile} | Vars]. + {erl_interface_include, quote(filename:nativename(Incl))}, + {erl_interface_mk_include, quote(filename:nativename(MkIncl))} + | Vars]. ic(Vars, OsType) -> {ClassPath, LibPath, Incl} = @@ -250,10 +246,10 @@ ic(Vars, OsType) -> end, filename:join(Dir, "include")} end, - [{ic_classpath, filename:nativename(ClassPath)}, - {ic_libpath, filename:nativename(LibPath)}, + [{ic_classpath, quote(filename:nativename(ClassPath))}, + {ic_libpath, quote(filename:nativename(LibPath))}, {ic_lib, link_library("ic", OsType)}, - {ic_include_path, filename:nativename(Incl)}|Vars]. + {ic_include_path, quote(filename:nativename(Incl))}|Vars]. jinterface(Vars, _OsType) -> ClassPath = @@ -263,7 +259,7 @@ jinterface(Vars, _OsType) -> Dir -> filename:join([Dir, "priv", "OtpErlang.jar"]) end, - [{jinterface_classpath, filename:nativename(ClassPath)}|Vars]. + [{jinterface_classpath, quote(filename:nativename(ClassPath))}|Vars]. lib_dir(Vars, Lib) -> LibLibDir = case Lib of @@ -276,8 +272,6 @@ lib_dir(Vars, Lib) -> case {get_var(crossroot, Vars), LibLibDir} of {{error, _}, _} -> %no crossroot LibLibDir; - {_, {error, _}} -> %no lib - LibLibDir; {CrossRoot, _} -> %% XXX: Ugly. So ugly I won't comment it %% /Patrik @@ -299,18 +293,16 @@ lib_dir(Vars, Lib) -> end. erl_root(Vars) -> - Root = code:root_dir(), - case ts_lib:erlang_type() of + Root = case get_var(crossroot,Vars) of + {error, notfound} -> code:root_dir(); + CrossRoot -> CrossRoot + end, + case ts_lib:erlang_type(Root) of {srctree, _Version} -> Target = get_var(target, Vars), {srctree, Root, Target}; {_, _Version} -> - case get_var(crossroot,Vars) of - {error, notfound} -> - {installed, Root}; - CrossRoot -> - {installed, CrossRoot} - end + {installed, Root} end. @@ -362,10 +354,17 @@ ssl(Vars, _OsType) -> {error, bad_name} -> throw({cannot_find_app, ssl}); Dir -> - [{ssl_libdir, filename:nativename(Dir)}| Vars] + [{ssl_libdir, quote(filename:nativename(Dir))}| Vars] end. separators(Vars, {win32,_}) -> [{'DS',"\\"},{'PS',";"}|Vars]; separators(Vars, _) -> [{'DS',"/"},{'PS',":"}|Vars]. + +quote([$ |R]) -> + "\\ "++quote(R); +quote([C|R]) -> + [C|quote(R)]; +quote([]) -> + []. diff --git a/lib/test_server/src/ts_install.erl b/lib/test_server/src/ts_install.erl index 9703478f20..99ccfbc9bc 100644 --- a/lib/test_server/src/ts_install.erl +++ b/lib/test_server/src/ts_install.erl @@ -28,12 +28,25 @@ install(install_local, Options) -> install(os:type(), Options); install(TargetSystem, Options) -> - io:format("Running configure for cross architecture, network target name~n" - "~p~n", [TargetSystem]), - case autoconf(TargetSystem) of + case file:consult(?variables) of + {ok, Vars} -> + case proplists:get_value(cross,Vars) of + "yes" when Options == []-> + target_install(Vars); + _ -> + build_install(TargetSystem, Options) + end; + _ -> + build_install(TargetSystem, Options) + end. + + +build_install(TargetSystem, Options) -> + XComp = parse_xcomp_file(proplists:get_value(xcomp,Options)), + case autoconf(TargetSystem, XComp++Options) of {ok, Vars0} -> OsType = os_type(TargetSystem), - Vars1 = ts_erl_config:variables(merge(Vars0,Options),OsType), + Vars1 = ts_erl_config:variables(Vars0++XComp++Options,OsType), {Options1, Vars2} = add_vars(Vars1, Options), Vars3 = lists:flatten([Options1|Vars2]), write_terms(?variables, Vars3); @@ -45,32 +58,43 @@ os_type({unix,_}=OsType) -> OsType; os_type({win32,_}=OsType) -> OsType; os_type(_Other) -> vxworks. -merge(Vars,[]) -> - Vars; -merge(Vars,[{crossroot,X}| Tail]) -> - merge([{crossroot, X} | Vars], Tail); -merge(Vars,[_X | Tail]) -> - merge(Vars,Tail). +target_install(CrossVars) -> + io:format("Cross installation detected, skipping configure and data_dir make~n"), + case file:rename(?variables,?cross_variables) of + ok -> + ok; + _ -> + io:format("Could not find variables file from cross make~n"), + throw(cross_installation_failed) + end, + CPU = proplists:get_value('CPU',CrossVars), + OS = proplists:get_value(os,CrossVars), + {Options,Vars} = add_vars([{cross,"yes"},{'CPU',CPU},{os,OS}],[]), + Variables = lists:flatten([Options|Vars]), + write_terms(?variables, Variables). %% Autoconf for various platforms. %% unix uses the configure script %% win32 uses ts_autoconf_win32 %% VxWorks uses ts_autoconf_vxworks. -autoconf(TargetSystem) -> - case autoconf1(TargetSystem) of +autoconf(TargetSystem, XComp) -> + case autoconf1(TargetSystem, XComp) of ok -> autoconf2(file:read_file("conf_vars")); Error -> Error end. -autoconf1({win32, _}) -> +autoconf1({win32, _},[{cross,"no"}]) -> ts_autoconf_win32:configure(); -autoconf1({unix, _}) -> - unix_autoconf(); -autoconf1(Other) -> - ts_autoconf_vxworks:configure(Other). +autoconf1({unix, _},XCompFile) -> + unix_autoconf(XCompFile); +autoconf1(Other,[{cross,"no"}]) -> + ts_autoconf_vxworks:configure(Other); +autoconf1(_,_) -> + io:format("cross compilation not supported for that this platform~n"), + throw(cross_installation_failed). autoconf2({ok, Bin}) -> get_vars(binary_to_list(Bin), name, [], []); @@ -92,27 +116,40 @@ get_vars([], name, [], Result) -> get_vars(_, _, _, _) -> {error, fatal_bad_conf_vars}. -unix_autoconf() -> +unix_autoconf(XConf) -> Configure = filename:absname("configure"), - Args = case catch erlang:system_info(threads) of - false -> ""; - _ -> " --enable-shlib-thread-safety" - end - ++ case catch string:str(erlang:system_info(system_version), - "debug") > 0 of - false -> ""; - _ -> " --enable-debug-mode" - end, + Flags = proplists:get_value(crossflags,XConf,[]), + Env = proplists:get_value(crossenv,XConf,[]), + Host = get_xcomp_flag("host", Flags), + Build = get_xcomp_flag("build", Flags), + Threads = [" --enable-shlib-thread-safety" || + erlang:system_info(threads) /= false], + Debug = [" --enable-debug-mode" || + string:str(erlang:system_info(system_version),"debug") > 0], + Args = Host ++ Build ++ Threads ++ Debug, case filelib:is_file(Configure) of true -> - Env = macosx_cflags(), - Port = open_port({spawn, Configure ++ Args}, - [stream, eof, {env,Env}]), + OSXEnv = macosx_cflags(), + io:format("Running ~sEnv: ~p~n", + [lists:flatten(Configure ++ Args),Env++OSXEnv]), + Port = open_port({spawn, lists:flatten(["\"",Configure,"\"",Args])}, + [stream, eof, {env,Env++OSXEnv}]), ts_lib:print_data(Port); false -> {error, no_configure_script} end. + +get_xcomp_flag(Flag, Flags) -> + get_xcomp_flag(Flag, Flag, Flags). +get_xcomp_flag(Flag, Tag, Flags) -> + case proplists:get_value(Flag,Flags) of + undefined -> ""; + "guess" -> [" --",Tag,"=",os:cmd("$ERL_TOP/erts/autoconf/config.guess")]; + HostVal -> [" --",Tag,"=",HostVal] + end. + + macosx_cflags() -> case os:type() of {unix, darwin} -> @@ -125,10 +162,33 @@ macosx_cflags() -> [] end. +parse_xcomp_file(undefined) -> + [{cross,"no"}]; +parse_xcomp_file(Filepath) -> + {ok,Bin} = file:read_file(Filepath), + Lines = binary:split(Bin,<<"\n">>,[global,trim]), + {Envs,Flags} = parse_xcomp_file(Lines,[],[]), + [{cross,"yes"},{crossroot,os:getenv("ERL_TOP")}, + {crossenv,Envs},{crossflags,Flags}]. + +parse_xcomp_file([<<A:8,_/binary>> = Line|R],Envs,Flags) + when $A =< A, A =< $Z -> + [Var,Value] = binary:split(Line,<<"=">>), + parse_xcomp_file(R,[{binary_to_list(Var), + binary_to_list(Value)}|Envs],Flags); +parse_xcomp_file([<<"erl_xcomp_",Line/binary>>|R],Envs,Flags) -> + [Var,Value] = binary:split(Line,<<"=">>), + parse_xcomp_file(R,Envs,[{binary_to_list(Var), + binary_to_list(Value)}|Flags]); +parse_xcomp_file([_|R],Envs,Flags) -> + parse_xcomp_file(R,Envs,Flags); +parse_xcomp_file([],Envs,Flags) -> + {lists:reverse(Envs),lists:reverse(Flags)}. + write_terms(Name, Terms) -> case file:open(Name, [write]) of {ok, Fd} -> - Result = write_terms1(Fd, Terms), + Result = write_terms1(Fd, remove_duplicates(Terms)), file:close(Fd), Result; {error, Reason} -> @@ -141,6 +201,17 @@ write_terms1(Fd, [Term|Rest]) -> write_terms1(_, []) -> ok. +remove_duplicates(List) -> + lists:reverse( + lists:foldl(fun({Key,Val},Acc) -> + R = make_ref(), + case proplists:get_value(Key,Acc,R) of + R -> [{Key,Val}|Acc]; + _Else -> + Acc + end + end,[],List)). + add_vars(Vars0, Opts0) -> {Opts,LongNames} = case lists:keymember(longnames, 1, Opts0) of @@ -209,12 +280,11 @@ platform(Vars) -> LC = lock_checking(), MT = modified_timing(), AsyncThreads = async_threads(), - HeapType = heap_type_label(), Debug = debug(), CpuBits = word_size(), Common = lists:concat([Hostname,"/",OsType,"/",CpuType,CpuBits,LinuxDist, Schedulers,BindType,KP,IOTHR,LC,MT,AsyncThreads, - HeapType,Debug,ExtraLabel]), + Debug,ExtraLabel]), PlatformId = lists:concat([ErlType, " ", Version, Common]), PlatformLabel = ErlType ++ Common, PlatformFilename = platform_as_filename(PlatformId), @@ -272,12 +342,6 @@ hostname() -> "/localhost" end. -heap_type_label() -> - case catch erlang:system_info(heap_type) of - hybrid -> "/Hybrid"; - _ -> "" %private - end. - async_threads() -> case catch erlang:system_info(threads) of true -> "/A"++integer_to_list(erlang:system_info(thread_pool_size)); diff --git a/lib/test_server/src/ts_install_cth.erl b/lib/test_server/src/ts_install_cth.erl index a41916fd0a..67f2df0cae 100644 --- a/lib/test_server/src/ts_install_cth.erl +++ b/lib/test_server/src/ts_install_cth.erl @@ -95,17 +95,12 @@ pre_init_per_suite(_Suite,Config,State) -> try {ok,Variables} = file:consult(filename:join(State#state.ts_conf_dir,"variables")), - - %% Make the stuff in all_SUITE_data if it exists - AllDir = filename:join(DataDir,"../all_SUITE_data"), - case filelib:is_dir(AllDir) of - true -> - make_non_erlang(AllDir,Variables); - false -> - ok + case proplists:get_value(cross,Variables) of + "yes" -> + ct:log("Not making data dir as tests have been cross compiled"); + _ -> + ts_lib:make_non_erlang(DataDir, Variables) end, - - make_non_erlang(DataDir, Variables), {add_node_name(Config, State), State} catch Error:Reason -> @@ -219,39 +214,6 @@ terminate(_State) -> %%% ============================================================================ %%% Local functions %%% ============================================================================ -%% Configure and run all the Makefiles in the data dirs of the suite -%% in question -make_non_erlang(DataDir, Variables) -> - {ok,CurrWD} = file:get_cwd(), - try - file:set_cwd(DataDir), - MakeCommand = proplists:get_value(make_command,Variables), - - FirstMakefile = filename:join(DataDir,"Makefile.first"), - case filelib:is_regular(FirstMakefile) of - true -> - ct:log("Making ~p",[FirstMakefile]), - ok = ts_make:make( - MakeCommand, DataDir, filename:basename(FirstMakefile)); - false -> - ok - end, - - MakefileSrc = filename:join(DataDir,"Makefile.src"), - MakefileDest = filename:join(DataDir,"Makefile"), - case filelib:is_regular(MakefileSrc) of - true -> - ok = ts_lib:subst_file(MakefileSrc,MakefileDest,Variables), - ct:log("Making ~p",[MakefileDest]), - ok = ts_make:make([{makefile,"Makefile"},{data_dir,DataDir} - | Variables]); - false -> - ok - end - after - file:set_cwd(CurrWD), - timer:sleep(100) - end. %% Add a nodename to config if it does not exist add_node_name(Config, State) -> diff --git a/lib/test_server/src/ts_lib.erl b/lib/test_server/src/ts_lib.erl index 2f0a4ea8c0..d521d2beda 100644 --- a/lib/test_server/src/ts_lib.erl +++ b/lib/test_server/src/ts_lib.erl @@ -24,10 +24,12 @@ %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). -export([error/1, var/2, erlang_type/0, + erlang_type/1, initial_capital/1, interesting_logs/1, specs/1, suites/2, last_test/1, force_write_file/2, force_delete/1, subst_file/3, subst/2, print_data/1, + make_non_erlang/2, maybe_atom_to_list/1, progress/4 ]). @@ -73,8 +75,10 @@ progress(Vars, Level, Format, Args) -> %% Returns: {Type, Version} where Type is otp|src erlang_type() -> + erlang_type(code:root_dir()). +erlang_type(RootDir) -> {_, Version} = init:script_id(), - RelDir = filename:join(code:root_dir(), "releases"), % Only in installed + RelDir = filename:join(RootDir, "releases"), % Only in installed case filelib:is_file(RelDir) of true -> {otp,Version}; % installed OTP false -> {srctree,Version} % source code tree @@ -333,3 +337,45 @@ maybe_atom_to_list(To_list) when is_list(To_list) -> maybe_atom_to_list(To_list) when is_atom(To_list)-> atom_to_list(To_list). + +%% Configure and run all the Makefiles in the data dir of the suite +%% in question +make_non_erlang(DataDir, Variables) -> + %% Make the stuff in all_SUITE_data if it exists + AllDir = filename:join(DataDir,"../all_SUITE_data"), + case filelib:is_dir(AllDir) of + true -> + make_non_erlang_do(AllDir,Variables); + false -> + ok + end, + make_non_erlang_do(DataDir, Variables). + +make_non_erlang_do(DataDir, Variables) -> + try + MakeCommand = proplists:get_value(make_command,Variables), + + FirstMakefile = filename:join(DataDir,"Makefile.first"), + case filelib:is_regular(FirstMakefile) of + true -> + io:format("Making ~p",[FirstMakefile]), + ok = ts_make:make( + MakeCommand, DataDir, filename:basename(FirstMakefile)); + false -> + ok + end, + + MakefileSrc = filename:join(DataDir,"Makefile.src"), + MakefileDest = filename:join(DataDir,"Makefile"), + case filelib:is_regular(MakefileSrc) of + true -> + ok = ts_lib:subst_file(MakefileSrc,MakefileDest,Variables), + io:format("Making ~p",[MakefileDest]), + ok = ts_make:make([{makefile,"Makefile"},{data_dir,DataDir} + | Variables]); + false -> + ok + end + after + timer:sleep(100) %% maybe unnecessary now when we don't do set_cwd anymore + end. diff --git a/lib/test_server/src/ts_make.erl b/lib/test_server/src/ts_make.erl index 3df66111a3..1d8ef230c7 100644 --- a/lib/test_server/src/ts_make.erl +++ b/lib/test_server/src/ts_make.erl @@ -25,12 +25,12 @@ %% Functions to be called from make test cases. make(Config) when is_list(Config) -> - DataDir = ?config(data_dir, Config), - Makefile = ?config(makefile, Config), - Make = ?config(make_command, Config), + DataDir = proplists:get_value(data_dir, Config), + Makefile = proplists:get_value(makefile, Config), + Make = proplists:get_value(make_command, Config), case make(Make, DataDir, Makefile) of ok -> ok; - {error,Reason} -> ?t:fail({make_failed,Reason}) + {error,Reason} -> exit({make_failed,Reason}) end. unmake(Config) when is_list(Config) -> @@ -85,7 +85,7 @@ run_make_script({win32, _}, Make, Dir, Makefile) -> {"run_make.bat", ".\\run_make", ["@echo off\r\n", - "cd ", filename:nativename(Dir), "\r\n", + "cd \"", filename:nativename(Dir), "\"\r\n", Make, " -f ", Makefile, " \r\n", "if errorlevel 1 echo *error*\r\n", "if not errorlevel 1 echo *ok*\r\n"]}; @@ -93,7 +93,7 @@ run_make_script({unix, _}, Make, Dir, Makefile) -> {"run_make", "/bin/sh ./run_make", ["#!/bin/sh\n", - "cd ", Dir, "\n", + "cd \"", Dir, "\"\n", Make, " -f ", Makefile, " 2>&1\n", "case $? in\n", " 0) echo '*ok*';;\n", diff --git a/lib/test_server/src/ts_run.erl b/lib/test_server/src/ts_run.erl index 885a3c9b96..a61028e4bc 100644 --- a/lib/test_server/src/ts_run.erl +++ b/lib/test_server/src/ts_run.erl @@ -229,7 +229,7 @@ make_command(Vars, Spec, State) -> %% uncomment the line below to disable exception formatting %% " -test_server_format_exception false", " -boot start_sasl -sasl errlog_type error", - " -pz ",Cwd, + " -pz \"",Cwd,"\"", " -ct_test_vars ",TestVars, " -eval \"file:set_cwd(\\\"",TestDir,"\\\")\" " " -eval \"ct:run_test(", diff --git a/lib/test_server/test/Makefile b/lib/test_server/test/Makefile index 198440bb17..b2ac95afaa 100644 --- a/lib/test_server/test/Makefile +++ b/lib/test_server/test/Makefile @@ -83,10 +83,10 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) $(RELSYSDIR) - $(INSTALL_DATA) test_server_test_lib.hrl test_server.spec test_server.cover $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(EMAKEFILE) $(ERL_FILES) $(COVERFILE) "$(RELSYSDIR)" + $(INSTALL_DATA) test_server_test_lib.hrl test_server.spec test_server.cover "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/toolbar/doc/src/Makefile b/lib/toolbar/doc/src/Makefile index 76147c111e..af907859d7 100644 --- a/lib/toolbar/doc/src/Makefile +++ b/lib/toolbar/doc/src/Makefile @@ -102,14 +102,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/toolbar/doc/src/notes.xml b/lib/toolbar/doc/src/notes.xml index ac6ad533fc..b901e6c8ff 100644 --- a/lib/toolbar/doc/src/notes.xml +++ b/lib/toolbar/doc/src/notes.xml @@ -31,6 +31,26 @@ <p>This document describes the changes made to the Toolbar application.</p> +<section><title>Toolbar 1.4.2.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + <section><title>Toolbar 1.4.2.1</title> <section><title>Improvements and New Features</title> diff --git a/lib/toolbar/src/Makefile b/lib/toolbar/src/Makefile index 14e1451609..91ce305e26 100644 --- a/lib/toolbar/src/Makefile +++ b/lib/toolbar/src/Makefile @@ -84,10 +84,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/toolbar/vsn.mk b/lib/toolbar/vsn.mk index b2b0764877..9fbfec871f 100644 --- a/lib/toolbar/vsn.mk +++ b/lib/toolbar/vsn.mk @@ -1,4 +1,4 @@ -TOOLBAR_VSN = 1.4.2.1 +TOOLBAR_VSN = 1.4.2.2 diff --git a/lib/tools/c_src/Makefile.in b/lib/tools/c_src/Makefile.in index b8c4aed6e2..0382d3228d 100644 --- a/lib/tools/c_src/Makefile.in +++ b/lib/tools/c_src/Makefile.in @@ -188,11 +188,11 @@ include ../vsn.mk RELSYSDIR = $(RELEASE_PATH)/lib/tools-$(TOOLS_VSN) release_spec: all - $(INSTALL_DIR) $(RELSYSDIR)/c_src - $(INSTALL_DATA) $(EMEM_SRCS) $(EMEM_HEADERS) $(RELSYSDIR)/c_src + $(INSTALL_DIR) "$(RELSYSDIR)/c_src" + $(INSTALL_DATA) $(EMEM_SRCS) $(EMEM_HEADERS) "$(RELSYSDIR)/c_src" ifneq ($(PROGS),) - $(INSTALL_DIR) $(RELSYSDIR)/bin - $(INSTALL_PROGRAM) $(PROGS) $(RELSYSDIR)/bin + $(INSTALL_DIR) "$(RELSYSDIR)/bin" + $(INSTALL_PROGRAM) $(PROGS) "$(RELSYSDIR)/bin" endif release_docs_spec: diff --git a/lib/tools/doc/src/Makefile b/lib/tools/doc/src/Makefile index 433f123ae5..a76ce98ad6 100644 --- a/lib/tools/doc/src/Makefile +++ b/lib/tools/doc/src/Makefile @@ -121,14 +121,14 @@ clean clean_docs: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/tools/doc/src/eprof.xml b/lib/tools/doc/src/eprof.xml index 8b614d8860..1c5e38109b 100644 --- a/lib/tools/doc/src/eprof.xml +++ b/lib/tools/doc/src/eprof.xml @@ -67,9 +67,9 @@ <p><c>Rootset</c> is a list of pids and registered names.</p> <p>The function returns <c>profiling</c> if tracing could be enabled for all processes in <c>Rootset</c>, or <c>error</c> otherwise.</p> - <p>A pattern can be selected to narrow the profiling. For instance ca a specific - module be selected and only the code processes executes in that module will be - profiled.</p> + <p>A pattern can be selected to narrow the profiling. For instance a + specific module can be selected, and only the code executed in that + module will be profiled.</p> </desc> </func> <func> @@ -147,8 +147,8 @@ </type> <desc> <p>This function ensures that the results displayed by - <c>analyze/0,1,2</c> are printed both to - the file <c>File</c> and the screen.</p> + <c>analyze/0,1,2</c> are printed both to the file + <c>File</c> and the screen.</p> </desc> </func> <func> diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml index e24e1c5977..f4da132102 100644 --- a/lib/tools/doc/src/notes.xml +++ b/lib/tools/doc/src/notes.xml @@ -30,6 +30,31 @@ </header> <p>This document describes the changes made to the Tools application.</p> +<section><title>Tools 2.6.7</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Makefiles in erts, hipe and tools have been corrected to + enable parallel make, i.e MAKEFLAGS=-jX where X is the + parallelity number. As a result of this dependencies were + corrected since that is what is needed for parallel make + to work.</p> + <p> + Own Id: OTP-9857 Aux Id: OTP-9451 </p> + </item> + <item> + <p>Minor suppressions and fixes of compilation + warnings</p> + <p> + Own Id: OTP-10016</p> + </item> + </list> + </section> + +</section> + <section><title>Tools 2.6.6.6</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile index 8533488463..e5ed56b412 100644 --- a/lib/tools/emacs/Makefile +++ b/lib/tools/emacs/Makefile @@ -71,9 +71,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/emacs + $(INSTALL_DIR) "$(RELSYSDIR)/emacs" $(INSTALL_DATA) $(EL_FILES) $(README_FILES) $(TEST_FILES) \ - $(RELSYSDIR)/emacs + "$(RELSYSDIR)/emacs" ifeq ($(DOCTYPE),pdf) release_docs_spec: @@ -82,7 +82,7 @@ ifeq ($(DOCTYPE),ps) release_docs_spec: else release_docs_spec: docs - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN_FILES) $(RELEASE_PATH)/man/man3 + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN_FILES) "$(RELEASE_PATH)/man/man3" endif endif diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el index bc7a190fb4..2f6c7f554e 100644 --- a/lib/tools/emacs/erlang.el +++ b/lib/tools/emacs/erlang.el @@ -2986,18 +2986,52 @@ This assumes that the preceding expression is either simple (forward-sexp (- arg)) (let ((col (current-column))) (skip-chars-backward " \t") - ;; Needed to match the colon in "'foo':'bar'". - (if (not (memq (preceding-char) '(?# ?:))) - col - ;; Special hack to handle: (note line break) - ;; [#myrecord{ - ;; foo = foo}] - (or - (ignore-errors - (backward-char 1) - (forward-sexp -1) - (current-column)) - col))))) + ;; Special hack to handle: (note line break) + ;; [#myrecord{ + ;; foo = foo}] + ;; where the call (forward-sexp -1) will fail when point is at the `#'. + (or + (ignore-errors + ;; Needed to match the colon in "'foo':'bar'". + (cond ((eq (preceding-char) ?:) + (backward-char 1) + (forward-sexp -1) + (current-column)) + ((eq (preceding-char) ?#) + ;; We may now be at: + ;; - either a construction of a new record + ;; - or update of a record, in which case we want + ;; the column of the expression to be updated. + ;; + ;; To see which of the two cases we are at, we first + ;; move an expression backwards, check for keywords, + ;; then immediately an expression forwards. Moving + ;; backwards skips past tokens like `,' or `->', but + ;; when moving forwards again, we won't skip past such + ;; tokens. We use this: if, after having moved + ;; forwards, we're back where we started, then it was + ;; a record update. + ;; The check for keywords is to detect cases like: + ;; case Something of #record_construction{...} + (backward-char 1) + (let ((record-start (point)) + (record-start-col (current-column))) + (forward-sexp -1) + (let ((preceding-expr-col (current-column)) + ;; white space definition according to erl_scan + (white-space "\000-\040\200-\240")) + (if (erlang-at-keyword) + ;; The (forward-sexp -1) call moved past a keyword + (1+ record-start-col) + (forward-sexp 1) + (skip-chars-forward white-space record-start) + ;; Are we back where we started? If so, it was an update. + (if (= (point) record-start) + preceding-expr-col + (goto-char record-start) + (1+ (current-column))))))) + (t col))) + col)))) (defun erlang-indent-parenthesis (stack-position) (let ((previous (erlang-indent-find-preceding-expr))) diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented index 2948ccf1b5..e0593c6522 100644 --- a/lib/tools/emacs/test.erl.indented +++ b/lib/tools/emacs/test.erl.indented @@ -657,3 +657,41 @@ indent_comprehensions() -> foo() -> [#foo{ foo = foo}]. + +%% Record indentation +some_function_with_a_very_long_name() -> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b}, + case dummy_function_with_a_very_very_long_name(x) of + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b} -> + ok; + Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b} -> + Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b}; + #xyz{ + a=1, + b=2} -> + ok + end. + +another_function_with_a_very_very_long_name() -> + #rec{ + field1=1, + field2=1}. + +some_function_name_xyz(xyzzy, #some_record{ + field1=Field1, + field2=Field2}) -> + SomeVariable = f(#'Some-long-record-name'{ + field_a = 1, + 'inter-xyz-parameters' = + #'Some-other-very-long-record-name'{ + field2 = Field1, + field2 = Field2}}), + {ok, SomeVariable}. diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig index 1221c5655e..69356aca9e 100644 --- a/lib/tools/emacs/test.erl.orig +++ b/lib/tools/emacs/test.erl.orig @@ -657,3 +657,41 @@ ok. foo() -> [#foo{ foo = foo}]. + +%% Record indentation +some_function_with_a_very_long_name() -> + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b}, + case dummy_function_with_a_very_very_long_name(x) of + #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b} -> + ok; + Var = #'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b} -> + Var#'a-long-record-name-like-it-sometimes-is-with-asn.1-records'{ + field1=a, + field2=b}; + #xyz{ + a=1, + b=2} -> + ok + end. + +another_function_with_a_very_very_long_name() -> + #rec{ + field1=1, + field2=1}. + +some_function_name_xyz(xyzzy, #some_record{ + field1=Field1, + field2=Field2}) -> + SomeVariable = f(#'Some-long-record-name'{ + field_a = 1, + 'inter-xyz-parameters' = + #'Some-other-very-long-record-name'{ + field2 = Field1, + field2 = Field2}}), + {ok, SomeVariable}. diff --git a/lib/tools/examples/Makefile b/lib/tools/examples/Makefile index 9fb8434633..fc14ee54d6 100644 --- a/lib/tools/examples/Makefile +++ b/lib/tools/examples/Makefile @@ -50,7 +50,7 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples + $(INSTALL_DIR) "$(RELSYSDIR)/examples" + $(INSTALL_DATA) $(EXAMPLE_FILES) "$(RELSYSDIR)/examples" release_docs_spec: diff --git a/lib/tools/priv/Makefile b/lib/tools/priv/Makefile index 6fea580c00..b32ba5820d 100644 --- a/lib/tools/priv/Makefile +++ b/lib/tools/priv/Makefile @@ -58,9 +58,9 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(TOOL_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(HTDOCS_FILES) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(TOOL_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/tools/src/Makefile b/lib/tools/src/Makefile index 360f4f8f29..4c0cc8cde7 100644 --- a/lib/tools/src/Makefile +++ b/lib/tools/src/Makefile @@ -105,10 +105,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(YRL_FILE) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \ - $(RELSYSDIR)/ebin + "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl index 8165a6c13a..4cbb910f11 100644 --- a/lib/tools/src/fprof.erl +++ b/lib/tools/src/fprof.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% Copyright Ericsson AB 2001-2012. 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 @@ -89,9 +89,7 @@ dbg(_, _, _) -> apply({M, F}, Args) when is_atom(M), is_atom(F), is_list(Args) -> - Arity = length(Args), - Function = fun M:F/Arity, - apply_1(Function, Args, []); + apply_1(M, F, Args, []); apply(Fun, Args) when is_function(Fun), is_list(Args) -> apply_1(Fun, Args, []); @@ -99,26 +97,25 @@ apply(A, B) -> erlang:error(badarg, [A, B]). apply(M, F, Args) when is_atom(M), is_atom(F), is_list(Args) -> - apply_1({M, F}, Args, []); + apply_1(M, F, Args, []); apply({M, F}, Args, Options) when is_atom(M), is_atom(F), is_list(Args), is_list(Options) -> - Arity = length(Args), - Function = fun M:F/Arity, - apply_1(Function, Args, Options); + apply_1(M, F, Args, Options); apply(Fun, Args, Options) when is_function(Fun), is_list(Args), is_list(Options) -> apply_1(Fun, Args, Options); apply(A, B, C) -> erlang:error(badarg, [A, B, C]). -apply(Module, Function, Args, Options) - when is_atom(Module), is_atom(Function), is_list(Args), is_list(Options) -> - Arity = length(Args), - Fun = fun Module:Function/Arity, - apply_1(Fun, Args, Options); +apply(M, F, Args, Options) + when is_atom(M), is_atom(F), is_list(Args), is_list(Options) -> + apply_1(M, F, Args, Options); apply(A, B, C, D) -> erlang:error(badarg, [A, B, C, D]). +apply_1(M, F, Args, Options) -> + Arity = length(Args), + apply_1(fun M:F/Arity, Args, Options). apply_1(Function, Args, Options) -> {[_, Procs, Continue], Options_1} = diff --git a/lib/tools/test/Makefile b/lib/tools/test/Makefile index 8019b7269f..b9a42041a2 100644 --- a/lib/tools/test/Makefile +++ b/lib/tools/test/Makefile @@ -84,11 +84,11 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: make_emakefile - $(INSTALL_DIR) $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" $(INSTALL_DATA) $(SPEC_FILES) $(COVER_FILE) $(EMAKEFILE) \ - $(ERL_FILES) $(RELSYSDIR) - chmod -R u+w $(RELSYSDIR) - @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -) + $(ERL_FILES) "$(RELSYSDIR)" + chmod -R u+w "$(RELSYSDIR)" + @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/tools/test/cover_SUITE.erl b/lib/tools/test/cover_SUITE.erl index 576d7e261c..0cd53a05db 100644 --- a/lib/tools/test/cover_SUITE.erl +++ b/lib/tools/test/cover_SUITE.erl @@ -574,14 +574,7 @@ otp_5418(Config) when is_list(Config) -> ok. -otp_6115(suite) -> []; otp_6115(Config) when is_list(Config) -> - case erlang:system_info(heap_type) of - hybrid -> {skip,"Hybrid-heap emulator doesn't keep track of funs"}; - _ -> otp_6115_1(Config) - end. - -otp_6115_1(Config) -> ?line {ok, CWD} = file:get_cwd(), ?line Dir = filename:join(?config(data_dir, Config), otp_6115), ?line ok = file:set_cwd(Dir), diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk index 269d3d7773..788ee12900 100644 --- a/lib/tools/vsn.mk +++ b/lib/tools/vsn.mk @@ -1 +1 @@ -TOOLS_VSN = 2.6.6.6 +TOOLS_VSN = 2.6.8 diff --git a/lib/tv/doc/src/Makefile b/lib/tv/doc/src/Makefile index 21478d0931..e36dd84b73 100644 --- a/lib/tv/doc/src/Makefile +++ b/lib/tv/doc/src/Makefile @@ -125,14 +125,14 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/tv/doc/src/notes.xml b/lib/tv/doc/src/notes.xml index 97c99e6202..9217c018e9 100644 --- a/lib/tv/doc/src/notes.xml +++ b/lib/tv/doc/src/notes.xml @@ -30,6 +30,26 @@ </header> <p>This document describes the changes made to the TV application.</p> +<section><title>TV 2.1.4.9</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The GS applications is now deprecated and will be + removed in the R16 release. The following GS-based + applications have been superseded by the Observer + application and will removed in R16: Appmon, Pman, + Tv.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-9907</p> + </item> + </list> + </section> + +</section> + <section><title>TV 2.1.4.8</title> <section><title>Improvements and New Features</title> diff --git a/lib/tv/priv/Makefile b/lib/tv/priv/Makefile index 69e3e32c8a..73ea8f4ee9 100644 --- a/lib/tv/priv/Makefile +++ b/lib/tv/priv/Makefile @@ -64,8 +64,8 @@ clean: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) $(TOOLBAR_FILES) $(RELSYSDIR)/priv + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) $(TOOLBAR_FILES) "$(RELSYSDIR)/priv" release_docs_spec: diff --git a/lib/tv/src/Makefile b/lib/tv/src/Makefile index 457b9d38c4..f078e5dee1 100644 --- a/lib/tv/src/Makefile +++ b/lib/tv/src/Makefile @@ -126,10 +126,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/tv/vsn.mk b/lib/tv/vsn.mk index 756aae2096..1bb8ca30f8 100644 --- a/lib/tv/vsn.mk +++ b/lib/tv/vsn.mk @@ -1 +1 @@ -TV_VSN = 2.1.4.8 +TV_VSN = 2.1.4.9 diff --git a/lib/typer/src/Makefile b/lib/typer/src/Makefile index 620b3ebb69..c3fae0ad42 100644 --- a/lib/typer/src/Makefile +++ b/lib/typer/src/Makefile @@ -101,10 +101,10 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DIR) "$(RELSYSDIR)/src" $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(YRL_FILES) \ - $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(INSTALL_FILES) $(RELSYSDIR)/ebin + "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(INSTALL_FILES) "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/typer/src/typer.erl b/lib/typer/src/typer.erl index 6392f5765f..1e40b8926e 100644 --- a/lib/typer/src/typer.erl +++ b/lib/typer/src/typer.erl @@ -83,6 +83,7 @@ start() -> {Args, Analysis} = process_cl_args(), %% io:format("Args: ~p\n", [Args]), %% io:format("Analysis: ~p\n", [Analysis]), + Timer = dialyzer_timing:init(false), TrustedFiles = filter_fd(Args#args.trusted, [], fun is_erl_file/1), Analysis2 = extract(Analysis, TrustedFiles), All_Files = get_all_files(Args), @@ -91,6 +92,7 @@ start() -> Analysis4 = collect_info(Analysis3), %% io:format("Final: ~p\n", [Analysis4#analysis.fms]), TypeInfo = get_type_info(Analysis4), + dialyzer_timing:stop(Timer), show_or_annotate(TypeInfo), %% io:format("\nTyper analysis finished\n"), erlang:halt(0). @@ -181,7 +183,6 @@ get_type_info(#analysis{callgraph = CallGraph, remove_external(CallGraph, PLT) -> {StrippedCG0, Ext} = dialyzer_callgraph:remove_external(CallGraph), - StrippedCG = dialyzer_callgraph:finalize(StrippedCG0), case get_external(Ext, PLT) of [] -> ok; Externals -> @@ -192,7 +193,7 @@ remove_external(CallGraph, PLT) -> _ -> msg(io_lib:format(" Unknown types: ~p\n", [ExtTypes])) end end, - StrippedCG. + StrippedCG0. -spec get_external([{mfa(), mfa()}], plt()) -> [mfa()]. @@ -901,8 +902,9 @@ analyze_core_tree(Core, Records, SpecInfo, CbInfo, ExpTypes, Analysis, File) -> MergedExpTypes = sets:union(ExpTypes, OldExpTypes), CS6 = dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes, CS5), Ex_Funcs = [{0,F,A} || {_,_,{F,A}} <- cerl:module_exports(Tree)], - TmpCG = Analysis#analysis.callgraph, - CG = dialyzer_callgraph:scan_core_tree(Tree, TmpCG), + CG = Analysis#analysis.callgraph, + {V, E} = dialyzer_callgraph:scan_core_tree(Tree, CG), + dialyzer_callgraph:add_edges(E, V, CG), Fun = fun analyze_one_function/2, All_Defs = cerl:module_defs(Tree), Acc = lists:foldl(Fun, #tmpAcc{file = File, module = Module}, All_Defs), diff --git a/lib/webtool/doc/src/Makefile b/lib/webtool/doc/src/Makefile index 7b86752738..32269e9424 100644 --- a/lib/webtool/doc/src/Makefile +++ b/lib/webtool/doc/src/Makefile @@ -112,16 +112,16 @@ debug opt: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 - $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DATA) $(MAN1_FILES) "$(RELEASE_PATH)/man/man1" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/webtool/priv/Makefile b/lib/webtool/priv/Makefile index 6e1c6606fe..6af997c2bb 100644 --- a/lib/webtool/priv/Makefile +++ b/lib/webtool/priv/Makefile @@ -67,14 +67,14 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DIR) $(RELSYSDIR)/priv/root - $(INSTALL_DIR) $(RELSYSDIR)/priv/root/conf - $(INSTALL_DIR) $(RELSYSDIR)/priv/root/doc - $(INSTALL_DATA) $(HTDOCS_FILES) $(RELSYSDIR)/priv/root/doc - $(INSTALL_DATA) $(WEBSERVER_CONFIG_FILES) $(RELSYSDIR)/priv/root/conf - $(INSTALL_DIR) $(RELSYSDIR)/priv/bin - $(INSTALL_SCRIPT) $(SCRIPTS) $(RELSYSDIR)/priv/bin + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/root" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/root/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/root/doc" + $(INSTALL_DATA) $(HTDOCS_FILES) "$(RELSYSDIR)/priv/root/doc" + $(INSTALL_DATA) $(WEBSERVER_CONFIG_FILES) "$(RELSYSDIR)/priv/root/conf" + $(INSTALL_DIR) "$(RELSYSDIR)/priv/bin" + $(INSTALL_SCRIPT) $(SCRIPTS) "$(RELSYSDIR)/priv/bin" release_docs_spec: diff --git a/lib/webtool/src/Makefile b/lib/webtool/src/Makefile index 62845cd370..45e8b2a6f0 100644 --- a/lib/webtool/src/Makefile +++ b/lib/webtool/src/Makefile @@ -87,11 +87,11 @@ $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \ - $(RELSYSDIR)/ebin + "$(RELSYSDIR)/ebin" release_docs_spec: diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in index ce7f4bf53e..1497ac4d16 100644 --- a/lib/wx/c_src/Makefile.in +++ b/lib/wx/c_src/Makefile.in @@ -176,10 +176,10 @@ $(TARGET_DIR)/erl_gl$(SO_EXT): $(GL_OBJECTS) # ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv - $(INSTALL_DATA) ../priv/erlang-logo32.png $(RELSYSDIR)/priv/ - $(INSTALL_DATA) ../priv/erlang-logo64.png $(RELSYSDIR)/priv/ - $(INSTALL_PROGRAM) $(TARGET_DIR)/wxe_driver$(SO_EXT) $(RELSYSDIR)/priv/ - $(INSTALL_PROGRAM) $(TARGET_DIR)/erl_gl$(SO_EXT) $(RELSYSDIR)/priv/ + $(INSTALL_DIR) "$(RELSYSDIR)/priv" + $(INSTALL_DATA) ../priv/erlang-logo32.png "$(RELSYSDIR)/priv/" + $(INSTALL_DATA) ../priv/erlang-logo64.png "$(RELSYSDIR)/priv/" + $(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/configure.in b/lib/wx/configure.in index b27e114a3d..8e5f696bc7 100755 --- a/lib/wx/configure.in +++ b/lib/wx/configure.in @@ -571,7 +571,7 @@ if test X"$WX_HAVE_STATIC_LIBS" = X"true" ; then LIBS=$WX_LIBS_STATIC fi -AC_LINK_IFELSE([ +AC_LINK_IFELSE([AC_LANG_SOURCE([ #ifdef WIN32 # include <windows.h> # include <gl/gl.h> @@ -583,6 +583,7 @@ AC_LINK_IFELSE([ #include "wx/wx.h" #include "wx/stc/stc.h" #include "wx/glcanvas.h" + ]) class MyApp : public wxApp { diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile index 834f887076..4e6727b6a6 100644 --- a/lib/wx/doc/src/Makefile +++ b/lib/wx/doc/src/Makefile @@ -95,13 +95,13 @@ ref_man.xml: ref_man.xml.src @echo "</application>" >> ref_man.xml @echo -$(ErlMods:%.erl=%.xml): +$(ErlMods:%.erl=%.xml): ../../src/$(@:%.xml=%.erl) escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -preprocess true -sort_functions false ../../src/$(@:%.xml=%.erl) -$(GenMods:%.erl=%.xml): +$(GenMods:%.erl=%.xml): ../../src/gen/$(@:%.xml=%.erl) escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -i ../../src -preprocess true -sort_functions false ../../src/gen/$(@:%.xml=%.erl) -$(XML_CHAPTER_FILES): +$(XML_CHAPTER_FILES): ../overview.edoc escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc debug opt: @@ -120,14 +120,14 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3_FILES) "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml index 4a94227a55..1ba7e62d7d 100644 --- a/lib/wx/doc/src/notes.xml +++ b/lib/wx/doc/src/notes.xml @@ -31,6 +31,23 @@ <p>This document describes the changes made to the wxErlang application.</p> +<section><title>Wx 0.99.2</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>Fix errors in wxDC and wxGraphicsContext api.</p> + <p>Add wxTaskBarIcon.</p> <p>Add + wxStyledTextControl:setEdgeMode/2.</p> <p>Add type and + specs for all functions and records.</p> + <p> + Own Id: OTP-9947</p> + </item> + </list> + </section> + +</section> + <section><title>Wx 0.99.1</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/wx/examples/demo/Makefile b/lib/wx/examples/demo/Makefile index 872723fb98..c60e9c3d50 100644 --- a/lib/wx/examples/demo/Makefile +++ b/lib/wx/examples/demo/Makefile @@ -69,7 +69,7 @@ docs: run: opt erl -smp -detached -pa $(TOPDIR)/ebin -s demo -EXRELSYSDIR = $(RELSYSDIR)/examples/demo +EXRELSYSDIR = "$(RELSYSDIR)/examples/demo" include $(ERL_TOP)/make/otp_release_targets.mk docs: diff --git a/lib/wx/examples/simple/Makefile b/lib/wx/examples/simple/Makefile index 0178aea890..3f2bf01556 100644 --- a/lib/wx/examples/simple/Makefile +++ b/lib/wx/examples/simple/Makefile @@ -40,7 +40,7 @@ docs: run: opt erl -smp -detached -pa $(TOPDIR)/ebin -s hello -EXRELSYSDIR = $(RELSYSDIR)/examples/simple +EXRELSYSDIR = "$(RELSYSDIR)/examples/simple" include $(ERL_TOP)/make/otp_release_targets.mk docs: diff --git a/lib/wx/examples/sudoku/Makefile b/lib/wx/examples/sudoku/Makefile index 89919ff50c..ec900f37e2 100644 --- a/lib/wx/examples/sudoku/Makefile +++ b/lib/wx/examples/sudoku/Makefile @@ -40,7 +40,7 @@ docs: run: opt erl -smp -detached -pa $(TOPDIR)/ebin -s sudoku -EXRELSYSDIR = $(RELSYSDIR)/examples/sudoku +EXRELSYSDIR = "$(RELSYSDIR)/examples/sudoku" include $(ERL_TOP)/make/otp_release_targets.mk docs: diff --git a/lib/wx/examples/xrc/Makefile b/lib/wx/examples/xrc/Makefile index 341fdbb2cc..9a976628a7 100644 --- a/lib/wx/examples/xrc/Makefile +++ b/lib/wx/examples/xrc/Makefile @@ -49,7 +49,7 @@ docs: run: opt erl -smp -detached -pa $(TOPDIR)/ebin -s xrc -EXRELSYSDIR = $(RELSYSDIR)/examples/xrc +EXRELSYSDIR = "$(RELSYSDIR)/examples/xrc" include $(ERL_TOP)/make/otp_release_targets.mk docs: diff --git a/lib/wx/src/Makefile b/lib/wx/src/Makefile index 16b425e6f0..777fb7d998 100644 --- a/lib/wx/src/Makefile +++ b/lib/wx/src/Makefile @@ -120,15 +120,15 @@ $(EBIN)/%.beam: $(EGEN)/%.erl $(HEADER_FILES) # ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/src/gen - $(INSTALL_DATA) $(GEN_HRL) $(GEN_FILES) $(RELSYSDIR)/src/gen - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(EXT_HRL) $(RELSYSDIR)/include - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(HRL_FILES) $(ERL_FILES) "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/src/gen" + $(INSTALL_DATA) $(GEN_HRL) $(GEN_FILES) "$(RELSYSDIR)/src/gen" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(EXT_HRL) "$(RELSYSDIR)/include" + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(APP_TARGET) $(APPUP_TARGET) "$(RELSYSDIR)/ebin" # $(INSTALL_DATA) ../$(ARCHIVE) $(RELEASE_PATH)/lib release_docs_spec: diff --git a/lib/wx/test/Makefile b/lib/wx/test/Makefile index ac8a4bdd60..836885a308 100644 --- a/lib/wx/test/Makefile +++ b/lib/wx/test/Makefile @@ -53,8 +53,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) wx.spec wx.cover wx_test_lib.hrl $(ErlSrc) $(ErlTargets) $(RELSYSDIR) - $(INSTALL_SCRIPT) wxt $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) wx.spec wx.cover wx_test_lib.hrl $(ErlSrc) $(ErlTargets) "$(RELSYSDIR)" + $(INSTALL_SCRIPT) wxt "$(RELSYSDIR)" release_docs_spec: diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk index 3f3e9422a8..719eb0daf0 100644 --- a/lib/wx/vsn.mk +++ b/lib/wx/vsn.mk @@ -1 +1 @@ -WX_VSN = 0.99.1 +WX_VSN = 0.99.2 diff --git a/lib/xmerl/doc/src/Makefile b/lib/xmerl/doc/src/Makefile index 100a2feb0a..4de06249df 100644 --- a/lib/xmerl/doc/src/Makefile +++ b/lib/xmerl/doc/src/Makefile @@ -161,15 +161,15 @@ info: include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs - $(INSTALL_DIR) $(RELSYSDIR)/doc/pdf - $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELSYSDIR)/doc/pdf - $(INSTALL_DIR) $(RELSYSDIR)/doc/html + $(INSTALL_DIR) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DATA) $(TOP_PDF_FILE) "$(RELSYSDIR)/doc/pdf" + $(INSTALL_DIR) "$(RELSYSDIR)/doc/html" $(INSTALL_DATA) $(HTMLDIR)/* \ - $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(EXAMPLE_FILES) $(HTML_EXAMPLE_FILES) $(HTML_STYLESHEET_FILES) $(RELSYSDIR)/doc/html - $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) - $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 - $(INSTALL_DATA) $(MAN3DIR)/* $(RELEASE_PATH)/man/man3 + "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(EXAMPLE_FILES) $(HTML_EXAMPLE_FILES) $(HTML_STYLESHEET_FILES) "$(RELSYSDIR)/doc/html" + $(INSTALL_DATA) $(INFO_FILE) "$(RELSYSDIR)" + $(INSTALL_DIR) "$(RELEASE_PATH)/man/man3" + $(INSTALL_DATA) $(MAN3DIR)/* "$(RELEASE_PATH)/man/man3" release_spec: diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml index 8734bd8771..bd12e688d0 100644 --- a/lib/xmerl/doc/src/notes.xml +++ b/lib/xmerl/doc/src/notes.xml @@ -31,6 +31,64 @@ <p>This document describes the changes made to the Xmerl application.</p> +<section><title>Xmerl 1.3.2</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> Fix a continuation bug when a new block of bytes is + to be read during parsing of a default declaration. </p> + <p> + Own Id: OTP-10063 Aux Id: seq12049 </p> + </item> + </list> + </section> + +</section> + +<section><title>Xmerl 1.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Add missing spaces in xmerl doc (Thanks to Ricardo + Catalinas Jim�nez)</p> + <p> + Own Id: OTP-9873</p> + </item> + <item> + <p> Fixed a continuation error in the sax parser and + added latin1 as recognized encoding (not only the + iso-8859 variants). </p> + <p> + Own Id: OTP-9961</p> + </item> + <item> + <p> Removed the unused file xmerl_xlink.hrl. Thanks to + Vlad Dumitrescu for informing us about it. </p> + <p> + Own Id: OTP-9965</p> + </item> + <item> + <p> xmerl couldn't handle comments inside a type + specification. </p> + <p> + Own Id: OTP-10023</p> + </item> + <item> + <p> Fix some small errors in the sax parser: error + message bug, removal of trailing blanks in DTD element + definitions and an documentation error of the startDTD + event in xmerl_sax_parser module. </p> + <p> + Own Id: OTP-10026</p> + </item> + </list> + </section> + +</section> + <section><title>Xmerl 1.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/xmerl/src/Makefile b/lib/xmerl/src/Makefile index a5dbe45909..ce1aa11fba 100644 --- a/lib/xmerl/src/Makefile +++ b/lib/xmerl/src/Makefile @@ -214,14 +214,14 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(APP_SRC) $(APPUP_SRC) $(RELSYSDIR)/src - $(INSTALL_DATA) xmerl_xpath_parse.yrl $(RELSYSDIR)/src - $(INSTALL_DATA) xmerl_b64Bin.yrl $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/include - $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) "$(RELSYSDIR)/ebin" + $(INSTALL_DATA) $(TARGET_FILES) "$(RELSYSDIR)/ebin" + $(INSTALL_DIR) "$(RELSYSDIR)/src" + $(INSTALL_DATA) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(APP_SRC) $(APPUP_SRC) "$(RELSYSDIR)/src" + $(INSTALL_DATA) xmerl_xpath_parse.yrl "$(RELSYSDIR)/src" + $(INSTALL_DATA) xmerl_b64Bin.yrl "$(RELSYSDIR)/src" + $(INSTALL_DIR) "$(RELSYSDIR)/include" + $(INSTALL_DATA) $(HRL_FILES) "$(RELSYSDIR)/include" release_docs_spec: diff --git a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc index df0970ef14..d38045f2a5 100644 --- a/lib/xmerl/src/xmerl_sax_parser_base.erlsrc +++ b/lib/xmerl/src/xmerl_sax_parser_base.erlsrc @@ -155,16 +155,16 @@ parse_xml_decl(?BYTE_ORDER_MARK_2, State) -> cf(?BYTE_ORDER_MARK_2, State, fun parse_xml_decl/2); parse_xml_decl(?BYTE_ORDER_MARK_REST(Rest), State) -> cf(Rest, State, fun parse_xml_decl/2); -parse_xml_decl(?STRING("<"), State) -> - cf(?STRING("<"), State, fun parse_xml_decl/2); -parse_xml_decl(?STRING("<?"), State) -> - cf(?STRING("<?"), State, fun parse_xml_decl/2); -parse_xml_decl(?STRING("<?x"), State) -> - cf(?STRING("<?x"), State, fun parse_xml_decl/2); -parse_xml_decl(?STRING("<?xm"), State) -> - cf(?STRING("<?xm"), State, fun parse_xml_decl/2); -parse_xml_decl(?STRING("<?xml"), State) -> - cf(?STRING("<?xml"), State, fun parse_xml_decl/2); +parse_xml_decl(?STRING("<") = Bytes, State) -> + cf(Bytes, State, fun parse_xml_decl/2); +parse_xml_decl(?STRING("<?") = Bytes, State) -> + cf(Bytes, State, fun parse_xml_decl/2); +parse_xml_decl(?STRING("<?x") = Bytes, State) -> + cf(Bytes, State, fun parse_xml_decl/2); +parse_xml_decl(?STRING("<?xm") = Bytes, State) -> + cf(Bytes, State, fun parse_xml_decl/2); +parse_xml_decl(?STRING("<?xml") = Bytes, State) -> + cf(Bytes, State, fun parse_xml_decl/2); parse_xml_decl(?STRING_REST("<?xml", Rest1), State) -> parse_xml_decl_1(Rest1, State); parse_xml_decl(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State) when is_binary(Bytes) -> @@ -204,8 +204,8 @@ parse_xml_decl_1(Bytes, State) -> %%---------------------------------------------------------------------- parse_prolog(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_prolog/2); -parse_prolog(?STRING("<"), State) -> - cf(?STRING("<"), State, fun parse_prolog/2); +parse_prolog(?STRING("<") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog/2); parse_prolog(?STRING_REST("<?", Rest), State) -> {Rest1, State1} = parse_pi(Rest, State), parse_prolog(Rest1, State1); @@ -223,18 +223,18 @@ parse_prolog(Bytes, State) -> parse_prolog_1(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("D"), State) -> - cf(?STRING("D"), State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("DO"), State) -> - cf(?STRING("DO"), State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("DOC"), State) -> - cf(?STRING("DOC"), State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("DOCT"), State) -> - cf(?STRING("DOCT"), State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("DOCTY"), State) -> - cf(?STRING("DOCTY"), State, fun parse_prolog_1/2); -parse_prolog_1(?STRING("DOCTYP"), State) -> - cf(?STRING("DOCTYP"), State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("D") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("DO") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("DOC") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("DOCT") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("DOCTY") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); +parse_prolog_1(?STRING("DOCTYP") = Bytes, State) -> + cf(Bytes, State, fun parse_prolog_1/2); parse_prolog_1(?STRING_REST("DOCTYPE", Rest), State) -> {Rest1, State1} = parse_doctype(Rest, State), State2 = event_callback(endDTD, State1), @@ -512,10 +512,10 @@ parse_ns_name(Bytes, State, Prefix, Name) -> %%---------------------------------------------------------------------- parse_pi_data(?STRING_EMPTY, State, Acc) -> cf(?STRING_EMPTY, State, Acc, fun parse_pi_data/3); -parse_pi_data(?STRING("?"), State, Acc) -> - cf(?STRING("?"), State, Acc, fun parse_pi_data/3); -parse_pi_data(?STRING("\r"), State, Acc) -> - cf(?STRING("\r"), State, Acc, fun parse_pi_data/3); +parse_pi_data(?STRING("?") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_pi_data/3); +parse_pi_data(?STRING("\r") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_pi_data/3); parse_pi_data(?STRING_REST("?>", Rest), State, Acc) -> {lists:reverse(Acc), Rest, State}; parse_pi_data(?STRING_REST("\n", Rest), #xmerl_sax_parser_state{line_no=N} = State, Acc) -> @@ -544,23 +544,23 @@ parse_pi_data(Bytes, State, Acc) -> %%---------------------------------------------------------------------- parse_cdata(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_cdata/2); -parse_cdata(?STRING("["), State) -> - cf(?STRING("["), State, fun parse_cdata/2); -parse_cdata(?STRING("[C"), State) -> - cf(?STRING("[C"), State, fun parse_cdata/2); -parse_cdata(?STRING("[CD"), State) -> - cf(?STRING("[CD"), State, fun parse_cdata/2); -parse_cdata(?STRING("[CDA"), State) -> - cf(?STRING("[CDA"), State, fun parse_cdata/2); -parse_cdata(?STRING("[CDAT"), State) -> - cf(?STRING("[CDAT"), State, fun parse_cdata/2); -parse_cdata(?STRING("[CDATA"), State) -> - cf(?STRING("[CDATA"), State, fun parse_cdata/2); -parse_cdata(?STRING_REST("[CDATA[", Rest), State) -> - State1 = event_callback(startCDATA, State), +parse_cdata(?STRING("[") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING("[C") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING("[CD") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING("[CDA") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING("[CDAT") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING("[CDATA") = Bytes, State) -> + cf(Bytes, State, fun parse_cdata/2); +parse_cdata(?STRING_REST("[CDATA[", Rest), State) -> + State1 = event_callback(startCDATA, State), parse_cdata(Rest, State1, []); -parse_cdata(Bytes, State) -> - unicode_incomplete_check([Bytes, State, fun parse_cdata/2], +parse_cdata(Bytes, State) -> + unicode_incomplete_check([Bytes, State, fun parse_cdata/2], "expecting comment or CDATA"). @@ -574,12 +574,12 @@ parse_cdata(Bytes, State) -> %%---------------------------------------------------------------------- parse_cdata(?STRING_EMPTY, State, Acc) -> cf(?STRING_EMPTY, State, Acc, fun parse_cdata/3); -parse_cdata(?STRING("\r"), State, Acc) -> - cf(?STRING("\r"), State, Acc, fun parse_cdata/3); -parse_cdata(?STRING("]"), State, Acc) -> - cf(?STRING("]"), State, Acc, fun parse_cdata/3); -parse_cdata(?STRING("]]"), State, Acc) -> - cf(?STRING("]]"), State, Acc, fun parse_cdata/3); +parse_cdata(?STRING("\r") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_cdata/3); +parse_cdata(?STRING("]") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_cdata/3); +parse_cdata(?STRING("]]") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_cdata/3); parse_cdata(?STRING_REST("]]>", Rest), State, Acc) -> State1 = event_callback({characters, lists:reverse(Acc)}, State), State2 = event_callback(endCDATA, State1), @@ -610,12 +610,12 @@ parse_cdata(Bytes, State, Acc) -> %%---------------------------------------------------------------------- parse_comment(?STRING_EMPTY, State, Acc) -> cf(?STRING_EMPTY, State, Acc, fun parse_comment/3); -parse_comment(?STRING("\r"), State, Acc) -> - cf(?STRING("\r"), State, Acc, fun parse_comment/3); -parse_comment(?STRING("-"), State, Acc) -> - cf(?STRING("-"), State, Acc, fun parse_comment/3); -parse_comment(?STRING("--"), State, Acc) -> - cf(?STRING("--"), State, Acc, fun parse_comment/3); +parse_comment(?STRING("\r") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_comment/3); +parse_comment(?STRING("-") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_comment/3); +parse_comment(?STRING("--") = Bytes, State, Acc) -> + cf(Bytes, State, Acc, fun parse_comment/3); parse_comment(?STRING_REST("-->", Rest), State, Acc) -> State1 = event_callback({comment, lists:reverse(Acc)}, State), {Rest, State1}; @@ -713,8 +713,8 @@ parse_stag(Bytes, State) -> %%---------------------------------------------------------------------- parse_attributes(?STRING_EMPTY, State, CurrentTag) -> cf(?STRING_EMPTY, State, CurrentTag, fun parse_attributes/3); -parse_attributes(?STRING("/"), State, CurrentTag) -> - cf(?STRING("/"), State, CurrentTag, fun parse_attributes/3); +parse_attributes(?STRING("/") = Bytes, State, CurrentTag) -> + cf(Bytes, State, CurrentTag, fun parse_attributes/3); parse_attributes(?STRING_REST("/>", Rest), State, {Tag, AttList, NewNsList}) -> CompleteNsList = NewNsList ++ State#xmerl_sax_parser_state.ns, {Uri, LocalName, QName, Attributes} = fix_ns(Tag, AttList, CompleteNsList), @@ -911,20 +911,20 @@ parse_att_value(?STRING_EMPTY, State, undefined, Acc) -> {Acc, [], State}; %% stop clause when parsing references parse_att_value(?STRING_EMPTY, State, Stop, Acc) -> cf(?STRING_EMPTY, State, Stop, Acc, fun parse_att_value/4); -parse_att_value(?STRING("\r"), State, Stop, Acc) -> - cf(?STRING("\r"), State, Stop, Acc, fun parse_att_value/4); +parse_att_value(?STRING("\r") = Bytes, State, Stop, Acc) -> + cf(Bytes, State, Stop, Acc, fun parse_att_value/4); parse_att_value(?STRING_REST("\n", Rest), #xmerl_sax_parser_state{line_no=N} = State, Stop, Acc) -> parse_att_value(Rest, - State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); + State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); parse_att_value(?STRING_REST("\r\n", Rest), #xmerl_sax_parser_state{line_no=N} = State, Stop, Acc) -> parse_att_value(Rest, - State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); + State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); parse_att_value(?STRING_REST("\r", Rest), #xmerl_sax_parser_state{line_no=N} = State, Stop, Acc) -> parse_att_value(Rest, - State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); + State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); parse_att_value(?STRING_REST("\t", Rest), #xmerl_sax_parser_state{line_no=N} = State, Stop, Acc) -> parse_att_value(Rest, - State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); + State#xmerl_sax_parser_state{line_no=N+1}, Stop, [?space |Acc]); parse_att_value(?STRING_REST("&", Rest), State, Stop, Acc) -> {Ref, Rest1, State1} = parse_reference(Rest, State, true), case Ref of @@ -1046,17 +1046,17 @@ parse_content(?STRING_EMPTY, State, Acc, IgnorableWS) -> Other -> throw(Other) end; -parse_content(?STRING("\r"), State, Acc, IgnorableWS) -> - cf(?STRING("\r"), State, Acc, IgnorableWS, fun parse_content/4); -parse_content(?STRING("<"), State, Acc, IgnorableWS) -> - cf(?STRING("<"), State, Acc, IgnorableWS, fun parse_content/4); +parse_content(?STRING("\r") = Bytes, State, Acc, IgnorableWS) -> + cf(Bytes, State, Acc, IgnorableWS, fun parse_content/4); +parse_content(?STRING("<") = Bytes, State, Acc, IgnorableWS) -> + cf(Bytes, State, Acc, IgnorableWS, fun parse_content/4); parse_content(?STRING_REST("</", Rest), State, Acc, IgnorableWS) -> State1 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State), parse_etag(Rest, State1); -parse_content(?STRING("<!"), State, _Acc, IgnorableWS) -> - cf(?STRING("<!"), State, [], IgnorableWS, fun parse_content/4); -parse_content(?STRING("<!-"), State, _Acc, IgnorableWS) -> - cf(?STRING("<!-"), State, [], IgnorableWS, fun parse_content/4); +parse_content(?STRING("<!") = Bytes, State, _Acc, IgnorableWS) -> + cf(Bytes, State, [], IgnorableWS, fun parse_content/4); +parse_content(?STRING("<!-") = Bytes, State, _Acc, IgnorableWS) -> + cf(Bytes, State, [], IgnorableWS, fun parse_content/4); parse_content(?STRING_REST("<!--", Rest), State, Acc, IgnorableWS) -> State1 = send_character_event(length(Acc), IgnorableWS, lists:reverse(Acc), State), {Rest1, State2} = parse_comment(Rest, State1, []), @@ -1227,8 +1227,8 @@ whitespace(Bytes, #xmerl_sax_parser_state{encoding=Enc} = State, Acc) when is_bi %%---------------------------------------------------------------------- parse_reference(?STRING_EMPTY, State, HaveToExist) -> cf(?STRING_EMPTY, State, HaveToExist, fun parse_reference/3); -parse_reference(?STRING("#"), State, HaveToExist) -> - cf(?STRING("#"), State, HaveToExist, fun parse_reference/3); +parse_reference(?STRING("#") = Bytes, State, HaveToExist) -> + cf(Bytes, State, HaveToExist, fun parse_reference/3); parse_reference(?STRING_REST("#x", Rest), State, _HaveToExist) -> {CharValue, RefString, Rest1, State1} = parse_hex(Rest, State, []), if @@ -1702,16 +1702,16 @@ parse_external_entity_1(?BYTE_ORDER_MARK_2, State) -> cf(?BYTE_ORDER_MARK_2, State, fun parse_external_entity_1/2); parse_external_entity_1(?BYTE_ORDER_MARK_REST(Rest), State) -> parse_external_entity_1(Rest, State); -parse_external_entity_1(?STRING("<"), State) -> - cf(?STRING("<"), State, fun parse_external_entity_1/2); -parse_external_entity_1(?STRING("<?"), State) -> - cf(?STRING("<?"), State, fun parse_external_entity_1/2); -parse_external_entity_1(?STRING("<?x"), State) -> - cf(?STRING("<?x"), State, fun parse_external_entity_1/2); -parse_external_entity_1(?STRING("<?xm"), State) -> - cf(?STRING("<?xm"), State, fun parse_external_entity_1/2); -parse_external_entity_1(?STRING("<?xml"), State) -> - cf(?STRING("<?xml"), State, fun parse_external_entity_1/2); +parse_external_entity_1(?STRING("<") = Bytes, State) -> + cf(Bytes, State, fun parse_external_entity_1/2); +parse_external_entity_1(?STRING("<?") = Bytes, State) -> + cf(Bytes, State, fun parse_external_entity_1/2); +parse_external_entity_1(?STRING("<?x") = Bytes, State) -> + cf(Bytes, State, fun parse_external_entity_1/2); +parse_external_entity_1(?STRING("<?xm") = Bytes, State) -> + cf(Bytes, State, fun parse_external_entity_1/2); +parse_external_entity_1(?STRING("<?xml") = Bytes, State) -> + cf(Bytes, State, fun parse_external_entity_1/2); parse_external_entity_1(?STRING_REST("<?xml", Rest) = Bytes, #xmerl_sax_parser_state{file_type=Type} = State) -> {Rest1, State1} = @@ -1781,29 +1781,29 @@ is_next_char_whitespace(Bytes, State) -> %%---------------------------------------------------------------------- parse_external_id(?STRING_EMPTY, State, OptionalSystemId) -> cf(?STRING_EMPTY, State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("S"), State,OptionalSystemId) -> - cf(?STRING("S"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("SY"), State, OptionalSystemId) -> - cf(?STRING("SY"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("SYS"), State, OptionalSystemId) -> - cf(?STRING("SYS"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("SYST"), State, OptionalSystemId) -> - cf(?STRING("SYST"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("SYSTE"), State, OptionalSystemId) -> - cf(?STRING("SYSTE"), State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("S") = Bytes, State,OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("SY") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("SYS") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("SYST") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("SYSTE") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); parse_external_id(?STRING_REST("SYSTEM", Rest), State, _) -> {SysId, Rest1, State1} = parse_system_id(Rest, State, false), {"", SysId, Rest1, State1}; -parse_external_id(?STRING("P"), State, OptionalSystemId) -> - cf(?STRING("P"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("PU"), State, OptionalSystemId) -> - cf(?STRING("PU"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("PUB"), State, OptionalSystemId) -> - cf(?STRING("PUB"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("PUBL"), State, OptionalSystemId) -> - cf(?STRING("PUBL"), State, OptionalSystemId, fun parse_external_id/3); -parse_external_id(?STRING("PUBLI"), State, OptionalSystemId) -> - cf(?STRING("PUBLI"), State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("P") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("PU") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("PUB") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("PUBL") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); +parse_external_id(?STRING("PUBLI") = Bytes, State, OptionalSystemId) -> + cf(Bytes, State, OptionalSystemId, fun parse_external_id/3); parse_external_id(?STRING_REST("PUBLIC", Rest), State, OptionalSystemId) -> parse_public_id(Rest, State, OptionalSystemId); parse_external_id(Bytes, State, OptionalSystemId) -> @@ -1923,70 +1923,70 @@ parse_doctype_decl(Bytes, State) -> parse_doctype_decl_1(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("E"), State) -> - cf(?STRING("E"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("EL"), State) -> - cf(?STRING("EL"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ELE"), State) -> - cf(?STRING("ELE"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ELEM"), State) -> - cf(?STRING("ELEM"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ELEME"), State) -> - cf(?STRING("ELEME"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ELEMEN"), State) -> - cf(?STRING("ELEMEN"), State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("E") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("EL") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ELE") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ELEM") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ELEME") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ELEMEN") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); parse_doctype_decl_1(?STRING_REST("ELEMENT", Rest), State) -> {Rest1, State1} = parse_element_decl(Rest, State), parse_doctype_decl(Rest1, State1); -parse_doctype_decl_1(?STRING("A"), State) -> - cf(?STRING("A"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("AT"), State) -> - cf(?STRING("AT"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ATT"), State) -> - cf(?STRING("ATT"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ATTL"), State) -> - cf(?STRING("ATTL"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ATTLI"), State) -> - cf(?STRING("ATTLI"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ATTLIS"), State) -> - cf(?STRING("ATTLIS"), State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("A") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("AT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ATT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ATTL") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ATTLI") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ATTLIS") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); parse_doctype_decl_1(?STRING_REST("ATTLIST", Rest), State) -> {Rest1, State1} = parse_att_list_decl(Rest, State), parse_doctype_decl(Rest1, State1); %% E clause not needed here because already taken care of above. -parse_doctype_decl_1(?STRING("EN"), State) -> - cf(?STRING("EN"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ENT"), State) -> - cf(?STRING("ENT"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ENTI"), State) -> - cf(?STRING("ENTI"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("ENTIT"), State) -> - cf(?STRING("ENTIT"), State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("EN") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ENT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ENTI") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("ENTIT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); parse_doctype_decl_1(?STRING_REST("ENTITY", Rest), State) -> {Rest1, State1} = parse_entity_decl(Rest, State), parse_doctype_decl(Rest1, State1); -parse_doctype_decl_1(?STRING("N"), State) -> - cf(?STRING("N"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NO"), State) -> - cf(?STRING("NO"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NOT"), State) -> - cf(?STRING("NOT"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NOTA"), State) -> - cf(?STRING("NOTA"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NOTAT"), State) -> - cf(?STRING("NOTAT"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NOTATI"), State) -> - cf(?STRING("NOTATI"), State, fun parse_doctype_decl_1/2); -parse_doctype_decl_1(?STRING("NOTATIO"), State) -> - cf(?STRING("NOTATIO"), State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("N") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NO") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NOT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NOTA") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NOTAT") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NOTATI") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("NOTATIO") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); parse_doctype_decl_1(?STRING_REST("NOTATION", Rest), State) -> {Rest1, State1} = parse_notation_decl(Rest, State), parse_doctype_decl(Rest1, State1); -parse_doctype_decl_1(?STRING("-"), State) -> - cf(?STRING("-"), State, fun parse_doctype_decl_1/2); +parse_doctype_decl_1(?STRING("-") = Bytes, State) -> + cf(Bytes, State, fun parse_doctype_decl_1/2); parse_doctype_decl_1(?STRING_REST("--", Rest), State) -> {Rest1, State1} = parse_comment(Rest, State, []), parse_doctype_decl(Rest1, State1); @@ -2264,52 +2264,52 @@ parse_default_decl(Bytes, State) -> %%---------------------------------------------------------------------- parse_default_decl_1(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_default_decl_1/2); -parse_default_decl_1(?STRING_REST("#", Rest), State) -> - case Rest of - ?STRING("R") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("RE") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("REQ") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("REQU") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("REQUI") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("REQUIR") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("REQUIRE") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING_REST("REQUIRED", Rest1) -> +parse_default_decl_1(?STRING_REST("#", _Rest) = Bytes, State) -> + case Bytes of + ?STRING("#R") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#RE") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#REQ") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#REQU") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#REQUI") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#REQUIR") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#REQUIRE") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING_REST("#REQUIRED", Rest1) -> {"#REQUIRED", undefined, Rest1, State}; - ?STRING("I") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("IM") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("IMP") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("IMPL") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("IMPLI") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("IMPLIE") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING_REST("IMPLIED", Rest1) -> + ?STRING("#I") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#IM") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#IMP") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#IMPL") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#IMPLI") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#IMPLIE") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING_REST("#IMPLIED", Rest1) -> {"#IMPLIED", undefined, Rest1, State}; - ?STRING("F") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("FI") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("FIX") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING("FIXE") -> - cf(Rest, State, fun parse_default_decl_1/2); - ?STRING_REST("FIXED", Rest1) -> + ?STRING("#F") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#FI") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#FIX") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING("#FIXE") -> + cf(Bytes, State, fun parse_default_decl_1/2); + ?STRING_REST("#FIXED", Rest1) -> parse_fixed(Rest1, State); _ -> - ?fatal_error(State, "REQUIRED, IMPLIED or FIXED expected") + ?fatal_error(State, "REQUIRED, IMPLIED or FIXED expected after #") end; parse_default_decl_1(?STRING_UNBOUND_REST(C, Rest), State) when C == $'; C == $" -> {DefaultValue, Rest1, State1} = parse_att_value(Rest, State, C, []), @@ -2560,14 +2560,14 @@ parse_ndata_decl(?STRING_EMPTY, State) -> cf(?STRING_EMPTY, State, fun parse_ndata_decl/2); parse_ndata_decl(?STRING_REST(">", Rest), State) -> {undefined, Rest, State}; -parse_ndata_decl(?STRING("N") = Rest, State) -> - cf(Rest, State, fun parse_ndata_decl/2); -parse_ndata_decl(?STRING("ND") = Rest, State) -> - cf(Rest, State, fun parse_ndata_decl/2); -parse_ndata_decl(?STRING("NDA") = Rest, State) -> - cf(Rest, State, fun parse_ndata_decl/2); -parse_ndata_decl(?STRING("NDAT") = Rest, State) -> - cf(Rest, State, fun parse_ndata_decl/2); +parse_ndata_decl(?STRING("N") = Bytes, State) -> + cf(Bytes, State, fun parse_ndata_decl/2); +parse_ndata_decl(?STRING("ND") = Bytes, State) -> + cf(Bytes, State, fun parse_ndata_decl/2); +parse_ndata_decl(?STRING("NDA") = Bytes, State) -> + cf(Bytes, State, fun parse_ndata_decl/2); +parse_ndata_decl(?STRING("NDAT") = Bytes, State) -> + cf(Bytes, State, fun parse_ndata_decl/2); parse_ndata_decl(?STRING_REST("NDATA", Rest), State) -> parse_ndata_decl_1(Rest, State); parse_ndata_decl(Bytes, State) -> diff --git a/lib/xmerl/test/Makefile b/lib/xmerl/test/Makefile index 5a2a585841..1fdbb7ca0d 100644 --- a/lib/xmerl/test/Makefile +++ b/lib/xmerl/test/Makefile @@ -113,15 +113,15 @@ include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt release_tests_spec: opt - $(INSTALL_DIR) $(RELSYSDIR) - $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR) - $(INSTALL_DATA) $(SUITE_FILES) $(RELSYSDIR) - $(INSTALL_DATA) xmerl.spec xmerl.cover $(RELSYSDIR) - cp $(XML_FILES) $(RELSYSDIR) - @tar cfh - xmerl_SUITE_data | (cd $(RELSYSDIR); tar xf -) - @tar cfh - xmerl_std_SUITE_data | (cd $(RELSYSDIR); tar xf -) - @tar cfh - xmerl_xsd_SUITE_data | (cd $(RELSYSDIR); tar xf -) - @tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -) - @tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -) - @tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd $(RELSYSDIR); tar xf -) - chmod -R u+w $(RELSYSDIR) + $(INSTALL_DIR) "$(RELSYSDIR)" + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) $(SUITE_FILES) "$(RELSYSDIR)" + $(INSTALL_DATA) xmerl.spec xmerl.cover "$(RELSYSDIR)" + cp $(XML_FILES) "$(RELSYSDIR)" + @tar cfh - xmerl_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_std_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_xsd_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_xsd_MS2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_xsd_NIST2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + @tar cfh - xmerl_xsd_Sun2002-01-16_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) + chmod -R u+w "$(RELSYSDIR)" diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk index de47e3418b..599bc0b9d3 100644 --- a/lib/xmerl/vsn.mk +++ b/lib/xmerl/vsn.mk @@ -1 +1 @@ -XMERL_VSN = 1.3 +XMERL_VSN = 1.3.2 |