• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "TypeFactory.h"
17 #include "Parser.h"
18 #include "VarType.h"
19 #include "strUtils.h"
20 
21 #include <map>
22 #include <string>
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 
27 
28 TypeFactory * TypeFactory::m_instance = NULL;
29 
30 typedef std::map<std::string, VarType> TypeMap;
31 static  TypeMap g_varMap;
32 static bool g_initialized = false;
33 static int g_typeId = 0;
34 
35 
36 #define ADD_TYPE(name, size, printformat,ispointer)                                           \
37     g_varMap.insert(std::pair<std::string, VarType>(name, VarType(g_typeId++, name, (size + 7) >> 3, printformat , ispointer)));
38 
initBaseTypes()39 void TypeFactory::initBaseTypes()
40 {
41     g_initialized = true;
42     ADD_TYPE("UNKNOWN", 0, "0x%x", false);
43     ADD_TYPE("void", 0, "0x%x", false);
44     ADD_TYPE("char", 8, "%c", false);
45     ADD_TYPE("int", 32, "%d", false);
46     ADD_TYPE("float", 32, "%d", false);
47     ADD_TYPE("short", 16, "%d", false);
48 }
49 
initFromFile(const std::string & filename)50 int TypeFactory::initFromFile(const std::string &filename)
51 {
52     if (!g_initialized) {
53         initBaseTypes();
54     }
55 
56     FILE *fp = fopen(filename.c_str(), "rt");
57     if (fp == NULL) {
58         perror(filename.c_str());
59         return -1;
60     }
61     char line[1000];
62     int lc = 0;
63     while(fgets(line, sizeof(line), fp) != NULL) {
64         lc++;
65         std::string str = trim(line);
66         if (str.size() == 0 || str.at(0) == '#') {
67             continue;
68         }
69         size_t pos = 0, last;
70         std::string name;
71         name = getNextToken(str, pos, &last, WHITESPACE);
72         name = normalizeTypeDeclaration(name);
73         if (name.size() == 0) {
74             fprintf(stderr, "Error: %d : missing type name\n", lc);
75             return -2;
76         }
77         pos = last + 1;
78         std::string size;
79         size = getNextToken(str, pos, &last, WHITESPACE);
80         if (size.size() == 0) {
81             fprintf(stderr, "Error: %d : missing type width\n", lc);
82             return -2;
83         }
84         pos = last + 1;
85         std::string printString;
86         printString = getNextToken(str, pos, &last, WHITESPACE);
87         if (printString.size() == 0) {
88             fprintf(stderr, "Error: %d : missing print-string\n", lc);
89             return -2;
90         }
91 
92         // The ispointer definition is optional since we can just
93         // look at the type name, and determine it is a pointer if
94         // it ends with '*'.
95         bool isPointer = (name[name.size() - 1U] == '*');
96 
97         pos = last + 1;
98         std::string pointerDef;
99         pointerDef = getNextToken(str, pos, &last, WHITESPACE);
100         if (pointerDef.size() != 0) {
101             // Just a little sanity check.
102             if (std::string("true")==pointerDef) {
103                 if (!isPointer) {
104                     fprintf(stderr, "Error: %d: invalid isPointer definition: 'true' but name does not end with '*'!\n", lc);
105                     return -2;
106                 }
107             } else if (std::string("false")==pointerDef) {
108                 if (isPointer) {
109                     fprintf(stderr, "Error: %d: invalid isPointer definition: 'false' but name does end with '*'!\n", lc);
110                     return -2;
111                 }
112             } else {
113                 fprintf(stderr, "Error: %d : invalid isPointer definition, must be either \"true\" or \"false\"\n", lc);
114                 return -2;
115             }
116         }
117 
118         size_t bitSize = atoi(size.c_str());
119         size_t byteSize = (bitSize + 7) >> 3;
120 
121         if (getVarTypeByName(name)->id() != 0) {
122             fprintf(stderr,
123                     "Warining: %d : type %s is already known, definition in line %d is taken\n",
124                     lc, name.c_str(), lc);
125         }
126         g_varMap.insert(std::pair<std::string, VarType>(
127                 name, VarType(g_typeId++,
128                               name,
129                               byteSize,
130                               printString,
131                               isPointer)));
132         std::string constName = "const " + name;
133         g_varMap.insert(std::pair<std::string, VarType>(
134                 constName, VarType(g_typeId++,
135                                    constName,
136                                    byteSize,
137                                    printString,
138                                    isPointer))); //add a const type
139     }
140     g_initialized = true;
141     return 0;
142 }
143 
144 
getVarTypeByName(const std::string & type)145 const VarType * TypeFactory::getVarTypeByName(const std::string & type)
146 {
147     if (!g_initialized) {
148         initBaseTypes();
149     }
150     TypeMap::iterator i = g_varMap.find(type);
151     if (i == g_varMap.end()) {
152         i = g_varMap.find("UNKNOWN");
153     }
154     return &(i->second);
155 }
156 
157