Home | History | Annotate | Download | only in emugen
      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 "VarType.h"
     18 #include <string>
     19 #include <map>
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include "strUtils.h"
     23 
     24 
     25 TypeFactory * TypeFactory::m_instance = NULL;
     26 
     27 static Var0 g_var0;
     28 static Var8 g_var8;
     29 static Var16 g_var16;
     30 static Var32 g_var32;
     31 
     32 typedef std::map<std::string, VarType> TypeMap;
     33 static  TypeMap g_varMap;
     34 static bool g_initialized = false;
     35 static int g_typeId = 0;
     36 
     37 
     38 static VarConverter * getVarConverter(int size)
     39 {
     40     VarConverter *v = NULL;
     41 
     42     switch(size) {
     43     case 0: v =  &g_var0; break;
     44     case 8: v =  &g_var8; break;
     45     case 16:    v =  &g_var16; break;
     46     case 32:    v =  &g_var32; break;
     47     }
     48     return v;
     49 }
     50 
     51 #define ADD_TYPE(name, size, printformat,ispointer)                                           \
     52     g_varMap.insert(std::pair<std::string, VarType>(name, VarType(g_typeId++, name, &g_var##size , printformat , ispointer)));
     53 
     54 void TypeFactory::initBaseTypes()
     55 {
     56     g_initialized = true;
     57     ADD_TYPE("UNKNOWN", 0, "0x%x", false);
     58     ADD_TYPE("void", 0, "0x%x", false);
     59     ADD_TYPE("char", 8, "%c", false);
     60     ADD_TYPE("int", 32, "%d", false);
     61     ADD_TYPE("float", 32, "%d", false);
     62     ADD_TYPE("short", 16, "%d", false);
     63 }
     64 
     65 int TypeFactory::initFromFile(const std::string &filename)
     66 {
     67     if (!g_initialized) {
     68         initBaseTypes();
     69     }
     70 
     71     FILE *fp = fopen(filename.c_str(), "rt");
     72     if (fp == NULL) {
     73         perror(filename.c_str());
     74         return -1;
     75     }
     76     char line[1000];
     77     int lc = 0;
     78     while(fgets(line, sizeof(line), fp) != NULL) {
     79         lc++;
     80         std::string str = trim(line);
     81         if (str.size() == 0 || str.at(0) == '#') {
     82             continue;
     83         }
     84         size_t pos = 0, last;
     85         std::string name;
     86         name = getNextToken(str, pos, &last, WHITESPACE);
     87         if (name.size() == 0) {
     88             fprintf(stderr, "Error: %d : missing type name\n", lc);
     89             return -2;
     90         }
     91         pos = last + 1;
     92         std::string size;
     93         size = getNextToken(str, pos, &last, WHITESPACE);
     94         if (size.size() == 0) {
     95             fprintf(stderr, "Error: %d : missing type width\n", lc);
     96             return -2;
     97         }
     98         pos = last + 1;
     99         std::string printString;
    100         printString = getNextToken(str, pos, &last, WHITESPACE);
    101         if (printString.size() == 0) {
    102             fprintf(stderr, "Error: %d : missing print-string\n", lc);
    103             return -2;
    104         }
    105 
    106         pos = last + 1;
    107         std::string pointerDef;
    108         pointerDef = getNextToken(str, pos, &last, WHITESPACE);
    109         if (pointerDef.size() == 0) {
    110             fprintf(stderr, "Error: %d : missing ispointer definition\n", lc);
    111             return -2;
    112         }
    113 
    114         bool isPointer=false;
    115         if (std::string("true")==pointerDef)
    116           isPointer = true;
    117         else if (std::string("false")==pointerDef)
    118           isPointer = false;
    119         else
    120         {
    121           fprintf(stderr, "Error: %d : invalid isPointer definition, must be either \"true\" or \"false\"\n", lc);
    122           return -2;
    123         }
    124 
    125         VarConverter *v = getVarConverter(atoi(size.c_str()));
    126         if (v == NULL) {
    127             fprintf(stderr, "Error: %d : unknown var width: %d\n", lc, atoi(size.c_str()));
    128             return -1;
    129         }
    130 
    131         if (getVarTypeByName(name)->id() != 0) {
    132             fprintf(stderr,
    133                     "Warining: %d : type %s is already known, definition in line %d is taken\n",
    134                     lc, name.c_str(), lc);
    135         }
    136         g_varMap.insert(std::pair<std::string, VarType>(name, VarType(g_typeId++, name, v ,printString,isPointer)));
    137         std::string constName = "const " + name;
    138         g_varMap.insert(std::pair<std::string, VarType>(constName, VarType(g_typeId++, constName, v ,printString,isPointer))); //add a const type
    139     }
    140     g_initialized = true;
    141     return 0;
    142 }
    143 
    144 
    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