📄 utmanage.c
字号:
uint8 *dest, char *value){ char c = toupper(*value++); uint8 byte; if(c >= '0' && c <= '9') { byte = c - '0'; } else if(c >= 'A' && c <= 'F') { byte = c - 'A' + 10; } else { return false; } byte <<= 4; c = toupper(*value); if(c >= '0' && c <= '9') { byte |= c - '0'; } else if(c >= 'A' && c <= 'F') { byte |= c - 'A' + 10; } else { return false; } *dest = byte; return true;}/*-------------------------------------------------------------------------------------------------- Parse a typedef value.--------------------------------------------------------------------------------------------------*/static bool readTypedef( uint8 *dest, char *value, uint32 size){ uint32 length = 0; while(*value != '\0' && length <= size) { if(!readHex(dest, value)) { return false; } dest++; value += 2; length++; } return length == size;}/*-------------------------------------------------------------------------------------------------- Convert any \ escapes into characters.--------------------------------------------------------------------------------------------------*/static char *unmungeString( char *string, char **end){ char *buffer = utMakeString(strlen(string) + 1); char *p = buffer; char value; *end = NULL; if(*string++ != '"') { return NULL; } while(*string != '\0' && *string != '"') { if(*string == '\\') { string++; if(*string >= '0' && *string <= '9') { value = 0; do { value = 10*value + *string++ - '0'; } while(*string >= '0' && *string <= '9'); *p++ = value; } else { *p++ = *string++; } } else { if(!isprint(*string)) { return NULL; } *p++ = *string++; } } *p = '\0'; if(*string == '\0') { return NULL; } *end = string + 1; return buffer;}/*-------------------------------------------------------------------------------------------------- Parse a symbol. Valid values are a string, or 0xffffffff--------------------------------------------------------------------------------------------------*/static bool readSym( uint8 *dest, char *value){ utSym *symPtr = (utSym *)dest; char *end; char *string; if(*value == '"') { string = unmungeString(value, &end); if(end == NULL) { return false; } *symPtr = utSymCreate(string); } else { readInteger(dest, value, sizeof(utSym), true); if(*symPtr != utSymNull) { return false; } } return true;}/*-------------------------------------------------------------------------------------------------- Parse an enumerated type, and write it to the destination.--------------------------------------------------------------------------------------------------*/static bool readEnum( utEnum theEnum, uint8 *dest, char *value){ utEntry entry; entry = findEntryFromName(theEnum, value); if(entry == NULL) { reportError("Unknown enumerated type value %s", value); entry = utEntries + theEnum->firstEntryIndex; } *(uint32 *)dest = entry->value; return true;}/*-------------------------------------------------------------------------------------------------- Parse a value of a given type, and write it to the destination.--------------------------------------------------------------------------------------------------*/static bool parseSpecificValue( uint8 *dest, char *value, utFieldType type, uint32 size, uint64 objectNumber){ switch(type) { case UT_BIT: if(!strcasecmp(value, "true")) { *(uint8 *)dest |= 1 << (objectNumber & 7); } else if(!strcasecmp(value, "false")) { *(uint8 *)dest &= ~(1 << (objectNumber & 7)); } else { return false; } return true; case UT_BOOL: if(!strcasecmp(value, "true")) { *(bool *)dest = true; } else if(!strcasecmp(value, "false")) { *(bool *)dest = false; } else { return readInteger(dest, value, 1, true); } return true; case UT_INT: return readInteger(dest, value, size, false); case UT_UINT: return readInteger(dest, value, size, true); case UT_CHAR: return readChar(dest, value); case UT_FLOAT: return readFloat(dest, value, true); case UT_DOUBLE: return readFloat(dest, value, true); case UT_POINTER: return readInteger(dest, value, size, true); case UT_TYPEDEF: return readTypedef(dest, value, size); case UT_SYM: return readSym(dest, value); default: utExit("Invalid type"); } return false; /* Dummy return */}/*-------------------------------------------------------------------------------------------------- Parse a value of a given type, and write it to the destination.--------------------------------------------------------------------------------------------------*/static bool parseValue( uint8 *dest, char *value, utField field, uint64 objectNumber){ utClass theClass = utClasses + field->classIndex; utModule module = utModules + theClass->moduleIndex; utUnion theUnion; utUnionCase theCase; utEnum theEnum; if(field->type == UT_ENUM) { theEnum = findEnum(module, field->destName); return readEnum(theEnum, dest, value); } if(field->type != UT_UNION) { return parseSpecificValue(dest, value, field->type, field->size, objectNumber); } theUnion = utUnions + field->unionIndex; theCase = findUnionCase(theUnion, objectNumber); if(theCase == NULL) { return readTypedef(dest, value, field->size); } if(theCase->type == UT_ENUM) { theEnum = findEnum(module, field->destName); return readEnum(theEnum, dest, value); } return parseSpecificValue(dest, value, theCase->type, theCase->size, objectNumber);}/*-------------------------------------------------------------------------------------------------- Skip to the next comma or the end of a value list. If we find a syntax error of some sort, return NULL.--------------------------------------------------------------------------------------------------*/static char *skipToNextComma( char *valueList){ char *end, *prevChar; if(*valueList == ',') { valueList++; } while(isspace(*valueList)) { valueList++; } if(*valueList == '"') { unmungeString(valueList, &end); if(end == NULL) { return NULL; } valueList = end; } else if(*valueList == '(') { valueList++; do { valueList = skipToNextComma(valueList); prevChar = valueList - 1; while(isspace(*prevChar)) { prevChar--; } } while(valueList != NULL && *prevChar != ')'); if(valueList == NULL) { return NULL; } } while(*valueList != '\0' && *valueList != ',') { valueList++; } if(*valueList != ',' && *valueList != '\0') { return NULL; } return valueList;}/*-------------------------------------------------------------------------------------------------- Count how many values are in the list.--------------------------------------------------------------------------------------------------*/static uint32 countListValues( char *valueList){ uint32 numValues = 0; while(isspace(*valueList)) { valueList++; } while(valueList != NULL && *valueList != '\0') { valueList = skipToNextComma(valueList); numValues++; } if(valueList == NULL || *valueList != '\0') { return 0; /* Invalid list */ } return numValues;}/*-------------------------------------------------------------------------------------------------- Return the next element in a list of array values. Update the list pointer to the next element.--------------------------------------------------------------------------------------------------*/static char *parseArrayValue( char **valueList){ char *end, *buffer, *prevChar; uint32 length; bool isArray; while(isspace(**valueList)) { (*valueList)++; } isArray = **valueList == '('; end = skipToNextComma(*valueList); if(end == NULL) { return NULL; } prevChar = end; if(isArray) { (*valueList)++; prevChar = end - 1; while(isspace(*prevChar)) { prevChar--; } } length = prevChar - *valueList; buffer = utMakeString(length + 1); strncpy(buffer, *valueList, length); buffer[length] = '\0'; if(*end == ',') { end++; } *valueList = end; utLastToken = buffer; return buffer;}/*-------------------------------------------------------------------------------------------------- Parse an array of values.--------------------------------------------------------------------------------------------------*/static bool parseArray( utField field, uint64 objectNumber, char *valueList){ uint32 numValues; uint8 *dest; char *value, *string, *end; if(field->type == UT_CHAR && *valueList == '"') { string = unmungeString(valueList, &end); if(end == NULL || *end != '\0') { return false; } numValues = strlen(string) + 1; dest = field->allocValues(objectNumber, numValues); strcpy((char *)dest, string); return true; } numValues = countListValues(valueList); dest = field->allocValues(objectNumber, numValues); while(numValues-- != 0) { value = parseArrayValue(&valueList); if(!parseValue(dest, value, field, objectNumber)) { return false; } dest += field->size; } if(*valueList != '\0') { return false; } return true;}/*-------------------------------------------------------------------------------------------------- Set a field of an object.--------------------------------------------------------------------------------------------------*/static bool setObjectField( utClass theClass, utField field, uint64 objectNumber, char *value){ uint64 numUsed = utFindIntValue(theClass->numUsedPtr, theClass->referenceSize); uint8 *dest; bool passed; if(objectNumber >= numUsed) { reportError("Invalid object ID"); return false; } if(!field->array) { if(field->type == UT_BIT) { dest = *(uint8 **)(field->arrayPtr) + (objectNumber >> 3)*field->size; } else { dest = *(uint8 **)(field->arrayPtr) + objectNumber*field->size; } passed = parseValue(dest, value, field, objectNumber); } else { passed = parseArray(field, objectNumber, value); } if(!passed) { reportError("Invalid value for field %s", field->name); } return passed;}/*-------------------------------------------------------------------------------------------------- Set all the fields of an object.--------------------------------------------------------------------------------------------------*/static bool setObjectFields( utClass theClass, uint64 objectNumber, char *valueList, utField *fieldTranslationTable){ utField field; uint32 numValues = countListValues(valueList); char *value; uint32 xField; if(numValues != theClass->numFields - theClass->numHiddenFields) { reportError("Incorrect number of values for class %s", theClass->name); return false; } for(xField = 0; xField < numValues; xField++) { if(fieldTranslationTable == NULL) { field = utFields + theClass->firstFieldIndex + xField;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -