From f863775f492d31f4f38fc6e661dd6391810cfc37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 5 Mar 2013 12:36:09 +0100
Subject: Introduce asn1ct_gen_per:gen_decode_external/3

Hiding the details of decoding an external type will facilitate
changing the calling convention in a future commit.
---
 lib/asn1/src/asn1ct_constructed_per.erl | 18 ++++--------
 lib/asn1/src/asn1ct_gen_per.erl         | 50 ++++++++++++++-------------------
 2 files changed, 26 insertions(+), 42 deletions(-)

(limited to 'lib/asn1')

diff --git a/lib/asn1/src/asn1ct_constructed_per.erl b/lib/asn1/src/asn1ct_constructed_per.erl
index bcd0a01bbb..7c0c3aae9e 100644
--- a/lib/asn1/src/asn1ct_constructed_per.erl
+++ b/lib/asn1/src/asn1ct_constructed_per.erl
@@ -658,7 +658,6 @@ gen_decode_sof_components(Erule,Typename,SeqOrSetOf,Cont) ->
 						       Cont#type.def),
     Conttype = asn1ct_gen:get_inner(Cont#type.def),
     Ctgenmod = asn1ct_gen:ct_gen_module(Erule),
-    CurrMod = get(currmod),
     case asn1ct_gen:type(Conttype) of
 	{primitive,bif} ->
 	    Ctgenmod:gen_dec_prim(Erule,Cont,"Bytes"),
@@ -667,10 +666,9 @@ gen_decode_sof_components(Erule,Typename,SeqOrSetOf,Cont) ->
 	    NewTypename = [Constructed_Suffix|Typename],
 	    emit({"'dec_",asn1ct_gen:list2name(NewTypename),
 		  "'(Bytes, telltype",ObjFun,"),",nl});
-	#'Externaltypereference'{module=CurrMod,type=EType} ->
-	    emit({"'dec_",EType,"'(Bytes,telltype),",nl});
-	#'Externaltypereference'{module=EMod,type=EType} ->
-	    emit({"'",EMod,"':'dec_",EType,"'(Bytes,telltype),",nl});
+	#'Externaltypereference'{}=Etype ->
+	    asn1ct_gen_per:gen_dec_external(Etype, "Bytes"),
+	    emit([com,nl]);
 	'ASN1_OPEN_TYPE' ->
 	    Ctgenmod:gen_dec_prim(Erule,#type{def='ASN1_OPEN_TYPE'},
 				  "Bytes"),
@@ -1504,16 +1502,10 @@ gen_dec_line_dec_inf(Comp, DecInfObj) ->
 
 gen_dec_line_other(Erule, Atype, TopType, Comp) ->
     #'ComponentType'{name=Cname,typespec=Type} = Comp,
-    CurrMod = get(currmod),
     case asn1ct_gen:type(Atype) of
-	#'Externaltypereference'{module=CurrMod,type=EType} ->
-	    fun(BytesVar) ->
-		    emit({"'dec_",EType,"'(",BytesVar,",telltype)"})
-	    end;
-	#'Externaltypereference'{module=Mod,type=EType} ->
+	#'Externaltypereference'{}=Etype ->
 	    fun(BytesVar) ->
-		    emit({"'",Mod,"':'dec_",EType,"'(",BytesVar,
-			  ",telltype)"})
+		    asn1ct_gen_per:gen_dec_external(Etype, BytesVar)
 	    end;
 	{primitive,bif} ->
 	    case Atype of
diff --git a/lib/asn1/src/asn1ct_gen_per.erl b/lib/asn1/src/asn1ct_gen_per.erl
index 37f5b9c960..ec3d7f61ce 100644
--- a/lib/asn1/src/asn1ct_gen_per.erl
+++ b/lib/asn1/src/asn1ct_gen_per.erl
@@ -30,6 +30,7 @@
 -export([gen_obj_code/3,gen_objectset_code/2]).
 -export([gen_decode/2, gen_decode/3]).
 -export([gen_encode/2, gen_encode/3]).
+-export([gen_dec_external/2]).
 -export([extaddgroup2sequence/1]).
 
 -import(asn1ct_gen, [emit/1,demit/1]).
@@ -547,16 +548,10 @@ gen_decode_objectfields(_, _, [], _, _, CAcc) ->
 
 
 gen_decode_field_call(_Erules, _ObjName, _FieldName, Bytes,
-		      #'Externaltypereference'{module=M,type=T}) ->
-    CurrentMod = get(currmod),
-    if
-	M == CurrentMod ->
-	    emit(["   'dec_",T,"'(",Bytes,", telltype)"]),
-	    [];
-	true ->
-	    emit(["   '",M,"':'dec_",T,"'(",Bytes,", telltype)"]),
-	    []
-    end;
+		      #'Externaltypereference'{}=Etype) ->
+    emit("   "),
+    gen_dec_external(Etype, Bytes),
+    [];
 gen_decode_field_call(Erules, ObjName, FieldName, Bytes, Type) ->
     Def = Type#typedef.typespec,
     case Type#typedef.name of
@@ -578,7 +573,6 @@ gen_decode_field_call(Erules, ObjName, FieldName, Bytes, Type) ->
     end.
 
 gen_decode_default_call(Erules, ClassName, FieldName, Bytes, Type) ->
-    CurrentMod = get(currmod),
     InnerType = asn1ct_gen:get_inner(Type#type.def),
     case asn1ct_gen:type(InnerType) of
     	{constructed,bif} ->
@@ -589,11 +583,8 @@ gen_decode_default_call(Erules, ClassName, FieldName, Bytes, Type) ->
 	{primitive,bif} ->
 	    gen_dec_prim(Erules, Type, Bytes),
 	    [];
-	#'Externaltypereference'{module=CurrentMod,type=Etype} ->
-	    emit(["   'dec_",Etype,"'(",Bytes,", telltype)",nl]),
-	    [];
-	#'Externaltypereference'{module=Emod,type=Etype} ->
-	    emit(["   '",Emod,"':'dec_",Etype,"'(",Bytes,", telltype)",nl]),
+	#'Externaltypereference'{}=Etype ->
+	    asn1ct_gen_per:gen_dec_external(Etype, Bytes),
 	    []
     end.
 
@@ -873,7 +864,6 @@ gen_inlined_dec_funs(Erule, Fields, List, ObjSetName, NthObj0) ->
 
 gen_inlined_dec_funs1(Erule, Fields, [{typefield,Name,_}|Rest],
 		      ObjSetName, Sep0, NthObj) ->
-    CurrentMod = get(currmod),
     InternalDefFunName = [NthObj,Name,ObjSetName],
     emit(Sep0),
     Sep = [";",nl],
@@ -883,13 +873,10 @@ gen_inlined_dec_funs1(Erule, Fields, [{typefield,Name,_}|Rest],
 	    {_,#typedef{}=Type} ->
 		emit([indent(9),{asis,Name}," ->",nl]),
 		emit_inner_of_decfun(Erule, Type, InternalDefFunName);
-	    {_,#'Externaltypereference'{module=CurrentMod,type=T}} ->
-		emit([indent(9),{asis,Name}," ->",nl,
-		      indent(12),"'dec_",T,"'(Val,telltype)"]),
-		0;
-	    {_,#'Externaltypereference'{module=M,type=T}} ->
+	    {_,#'Externaltypereference'{}=Etype} ->
 		emit([indent(9),{asis,Name}," ->",nl,
-		      indent(12),"'",M,"':'dec_",T,"'(Val,telltype)"]),
+		      indent(12)]),
+		gen_dec_external(Etype, "Val"),
 		0;
 	    false ->
 		emit([indent(9),{asis,Name}," -> {Val,Type}"]),
@@ -946,7 +933,6 @@ gen_internal_funcs(Erules,[TypeDef|Rest]) ->
 %% DECODING *****************************
 %%***************************************
 
-
 gen_decode(Erules,Type) when is_record(Type,typedef) ->
     D = Type,
     emit({nl,nl}),
@@ -983,7 +969,6 @@ dbdec(Type) ->
     demit({"io:format(\"decoding: ",{asis,Type},"~w~n\",[Bytes]),",nl}).
 
 gen_decode_user(Erules,D) when is_record(D,typedef) ->
-    CurrMod = get(currmod),
     Typename = [D#typedef.name],
     Def = D#typedef.typespec,
     InnerType = asn1ct_gen:get_inner(Def#type.def),
@@ -996,14 +981,21 @@ gen_decode_user(Erules,D) when is_record(D,typedef) ->
 	    emit({".",nl,nl});
 	{constructed,bif} ->
 	    asn1ct_gen:gen_decode_constructed(Erules,Typename,InnerType,D);
-	#'Externaltypereference'{module=CurrMod,type=Etype} ->
-	    emit({"'dec_",Etype,"'(Bytes,telltype).",nl,nl});
-	#'Externaltypereference'{module=Emod,type=Etype} ->
-	    emit({"'",Emod,"':'dec_",Etype,"'(Bytes,telltype).",nl,nl});
+	#'Externaltypereference'{}=Etype ->
+	    gen_dec_external(Etype, "Bytes"),
+	    emit([".",nl,nl]);
 	Other ->
 	    exit({error,{asn1,{unknown,Other}}})
     end.
 
+gen_dec_external(Ext, BytesVar) ->
+    CurrMod = get(currmod),
+    #'Externaltypereference'{module=Mod,type=Type} = Ext,
+    emit([case CurrMod of
+	      Mod -> [];
+	      _ -> ["'",Mod,"':"]
+	  end,"'dec_",Type,"'(",BytesVar,",telltype)"]).
+
 gen_dec_imm(Erule, #type{def=Name,constraint=C}) ->
     Aligned = case Erule of
 		  uper -> false;
-- 
cgit v1.2.3