📄 utmanage.c
字号:
/* * This file was written by Bill Cox. It is hereby placed into the public domain. *//*-------------------------------------------------------------------------------------------------- This module provides basic database administration capabilities.--------------------------------------------------------------------------------------------------*/#include <stdlib.h>#include <ctype.h>#include "ddutil.h"#include "utpersist.h"static char *utLineBuffer;static uint32 utLineSize, utLinePosition;static uint64 utLineNum;static bool utAtEndOfFile;static char *utLastToken;static bool utShowHidden;static FILE *utInputFile, *utOutputFile;static utField *utFieldTranslationTable;static uint32 utNumFields;/*-------------------------------------------------------------------------------------------------- Read a module header.--------------------------------------------------------------------------------------------------*/static void reportError( char *format, ...){ char *buff; va_list ap; va_start(ap, format); buff = utVsprintf(format, ap); va_end(ap); if(utInputFile != stdin) { utWarning("Line %lld, token \"%s\": %s", utLineNum, utLastToken, buff); } else { utWarning("Token \"%s\": %s", utLastToken, buff); }}/*-------------------------------------------------------------------------------------------------- Return an integer of the given size.--------------------------------------------------------------------------------------------------*/uint64 utFindIntValue( void *values, uint8 size){ switch(size) { case 1: return *(uint8 *)values; case 2: return *(uint16 *)values; case 4: return *(uint32 *)values; case 8: return *(uint64 *)values; } utExit("Illegal integer size"); return 0;}/*-------------------------------------------------------------------------------------------------- Print out help.--------------------------------------------------------------------------------------------------*/static void printHelp(void){ fprintf(utOutputFile, "create <module> <class> – allocate a new object, and return it's object number\n" "compact – Compact the database, and delete the recent_changes file\n" "destroy <module> <class> <object number> – Destroy an object\n" "help - this command\n" "list – list the modules in the database, their object counts and memory usage\n" "list <module> – list classes in the module, their object counts and memory usage\n" "list <module> <class> – list fields of a class\n" "quit - quit the database manager\n" "set <module> <class> <object number> = comma separated values – \n" " set all fields of an object\n" "set <module> <class> <object number> <field> = <value> – set a value\n" "show <module> <class> – show all field values of all objects of the class\n" "show <module> <class> <object number> – show an object's fields\n" "show_hidden <true or false> - Enable/disable listing of DataDraw internal fields\n" "load_binary <file> - Read the data from the binary database file into the database\n" "save_binary <file> - Write out the database in binary format to the file\n" "load_text <file> - Read the data from the text database file into the database\n" "save_text <file> - Write out the database in text format to the file\n");}/*-------------------------------------------------------------------------------------------------- Return the number of objects allocated for the module.--------------------------------------------------------------------------------------------------*/static uint64 countModuleObjects( utModule module){ utClass theClass; uint16 xClass; uint64 numObjects = 0; for(xClass = 0; xClass < module->numClasses; xClass++) { theClass = utClasses + module->firstClassIndex + xClass; numObjects += utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); } return numObjects;}/*-------------------------------------------------------------------------------------------------- Return the total memory size used by the class.--------------------------------------------------------------------------------------------------*/static uint64 findClassMemory( utClass theClass){ utField field; uint16 xField; uint64 memory = 0; uint64 numUsed; for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(field->array) { numUsed = *(field->numUsedPtr); } else { numUsed = utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); } memory += field->size*numUsed; } return memory;}/*-------------------------------------------------------------------------------------------------- List the modules in the database.--------------------------------------------------------------------------------------------------*/static uint64 findModuleMemory( utModule module){ utClass theClass; uint16 xClass; uint64 memory = 0; for(xClass = 0; xClass < module->numClasses; xClass++) { theClass = utClasses + module->firstClassIndex + xClass; memory += findClassMemory(theClass); } return memory;}/*-------------------------------------------------------------------------------------------------- Find the ammount in memory units.--------------------------------------------------------------------------------------------------*/char *utMemoryUnits( uint64 memory){ if(memory > 1024*1024) { return utSprintf("%.5g MB", memory/(1024.0*1024.0)); } else if(memory > 1024) { return utSprintf("%.5g KB", memory/1024.0); } return utSprintf("%lu bytes", memory);}/*-------------------------------------------------------------------------------------------------- List the modules in the database.--------------------------------------------------------------------------------------------------*/static void listModules(void){ utModule module; uint8 xModule; fprintf(utOutputFile, "modules:\n"); for(xModule = 0; xModule < utUsedModules; xModule++) { module = utModules + xModule; if(module->initialized) { fprintf(utOutputFile, " %s - %llu objects, %s memory\n", module->prefix, countModuleObjects(module), utMemoryUnits(findModuleMemory(module))); } }}/*-------------------------------------------------------------------------------------------------- List the classes in the module.--------------------------------------------------------------------------------------------------*/static void listClasses( utModule module){ utClass theClass; uint16 xClass; uint64 numUsed; fprintf(utOutputFile, "Module %s classes:\n", module->prefix); for(xClass = 0; xClass < module->numClasses; xClass++) { theClass = utClasses + module->firstClassIndex + xClass; numUsed = utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); fprintf(utOutputFile, " %s - %llu objects, %s memory\n", theClass->name, numUsed, utMemoryUnits(findClassMemory(theClass))); }}/*-------------------------------------------------------------------------------------------------- Just return a name for the field type.--------------------------------------------------------------------------------------------------*/static char *findBaseFieldTypeName( utField field){ switch(field->type) { case UT_INT: return utSprintf("int%u", field->size << 3); case UT_UINT: return utSprintf("uint%u", field->size << 3); case UT_FLOAT: return "float"; case UT_DOUBLE: return "double"; case UT_BIT: return "bit"; case UT_BOOL: return "bool"; case UT_CHAR: return "char"; case UT_SYM: return "sym"; case UT_ENUM: return "enum"; case UT_TYPEDEF: return "typedef"; case UT_POINTER: return utSprintf("pointer %s", field->destName); case UT_UNION: return utSprintf("union %s", field->destName); default: utExit("Unknown property type"); } return NULL; /* Dummy return */}/*-------------------------------------------------------------------------------------------------- Just return a name for the field type.--------------------------------------------------------------------------------------------------*/static char *findFieldTypeName( utField field){ char *baseName = findBaseFieldTypeName(field); if(field->array) { return utSprintf("array %s", baseName); } return baseName;}/*-------------------------------------------------------------------------------------------------- List the fields of the class.--------------------------------------------------------------------------------------------------*/static void listFields( utClass theClass){ utField field; uint16 xField; fprintf(utOutputFile, "Class %s fields:\n", theClass->name); for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->hidden || utShowHidden) { fprintf(utOutputFile, " %s %s\n", findFieldTypeName(field), field->name); } }}/*-------------------------------------------------------------------------------------------------- Find the enum with the given name.--------------------------------------------------------------------------------------------------*/static utEnum findEnum( utModule module, char *name){ utEnum theEnums; uint16 xEnums; for(xEnums = 0; xEnums < module->numEnums; xEnums++) { theEnums = utEnums + module->firstEnumIndex + xEnums; if(!strcmp(theEnums->name, name)) { return theEnums; } } return NULL;}/*-------------------------------------------------------------------------------------------------- Find the entry with the given value.--------------------------------------------------------------------------------------------------*/static utEntry findEntryFromValue( utEnum theEnum, uint32 value){ utEntry entry; uint16 xEntry; for(xEntry = 0; xEntry < theEnum->numEntries; xEntry++) { entry = utEntries + theEnum->firstEntryIndex + xEntry; if(entry->value == value) { return entry; } } return NULL;}/*-------------------------------------------------------------------------------------------------- Find the entry with the given name.--------------------------------------------------------------------------------------------------*/static utEntry findEntryFromName( utEnum theEnum, char *name){ utEntry entry; uint16 xEntry; for(xEntry = 0; xEntry < theEnum->numEntries; xEntry++) { entry = utEntries + theEnum->firstEntryIndex + xEntry; if(!strcmp(entry->name, name)) { return entry; } } return NULL;}/*-------------------------------------------------------------------------------------------------- Return a hexidecimal digit representation of the 4-bit value.--------------------------------------------------------------------------------------------------*/static char findHexDigit( uint8 value){ if(value <= 9) { return '0' + value; } return 'A' + value - 10;}/*-------------------------------------------------------------------------------------------------- Return a long hexidecimal string representing the binary value.--------------------------------------------------------------------------------------------------*/char *utFindHexString( uint8 *values, uint32 size){ char *buffer = utMakeString((size << 1) + 1); char *p = buffer + (size << 1) - 1; buffer[size*2] = '\0'; while(size-- != 0) { *p-- = findHexDigit(*values & 0xf); *p-- = findHexDigit((*values++) >> 4); } return buffer;}/*-------------------------------------------------------------------------------------------------- Count the non "isprint" characters in the string.--------------------------------------------------------------------------------------------------*/static uint32 countNonprintableChars( char *string){ uint32 nonPrintableChars = 0; while(*string) { if(!isprint(*string)) { nonPrintableChars++; } string++; } return nonPrintableChars;}/*-------------------------------------------------------------------------------------------------- Convert any non-string friendly characters to \" or \<number> format.--------------------------------------------------------------------------------------------------*/static char *mungeString( char *string){ char *buffer = utMakeString(strlen(string) + 4*countNonprintableChars(string) + 1); char *p = buffer; char intValue[4]; while(*string != '\0') { if(isprint(*string)) { if(*string == '"' || *string == '\\') { *p++ = '\\'; } *p++ = *string++; } else { snprintf(intValue, 4, "\\%u", *string); intValue[3] = '\0'; strcpy(p, intValue); p += strlen(intValue); string++; } } *p = '\0'; return buffer;}/*-------------------------------------------------------------------------------------------------- Find the union case based on the switch field.--------------------------------------------------------------------------------------------------*/static utUnionCase findUnionCase( utUnion theUnion, uint64 objectNumber){ utField switchField = utFields + theUnion->switchFieldIndex; utUnionCase unionCase; uint32 value = *(*(uint32 **)(switchField->arrayPtr) + objectNumber); uint16 xUnionCase; for(xUnionCase = 0; xUnionCase < theUnion->numUnionCases; xUnionCase++) { unionCase = utUnionCases + theUnion->firstUnionCaseIndex + xUnionCase; if(unionCase->value == value) { return unionCase; } } return NULL;}/*-------------------------------------------------------------------------------------------------- Return a string representation of the field value.--------------------------------------------------------------------------------------------------*/static char *findFieldValue( utField field, uint64 objectNumber){ utModule module; utClass theClass;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -