void BuildProductionTable() { int i,j,k,LHS,index; ProductionNode *p; RHSNode *s; ProductionCount++; ProductTab = (ProductTableElem *) /**/ Allocate(ProductionCount * sizeof(ProductTableElem)); ProductTab[0].LHS = LookupSymbol(StartSymbol); ProductTab[0].RHS = (short *)Allocate(2 * sizeof(short)); ProductTab[0].RHSA = (short *)Allocate(2 * sizeof(short)); ProductTab[0].lenRHS = ProductTab[0].lenRHSA = 2; ProductTab[0].RHS[0] = ProductTab[0].RHSA[0] = LookupSymbol(ProductionList->symbol->text); ProductTab[0].RHS[1] = ProductTab[0].RHSA[1] = LookupSymbol(EOFSymbol); RHSLenCount = ProductTab[0].lenRHSA; for (i=1, p=ProductionList; p != NULL; i++,p=p->next) { LHS = LookupSymbol(p->symbol->text); ProductTab[i].LHS = LHS; ProductTab[i].RHS = (short *)Allocate(p->length * sizeof(short)); ProductTab[i].RHSA = (short *)Allocate(p->length * sizeof(short)); for (j=k=0, s=p->rhs; s != NULL; k++, s=s->next) { index = LookupSymbol(s->symbol->text); if (SymTab[index].type == Action) ProductTab[i].RHSA[k] = index; else ProductTab[i].RHSA[k] = ProductTab[i].RHS[j++] = index; } ProductTab[i].lenRHS = j; ProductTab[i].lenRHSA = k; RHSLenCount += ProductTab[i].lenRHSA; } }
/* lookup in all symbol tables */ TreeNode *Lookup(char *name, char *path){ SymbolTable *p = SymTab; int ansLevel = -1; TreeNode *ret = NULL; TreeNode *tmp = NULL; // printf("lookup:%s, path:%s\n", name, path); while (p){ if (sub_str(p->path, path)){ // cout<<"lookup symbol"<<endl; tmp = LookupSymbol(name, p); // cout<<"end"<<endl; if (tmp){ // cout<<"find"<<endl; if (ansLevel<p->nestLevel){ ret = tmp; ansLevel = p->nestLevel; } } } if (!strcmp(p->path, path)) break; p = p->sibling; } /* if (ret){ switch (ret->type){ case integer_type: printf("find %s: integer\n", name); break; case real_type: printf("find %s: real\n", name); break; case char_type: printf("find %s: char\n", name); break; case boolean_type: printf("find %s: boolean\n", name); break; case string_type: printf("find %s: string\n", name); break; } }*/ return ret; }
static void PrintConstantDecl(FILE *f, AST *ast) { const char *name = ast->d.string; AST *expr = NULL; Symbol *sym; if (!IsConstExpr(ast)) { ERROR(ast, "%s is not constant", name); return; } sym = LookupSymbol(name); if (!sym) { ERROR(ast, "constant symbol %s not declared??", name); return; } expr = (AST *)sym->val; if (gl_ccode) { fprintf(f, "#define %s (", ast->d.string); PrintConstant(f, expr); fprintf(f, ")\n"); } else { fprintf(f, " static const int %s = ", ast->d.string); PrintConstant(f, expr); fprintf(f, ";\n"); } }
// // compile an expression as an inine asm operand // static Operand * CompileInlineOperand(IRList *irl, AST *expr) { Operand *r; if (expr->kind == AST_IDENTIFIER) { Symbol *sym = LookupSymbol(expr->d.string); if (!sym) { ERROR(expr, "Unknown symbol %s", expr->d.string); return NULL; } switch(sym->type) { case SYM_PARAMETER: case SYM_RESULT: case SYM_LOCALVAR: case SYM_TEMPVAR: r = CompileIdentifier(irl, expr); if (!r) { ERROR(expr, "Bad identifier expression %s", sym->name); } return r; default: ERROR(expr, "Symbol %s is not usable in inline asm", sym->name); return NULL; } } else if (expr->kind == AST_INTEGER) { return NewImmediate(expr->d.ival); } else { ERROR(expr, "Operand too complex for inline assembly"); return NULL; } }
Enum * FindEnum(char *enumName) { Symbol *sym; if((sym = LookupSymbol(globalTagSymbolList, enumName)) != 0) { if(sym->type && sym->type->ty == typeENUM) return sym->type->eptr; } if((sym = LookupSymbol(globalIdentifierList, enumName)) != 0) { Type *baseType = BaseNode(sym->type); if(baseType && baseType->ty == typeENUM) return baseType ->eptr; } return 0; }
/* 没有真的删除, 只是将有效位标记 */ static Symbol DeleteSymbol (Table tbl, const char *name) { Symbol p = LookupSymbol (tbl, name); if (p == NULL) return NULL; /* 无效 */ p->unvalid = true; return p; }
HGRIDITEM FindGridItem(HGRIDITEM hParent, ExprNode * expr, HWND hwndGridView) { Symbol *sym; HGRIDITEM hItem = 0; Structure *parent; GVITEM gvitem = { 0, 0, 0, GVIF_PARAM }; Type *t = TypeView_GetType(hwndGridView, hParent); if(IsStruct(t) == false) return 0; parent = BaseNode(t)->sptr; for(; expr; expr = expr->right) { // expr->left will always be EXPR_IDENTIFIER if((sym = LookupSymbol(parent->symbolTable, expr->left ? expr->left->str : expr->str)) == 0) return 0; // look for the Type* node in the GridView gvitem.iSubItem = COLIDX_NAME; gvitem.mask = GVIF_PARAM; gvitem.param = (ULONG_PTR)sym->type; // this *should* succeed, but just in case... if((hItem = GridView2_FindChild(hwndGridView, hParent, &gvitem)) == 0) return 0; Type *base = BaseNode(sym->type); if(IsStruct(base) && expr->left) { //sptr = base->sptr; parent = base->sptr; hParent = hItem; } else if(expr->left == 0) { return hItem; } else { // lvalue is not a structure return 0; } } return 0; }
nsresult XPCOMGlueLoadXULFunctions(const nsDynamicFunctionLoad *symbols) { nsresult rv = NS_OK; while (symbols->functionName) { char buffer[512]; snprintf(buffer, sizeof(buffer), "_%s", symbols->functionName); *symbols->function = (NSFuncPtr) LookupSymbol(sXULLibImage, buffer); if (!*symbols->function) rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA; ++symbols; } return rv; }
int DuplicateIdentifier(char *name, char *path){ SymbolTable *p = SymTab; int ansLevel = -1; TreeNode *tmp = NULL; // printf("lookup:%s, path:%s\n", name, path); while (p){ if (!strcmp(p->path, path)){ tmp = LookupSymbol(name, p); // if (tmp) printf("duplicate %s\n", name); break; } p = p->sibling; } if (tmp) return 1; else return 0; }
nsresult XPCOMGlueLoad(const char *xpcomFile, GetFrozenFunctionsFunc *func) { const mach_header* lib = nsnull; if (xpcomFile[0] != '.' || xpcomFile[1] != '\0') { char xpcomDir[PATH_MAX]; if (realpath(xpcomFile, xpcomDir)) { char *lastSlash = strrchr(xpcomDir, '/'); if (lastSlash) { *lastSlash = '\0'; XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB); snprintf(lastSlash, PATH_MAX - strlen(xpcomDir), "/" XUL_DLL); sXULLibImage = NSAddImage(xpcomDir, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); } } lib = NSAddImage(xpcomFile, NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME); if (!lib) { NSLinkEditErrors linkEditError; int errorNum; const char *errorString; const char *fileName; NSLinkEditError(&linkEditError, &errorNum, &fileName, &errorString); fprintf(stderr, "XPCOMGlueLoad error %d:%d for file %s:\n%s\n", linkEditError, errorNum, fileName, errorString); } } *func = (GetFrozenFunctionsFunc) LookupSymbol(lib, "_NS_GetFrozenFunctions"); return *func ? NS_OK : NS_ERROR_NOT_AVAILABLE; }
Symbol AddDefine (char *name, char *content) { Symbol p, res; CALLOC (p); p->name = name; p->val.p = content; res = LookupSymbol (&DefineTable, name); if (res == NULL) { return AddSymbol (&DefineTable, p); } // 添加时无论前边的define 定义是否有效,均覆盖 res->unvalid = false; res->val.p = content; return res; }
bool GLLibraryLoader::LoadSymbols(PRLibrary *lib, SymLoadStruct *firstStruct, PlatformLookupFunction lookupFunction, const char *prefix) { char sbuf[MAX_SYMBOL_LENGTH * 2]; int failCount = 0; SymLoadStruct *ss = firstStruct; while (ss->symPointer) { *ss->symPointer = 0; for (int i = 0; i < MAX_SYMBOL_NAMES; i++) { if (ss->symNames[i] == nullptr) break; const char *s = ss->symNames[i]; if (prefix && *prefix != 0) { strcpy(sbuf, prefix); strcat(sbuf, ss->symNames[i]); s = sbuf; } PRFuncPtr p = LookupSymbol(lib, s, lookupFunction); if (p) { *ss->symPointer = p; break; } } if (*ss->symPointer == 0) { fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]); failCount++; } ss++; } return failCount == 0 ? true : false; }
//-------------------------------------------------------------------------------------- VOID Fini(INT32 ExitCode, VOID *v) { std::string LogCommon = KnobOutputDir.Value(); LogCommon += "/"; LogCommon += KnobOutputFile.Value(); std::string LogBlocks = LogCommon + std::string(".blocks"); std::string LogRoutines = LogCommon + std::string(".routines"); std::string LogModules = LogCommon + std::string(".modules"); // create common log FILE *f = fopen(LogCommon.c_str(), "wb+"); if (f) { UINT32 CoverageSize = 0; // enumerate loged basic blocks for (BASIC_BLOCKS::iterator it = m_BasicBlocks.begin(); it != m_BasicBlocks.end(); it++) { // calculate total coverage size CoverageSize += (*it).first.second; } fprintf(f, APP_NAME); fprintf(f, "===============================================\r\n"); fprintf(f, "Program command line: %s\r\n", m_CommandLine.c_str()); fprintf(f, " Process ID: %d\r\n", m_ProcessId); fprintf(f, " Number of threads: %d\r\n", m_ThreadCount); fprintf(f, " Number of modules: %d\r\n", m_ModuleList.size()); fprintf(f, " Number of routines: %d\r\n", m_RoutinesList.size()); fprintf(f, " Number of BBLs: %d\r\n", m_BasicBlocks.size()); fprintf(f, " Total coverage size: %d\r\n", CoverageSize); fprintf(f, "===============================================\r\n"); fclose(f); } // create basic blocks log f = fopen(LogBlocks.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Basic blocks log file\r\n#\r\n"); // enumerate loged basic blocks for (BASIC_BLOCKS::iterator it = m_BasicBlocks.begin(); it != m_BasicBlocks.end(); it++) { const string *Symbol = LookupSymbol((*it).first.first); // dump single basic block information fprintf( f, "0x%.8x:%s:0x%.8x:%d\r\n", (*it).first.first, Symbol->c_str(), (*it).first.second, (*it).second ); delete Symbol; } fclose(f); } // create routines log f = fopen(LogRoutines.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Routines log file\r\n#\r\n"); // enumerate loged routines for (ROUTINES_LIST::iterator it = m_RoutinesList.begin(); it != m_RoutinesList.end(); it++) { const string *Symbol = LookupSymbol((*it).first); // dump single routine information fprintf(f, "0x%.8x:%s:%d\r\n", (*it).first, Symbol->c_str(), (*it).second); delete Symbol; } fclose(f); } // create modules log f = fopen(LogModules.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Modules log file\r\n#\r\n"); // have to do this whole thing because the IMG_* functions don't work here for (std::list<std::string>::iterator it = m_ModulePathList.begin(); it != m_ModulePathList.end(); it++) { // dump single routine information fprintf(f, "%s\r\n", (*it).c_str()); } fclose(f); } }
int InTable(char* N) { return LookupSymbol(N, 100) != -1; }
Symbol LookupDefine (const char *name) { Symbol p = LookupSymbol (&DefineTable, name); return (!p || p->unvalid) ? NULL : p; }
//-------------------------------------------------------------------------------------- VOID Fini(INT32 ExitCode, VOID *v) { std::string LogCommon = KnobOutputDir.Value(); LogCommon += "/"; LogCommon += KnobOutputFile.Value(); std::string LogBlocks = LogCommon + std::string(".blocks"); std::string LogRoutines = LogCommon + std::string(".routines"); std::string LogModules = LogCommon + std::string(".modules"); // create common log FILE *f = fopen(LogCommon.c_str(), "wb+"); if (f) { UINT32 CoverageSize = 0; // enumerate loged basic blocks for (BASIC_BLOCKS::iterator it = m_BasicBlocks.begin(); it != m_BasicBlocks.end(); it++) { // calculate total coverage size CoverageSize += (*it).first.second; } time_t Now; time(&Now); fprintf(f, APP_NAME_INI); fprintf(f, "; =============================================\r\n"); fprintf(f, "[coverager]\r\n"); fprintf(f, "cmdline = %s ; program command line\r\n", m_CommandLine.c_str()); fprintf(f, "pid = %d ; process ID\r\n", m_ProcessId); fprintf(f, "threads = %d ; number of threads\r\n", m_ThreadCount); fprintf(f, "modules = %d ; number of modules\r\n", m_ModuleList.size()); fprintf(f, "routines = %d ; number of routines\r\n", m_RoutinesList.size()); fprintf(f, "blocks = %d ; number of basic blocks\r\n", m_BasicBlocks.size()); fprintf(f, "total_size = %d ; Total coverage size\r\n", CoverageSize); fprintf(f, "time = %d ; Execution time in seconds\r\n", Now - m_StartTime); fprintf(f, "; =============================================\r\n"); fclose(f); } // create basic blocks log f = fopen(LogBlocks.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Basic blocks log file\r\n#\r\n"); fprintf(f, "# <address>:<size>:<instructions>:<name>:<calls>\r\n#\r\n"); // enumerate loged basic blocks for (BASIC_BLOCKS::iterator it = m_BasicBlocks.begin(); it != m_BasicBlocks.end(); it++) { const string *Symbol = LookupSymbol((*it).first.first); // dump single basic block information fprintf( f, "0x%.8x:0x%.8x:%d:%s:%d\r\n", (*it).first.first, (*it).first.second, (*it).second.Instructions, Symbol->c_str(), (*it).second.Calls ); delete Symbol; } fclose(f); } // create routines log f = fopen(LogRoutines.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Routines log file\r\n#\r\n"); fprintf(f, "# <address>:<name>:<calls>\r\n#\r\n"); // enumerate loged routines for (ROUTINES_LIST::iterator it = m_RoutinesList.begin(); it != m_RoutinesList.end(); it++) { const string *Symbol = LookupSymbol((*it).first); // dump single routine information fprintf(f, "0x%.8x:%s:%d\r\n", (*it).first, Symbol->c_str(), (*it).second); delete Symbol; } fclose(f); } // create modules log f = fopen(LogModules.c_str(), "wb+"); if (f) { PrintLogFileHeader(f); fprintf(f, "# Modules log file\r\n#\r\n"); fprintf(f, "# <address>:<size>:<name>\r\n#\r\n"); // have to do this whole thing because the IMG_* functions don't work here for (std::list<std::string>::iterator it = m_ModulePathList.begin(); it != m_ModulePathList.end(); it++) { // get image file name from full path std::string ModuleName = NameFromPath((*it)); // lookup for module information if (m_ModuleList.find(ModuleName) != m_ModuleList.end()) { // dump single routine information fprintf( f, "0x%.8x:0x%.8x:%s\r\n", m_ModuleList[ModuleName].first, m_ModuleList[ModuleName].second, (*it).c_str() ); } } fclose(f); } }
// // Evaluate (flatten) the specified expression and // return it's numeric value // bool Evaluate(HGRIDITEM hParent, ExprNode *expr, INUMTYPE *result, size_w baseOffset, HWND hwndHV, HWND hwndGV) { INUMTYPE left, right, cond; Symbol *sym; GVITEM gvitem = { 0 }; GVITEM gvi2 = { 0 }; if(expr == 0) return false; switch(expr->type) { case EXPR_IDENTIFIER: case EXPR_FIELD: HGRIDITEM hItem; ExprNode *baseType; baseType = expr->type == EXPR_FIELD ? expr->right : expr; // look for the note in the GridView that corresponds to the field expression! if((hItem = FindGridItem(hParent, expr, hwndGV)) == 0) { // not a field. maybe it's an enum tag though? if(expr->type == EXPR_IDENTIFIER) { if((sym = LookupSymbol(globalIdentifierList, expr->str)) == 0) return false; if(sym->type->ty == typeENUMVALUE) { *result = sym->type->evptr->val; return true; } else { // lvalue is not a structure! return false; } } return false; } gvitem.iSubItem = COLIDX_OFFSET; gvitem.mask = GVIF_PARAM; GridView2_GetItem(hwndGV, hItem, &gvitem); gvi2.iSubItem = COLIDX_OFFSET; gvi2.mask = GVIF_PARAM; GridView2_GetItem(hwndGV, hParent, &gvi2); *result = 0; HexView_GetData(hwndHV, gvitem.param + gvi2.param, (BYTE *)result, sizeof(*result)); return true; case EXPR_NUMBER: *result = (expr->tok == TOK_INUMBER) ? expr->val : (int)expr->fval; return true; case EXPR_UNARY: if(!Evaluate(hParent, expr->left, &left, baseOffset, hwndHV, hwndGV)) return false; switch(expr->tok) { case '+': *result = +left; break; case '-': *result = /*-*/left; break; case '!': *result = !left; break; case '~': *result = ~left; break; default: return false; } return true; case EXPR_BINARY: if(!Evaluate(hParent, expr->left, &left, baseOffset, hwndHV, hwndGV) || !Evaluate(hParent, expr->right, &right, baseOffset, hwndHV, hwndGV)) return false; switch(expr->tok) { case '+': *result = left + right; break; case '-': *result = left - right; break; case '*': *result = left * right; break; case '%': *result = left % right; break; case '/': *result = left / right; break; case '|': *result = left | right; break; case '&': *result = left & right; break; case '^': *result = left ^ right; break; case TOK_ANDAND: *result = left && right; break; case TOK_OROR: *result = left || right; break; case TOK_SHR: *result = left << right; break; case TOK_SHL: *result = left >> right; break; case TOK_GE: *result = left >= right; break; case TOK_LE: *result = left <= right; break; default: return false; } case EXPR_TERTIARY: if(!Evaluate(hParent, expr->cond, &cond, baseOffset, hwndHV, hwndGV)) return false; if(cond) { if(Evaluate(hParent, expr->left, &left, baseOffset, hwndHV, hwndGV)) *result = left; else return false; } else { if(Evaluate(hParent, expr->right, &right, baseOffset, hwndHV, hwndGV)) *result = right; else return false; } return true; default: // don't understand anything else return false; } }
/* 查找某个类型 */ Symbol LookupTag (const char *name) { return LookupSymbol (Tags, name); }
/* 查找某个标示符 */ Symbol LookupID (const char *name) { return LookupSymbol (Identifiers, name); }
// // Evaluate (flatten) the specified expression and // return it's numeric value // bool Evaluate(HGRIDITEM hParent, ExprNode *expr, size_w baseOffset, HWND hwndHV, HWND hwndGV, ExprNode *result) { //unsigned left, right, cond; ExprNode left;//(EXPR_NUMBER, TOK_INUMBER); ExprNode right;//(EXPR_NUMBER, TOK_INUMBER); ExprNode cond;//(/EXPR_NUMBER, TOK_INUMBER); Symbol *sym; GVITEM gvitem = { 0 }; GVITEM gvi2 = { 0 }; if(expr == 0) return false; switch(expr->type) { case EXPR_IDENTIFIER: case EXPR_FIELD: HGRIDITEM hItem; // look for the note in the GridView that corresponds to the field expression! if((hItem = FindGridItem(hParent, expr, hwndGV)) == 0) { // not a field. maybe it's an enum tag though? if(expr->type == EXPR_IDENTIFIER) { if((sym = LookupSymbol(globalIdentifierList, expr->str)) == 0) return false; if(sym->type->ty == typeENUMVALUE) { result->val = sym->type->evptr->val; result->tok = TOK_INUMBER; return true; //Enum *e = sym->type->evptr->parent; //return e->Evaluate(sym->name, &result); } else { // lvalue is not a structure! return false; } } return false; } gvitem.iSubItem = COLIDX_OFFSET; gvitem.mask = GVIF_PARAM; GridView2_GetItem(hwndGV, hItem, &gvitem); gvi2.iSubItem = COLIDX_OFFSET; gvi2.mask = GVIF_PARAM; GridView2_GetItem(hwndGV, hParent, &gvi2); HexView_GetData(hwndHV, gvitem.param + gvi2.param, (BYTE *)result, sizeof(*result)); return true; case EXPR_NUMBER: *result = *expr; //*result = (expr->tok == TOK_INUMBER) ? expr->val : (int)expr->fval; return true; //case EXPR_IDENTIFIER: // is it a structure member? case EXPR_UNARY: if(Evaluate(hParent, expr->left, baseOffset, hwndHV, hwndGV, &left)) { if(left.tok == TOK_INUMBER) { result->tok = TOK_INUMBER; return EvaluateUnary(left.val, expr->tok, &result->val); } else { result->tok = TOK_FNUMBER; return EvaluateUnary(left.fval, expr->tok, &result->fval); } } else { return false; } case EXPR_BINARY: if(Evaluate(hParent, expr->left, baseOffset, hwndHV, hwndGV, &left) && Evaluate(hParent, expr->right, baseOffset, hwndHV, hwndGV, &right)) { if(left.tok == TOK_INUMBER && right.tok == TOK_FNUMBER) { // we need to convert so they are the same base left.fval = (double)(signed __int64)left.val; left.tok = TOK_FNUMBER; } else if(left.tok == TOK_FNUMBER && right.tok == TOK_INUMBER) { right.fval = (double)(signed __int64)right.val; right.tok = TOK_FNUMBER; } if(left.tok == TOK_INUMBER) { result->tok = TOK_INUMBER; return EvaluateBinary(left.val, right.val, expr->tok, &result->val); } else { result->tok = TOK_FNUMBER; return EvaluateBinary(left.fval, right.fval, expr->tok, &result->fval); } } else { return false; } case EXPR_TERTIARY: if(Evaluate(hParent, expr->cond, baseOffset, hwndHV, hwndGV, &cond)) { if(cond.val) { if(Evaluate(hParent, expr->left, baseOffset, hwndHV, hwndGV, &left)) *result = left; else return false; } else { if(Evaluate(hParent, expr->right, baseOffset, hwndHV, hwndGV, &right)) *result = right; else return false; } return true; } else { return false; } default: // don't understand anything else return false; } }
// // hwndGV - handle to GridView control // hRoot - root item-handle // type - node in the type-chain // dwOffset - current offset // // returns: size of type // size_w RecurseType(HWND hwndGV, HGRIDITEM hRoot, Type *type, size_w dwOffset, TypeDecl *typeDecl) { GVITEM gvitem = { 0 }; Structure *sptr; size_t i; TCHAR buf[200]; if(type == 0) return 0; size_w dwLength = 0; INUMTYPE switchVal = 0;//1; HWND hwndHV = GetActiveHexView(g_hwndMain); switch(type->ty) { case typeDOSTIME: case typeDOSDATE: case typeFILETIME: case typeTIMET: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeCHAR: case typeWCHAR: case typeBYTE: case typeWORD: case typeDWORD: case typeQWORD: case typeFLOAT: case typeDOUBLE: case typeENUM: dwLength = FmtData(hwndGV, hRoot, type, dwOffset, typeDecl); break; case typeUNION: // evaluate the switch_is() ExprNode *switchExpr; if(FindTag(typeDecl->tagList, TOK_SWITCHIS, &switchExpr)) { switchVal = Evaluate(switchExpr); } sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; ExprNode *caseExpr; size_w tmpLen = 0; if(FindTag(typeDecl->tagList, TOK_CASE, &caseExpr)) { if(Evaluate(caseExpr) == switchVal) tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } else { tmpLen = InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset); } dwLength = max(dwLength, tmpLen); } break; case typeSTRUCT: sptr = type->sptr; for(i = 0; i < sptr->typeDeclList.size(); i++) { TypeDecl *typeDecl = sptr->typeDeclList[i]; dwLength += InsertTypeGV(hwndGV, hRoot, typeDecl, dwOffset + dwLength); } break; case typeIDENTIFIER: hRoot = InsertIdentifier(hwndGV, hRoot, type, dwOffset, typeDecl); dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #if 0 if(fShowFullType) { RenderType(buf, 200, type); gvitem.pszText = buf; } else { _stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.pszText = buf;//type->sym->name; } gvitem.state = 0; if(type->link && type->link->ty != typeARRAY) gvitem.state |= GVIS_EXPANDED; gvitem.iImage = IsStruct(type) ? 1 : 0; if(typeDecl->tagList) gvitem.iImage+=2; gvitem.param = (ULONG_PTR)type;//typeDecl; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE | GVIF_IMAGE; GridView2_SetItem(hwndGV, hRoot, &gvitem); if(type->link && type->link->ty == typeARRAY) { FormatDataItem(hwndGV, hRoot, type, dwOffset); } if(IsStruct(type)) { gvitem.iSubItem = COLIDX_DATA; gvitem.state = GVIS_READONLY; gvitem.pszText = TEXT("{...}"); gvitem.param = 0; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } if(!fShowFullType) { RenderType(buf, 200, type->link); //_stprintf(buf, TEXT("%hs"), type->sym->name); gvitem.iSubItem = 0;//COLIDX_TYPE; gvitem.state = GVIS_READONLY; gvitem.pszText = buf; gvitem.param = (UINT64)type; gvitem.mask = GVIF_PARAM | GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; #endif case typeTYPEDEF: case typeSIGNED: case typeUNSIGNED: case typeCONST: // return 0; case typePOINTER: dwLength = RecurseType(hwndGV, hRoot, type->link, dwOffset, typeDecl); break; case typeARRAY: Symbol *sym; ExprNode *nameExpr; if(FindTag(typeDecl->tagList, TOK_NAME, &nameExpr)) { if((sym = LookupSymbol(globalTagSymbolList, nameExpr->str)) != 0) { if(sym->type && sym->type->ty == typeENUM) ; else sym = 0; } } else { sym = 0; } UINT64 count; count = 0; Evaluate(GridView_GetParent(hwndGV, hRoot), type->elements, &count, dwOffset, hwndHV, hwndGV); count &= 0xffff; count = min(count,100); for(i = 0; i < count; i++) { HGRIDITEM hItem; TCHAR buf[164]; int len = _stprintf(buf, TEXT("[%d] "), (int)i); if(sym) { Enum *eptr = sym->type->eptr; char *s = 0; for(size_t x = 0; x < eptr->fieldList.size(); x++) { if(i == eptr->fieldList[x]->val) { s = eptr->fieldList[i]->name->name; } } _stprintf(buf + 5, TEXT("- %hs"), s); } gvitem.pszText = buf; gvitem.state = GVIS_READONLY; gvitem.iImage = 0;//rand() % 2; gvitem.param = (ULONG_PTR)type->link; gvitem.iSubItem = COLIDX_NAME; gvitem.mask = GVIF_STATE|GVIF_PARAM|GVIF_TEXT; hItem = GridView2_InsertUniqueChild(hwndGV, hRoot, &gvitem); // used to pass '0' as typeDecl??? why?? because this is an array element we // are recursing through!!!! dwLength += RecurseType(hwndGV, hItem, type->link, dwOffset + dwLength, 0);//typeDecl); } break; default: break; } // add the 'offset' column to all items if(hRoot) { _stprintf(buf, TEXT("%08x"), (DWORD)dwOffset); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_OFFSET; gvitem.state = 0; gvitem.param = dwOffset; gvitem.mask = GVIF_TEXT | GVIF_STATE | GVIF_PARAM; GridView2_SetItem(hwndGV, hRoot, &gvitem); // add the 'comment' column item - only do this for items that aren't array elements if(typeDecl)// && type->ty != typeARRAY) { FILEREF *ref; ref = &typeDecl->postRef; buf[0] = '\0'; FormatWhitespace(ref, buf); gvitem.pszText = buf; gvitem.iSubItem = COLIDX_COMMENT; gvitem.state = 0; gvitem.mask = GVIF_TEXT | GVIF_STATE; GridView2_SetItem(hwndGV, hRoot, &gvitem); } } return dwLength; }