1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1998-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22-module(ic_code). 23 24 25-include_lib("ic/src/ic.hrl"). 26-include_lib("ic/src/icforms.hrl"). 27 28%%----------------------------------------------------------------- 29%% External exports 30%%----------------------------------------------------------------- 31-export([get_basetype/2, insert_typedef/3, codeDirective/2]). 32-export([gen_includes/3, gen_includes/4, mk_list/1]). 33 34-export([type_expand_op/4, type_expand_handle_op/4]). 35-export([ type_expand_op_exec/4, type_expand_all/6, type_expand/7]). 36 37-export([type_expand_null/3, type_expand_void/3, type_expand_float/3, type_expand_double/3]). 38-export([type_expand_short/3, type_expand_ushort/3, type_expand_long/3, type_expand_ulong/3]). 39-export([type_expand_longlong/3, type_expand_ulonglong/3]). 40-export([type_expand_char/3, type_expand_wchar/3, type_expand_boolean/3]). 41-export([type_expand_octet/3, type_expand_any/3, type_expand_wstring/3]). 42-export([type_expand_object/3, type_expand_string/3, type_expand_struct/7, type_expand_union/7]). 43-export([type_expand_enum/4, type_expand_sequence/7, type_expand_array/7, type_expand_error/3]). 44 45-export([type_expand_struct_rule/3, type_expand_union_rule/2, type_expand_enum_rule/4]). 46-export([type_expand_enum_elements/3, type_expand_longdouble/3, type_expand_typecode/3]). 47-export([type_expand_principal/3, type_expand_exception/7]). 48 49%%----------------------------------------------------------------- 50%% External functions 51%%----------------------------------------------------------------- 52 53%%------------------------------------------------------------------------------------- 54%% 55%% Trackrecording of generated sequence type structs, thist is just used for C today. 56%% 57%%------------------------------------------------------------------------------------- 58 59get_basetype(G, MyId) -> 60 case ?lookup(ic_genobj:typedeftab(G), MyId) of 61 [] -> 62 MyId; 63 X -> 64 get_basetype(G, X) 65 end. 66 67insert_typedef(_G, "erlang_term", _) -> 68 ok; 69insert_typedef(G, MyId, DefinedAsId) -> 70 ?insert(ic_genobj:typedeftab(G), MyId, DefinedAsId). 71 72codeDirective(G,X) -> 73 case produceCode(X) of 74 true -> 75 case ic_options:get_opt(G, be) of 76 c_genserv -> 77 c; 78 c_client -> 79 c; 80 c_server -> 81 c_server; 82 _ -> 83 erlang 84 end; 85 false -> 86 case ic_options:get_opt(G, be) of 87 c_genserv -> 88 c_no_stub; 89 c_client -> 90 c_no_stub; 91 c_server -> 92 c_server_no_stub; 93 _ -> 94 erlang_no_stub 95 end 96 end. 97 98%% Checks if X should produce code 99produceCode(X) when is_record(X, module) -> 100 case ic_forms:get_body(X) of 101 [] -> 102 true; 103 List -> 104 produceModuleCode(List) 105 end; 106produceCode(_X) -> 107 false. 108 109produceModuleCode([]) -> 110 false; 111produceModuleCode([X|_Xs]) when is_record(X, const) -> 112 true; 113produceModuleCode([_X|Xs]) -> 114 produceModuleCode(Xs). 115 116%% Includes needed c file headers for included idl files 117gen_includes(Fd,G,Type) -> 118 case Type of 119 c_client -> 120 IncludeList = 121 ic_pragma:get_included_c_headers(G), 122 gen_includes_loop(Fd,IncludeList,Type); 123 c_server -> 124 IncludeList = 125 ic_pragma:get_included_c_headers(G), 126 gen_includes_loop(Fd,IncludeList,Type); 127 _ -> 128 ok 129 end, 130 ic_codegen:nl(Fd), 131 ic_codegen:emit(Fd, "#ifdef __cplusplus\n"), 132 ic_codegen:emit(Fd, "extern \"C\" {\n"), 133 ic_codegen:emit(Fd, "#endif\n\n"). 134 135 136%% Includes needed c file headers for local interfaces 137gen_includes(Fd,G,X,Type) -> 138 case Type of 139 c_client -> 140 IncludeList = 141 ic_pragma:get_local_c_headers(G,X), 142 gen_includes_loop(Fd,IncludeList,Type); 143 c_server -> 144 IncludeList = 145 ic_pragma:get_local_c_headers(G,X), 146 gen_includes_loop(Fd,IncludeList,Type); 147 _ -> 148 ok 149 end, 150 ic_codegen:nl(Fd), 151 ic_codegen:emit(Fd, "#ifdef __cplusplus\n"), 152 ic_codegen:emit(Fd, "extern \"C\" {\n"), 153 ic_codegen:emit(Fd, "#endif\n\n"). 154 155 156gen_includes_loop(_,[],_) -> 157 ok; 158gen_includes_loop(Fd,[I|Is],Type) -> 159 L = string:tokens(I,"/"), 160 File = lists:last(L), 161 case File of 162 "erlang" -> % Erlang is NOT generated that way ! 163 gen_includes_loop(Fd,Is,Type); 164 "oe_erlang" -> % Erlang is NOT generated that way ! 165 gen_includes_loop(Fd,Is,Type); 166 _ -> 167 case Type of 168 c_client -> 169 ic_codegen:emit(Fd, "#include \"~s.h\"\n", [File]); 170 c_server -> 171 ic_codegen:emit(Fd, "#include \"~s__s.h\"\n", [File]) 172 end, 173 gen_includes_loop(Fd,Is,Type) 174 end. 175 176 177 178 179%% 180%% Used in NOC only 181%% 182 183 184%% 185%% Type expand on function head comments 186%% 187type_expand_op(G,N,X,Fd) -> 188 case catch type_expand_op_exec(G,N,X,Fd) of 189 {'EXIT',_Reason} -> 190 ic_codegen:nl(Fd), 191 ic_codegen:emit(Fd,"%% Error under type expansion, does not affect generated code.~n",[]), 192 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]); 193 _ -> 194 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]) 195 end. 196 197 198type_expand_op_exec(G,N,X,Fd) -> 199 InArgs = ic:filter_params([in,inout], X#op.params), 200 OutArgs = ic:filter_params([out,inout], X#op.params), 201 ParamNr = length(InArgs)+1, 202 Tabs = "", 203 204 ic_codegen:nl(Fd), 205 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]), 206 207 case ic_forms:is_oneway(X) of 208 false -> 209 ic_codegen:emit(Fd,"%% Operation: ~s/~p~n",[ic_forms:get_id2(X),ParamNr]); 210 true -> 211 ic_codegen:emit(Fd,"%% Operation: ~s/~p (oneway)~n",[ic_forms:get_id2(X),ParamNr]) 212 end, 213 214 if X#op.raises == [] -> []; 215 true -> 216 ic_codegen:emit(Fd,"%%~n",[]), 217 RaisesList=["%% Raises: " ++ 218 mk_list(lists:map(fun(E) -> ic_util:to_colon(E) end, 219 X#op.raises))], 220 ic_codegen:emit(Fd,RaisesList,[]), 221 ic_codegen:nl(Fd) 222 end, 223 224 %% Print argument names 225 ic_codegen:emit(Fd,"%%\n",[]), 226 InArgNames = ["OE_Ref"]++[ic_util:mk_var(ic_forms:get_id(InArg#param.id)) || InArg <- InArgs ], 227 OutArgNames = ["Ret"]++[ic_util:mk_var(ic_forms:get_id(OutArg#param.id)) || OutArg <- OutArgs ], 228 case length(InArgNames) > 1 of 229 true -> 230 ic_codegen:emit(Fd,"%% Input value(s) : ~s~n",[mk_list(InArgNames)]); 231 false -> 232 ic_codegen:emit(Fd,"%% Input value : ~s~n",[mk_list(InArgNames)]) 233 end, 234 case length(OutArgNames) > 1 of 235 true -> 236 ic_codegen:emit(Fd,"%% Return value(s) : ~s~n",[mk_list(OutArgNames)]); 237 false -> 238 ic_codegen:emit(Fd,"%% Return value : ~s~n",[mk_list(OutArgNames)]) 239 end, 240 ic_codegen:emit(Fd,"%%\n",[]), 241 242 InArgsTypeList = 243 [{ic_util:mk_var(ic_forms:get_id(InArg#param.id)),ic_forms:get_tk(InArg)} || InArg <- InArgs ], 244 case InArgsTypeList of 245 [] -> %% no input parameters 246 ok; 247 _ -> 248 ic_codegen:emit(Fd,"%% --input-params-~n",[]), 249 type_expand_all(G,N,X,Fd,Tabs,InArgsTypeList) 250 end, 251 252 ReturnTypeList =[{"Ret",X#op.tk}], 253 ic_codegen:emit(Fd,"%% --return-value-~n",[]), 254 type_expand_all(G,N,X,Fd,Tabs,ReturnTypeList), 255 256 OutArgsTypeList = 257 [{ic_util:mk_var(ic_forms:get_id(OutArg#param.id)),ic_forms:get_tk(OutArg)} || OutArg <- OutArgs ], 258 case OutArgsTypeList of 259 [] -> %% no input parameters 260 ok; 261 _ -> 262 ic_codegen:emit(Fd,"%% -output-values-~n",[]), 263 type_expand_all(G,N,X,Fd,Tabs,OutArgsTypeList) 264 end. 265 266 267 268 269type_expand_handle_op(G,N,X,Fd) -> 270 case catch type_expand_handle_op_exec(G,N,X,Fd) of 271 {'EXIT',_Reason} -> 272 ic_codegen:nl(Fd), 273 ic_codegen:emit(Fd,"%% Error under type expansion, does not affect generated code.~n",[]), 274 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]); 275 _ -> 276 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]) 277 end. 278 279 280type_expand_handle_op_exec(_G,_N,X,Fd) -> 281 InArgs = ic:filter_params([in,inout], X#op.params), 282 ParamNr = length(InArgs)+1, 283 284 ic_codegen:nl(Fd), 285 ic_codegen:emit(Fd,"%%------------------------------------------------------------~n",[]), 286 287 case ic_forms:is_oneway(X) of 288 false -> 289 ic_codegen:emit(Fd,"%% Handle operation: handle_call/3~n",[]); 290 true -> 291 ic_codegen:emit(Fd,"%% Handle operation: handle_cast/3~n",[]) 292 end, 293 ic_codegen:emit(Fd,"%%~n",[]), 294 ic_codegen:emit(Fd,"%% Used for operation ~s/~p implementation~n",[ic_forms:get_id2(X),ParamNr]). 295 296 297 298type_expand_all(_G,_N,_X,_Fd,_Tabs,[]) -> 299 ok; 300type_expand_all(G,N,X,Fd,Tabs,[{ArgName,Type}|Rest]) -> 301 type_expand(G,N,X,Fd,Tabs,ArgName,Type), 302 type_expand_all(G,N,X,Fd,Tabs,Rest); 303type_expand_all(G,N,X,Fd,Tabs,[{default,_ArgName,Type}|Rest]) -> 304 type_expand(G,N,X,Fd,Tabs,"Def",Type), 305 type_expand_all(G,N,X,Fd,Tabs,Rest); 306type_expand_all(G,N,X,Fd,Tabs,[{LabelNr,_ArgName,Type}|Rest]) when is_integer(LabelNr) -> 307 type_expand(G,N,X,Fd,Tabs,"V" ++ integer_to_list(LabelNr),Type), 308 type_expand_all(G,N,X,Fd,Tabs,Rest); 309type_expand_all(G,N,X,Fd,Tabs,[{Label,_ArgName,Type}|Rest]) -> 310 type_expand(G,N,X,Fd,Tabs,Label,Type), 311 type_expand_all(G,N,X,Fd,Tabs,Rest). 312 313 314 315type_expand(_G,_N,_X,Fd,Tabs,Name,tk_null) -> 316 type_expand_null(Fd,Tabs,Name); 317type_expand(_G,_N,_X,Fd,Tabs,Name,tk_void) -> 318 type_expand_void(Fd,Tabs,Name); 319type_expand(_G,_N,_X,Fd,Tabs,Name,tk_float) -> 320 type_expand_float(Fd,Tabs,Name); 321type_expand(_G,_N,_X,Fd,Tabs,Name,tk_double) -> 322 type_expand_double(Fd,Tabs,Name); 323type_expand(_G,_N,_X,Fd,Tabs,Name,tk_longdouble) -> 324 type_expand_longdouble(Fd,Tabs,Name); 325type_expand(_G,_N,_X,Fd,Tabs,Name,tk_short) -> 326 type_expand_short(Fd,Tabs,Name); 327type_expand(_G,_N,_X,Fd,Tabs,Name,tk_ushort) -> 328 type_expand_ushort(Fd,Tabs,Name); 329type_expand(_G,_N,_X,Fd,Tabs,Name,tk_long) -> 330 type_expand_long(Fd,Tabs,Name); 331type_expand(_G,_N,_X,Fd,Tabs,Name,tk_longlong) -> 332 type_expand_longlong(Fd,Tabs,Name); 333type_expand(_G,_N,_X,Fd,Tabs,Name,tk_ulong) -> 334 type_expand_ulong(Fd,Tabs,Name); 335type_expand(_G,_N,_X,Fd,Tabs,Name,tk_ulonglong) -> 336 type_expand_ulonglong(Fd,Tabs,Name); 337type_expand(_G,_N,_X,Fd,Tabs,Name,tk_char) -> 338 type_expand_char(Fd,Tabs,Name); 339type_expand(_G,_N,_X,Fd,Tabs,Name,tk_wchar) -> 340 type_expand_wchar(Fd,Tabs,Name); 341type_expand(_G,_N,_X,Fd,Tabs,Name,tk_boolean) -> 342 type_expand_boolean(Fd,Tabs,Name); 343type_expand(_G,_N,_X,Fd,Tabs,Name,tk_octet) -> 344 type_expand_octet(Fd,Tabs,Name); 345type_expand(_G,_N,_X,Fd,Tabs,Name,tk_any) -> 346 type_expand_any(Fd,Tabs,Name); 347type_expand(_G,_N,_X,Fd,Tabs,Name,tk_TypeCode) -> 348 type_expand_typecode(Fd,Tabs,Name); 349type_expand(_G,_N,_X,Fd,Tabs,Name,tk_Principal) -> 350 type_expand_principal(Fd,Tabs,Name); 351type_expand(G, N, X,Fd,Tabs,Name, {tk_except, Id, ExcName, ElementList}) -> 352 type_expand_exception(G, N, X, Fd,Tabs,Name, 353 {tk_except, Id, ExcName, ElementList}); 354type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_fixed, _Digits, _Scale}) -> 355 type_expand_fixed(Fd,Tabs,Name); 356type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_objref, _IFRId, _ObjTabs, _ObjName}) -> 357 type_expand_object(Fd,Tabs,Name); 358type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_objref, _IFRId, _ObjName}) -> 359 type_expand_object(Fd,Tabs,Name); 360type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_string, _Length}) -> 361 type_expand_string(Fd,Tabs,Name); 362type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_wstring, _Length}) -> 363 type_expand_wstring(Fd,Tabs,Name); 364type_expand(G,N,X,Fd,Tabs,Name,{tk_union, IFRId, UnionName, DTC, DNr, LblList}) -> 365 type_expand_union(G,N,X,Fd,Tabs,Name,{tk_union, IFRId, UnionName, DTC, DNr, LblList}); 366type_expand(_G,_N,_X,Fd,Tabs,Name,{tk_enum, IFRId, EnumName, ElemNameList}) -> 367 type_expand_enum(Fd,Tabs,Name,{tk_enum, IFRId, EnumName, ElemNameList}); 368type_expand(G,N,X,Fd,Tabs,Name,{tk_sequence, ElemTC, Length}) -> 369 type_expand_sequence(G,N,X,Fd,Tabs,Name,{tk_sequence, ElemTC, Length}); 370type_expand(G,N,X,Fd,Tabs,Name,{tk_array, ElemTC, Length}) -> 371 type_expand_array(G,N,X,Fd,Tabs,Name,{tk_array, ElemTC, Length}); 372type_expand(G,N,X,Fd,Tabs,Name,{tk_struct, IFRId, StructName, TcList}) -> 373 type_expand_struct(G,N,X,Fd,Tabs,Name,{tk_struct, IFRId, StructName, TcList}); 374type_expand(_G,_N,_X,Fd,Tabs,Name,_) -> 375 type_expand_error(Fd,Tabs,Name). 376 377 378%% Basic OMG IDL types 379 380type_expand_null(Fd,Tabs,Name) -> 381 ic_codegen:emit(Fd,"%%~s ~s = null()~n",[Tabs,Name]). 382 383type_expand_void(Fd,Tabs,Name) -> 384 ic_codegen:emit(Fd,"%%~s ~s = void()~n",[Tabs,Name]). 385 386type_expand_float(Fd,Tabs,Name) -> 387 ic_codegen:emit(Fd,"%%~s ~s = float()~n",[Tabs,Name]). 388 389type_expand_double(Fd,Tabs,Name) -> 390 ic_codegen:emit(Fd,"%%~s ~s = double()~n",[Tabs,Name]). 391 392type_expand_longdouble(Fd,Tabs,Name) -> 393 ic_codegen:emit(Fd,"%%~s ~s = long_double()~n",[Tabs,Name]). 394 395type_expand_short(Fd,Tabs,Name) -> 396 ic_codegen:emit(Fd,"%%~s ~s = short()~n",[Tabs,Name]). 397 398type_expand_ushort(Fd,Tabs,Name) -> 399 ic_codegen:emit(Fd,"%%~s ~s = unsigned_Short()~n",[Tabs,Name]). 400 401type_expand_long(Fd,Tabs,Name) -> 402 ic_codegen:emit(Fd,"%%~s ~s = long()~n",[Tabs,Name]). 403 404type_expand_longlong(Fd,Tabs,Name) -> 405 ic_codegen:emit(Fd,"%%~s ~s = long_Long()~n",[Tabs,Name]). 406 407type_expand_ulong(Fd,Tabs,Name) -> 408 ic_codegen:emit(Fd,"%%~s ~s = unsigned_Long()~n",[Tabs,Name]). 409 410type_expand_ulonglong(Fd,Tabs,Name) -> 411 ic_codegen:emit(Fd,"%%~s ~s = unsigned_Long_Long()~n",[Tabs,Name]). 412 413type_expand_char(Fd,Tabs,Name) -> 414 ic_codegen:emit(Fd,"%%~s ~s = char()~n",[Tabs,Name]). 415 416type_expand_wchar(Fd,Tabs,Name) -> 417 ic_codegen:emit(Fd,"%%~s ~s = wchar()~n",[Tabs,Name]). 418 419type_expand_boolean(Fd,Tabs,Name) -> 420 ic_codegen:emit(Fd,"%%~s ~s = boolean()~n",[Tabs,Name]). 421 422type_expand_octet(Fd,Tabs,Name) -> 423 ic_codegen:emit(Fd,"%%~s ~s = octet()~n",[Tabs,Name]). 424 425type_expand_any(Fd,Tabs,Name) -> 426 ic_codegen:emit(Fd,"%%~s ~s = any()~n",[Tabs,Name]). 427 428type_expand_typecode(Fd,Tabs,Name) -> 429 ic_codegen:emit(Fd,"%%~s ~s = TypeCode()~n",[Tabs,Name]). 430 431type_expand_principal(Fd,Tabs,Name) -> 432 ic_codegen:emit(Fd,"%%~s ~s = principal()~n",[Tabs,Name]). 433 434 435type_expand_fixed(Fd,Tabs,Name) -> 436 ic_codegen:emit(Fd,"%%~s ~s = fixed()~n",[Tabs,Name]). 437 438type_expand_object(Fd,Tabs,Name) -> 439 ic_codegen:emit(Fd,"%%~s ~s = Object_Ref()~n",[Tabs,Name]). 440 441 442%% Constructed OMG IDL types 443 444type_expand_string(Fd,Tabs,Name) -> 445 ic_codegen:emit(Fd,"%%~s ~s = String()~n",[Tabs,Name]). 446 447type_expand_wstring(Fd,Tabs,Name) -> 448 ic_codegen:emit(Fd,"%%~s ~s = WString()~n",[Tabs,Name]). 449 450type_expand_exception(G, N, X, Fd, Tabs, Name, {tk_except, Id, ExcName, ElementList}) -> 451 ScopedStructName = getScopedName(G, N, ExcName, Id), 452 ic_codegen:emit(Fd,"%%~s ~s = ",[Tabs, Name]), 453 type_expand_exception_rule(Fd, ScopedStructName, ElementList), 454 type_expand_all(G, N, X, Fd, Tabs, ElementList). 455 456type_expand_struct(G,N,X,Fd,Tabs,Name,{tk_struct, IFRId, StructName, TcList}) -> 457 ScopedStructName = getScopedName(G,N,StructName,IFRId), 458 ic_codegen:emit(Fd,"%%~s ~s = ",[Tabs,Name]), 459 type_expand_struct_rule(Fd,ScopedStructName,TcList), 460 type_expand_all(G,N,X,Fd,Tabs,TcList). 461 462type_expand_union(G,N,X,Fd,Tabs,Name,{tk_union, IFRId, UnionName, DTC, _DNr, LblList}) -> 463 ScopedUnionName = getScopedName(G,N,UnionName,IFRId), 464 ic_codegen:emit(Fd,"%%~s ~s = #'~s'{label, value}\n",[Tabs,Name,ScopedUnionName]), 465 type_expand(G,N,X,Fd,Tabs,"label",DTC), 466 ic_codegen:emit(Fd,"%%~s value = ",[Tabs]), 467 type_expand_union_rule(Fd,LblList), 468 type_expand_all(G,N,X,Fd,Tabs,LblList). 469 470type_expand_enum(Fd,Tabs,Name,{tk_enum, _IFRId, EnumName, ElemNameList}) -> 471 ic_codegen:emit(Fd,"%%~s ~s = ~s~n",[Tabs,Name,EnumName]), 472 type_expand_enum_rule(Fd,Tabs,EnumName,ElemNameList). 473 474type_expand_sequence(G,N,X,Fd,Tabs,Name,{tk_sequence, ElemTC, _Length}) -> 475 ic_codegen:emit(Fd,"%%~s ~s = [ ~sElem ]~n",[Tabs,Name,Name]), 476 type_expand(G,N,X,Fd,Tabs,Name++"Elem",ElemTC). 477 478type_expand_array(G,N,X,Fd,Tabs,Name,{tk_array, ElemTC, _Length}) -> 479 ic_codegen:emit(Fd,"%%~s ~s = { ~sElem[,..~sElem] }~n",[Tabs,Name,Name,Name]), 480 type_expand(G,N,X,Fd,Tabs,Name++"Elem",ElemTC). 481 482type_expand_error(Fd,Tabs,Name) -> 483 ic_codegen:emit(Fd,"%%~s ~s = ????~n",[Tabs,Name]). 484 485 486type_expand_exception_rule(Fd,_Name,[]) -> 487 ic_codegen:emit(Fd," ???? "); 488type_expand_exception_rule(Fd,Name,TcList) -> 489 ic_codegen:emit(Fd,"#'~s'{",[Name]), 490 type_expand_exception_rule(Fd,TcList). 491 492type_expand_exception_rule(Fd,[{Name,_TC}]) -> 493 ic_codegen:emit(Fd,"~s}~n",[Name]); 494type_expand_exception_rule(Fd,[{Name,_TC}|Rest]) -> 495 ic_codegen:emit(Fd,"~s,",[Name]), 496 type_expand_exception_rule(Fd,Rest). 497 498type_expand_struct_rule(Fd,_Name,[]) -> 499 ic_codegen:emit(Fd," ???? "); 500type_expand_struct_rule(Fd,Name,TcList) -> 501 ic_codegen:emit(Fd,"#'~s'{",[Name]), 502 type_expand_struct_rule(Fd,TcList). 503 504type_expand_struct_rule(Fd,[{Name,_TC}]) -> 505 ic_codegen:emit(Fd,"~s}~n",[Name]); 506type_expand_struct_rule(Fd,[{Name,_TC}|Rest]) -> 507 ic_codegen:emit(Fd,"~s,",[Name]), 508 type_expand_struct_rule(Fd,Rest). 509 510 511type_expand_union_rule(Fd,[]) -> 512 ic_codegen:emit(Fd," ????"); 513type_expand_union_rule(Fd,[{default,_Name,_TC}]) -> 514 ic_codegen:emit(Fd,"Def~n",[]); 515type_expand_union_rule(Fd,[{LNr,_Name,_TC}]) when is_integer(LNr)-> 516 ic_codegen:emit(Fd,"V~p~n",[LNr]); 517type_expand_union_rule(Fd,[{Label,_Name,_TC}]) -> 518 ic_codegen:emit(Fd,"~s~n",[Label]); 519type_expand_union_rule(Fd,[{default,_Name,_TC}|Rest]) -> 520 ic_codegen:emit(Fd,"Default | "), 521 type_expand_union_rule(Fd,Rest); 522type_expand_union_rule(Fd,[{LNr,_Name,_TC}|Rest]) when is_integer(LNr) -> 523 ic_codegen:emit(Fd,"V~p | ",[LNr]), 524 type_expand_union_rule(Fd,Rest); 525type_expand_union_rule(Fd,[{Label,_Name,_TC}|Rest]) -> 526 ic_codegen:emit(Fd,"~s | ",[Label]), 527 type_expand_union_rule(Fd,Rest). 528 529 530type_expand_enum_rule(Fd,Tabs,Name,[]) -> 531 ic_codegen:emit(Fd,"%%~s ~s = ????",[Tabs,Name]); 532type_expand_enum_rule(Fd,Tabs,Name,ElList) -> 533 ic_codegen:emit(Fd,"%%~s ~s = ",[Tabs,Name]), 534 type_expand_enum_rule(Fd,ElList). 535 536type_expand_enum_rule(Fd,[ElName]) -> 537 ic_codegen:emit(Fd,"'~s' ~n",[ElName]); 538type_expand_enum_rule(Fd,[First|Rest]) -> 539 ic_codegen:emit(Fd,"'~s' | ",[First]), 540 type_expand_enum_rule(Fd,Rest). 541 542type_expand_enum_elements(_Fd,_Tabs,[]) -> 543 ok; 544type_expand_enum_elements(Fd,Tabs,[Elem|Elems]) -> 545 ic_codegen:emit(Fd,"%%~s ~s = Atom()~n",[Tabs,Elem]), 546 type_expand_enum_elements(Fd,Tabs,Elems). 547 548 549 550%% Returns the right scoped name to be used 551%% along with the expansion comments 552getScopedName(G,N,Name,IfrId) -> 553 PTab = ic_genobj:pragmatab(G), 554 case ets:match(PTab,{alias,'$0',IfrId}) of 555 [] -> %% No Alias - should never happen 556 ic_util:to_undersc(ic_pragma:mk_scope(IfrId)); 557 [[[_S|N]]] -> %% An alias 558 ic_util:to_undersc([Name|N]); 559 [[[S|FoundScope]]] -> %% Maybe inherited 560 case ic_pragma:is_inherited_by(FoundScope,N,PTab) of 561 false -> %% Not inherited 562 ic_util:to_undersc([S|FoundScope]); 563 true -> %% inherited 564 ic_util:to_undersc([Name|N]) 565 end 566 end. 567 568 569%% mk_list produces a nice comma separated 570%% string of variable names 571mk_list([]) -> []; 572mk_list([Arg | Args]) -> 573 Arg ++ mk_list2(Args). 574mk_list2([Arg | Args]) -> 575 ", " ++ Arg ++ mk_list2(Args); 576mk_list2([]) -> []. 577 578 579 580%%----------------------------------------------------------------- 581%% Internal functions 582%%----------------------------------------------------------------- 583 584 585 586