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%% File: icenum.erl 23%% 24%% 25%%----------------------------------------------------------------- 26%% 27%% Code generation for enum's. 28%%----------------------------------------------------------------- 29-module(icenum). 30 31-import(ic_codegen, [emit/2, emit/3, emit/4, emit_c_enc_rpt/4, emit_c_dec_rpt/4]). 32 33-include("icforms.hrl"). 34-include("ic.hrl"). 35 36%%----------------------------------------------------------------- 37%% External exports 38%%----------------------------------------------------------------- 39-export([enum_gen/4]). 40 41%%----------------------------------------------------------------- 42%% Internal exports 43%%----------------------------------------------------------------- 44-export([]). 45 46enum_gen(G, N, X, c) when is_record(X, enum) -> 47 emit_c_enum(G, N, X); 48enum_gen(_G, _N, _X, _L) -> 49 ok. 50 51 52emit_c_enum(G, N, X) -> 53 case ic_genobj:is_hrlfile_open(G) of 54 true -> 55 EnumName = [ic_forms:get_id2(X) | N], 56 57 case ic_pragma:is_local(G,EnumName) of 58 true -> 59 60 Fd = ic_genobj:hrlfiled(G), 61 EnumNameStr = ic_util:to_undersc(EnumName), 62 ic_code:insert_typedef(G, EnumNameStr, {enum, EnumNameStr}), 63 {tk_enum,_,_,EList} = ic_forms:get_tk(X), 64 emit(Fd, "\n#ifndef __~s__\n",[ic_util:to_uppercase(EnumNameStr)]), 65 emit(Fd, "#define __~s__\n",[ic_util:to_uppercase(EnumNameStr)]), 66 ic_codegen:mcomment_light(Fd, 67 [io_lib:format("Enum definition: ~s", 68 [EnumNameStr])], 69 c), 70 emit(Fd, "typedef CORBA_enum {", []), 71 emit_c_enum_values(G, N, Fd, EList), 72 emit(Fd, "} ~s ;\n\n", [EnumNameStr]), 73 create_c_enum_file(G, N, EnumNameStr, EList), 74 emit(Fd, "\n#endif\n\n"); 75 76 false -> %% Do not generate included types att all. 77 ok 78 end; 79 80 false -> 81 ok 82 end. 83 84 85emit_c_enum_values(_G, N, Fd, [E]) -> 86 emit(Fd, "~s", [ic_util:to_undersc([E| N])]); 87emit_c_enum_values(G, N, Fd, [E |Es]) -> 88 emit(Fd, "~s, ", [ic_util:to_undersc([E| N])]), 89 emit_c_enum_values(G, N, Fd, Es). 90 91 92open_c_coding_file(G, Name) -> 93 SName = string:concat(ic_util:mk_oe_name(G, "code_"), Name), 94 FName = 95 ic_file:join(ic_options:get_opt(G, stubdir),ic_file:add_dot_c(SName)), 96 case file:open(FName, [write]) of 97 {ok, Fd} -> 98 {Fd, SName}; 99 Other -> 100 exit(Other) 101 end. 102 103 104create_c_enum_file(G, N, Name, Elist) -> 105 106 {Fd , SName} = open_c_coding_file(G, Name), 107 HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header 108 HrlFName = filename:basename(ic_genobj:include_file(G)), 109 ic_codegen:emit_stub_head(G, Fd, SName, c), 110 emit(Fd, "#include \"~s\"\n\n",[HrlFName]), 111 112 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113 %% Fd = ic_genobj:stubfiled(G), %% Write on stubfile 114 %% HFd = ic_genobj:hrlfiled(G), %% Write on stubfile header 115 %% HrlFName = filename:basename(ic_genobj:include_file(G)), 116 %% emit(Fd, "#include \"~s\"\n\n",[HrlFName]), 117 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 118 119 emit(Fd, "char* ~s[~p] = {\n", [ic_util:mk_oe_name(G, Name), 120 length(Elist)]), 121 emit_c_enum_array_values(Fd, Elist), 122 emit(Fd, "};\n\n",[]), 123 emit_sizecount(G, N, Fd, HFd, Name, Elist), 124 emit_encode(G, N, Fd, HFd, Name, Elist), 125 emit_decode(G, N, Fd, HFd, Name, Elist), 126 file:close(Fd). 127 128emit_c_enum_array_values(Fd, [E]) -> 129 emit(Fd, " ~p\n", [E]); 130emit_c_enum_array_values(Fd, [E |Es]) -> 131 emit(Fd, " ~p,\n", [E]), 132 emit_c_enum_array_values(Fd, Es). 133 134 135emit_sizecount(G, _N, Fd, HFd, Name, _Elist) -> 136 137 emit(HFd, "int ~s~s(CORBA_Environment *oe_env, int*, int*);\n", 138 [ic_util:mk_oe_name(G, "sizecalc_"), Name]), 139 140 emit(Fd, "int ~s~s(CORBA_Environment *oe_env, int* oe_size_count_index, int* oe_size)\n" 141 "{\n", 142 [ic_util:mk_oe_name(G, "sizecalc_"), Name]), 143 emit(Fd, " int oe_error_code = 0;\n\n",[]), 144 145 AlignName = lists:concat(["*oe_size + sizeof(",Name,")"]), 146 emit(Fd, " *oe_size = ~s;\n\n",[ic_util:mk_align(AlignName)]), 147 148 emit(Fd, " if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, oe_size_count_index, 0)) < 0) {\n"), 149 emit_c_enc_rpt(Fd, " ", "ei_decode_atom", []), 150 emit(Fd, " return oe_error_code;\n }\n"), 151 emit(Fd, " return 0;\n\n",[]), 152 emit(Fd, "}\n\n",[]). 153 154 155emit_encode(G, _N, Fd, HFd, Name, _Elist) -> 156 157 emit(HFd, "int ~s~s(CORBA_Environment *oe_env, ~s);\n", 158 [ic_util:mk_oe_name(G, "encode_"), Name, Name]), 159 160 emit(Fd, "int ~s~s(CORBA_Environment *oe_env, ~s oe_rec) {\n", 161 [ic_util:mk_oe_name(G, "encode_"), Name, Name]), 162 emit(Fd, " int oe_error_code = 0;\n\n",[]), 163 164 emit(Fd, " if ((oe_error_code = oe_ei_encode_atom(oe_env, ~s[oe_rec])) < 0) {\n", 165 [ic_util:mk_oe_name(G, Name)]), 166 emit_c_enc_rpt(Fd, " ", "oe_ei_encode_atom", []), 167 emit(Fd, " return oe_error_code;\n }\n"), 168 169 emit(Fd, " return 0;\n\n",[]), 170 emit(Fd, "}\n\n",[]). 171 172emit_decode(G, _N, Fd, HFd, Name, Elist) -> 173 174 emit(HFd, "int ~s~s(CORBA_Environment *oe_env, char *, int*, ~s *);\n", 175 [ic_util:mk_oe_name(G, "decode_"), Name, Name]), 176 177 emit(Fd, "int ~s~s(CORBA_Environment *oe_env, char *oe_first, int* oe_outindex, " 178 "~s *oe_out) {\n\n", 179 [ic_util:mk_oe_name(G, "decode_"), Name, Name]), 180 emit(Fd, " int oe_error_code = 0;\n",[]), 181 emit(Fd, " int oe_i;\n",[]), 182 emit(Fd, " char oe_atom[256];\n\n",[]), 183 184 AlignName = lists:concat(["*oe_outindex + sizeof(",Name,")"]), 185 emit(Fd, " *oe_outindex = ~s;\n\n",[ic_util:mk_align(AlignName)]), 186 187 emit(Fd, " if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, &oe_env->_iin, oe_atom)) < 0) {\n"), 188 emit_c_enc_rpt(Fd, " ", "ei_decode_atom", []), 189 emit(Fd, " return oe_error_code;\n }\n"), 190 191 Len = length(Elist), 192 emit(Fd, " for(oe_i = 0; oe_i < ~p && strcmp(oe_atom, ~s[oe_i]); oe_i++);\n", 193 [Len, ic_util:mk_oe_name(G, Name)]), 194 emit(Fd, " *oe_out = oe_i;\n\n", []), 195 196 emit(Fd, " if (oe_i == ~p) {\n",[Len]), 197 emit_c_enc_rpt(Fd, " ", "decode atom failure", []), 198 emit(Fd, " return oe_error_code;\n }\n"), 199 200 emit(Fd, " return 0;\n",[]), 201 emit(Fd, "}\n\n",[]). 202 203 204 205 206 207