📄 utmanage.c
字号:
}/*-------------------------------------------------------------------------------------------------- Process a show_hidden command.--------------------------------------------------------------------------------------------------*/static void processShowHiddenCommand(void){ char *token = readToken(); if(!expectEnd()) { return; } if(!strcasecmp(token, "true")) { utShowHidden = true; } else if(!strcasecmp(token, "false")) { utShowHidden = false; } else { reportError("Expecting 'true' or 'false'\n"); }}/*-------------------------------------------------------------------------------------------------- Process a load text command.--------------------------------------------------------------------------------------------------*/static void processLoadTextCommand(void){ char *fileName = readToken(); FILE *file; if(!expectEnd()) { return; } file = fopen(fileName, "r"); if(file == NULL) { reportError("Could not open file %s for reading", fileName); return; } utLoadTextDatabase(file); fclose(file); utMemCheck();}/*-------------------------------------------------------------------------------------------------- Process a write command.--------------------------------------------------------------------------------------------------*/static void processSaveTextCommand(void){ char *fileName = readToken(); FILE *file; if(!expectEnd()) { return; } file = fopen(fileName, "w"); if(file == NULL) { reportError("Could not open file %s for writing", fileName); return; } utSaveTextDatabase(file); fclose(file);}/*-------------------------------------------------------------------------------------------------- Process a load binary command.--------------------------------------------------------------------------------------------------*/static void processLoadBinaryCommand(void){ char *fileName = readToken(); FILE *file; if(!expectEnd()) { return; } file = fopen(fileName, "rb"); if(file == NULL) { reportError("Could not open file %s for reading", fileName); return; } utLoadBinaryDatabase(file); fclose(file);}/*-------------------------------------------------------------------------------------------------- Process a save binary command.--------------------------------------------------------------------------------------------------*/static void processSaveBinaryCommand(void){ char *fileName = readToken(); FILE *file; if(!expectEnd()) { return; } file = fopen(fileName, "wb"); if(file == NULL) { reportError("Could not open file %s for writing", fileName); return; } utSaveBinaryDatabase(file); fclose(file);}/*-------------------------------------------------------------------------------------------------- Process the command in the line buffer.--------------------------------------------------------------------------------------------------*/static bool processCommand(void){ char *token = readToken(); if(*token == '\0') { return true; /* Empty line */ } if(!strcmp(token, "create")) { processCreateCommand(); } else if(!strcmp(token, "compact")) { if(utPersistenceInitialized) { utCompactDatabase(); } else { reportError("Compact is only for persitent databases."); } } else if(!strcmp(token, "destroy")) { processDestroyCommand(); } else if(!strcmp(token, "help")) { printHelp(); return true; } else if(!strcmp(token, "list")) { processListCommand(); } else if(!strcmp(token, "quit")) { return false; } else if(!strcmp(token, "set")) { processSetCommand(); } else if(!strcmp(token, "show")) { processShowCommand(); } else if(!strcmp(token, "show_hidden")) { processShowHiddenCommand(); } else if(!strcmp(token, "load_text")) { processLoadTextCommand(); } else if(!strcmp(token, "save_text")) { processSaveTextCommand(); } else if(!strcmp(token, "load_binary")) { processLoadBinaryCommand(); } else if(!strcmp(token, "save_binary")) { processSaveBinaryCommand(); } else { fprintf(utOutputFile, "Invalid command. Type 'help' for a list of commands\n"); } return true;}/*-------------------------------------------------------------------------------------------------- Initialize the database manager.--------------------------------------------------------------------------------------------------*/void utDatabaseManagerStart(void){ utLineSize = 42; utLineBuffer = utNewA(char, utLineSize); utOutputFile = stdout; utInputFile = stdin;}/*-------------------------------------------------------------------------------------------------- Clean up after the database manager.--------------------------------------------------------------------------------------------------*/void utDatabaseManagerStop(void){ utFree(utLineBuffer);}/*-------------------------------------------------------------------------------------------------- Interpret commands to manage the database.--------------------------------------------------------------------------------------------------*/void utManager(void){ utAtEndOfFile = false; fprintf(utOutputFile, "For help, enter the 'help' command\n"); do { fprintf(utOutputFile, "> "); readLine(); } while(processCommand());}/*-------------------------------------------------------------------------------------------------- Skip blank lines.--------------------------------------------------------------------------------------------------*/static void skipBlankLines(void){ while(readLine()) { if(utLineBuffer[0] != '\0') { return; } }}/*-------------------------------------------------------------------------------------------------- Read a module header.--------------------------------------------------------------------------------------------------*/static utModule readModuleHeader(void){ utModule module; char *token; token = readToken(); if(strcmp(token, "module")) { if(!utAtEndOfFile) { reportError("Expected 'module' keyword"); } return NULL; } token = readToken(); if(token == NULL) { reportError("Expected module name"); return NULL; } module = utFindModule(token); if(module == NULL) { reportError("Module %s not found", token); return NULL; } if(!expectEnd()) { return NULL; } return module;}/*-------------------------------------------------------------------------------------------------- Reallocate object fields for the class.--------------------------------------------------------------------------------------------------*/static void reallocObjects( utClass theClass, uint64 numUsed){ utField field; uint16 xField; setInteger(theClass->numAllocatedPtr, numUsed, theClass->referenceSize); for(xField = 0; xField < theClass->numFields; xField++) { field = utFields + theClass->firstFieldIndex + xField; if(!field->array) { *(uint8 **)(field->arrayPtr) = utRealloc(*(uint8 **)field->arrayPtr, numUsed, field->size); } }}/*-------------------------------------------------------------------------------------------------- Read a class header, and allocate space for the objects.--------------------------------------------------------------------------------------------------*/static utClass readClassHeader( utModule module){ utClass theClass; char *token; uint64 numUsed; skipBlankLines(); token = readToken(); if(strcmp(token, "class")) { utLinePosition = 0; return NULL; } token = readToken(); if(token == NULL) { reportError("Expected class name"); return NULL; } theClass = findClass(module, token); if(theClass == NULL) { reportError("Class %s not found", token); return NULL; } token = readToken(); if(!readInteger(theClass->numUsedPtr, token, theClass->referenceSize, true)) { reportError("Expected number of objects"); return NULL; } if(!expectEnd()) { return NULL; } numUsed = utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); numUsed = utMax(2, numUsed); reallocObjects(theClass, numUsed); return theClass;}/*-------------------------------------------------------------------------------------------------- Read in column headers. Build a translation table from column number to field. The caller will have to free utFieldTranslationTable.--------------------------------------------------------------------------------------------------*/static bool readColumnHeaders( utClass theClass){ utField field; char *valueList, *value; uint32 numFields, xField; if(!readLine()) { reportError("Expected column headers"); return false; } valueList = utLineBuffer; numFields = countListValues(valueList) - 1; utFieldTranslationTable = calloc(numFields, sizeof(utField)); value = parseArrayValue(&valueList); if(value == NULL || strcmp(value, "ObjectNumber")) { reportError("Expected 'objectNumber' to be the first field"); return false; } for(xField = 0; xField < numFields; xField++) { value = parseArrayValue(&valueList); if(value == NULL) { return false; } field = utFindField(theClass, value); if(field == NULL) { reportError("Unknown field %s in class %s -- dropping", value, theClass->name); } utFieldTranslationTable[xField] = field; } utNumFields = numFields; return true;}/*-------------------------------------------------------------------------------------------------- Read in column types. If it is incompatible with the field, print a warning, and null out the entry in the translation table.--------------------------------------------------------------------------------------------------*/static bool readColumnTypes( utClass theClass){ char *valueList, *value; uint32 numFields, xField; if(!readLine()) { reportError("Expected column types"); return false; } valueList = utLineBuffer; numFields = countListValues(valueList) - 1; if(numFields != utNumFields) { reportError("Column number mismatch"); return false; } value = parseArrayValue(&valueList); if(value == NULL) { reportError("Expected class reference type to be the first field"); return false; } for(xField = 0; xField < numFields; xField++) { value = parseArrayValue(&valueList); if(value == NULL) { return false; } } return true;}/*-------------------------------------------------------------------------------------------------- Add the objects between the start and stop to the free list.--------------------------------------------------------------------------------------------------*/static void addObjectsToFreeList( utModule module, utClass theClass, uint32 start, uint32 stop){ utField field = utFields + module->firstFieldIndex + theClass->nextFreeFieldIndex; uint64 firstFree = utFindIntValue(theClass->firstFreePtr, theClass->referenceSize); uint64 xObject; uint8 *dest; for(xObject = start + 1; xObject < stop; xObject++) { firstFree = utFindIntValue(theClass->firstFreePtr, theClass->referenceSize); dest = *(uint8 **)(field->arrayPtr) + xObject*field->size; setInteger(dest, firstFree, theClass->referenceSize); setInteger(theClass->firstFreePtr, xObject, theClass->referenceSize); }}/*-------------------------------------------------------------------------------------------------- Read in a table of objects. A blank line ends the table.--------------------------------------------------------------------------------------------------*/static bool readClassTable( utModule module, utClass theClass){ char *valueList; uint32 numValues; uint64 objectNumber, lastObjectNumber = 0; bool error; utDo { if(!readLine()) { return false; } skipSpace(); } utWhile(utLineBuffer[utLinePosition] != '\0') { objectNumber = parseObjectNumber(theClass, true, &error); if(error) { return false; } if(strcmp(readToken(), ",")) { reportError("Expecting a ','"); } valueList = utLineBuffer + utLinePosition; numValues = countListValues(valueList); if(numValues != utNumFields) { reportError("Mismatched number of fields"); return false; } if(!setObjectFields(theClass, objectNumber, valueList, utFi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -