TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / android-emugl / host / tools / emugen / EntryPoint.cpp
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "EntryPoint.h"
17
18 #include "Parser.h"
19 #include "TypeFactory.h"
20 #include "strUtils.h"
21
22 #include <sstream>
23 #include <string>
24
25 #include <stdio.h>
26
27 EntryPoint::EntryPoint()
28 {
29     reset();
30 }
31
32 EntryPoint::~EntryPoint()
33 {
34 }
35
36 void EntryPoint::reset()
37 {
38     m_unsupported = false;
39     m_customDecoder = false;
40     m_notApi = false;
41     m_flushOnEncode = false;
42     m_vars.empty();
43 }
44
45 // return true for valid line (need to get into the entry points list)
46 bool EntryPoint::parse(unsigned int lc, const std::string & str)
47 {
48     size_t pos, last;
49     std::string field;
50
51     reset();
52     std::string linestr = trim(str);
53
54     if (linestr.size() == 0) return false;
55     if (linestr.at(0) == '#') return false;
56
57     // skip PREFIX
58     field = getNextToken(linestr, 0, &last, "(");
59     pos = last + 1;
60     // return type
61     field = getNextToken(linestr, pos, &last, ",)");
62
63     std::string error;
64     std::string retTypeName;
65     if (!parseTypeDeclaration(field, &retTypeName, &error)) {
66         fprintf(stderr,
67                 "line: %d: Parsing error in field <%s>: %s\n",
68                 lc, 
69                 field.c_str(), 
70                 error.c_str());
71         return false;
72     }
73     pos = last + 1;
74     const VarType *theType = TypeFactory::instance()->getVarTypeByName(retTypeName);
75     if (theType->name() == "UNKNOWN") {
76         fprintf(stderr, "UNKNOWN retval: %s\n", linestr.c_str());
77     }
78
79     m_retval.init(std::string(""),
80                   theType,
81                   std::string(""),
82                   Var::POINTER_OUT,
83                   std::string(""),
84                   std::string(""));
85
86     // function name
87     m_name = getNextToken(linestr, pos, &last, ",)");
88     pos = last + 1;
89
90     // parameters;
91     int nvars = 0;
92     while (pos < linestr.size() - 1) {
93         field = getNextToken(linestr, pos, &last, ",)");
94         if (field == "void") {
95             // 'void' is used as a special case for functions that don't take
96             // parameters at all.
97             break;
98         }
99         std::string vartype, varname;
100         if (!parseParameterDeclaration(field, &vartype, &varname, &error)) {
101             fprintf(stderr,
102                     "line: %d: Parsing error in field <%s>, error: %s\n",
103                     lc,
104                     field.c_str(),
105                     error.c_str());
106             return false;
107         }
108         nvars++;
109         const VarType *v = TypeFactory::instance()->getVarTypeByName(vartype);
110         if (v->id() == 0) {
111             fprintf(stderr, "%d: Unknown type: %s\n", lc, vartype.c_str());
112         } else {
113             if (varname == "" &&
114                 !(v->name() == "void" && !v->isPointer())) {
115                 std::ostringstream oss;
116                 oss << "var" << nvars;
117                 varname = oss.str();
118             }
119
120             m_vars.push_back(Var(varname, v, std::string(""), Var::POINTER_IN, "", ""));
121         }
122         pos = last + 1;
123     }
124     return true;
125 }
126
127 void EntryPoint::print(FILE *fp, bool newline,
128                        const std::string & name_suffix,
129                        const std::string & name_prefix,
130                        const std::string & ctx_param ) const
131 {
132     fprintf(fp, "%s %s%s%s(",
133             m_retval.type()->name().c_str(),
134             name_prefix.c_str(),
135             m_name.c_str(),
136             name_suffix.c_str());
137
138     if (ctx_param != "") fprintf(fp, "%s ", ctx_param.c_str());
139
140     for (size_t i = 0; i < m_vars.size(); i++) {
141         if (m_vars[i].isVoid()) continue;
142         if (i != 0 || ctx_param != "") fprintf(fp, ", ");
143         fprintf(fp, "%s %s", m_vars[i].type()->name().c_str(),
144                 m_vars[i].name().c_str());
145     }
146     fprintf(fp, ")%s", newline? "\n" : "");
147 }
148
149 Var * EntryPoint::var(const std::string & name)
150 {
151     Var *v = NULL;
152     for (size_t i = 0; i < m_vars.size(); i++) {
153         if (m_vars[i].name() == name) {
154             v = &m_vars[i];
155             break;
156         }
157     }
158     return v;
159 }
160
161 bool EntryPoint::hasPointers()
162 {
163     bool pointers = false;
164     if (m_retval.isPointer()) pointers = true;
165     if (!pointers) {
166         for (size_t i = 0; i < m_vars.size(); i++) {
167             if (m_vars[i].isPointer()) {
168                 pointers = true;
169                 break;
170             }
171         }
172     }
173     return pointers;
174 }
175
176 int EntryPoint::setAttribute(const std::string &line, size_t lc)
177 {
178     size_t pos = 0;
179     size_t last;
180     std::string token = getNextToken(line, 0, &last, WHITESPACE);
181
182     if (token == "len") {
183         pos = last;
184         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
185
186         if (varname.size() == 0) {
187             fprintf(stderr, "ERROR: %u: Missing variable name in 'len' attribute\n", (unsigned int)lc);
188             return -1;
189         }
190         Var * v = var(varname);
191         if (v == NULL) {
192             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
193                     (unsigned int)lc, varname.c_str(), name().c_str());
194             return -2;
195         }
196         // set the size expression into var
197         pos = last;
198         v->setLenExpression(line.substr(pos));
199     } else if (token == "param_check") {
200         pos = last;
201         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
202
203         if (varname.size() == 0) {
204             fprintf(stderr, "ERROR: %u: Missing variable name in 'param_check' attribute\n", (unsigned int)lc);
205             return -1;
206         }
207         Var * v = var(varname);
208         if (v == NULL) {
209             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
210                     (unsigned int)lc, varname.c_str(), name().c_str());
211             return -2;
212         }
213         // set the size expression into var
214         pos = last;
215         v->setParamCheckExpression(line.substr(pos));
216
217     } else if (token == "dir") {
218         pos = last;
219         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
220         if (varname.size() == 0) {
221             fprintf(stderr, "ERROR: %u: Missing variable name in 'dir' attribute\n", (unsigned int)lc);
222             return -1;
223         }
224         Var * v = var(varname);
225         if (v == NULL) {
226             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
227                     (unsigned int)lc, varname.c_str(), name().c_str());
228             return -2;
229         }
230
231         pos = last;
232         std::string pointerDirStr = getNextToken(line, pos, &last, WHITESPACE);
233         if (pointerDirStr.size() == 0) {
234             fprintf(stderr, "ERROR: %u: missing pointer directions\n", (unsigned int)lc);
235             return -3;
236         }
237
238         if (pointerDirStr == "out") {
239             v->setPointerDir(Var::POINTER_OUT);
240         } else if (pointerDirStr == "inout") {
241             v->setPointerDir(Var::POINTER_INOUT);
242         } else if (pointerDirStr == "in") {
243             v->setPointerDir(Var::POINTER_IN);
244         } else {
245             fprintf(stderr, "ERROR: %u: unknow pointer direction %s\n", (unsigned int)lc, pointerDirStr.c_str());
246         }
247     } else if (token == "var_flag") {
248         pos = last;
249         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
250         if (varname.size() == 0) {
251             fprintf(stderr, "ERROR: %u: Missing variable name in 'var_flag' attribute\n", (unsigned int)lc);
252             return -1;
253         }
254         Var * v = var(varname);
255         if (v == NULL) {
256             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
257                     (unsigned int)lc, varname.c_str(), name().c_str());
258             return -2;
259         }
260         int count = 0;
261         for (;;) {
262             pos = last;
263             std::string flag = getNextToken(line, pos, &last, WHITESPACE);
264             if (flag.size() == 0) {
265                 if (count == 0) {
266                     fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
267                     return -3;
268                 }
269                 break;
270             }
271             count++;
272
273             if (flag == "nullAllowed") {
274                 if (v->isPointer()) {
275                     v->setNullAllowed(true);
276                 } else {
277                     fprintf(stderr, "WARNING: %u: setting nullAllowed for non-pointer variable %s\n",
278                             (unsigned int) lc, v->name().c_str());
279                 }
280             } else if (flag == "isLarge") {
281                 if (v->isPointer()) {
282                     v->setIsLarge(true);
283                 } else {
284                     fprintf(stderr, "WARNING: %u: setting isLarge flag for a non-pointer variable %s\n",
285                             (unsigned int) lc, v->name().c_str());
286                 }
287             } else {
288                 fprintf(stderr, "WARNING: %u: unknow flag %s\n", (unsigned int)lc, flag.c_str());
289             }
290         }
291     } else if (token == "custom_pack") {
292         pos = last;
293         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
294
295         if (varname.size() == 0) {
296             fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_pack' attribute\n", (unsigned int)lc);
297             return -1;
298         }
299         Var * v = var(varname);
300         if (v == NULL) {
301             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
302                     (unsigned int)lc, varname.c_str(), name().c_str());
303             return -2;
304         }
305         // set the size expression into var
306         pos = last;
307         v->setPackExpression(line.substr(pos));
308     } else if (token == "custom_write") {
309         pos = last;
310         std::string varname = getNextToken(line, pos, &last, WHITESPACE);
311
312         if (varname.size() == 0) {
313             fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_write' attribute\n", (unsigned int)lc);
314             return -1;
315         }
316         Var * v = var(varname);
317         if (v == NULL) {
318             fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
319                     (unsigned int)lc, varname.c_str(), name().c_str());
320             return -2;
321         }
322         // set the size expression into var
323         pos = last;
324         v->setWriteExpression(line.substr(pos));
325     } else if (token == "flag") {
326         pos = last;
327         std::string flag = getNextToken(line, pos, &last, WHITESPACE);
328         if (flag.size() == 0) {
329             fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
330             return -4;
331         }
332
333         if (flag == "unsupported") {
334             setUnsupported(true);
335         } else if (flag == "custom_decoder") {
336             setCustomDecoder(true);
337         } else if (flag == "not_api") {
338             setNotApi(true);
339         } else if (flag == "flushOnEncode") {
340             setFlushOnEncode(true);
341         } else {
342             fprintf(stderr, "WARNING: %u: unknown flag %s\n", (unsigned int)lc, flag.c_str());
343         }
344     } else {
345         fprintf(stderr, "WARNING: %u: unknown attribute %s\n", (unsigned int)lc, token.c_str());
346     }
347
348     return 0;
349 }