📄 utmanage.c
字号:
utEnum theEnum; utEntry entry; utUnion theUnion; utUnionCase unionCase; utSym sym; uint8 *values; uint32 size = field->size; utFieldType type = field->type; if(type == UT_BIT) { values = *(uint8 **)(field->arrayPtr) + (objectNumber >> 3)*field->size; } else { values = *(uint8 **)(field->arrayPtr) + objectNumber*field->size; } if(type == UT_UNION) { theUnion = utUnions + field->unionIndex; unionCase = findUnionCase(theUnion, objectNumber); if(unionCase != NULL) { type = unionCase->type; size = unionCase->size; } } switch(type) { case UT_BIT: if((*values >> (objectNumber & 7)) & 1) { return "true"; } return "false"; case UT_BOOL: if(*values == 1) { return "true"; } else if(*values == 0) { return "false"; } return utSprintf("%d", *values); case UT_INT: switch(size) { case 1: return utSprintf("%d", *(int8 *)values); case 2: return utSprintf("%d", *(int16 *)values); case 4: return utSprintf("%d", *(int32 *)values); case 8: return utSprintf("%d", *(int64 *)values); } utExit("Invalid integer size"); case UT_UINT: switch(size) { case 1: return utSprintf("%u", *(uint8 *)values); case 2: return utSprintf("%u", *(uint16 *)values); case 4: return utSprintf("%u", *(uint32 *)values); case 8: return utSprintf("%u", *(uint64 *)values); } utExit("Invalid integer size"); case UT_CHAR: if(isprint(*values)) { return utSprintf("'%c'", *values); } return utSprintf("'\\%u'", *values); case UT_FLOAT: return utSprintf("%g", *(float *)values); case UT_DOUBLE: return utSprintf("%g", *(double *)values); case UT_POINTER: switch(size) { case 1: return utSprintf("0x%x", *(uint8 *)values); case 2: return utSprintf("0x%x", *(uint16 *)values); case 4: return utSprintf("0x%x", *(uint32 *)values); case 8: return utSprintf("0x%x", *(uint64 *)values); } case UT_TYPEDEF: case UT_UNION: return utFindHexString(values, size); case UT_ENUM: theClass = utClasses + field->classIndex; module = utModules + theClass->moduleIndex; theEnum = findEnum(module, field->destName); entry = findEntryFromValue(theEnum, *(uint32 *)values); return entry->name; case UT_SYM: sym = *(utSym *)values; if(sym == utSymNull) { return utSprintf("0x%x", utSymNull); } return utSprintf("\"%s\"", mungeString(utSymGetName(*(utSym *)values))); } utExit("Unknow field type"); return NULL;}/*-------------------------------------------------------------------------------------------------- Determine if the only '\0' is at the end of the character array.--------------------------------------------------------------------------------------------------*/static bool zeroTerminated( char *values, uint32 length){ if(values[--length] != '\0') { return false; } while(length != 0 && values[length] != '\0') { length--; } return values[length] == '\0';}/*-------------------------------------------------------------------------------------------------- Show the data in the array. If we go over maxFields, we print '...'.--------------------------------------------------------------------------------------------------*/static void writeArray( utField field, uint64 objectNumber, uint32 maxFields){ uint32 numElements; uint32 xElement; bool firstTime = true; char *values = field->getValues(objectNumber, &numElements); uint32 firstElement = (values - *(char **)(field->arrayPtr))/field->size; if(numElements != 0 && field->type == UT_CHAR && zeroTerminated(values, numElements)) { fprintf(utOutputFile, "\"%s\"", mungeString(values)); return; } fprintf(utOutputFile, "("); for(xElement = 0; xElement < numElements && xElement < maxFields; xElement++) { if(!firstTime) { fprintf(utOutputFile, ", "); } firstTime = false; fprintf(utOutputFile, "%s", findFieldValue(field, firstElement + xElement)); } if(xElement == maxFields) { fprintf(utOutputFile, ", ..."); } fprintf(utOutputFile, ")");}/*-------------------------------------------------------------------------------------------------- Show the fields of an object.--------------------------------------------------------------------------------------------------*/static void showObject( utClass theClass, uint64 objectNumber){ utField field; uint16 xField; bool firstTime = true; for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->hidden || utShowHidden) { if(!firstTime) { fprintf(utOutputFile, ", "); } firstTime = false; fprintf(utOutputFile, "%s=", field->name); if(!field->array) { fprintf(utOutputFile, "%s", findFieldValue(field, objectNumber)); } else { writeArray(field, objectNumber, 16); } } } fprintf(utOutputFile, "\n");}/*-------------------------------------------------------------------------------------------------- Just print the field names.--------------------------------------------------------------------------------------------------*/static void printColumnHeaders( utClass theClass){ utField field; uint16 xField; bool firstTime = true; fprintf(utOutputFile, "ObjectNumber, "); for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->hidden) { if(!firstTime) { fprintf(utOutputFile, ", "); } firstTime = false; fprintf(utOutputFile, "%s", field->name); } } fprintf(utOutputFile, "\n");}/*-------------------------------------------------------------------------------------------------- Just print the field types.--------------------------------------------------------------------------------------------------*/static void printColumnTypes( utClass theClass){ utField field; uint16 xField; bool firstTime = true; fprintf(utOutputFile, "uint%u, ", theClass->referenceSize << 3); for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->hidden) { if(!firstTime) { fprintf(utOutputFile, ", "); } firstTime = false; fprintf(utOutputFile, "%s", findFieldTypeName(field)); } } fprintf(utOutputFile, "\n");}/*-------------------------------------------------------------------------------------------------- Print the object's values in a comma separated list.--------------------------------------------------------------------------------------------------*/static void showObjectFields( utClass theClass, uint64 objectNumber){ utField field; uint16 xField; bool firstTime = true; fprintf(utOutputFile, "0x%llx, ", objectNumber); for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->hidden || utShowHidden) { if(!firstTime) { fprintf(utOutputFile, ", "); } firstTime = false; if(!field->array) { fprintf(utOutputFile, "%s", findFieldValue(field, objectNumber)); } else { writeArray(field, objectNumber, UINT32_MAX); } } } fprintf(utOutputFile, "\n");}/*-------------------------------------------------------------------------------------------------- Return the null reference for references of the given size.--------------------------------------------------------------------------------------------------*/static uint64 findNullReference( uint8 size){ switch(size) { case 1: return UINT8_MAX; case 2: return UINT16_MAX; case 4: return UINT32_MAX; case 8: return UINT64_MAX; default: utExit("Invalid reference size"); } return 0;}/*-------------------------------------------------------------------------------------------------- Set the used flags for the objects of the class.--------------------------------------------------------------------------------------------------*/static void setObjectFreeFlags( utModule module, utClass theClass, uint8 *objectFree){ utField field = utFields + module->firstFieldIndex + theClass->nextFreeFieldIndex; uint64 objectNumber = utFindIntValue(theClass->firstFreePtr, theClass->referenceSize); while(objectNumber != findNullReference(theClass->referenceSize)) { objectFree[objectNumber >> 3] |= 1 << (objectNumber & 7); objectNumber = utFindIntValue(*(uint8 **)(field->arrayPtr) + objectNumber*field->size, field->size); }}/*-------------------------------------------------------------------------------------------------- Show all the objects of a class.--------------------------------------------------------------------------------------------------*/static void showClass( utModule module, utClass theClass){ uint64 numUsed = utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); uint64 objectNumber; bool hasFreeList = theClass->destructor != NULL; uint64 spaceNeeded = (numUsed + 7) >> 3; uint8 *objectFree = NULL; if(hasFreeList) { objectFree = calloc(spaceNeeded, sizeof(uint8)); setObjectFreeFlags(module, theClass, objectFree); } fprintf(utOutputFile, "class %s %llu\n", theClass->name, numUsed); printColumnHeaders(theClass); printColumnTypes(theClass); for(objectNumber = 0; objectNumber < numUsed; objectNumber++) { if(!hasFreeList || !(objectFree[objectNumber >> 3] & (1 << (objectNumber & 7)))) { showObjectFields(theClass, objectNumber); } } if(hasFreeList) { free(objectFree); }}/*-------------------------------------------------------------------------------------------------- Write the integer, given the width.--------------------------------------------------------------------------------------------------*/void setInteger( uint8 *dest, uint64 value, uint8 width){ switch(width) { case 1: *dest = (uint8)value; break; case 2: *(uint16 *)dest = (uint16)value; break; case 4: *(uint32 *)dest = (uint32)value; break; case 8: *(uint64 *)dest = (uint64)value; break; default: utExit("Invalid integer width"); }}/*-------------------------------------------------------------------------------------------------- Read an integer and complain if it has bad width or syntax.--------------------------------------------------------------------------------------------------*/static bool readInteger( uint8 *dest, char *string, uint8 width, bool unsignedInt){ int64 value; char *endPtr; value = strtoll(string, &endPtr, 0); if(endPtr == NULL || *endPtr != '\0') { return false; } if(width <= 4) { if(unsignedInt) { if(((uint64)value) >> (width << 3) != 0) { return false; } } else { if(value >> (width << 3) != 0 && value >> (width << 3) != -1) { return false; } } } setInteger(dest, value, width); return true;}/*-------------------------------------------------------------------------------------------------- Parse a character value.--------------------------------------------------------------------------------------------------*/static bool readChar( uint8 *dest, char *value){ char *end = value + strlen(value) - 1; if(*value++ != '\'') { return false; } if(*--end != '\'') { return false; } *end = '\0'; if(*value == '\\') { return readInteger(dest, value, 1, true); } *(char *)dest = *value; return true;}/*-------------------------------------------------------------------------------------------------- Parse a floating point number.--------------------------------------------------------------------------------------------------*/static bool readFloat( uint8 *dest, char *value, bool isFloat){ double floatVal; char *endPtr; floatVal = strtod(value, &endPtr); if(endPtr == NULL || *endPtr != '\0') { return false; } if(isFloat) { *(float *)dest = (float)floatVal; } else { *(double *)dest = floatVal; } return true;}/*-------------------------------------------------------------------------------------------------- Read a 2-character hex byte.--------------------------------------------------------------------------------------------------*/static bool readHex(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -