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_util).
23
24
25-include("icforms.hrl").
26-include("ic.hrl").
27-include("ic_debug.hrl").
28
29%%-----------------------------------------------------------------
30%% External exports
31%%-----------------------------------------------------------------
32
33-export([mk_align/1, mk_list/1, join/2, chain/2, mk_name/2,
34	 mk_OE_name/2, mk_oe_name/2, mk_var/1]).
35
36-export([to_atom/1, to_colon/1, to_list/1, to_undersc/1, to_dot/1,
37	 to_dot/2]).
38-export([to_uppercase/1, adjustScopeToJava/2, eval_java/3, eval_c/3]).
39
40%%-----------------------------------------------------------------
41%% Internal exports
42%%-----------------------------------------------------------------
43-export([]).
44
45%%-----------------------------------------------------------------
46%% External functions
47%%-----------------------------------------------------------------
48
49%% mk_list produces a nice comma separated string of variable names
50mk_list([]) -> [];
51mk_list([Arg | Args]) ->
52    Arg ++ mk_list2(Args).
53mk_list2([Arg | Args]) ->
54    ", " ++ Arg ++ mk_list2(Args);
55mk_list2([]) -> [].
56
57%% Produce a list of items separated by S.
58join([E1, E2| Es], S) ->
59        [E1, S| join([E2| Es], S)];
60join([E], _) ->
61    [E];
62join([], _) ->
63    [].
64
65%% Produce a list of items, each terminated by T.
66chain([E| Es], T) ->
67    [E, T| chain(Es, T)];
68chain([], _) ->
69    [].
70
71
72%% Shall convert a string to a Erlang variable name (Capitalise)
73mk_var( [N | Str] ) when N >= $a, N =< $z ->
74    [ N+$A-$a | Str ];
75mk_var( [N | Str] )  when N >= $A, N =< $Z -> [N | Str].
76
77%% Shall produce a "public" name for name. When we introduce new
78%% identifiers in the mapping that must not collide with those from
79%% the IDL spec.
80%%
81%% NOTE: Change name of IFR ID in system exceptions in corba.hrl when
82%% prefix is changed here.
83%%
84mk_name(_Gen, Name) -> lists:flatten(["OE_" | Name]).
85mk_OE_name(_Gen, Name) -> lists:flatten(["OE_" | Name]).
86mk_oe_name(_Gen, Name) -> lists:flatten(["oe_" | Name]).
87
88mk_align(String) ->
89    io_lib:format("OE_ALIGN(~s)",[String]).
90
91to_atom(A) when is_atom(A) -> A;
92to_atom(L) when is_list(L) -> list_to_atom(L).
93
94to_list(A) when is_list(A) -> A;
95to_list(L) when is_atom(L) -> atom_to_list(L);
96to_list(X) when is_integer(X) -> integer_to_list(X).
97
98
99
100%% Produce a colon (or under score) separated string repr of the name
101%% X
102%%
103to_colon(X) when element(1, X) == scoped_id ->
104    to_colon2(ic_symtab:scoped_id_strip(X));
105to_colon(L) -> to_colon2(L).
106
107to_colon2([X]) -> X;
108to_colon2([X | Xs]) -> to_colon2(Xs) ++ "::" ++ X;
109to_colon2([]) -> "".
110
111
112to_undersc(X) when element(1, X) == scoped_id ->
113    to_undersc2(ic_symtab:scoped_id_strip(X));
114to_undersc(L) -> to_undersc2(L).
115
116to_undersc2([X]) -> X;
117to_undersc2([X | Xs]) -> to_undersc2(Xs) ++ "_" ++ X;
118to_undersc2([]) -> "".
119
120
121%% Z is a single name
122to_uppercase(Z) ->
123    lists:map(fun(X) when X>=$a, X=<$z -> X-$a+$A;
124		 (X) -> X end, Z).
125
126
127%%
128to_dot(X) when element(1, X) == scoped_id ->
129    to_dotLoop(ic_symtab:scoped_id_strip(X));
130to_dot(L) -> to_dotLoop(L).
131
132to_dotLoop([X]) -> ic_forms:get_java_id(X);
133to_dotLoop([X | Xs]) -> to_dotLoop(Xs) ++ "." ++ ic_forms:get_java_id(X);
134to_dotLoop([]) -> "".
135
136
137
138%%
139to_dot(G,X) when element(1, X) == scoped_id ->
140    S = ic_genobj:pragmatab(G),
141    ScopedId = ic_symtab:scoped_id_strip(X),
142    case isConstScopedId(S, ScopedId) of  %% Costants are left as is
143	true ->
144	    to_dotLoop(ScopedId) ++ addDotValue(S, ScopedId);
145	false ->
146	    to_dotLoop(S,ScopedId)
147    end;
148to_dot(G,ScopedId) ->
149    S = ic_genobj:pragmatab(G),
150    case isConstScopedId(S, ScopedId) of  %% Costants are left as is
151	true ->
152	    to_dotLoop(ScopedId) ++ addDotValue(S, ScopedId);
153	false ->
154	    to_dotLoop(S,ScopedId)
155    end.
156
157addDotValue(S, [_C | Ss]) ->
158    case isInterfaceScopedId(S, Ss) of
159	true ->
160	    "";
161	false ->
162	    ".value"
163    end.
164
165to_dotLoop(S,[X]) ->
166    case isInterfaceScopedId(S, [X]) of
167	true ->
168	    ic_forms:get_java_id(X) ++ "Package";
169	false ->
170	    ic_forms:get_java_id(X)
171    end;
172to_dotLoop(S,[X | Xs]) ->
173    case isInterfaceScopedId(S, [X | Xs]) of
174	true ->
175	    to_dotLoop(S,Xs) ++ "." ++ ic_forms:get_java_id(X) ++ "Package";
176	false ->
177	    to_dotLoop(S,Xs) ++ "." ++ ic_forms:get_java_id(X)
178    end;
179to_dotLoop(_S,[]) -> "".
180
181isInterfaceScopedId(_S,[]) ->
182    false;
183isInterfaceScopedId(S,[X|Xs]) ->
184    case ets:match(S,{file_data_local,'_','_',interface,Xs,X,'_','_','_'}) of
185	[] ->
186	    case ets:match(S,{file_data_included,'_','_',interface,Xs,X,'_','_','_'}) of
187		[] ->
188		    false;
189		_ ->
190		    true
191	    end;
192	_ ->
193	    true
194    end.
195
196isConstScopedId(_S,[]) ->
197    false;
198isConstScopedId(S,[X|Xs]) ->
199    case ets:match(S,{file_data_local,'_','_',const,Xs,X,'_','_','_'}) of
200	[] ->
201	    case ets:match(S,{file_data_included,'_','_',const,Xs,X,'_','_','_'}) of
202		[] ->
203		    false;
204		_ ->
205		    true
206	    end;
207	_ ->
208	    true
209    end.
210
211
212
213%%
214adjustScopeToJava(G,X) when element(1, X) == scoped_id ->
215    S = ic_genobj:pragmatab(G),
216    ScopedId = ic_symtab:scoped_id_strip(X),
217    case isConstScopedId(S, ScopedId) of  %% Costants are left as is
218	true ->
219	    ic_forms:get_java_id(ScopedId);
220	false ->
221	    adjustScopeToJavaLoop(S,ScopedId)
222    end;
223adjustScopeToJava(G,ScopedId) ->
224    S = ic_genobj:pragmatab(G),
225    case isConstScopedId(S, ScopedId) of  %% Costants are left as is
226	true ->
227	    ic_forms:get_java_id(ScopedId);
228	false ->
229	    adjustScopeToJavaLoop(S,ScopedId)
230    end.
231
232
233
234adjustScopeToJavaLoop(_S,[]) ->
235    [];
236adjustScopeToJavaLoop(S,[X | Xs]) ->
237    case isInterfaceScopedId(S, [X | Xs]) of
238	true ->
239	    [ic_forms:get_java_id(X) ++ "Package" | adjustScopeToJavaLoop(S,Xs)];
240	false ->
241	    [ic_forms:get_java_id(X) | adjustScopeToJavaLoop(S,Xs)]
242    end.
243
244
245%%
246%%  Expression evaluator for java
247%%
248%% Well, this is not an evaluator, it just
249%% prints the hole operation, sorry.
250%%
251eval_java(G,N,Arg) when is_record(Arg, scoped_id) ->
252    {FSN, _, _, _} =
253	ic_symtab:get_full_scoped_name(G, N, Arg),
254    ic_util:to_dot(G,FSN);
255eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<integer_literal>' ->
256    element(3,Arg);
257eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<character_literal>' ->
258    element(3,Arg);
259eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<wcharacter_literal>' ->
260    element(3,Arg);
261eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<boolean_literal>' ->
262    element(3,Arg);
263eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<floating_pt_literal>' ->
264    element(3,Arg);
265eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<string_literal>' ->
266    element(3,Arg);
267eval_java(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<wstring_literal>' ->
268    element(3,Arg);
269eval_java(G,N,{Op,Arg1,Arg2}) ->
270    "(" ++ eval_java(G,N,Arg1) ++
271	ic_forms:get_java_id(Op) ++
272	eval_java(G,N,Arg2) ++ ")".
273
274
275
276%%
277%%  Expression evaluator for c
278%%
279%% Well, this is not an evaluator, it just
280%% prints the hole operation, sorry.
281%%
282eval_c(G,N,Arg) when is_record(Arg, scoped_id) ->
283    {FSN, _, _, _} =
284	ic_symtab:get_full_scoped_name(G, N, Arg),
285    ic_util:to_undersc(FSN);
286eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<integer_literal>' ->
287    element(3,Arg);
288eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<character_literal>' ->
289    element(3,Arg);
290eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<wcharacter_literal>' ->
291    element(3,Arg);
292eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<boolean_literal>' ->
293    element(3,Arg);
294eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<floating_pt_literal>' ->
295    element(3,Arg);
296eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<string_literal>' ->
297    element(3,Arg);
298eval_c(_G,_N,Arg) when is_tuple(Arg) andalso element(1,Arg) == '<wstring_literal>' ->
299    element(3,Arg);
300eval_c(G,N,{Op,Arg1,Arg2}) ->
301    "(" ++ eval_c(G,N,Arg1) ++
302	atom_to_list(Op) ++
303	eval_c(G,N,Arg2) ++ ")".
304
305
306%%-----------------------------------------------------------------
307%% Internal functions
308%%-----------------------------------------------------------------
309
310
311
312
313
314
315