static const char *ParseObject(ParseArgs& args, const char *data) { data = SkipWS(data + 1); if ('}' == *data) return data + 1; size_t pathIdx = args.path.Size(); for (;;) { data = SkipWS(data); if ('"' != *data) return NULL; args.path.Append('/'); data = ExtractString(args.path, data); if (!data) return NULL; data = SkipWS(data); if (':' != *data) return NULL; data = ParseValue(args, data + 1); if (args.canceled || !data) return data; args.path.RemoveAt(pathIdx, args.path.Size() - pathIdx); data = SkipWS(data); if ('}' == *data) return data + 1; if (',' != *data) return NULL; data++; } }
ASM_DATA *GetAsmInternal(const char *m_line, int lineno) { ASM_DATA *ret = CreateAsmData(); const char *ptr; int regsize = 0; ret->lineno = lineno; SkipWS(&m_line); LastPoint(&(ptr = m_line)); ptr -= 1; // // Jcc용 라벨 // if (*ptr == ':') { ret->setlabel = true; ret->labelindex = label_index++; int i = 0; for (; m_line[i]; i++) ret->labelname[i] = m_line[i]; ret->labelname[i] = 0; } else { ret->opcode = GetOpcode(&m_line); } return ret; }
bool Parse(const char *data, ValueVisitor *visitor) { ParseArgs args(visitor); if (str::StartsWith(data, UTF8_BOM)) data += 3; const char *end = ParseValue(args, data); if (!end) return false; return args.canceled || !*SkipWS(end); }
static const char *ParseArray(ParseArgs& args, const char *data) { data = SkipWS(data + 1); if (']' == *data) return data + 1; size_t pathIdx = args.path.Size(); for (int idx = 0; ; idx++) { args.path.AppendFmt("[%d]", idx); data = ParseValue(args, data); if (args.canceled || !data) return data; args.path.RemoveAt(pathIdx, args.path.Size() - pathIdx); data = SkipWS(data); if (']' == *data) return data + 1; if (',' != *data) return NULL; data++; } }
static const char *ParseValue(ParseArgs& args, const char *data) { data = SkipWS(data); switch (*data) { case '"': return ParseString(args, data); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': return ParseNumber(args, data); case '{': return ParseObject(args, data); case '[': return ParseArray(args, data); case 't': return ParseKeyword(args, data, "true", Type_Bool); case 'f': return ParseKeyword(args, data, "false", Type_Bool); case 'n': return ParseKeyword(args, data, "null", Type_Null); default: return NULL; } }
void GetRegister(const char const* *m_str, PASM_REG m_reg) { const char *m_ptr = *m_str; ASM_REG reg = *m_reg; int thirdc; const char *m_ch; // 중요 : 이 함수는 다음과 같은 구문은 처리하지 못합니다. // [<num2> + <reg> * <num1>] // [<num1> * <reg> + <num2>] // [<num2> + <num1> * <reg>] // [<num1> * <reg>] // [<num1> + <reg>] if (reg.isprocess) return; reg.isprocess = true; reg.error = SYNTAX_ERROR::_Not_Found_Error; // [<reg> * <num1> + <num2>] 형식일 경우 이 플래그는 활성화됨 thirdc = FALSE; // 상수식 분석 if ( isdigit(*m_ptr) || // isxdigit(*m_ptr) || *m_ptr == '-' || *m_ptr == '+' ) { const char *foresee = m_ptr + 1; int get; int radix = 0; reg.type = REG_TYPE::_Reg_Numberic; // 맨 끝의 문자를 확인하기 위해 포인터를 옮김 // SkipFunc(&foresee, isspace); SkipFunc(&foresee, isxdigit); // SkipFunc(&foresee, isspace); if (*foresee == 'o') get = get_oct(m_ptr); else if (*foresee == 'x') get = get_hex(m_ptr); else get = get_dec(m_ptr); reg.first = get; m_ptr = foresee + 1; goto PROC_END; } // // rxx, exx와 참조형 오퍼랜드를 분석함 // 디폴트 값은 16bit형 오퍼랜드임 // RE: switch(tolower(*m_ptr)) { case '[': reg.type = REG_TYPE::_Reg_Reference; SkipWS(&m_ptr); m_ptr++; goto RE; { case 'e': reg.bit = 32; goto SET; } // { case 'r': bit = 64; goto SET; } { default: reg.bit = 16; break; } SET: if (reg.type != REG_TYPE::_Reg_Reference) reg.type = REG_TYPE::_Reg_Normal; m_ptr++; } // // exx에서 e을 넘긴 레지스터를 분석함 // 형식은 모두 16bit로 통일 // switch(tolower(*((m_ch = m_ptr + 1) - 1))) { case 'a': if (*m_ch == 'x') reg.first = AX; else if (*m_ch == 'l') reg.first = AL; else if (*m_ch == 'h') reg.first = AH; break; case 'b': if (*m_ch == 'p') reg.first = BP; else if (*m_ch == 'x') reg.first = BX; else if (*m_ch == 'l') reg.first = BL; else if (*m_ch == 'h') reg.first = BH; break; case 'c': if (*m_ch == 'x') reg.first = CX; else if (*m_ch == 'l') reg.first = CL; else if (*m_ch == 'h') reg.first = CH; break; case 'd': if (*m_ch == 'i') reg.first = DI; else if (*m_ch == 'x') reg.first = DX; else if (*m_ch == 'l') reg.first = DL; else if (*m_ch == 'h') reg.first = DH; break; case 's': if (*m_ch == 'p') reg.first = SP; else if (*m_ch == 'i') reg.first = SI; break; } // // 분석했던 레지스터의 총 길이가 2이므로 // m_ptr += 2; SkipWS(&m_ptr); // // 일반 레지스터 형식이면 더 이상 분석할 필요없으니 // 그냥 끝냄 // if (reg.type == REG_TYPE::_Reg_Normal) goto PROC_END; // // 일반 참조형 레지스터 형식 // if (*m_ptr == ']') { reg.type = REG_TYPE::_Reg_SingleReference; goto PROC_END; } // // ']'를 만나지 않으면 뭔가 더 있는 것임으로 // if (*m_ptr == '+') reg.sign = REG_SIGN::_Sign_Plus; else if (*m_ptr == '-') reg.sign = REG_SIGN::_Sign_Minus; else if (*m_ptr == '*') reg.sign = REG_SIGN::_Sign_Multiple; SkipWS(&m_ptr); m_ptr++; // // 16진수의 문자열일 경우 ffh나, a2h같은 문자가 먼저 나와있을 수 있는데 // 이 경우엔 분석을 막아 변수로 취급한다. 그로 인해 16진수의 경우엔 // 0ffh, 0a2h와 같이 나타내어야 한다. // if(isdigit(*m_ptr)) { const char * t = m_ptr; int get; for (; *t != ']' && *t; t++) if (*t == '-' || *t == '+') { // // [<reg> * <num1> + <num2>] 형식임이 확증됨 // thirdc = TRUE; break; } // // *t == NULL이면 열린 괄호가 닫히지 않았으므로 당연한 오류 // if (!*t--) { reg.error = SYNTAX_ERROR::_Not_Find_Comma; goto PROC_END; } // // ']'가 나오기 전에 공백이 포함되어있을 수 있으므로 // for (; isspace(*t); t--) ; if (*t == 'o') get = get_oct(m_ptr); else if (*t == 'h') get = get_hex(m_ptr); else get = get_dec(m_ptr); reg.second = get; reg.type = REG_TYPE::_Reg_Reference; m_ptr = t + 1; if (thirdc == TRUE) { // // 이 코드구역은 상기구역과 동일함 // const char * ptr = t+1; int get; SkipWS(&m_ptr); if (*ptr == '+') reg.sign = REG_SIGN::_Sign_Multiple_Plus; else if (*ptr == '-') reg.sign = REG_SIGN::_Sign_Multiple_Minus; SkipWS(&m_ptr); for (; *t != ']' && *t; t++) ; if (!*t--) { reg.error = SYNTAX_ERROR::_Not_Find_Comma; goto PROC_END; } for (; isspace(*t); t--) ; if (*t == 'o') get = get_oct(m_ptr); else if (*t == 'h') get = get_hex(m_ptr); else get = get_dec(m_ptr); reg.third = get; m_ptr = ptr + 1; } } PROC_END: *m_reg = reg; *m_str = m_ptr; }
/* BalsaTypeParseFromString : parse a Balsa type in the Breeze format from a string skipping whitespace. Returns the pointer to the first character beyond the end of the first type defn. in the string or NULL on error, puts it's result in *type only on success. index is used for error reporting and should usually be set to 0 */ const char *BalsaTypeParseFromString (const char *string, unsigned index, BalsaType ** type) { const char *stringPtr = SkipWS (string); const char *newStringPtr; BalsaType *ret = NULL; unsigned symbolLength; #define EXPECTING(thing) do { \ fprintf (stderr, "%s:%d: expecting " thing " at `%s' index %d (%c)\n", \ __func__, __LINE__, string, (int) (stringPtr - string), *stringPtr); \ return NULL; \ } while (0) stringPtr = SkipWS (stringPtr); if (*stringPtr == '(') /* ) */ { const char *symbolPtr = stringPtr + 1; bool isAlias; symbolLength = SymbolLength (symbolPtr); stringPtr = SkipWS (symbolPtr + symbolLength); isAlias = SymbolEqual (symbolPtr, "alias-type", symbolLength); if (isAlias || SymbolEqual (symbolPtr, "named-type", symbolLength)) { char *typeName; if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr++; symbolLength = SymbolLength (stringPtr); typeName = malloc (symbolLength + 1); strncpy (typeName, stringPtr, symbolLength); typeName[symbolLength] = '\0'; stringPtr += symbolLength; if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr = SkipWS (stringPtr + 1); ret = BalsaLookupInternedType (typeName); if (!ret) { stringPtr -= symbolLength + 1; /* Report error at start of name */ EXPECTING ("valid type name"); } if (isAlias) ret = BalsaTypeAlias (NULL, ret); free (typeName); } else if (SymbolEqual (symbolPtr, "numeric-type", symbolLength)) { symbolLength = SymbolLength (stringPtr); bool isSigned = SymbolEqual (stringPtr, "#t", symbolLength); unsigned length; if (!isSigned && !SymbolEqual (stringPtr, "#f", symbolLength)) EXPECTING ("signedness"); stringPtr = SkipWS (stringPtr + symbolLength); symbolLength = SymbolLength (stringPtr); if (!isdigit (*stringPtr)) EXPECTING ("bitwise type length"); length = strtoul (stringPtr, NULL, 10); stringPtr = stringPtr + symbolLength; ret = NewBalsaType (BalsaNumericType, NULL, (isSigned ? -length : length)); } else if (SymbolEqual (symbolPtr, "enumeration-type", symbolLength)) { symbolLength = SymbolLength (stringPtr); bool isSigned = SymbolEqual (stringPtr, "#t", symbolLength); unsigned length; BalsaList *elementNames = NULL; BalsaList *elementValues = NULL; if (!isSigned && !SymbolEqual (stringPtr, "#f", symbolLength)) EXPECTING ("signedness"); stringPtr = SkipWS (stringPtr + symbolLength); symbolLength = SymbolLength (stringPtr); if (!isdigit (*stringPtr)) EXPECTING ("bitwise type length"); length = strtoul (stringPtr, NULL, 10); stringPtr = SkipWS (stringPtr + symbolLength); ret = NewBalsaType (BalsaEnumerationType, NULL, (isSigned ? -length : length)); while (*stringPtr != ')') { bool elementIsNegate = false; char *elementName; FormatData *elementValue; if (*stringPtr != '(') EXPECTING ("`('"); stringPtr = SkipWS (stringPtr + 1); if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr++; symbolLength = SymbolLength (stringPtr); if (!(isalnum (*stringPtr) || *stringPtr == '_')) EXPECTING ("element name"); elementName = malloc (symbolLength + 1); strncpy (elementName, stringPtr, symbolLength); elementName[symbolLength] = '\0'; stringPtr += symbolLength; if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr = SkipWS (stringPtr + 1); /* Parse a multi-precision (possibly negative) integer */ if (*stringPtr == '-') { elementIsNegate = true; stringPtr++; } symbolLength = SymbolLength (stringPtr); elementValue = FormatDataParseUInt (stringPtr, 10); if (!elementValue) EXPECTING ("element type"); if (elementIsNegate) { FormatData *negElementValue = elementValue; elementValue = FormatDataNegate (negElementValue, length); DeleteFormatData (negElementValue); } stringPtr = SkipWS (stringPtr + symbolLength); elementNames = NewBalsaList (elementName, elementNames); elementValues = NewBalsaList (elementValue, elementValues); if (*stringPtr != ')') EXPECTING ("`)'"); stringPtr = SkipWS (stringPtr + 1); } elementNames = BalsaListReverse (elementNames); elementValues = BalsaListReverse (elementValues); ret->info.enumeration.elementNames = (char **) BalsaListToArray (elementNames, &(ret->info.enumeration.elementCount)); ret->info.enumeration.elementValues = (FormatData **) BalsaListToArray (elementValues, NULL); BalsaListDelete (elementNames); BalsaListDelete (elementValues); } else if (SymbolEqual (symbolPtr, "record-type", symbolLength)) { unsigned length; BalsaList *elementNames = NULL; BalsaList *elementTypes = NULL; symbolLength = SymbolLength (stringPtr); if (!isdigit (*stringPtr)) EXPECTING ("bitwise type length"); length = strtoul (stringPtr, NULL, 10); stringPtr = SkipWS (stringPtr + symbolLength); ret = NewBalsaType (BalsaRecordType, NULL, length); while (*stringPtr != ')') { char *elementName; BalsaType *elementType; if (*stringPtr != '(') EXPECTING ("`('"); stringPtr = SkipWS (stringPtr + 1); if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr++; symbolLength = SymbolLength (stringPtr); if (!(isalnum (*stringPtr) || *stringPtr == '_')) EXPECTING ("element name"); elementName = malloc (symbolLength + 1); strncpy (elementName, stringPtr, symbolLength); elementName[symbolLength] = '\0'; stringPtr += symbolLength; if (*stringPtr != '"') EXPECTING ("`\"'"); stringPtr = SkipWS (stringPtr + 1); newStringPtr = BalsaTypeParseFromString (stringPtr, index + (unsigned) (stringPtr - string), &elementType); if (!newStringPtr) EXPECTING ("element type"); stringPtr = SkipWS (newStringPtr); elementNames = NewBalsaList (elementName, elementNames); elementTypes = NewBalsaList (elementType, elementTypes); if (*stringPtr != ')') EXPECTING ("`)'"); stringPtr = SkipWS (stringPtr + 1); } elementNames = BalsaListReverse (elementNames); elementTypes = BalsaListReverse (elementTypes); ret->info.record.elementNames = (char **) BalsaListToArray (elementNames, &(ret->info.record.elementCount)); ret->info.record.elementTypes = (BalsaType **) BalsaListToArray (elementTypes, NULL); BalsaListDelete (elementNames); BalsaListDelete (elementTypes); } else if (SymbolEqual (symbolPtr, "array-type", symbolLength)) { BalsaType *elementType; BalsaType *boundingType; int lowIndex; unsigned elementCount; newStringPtr = BalsaTypeParseFromString (stringPtr, index + (unsigned) (stringPtr - string), &elementType); if (!newStringPtr) EXPECTING ("element type"); stringPtr = SkipWS (newStringPtr); symbolLength = SymbolLength (stringPtr); if (!isdigit (*stringPtr) && *stringPtr != '-') EXPECTING ("low index"); lowIndex = strtoul (stringPtr, NULL, 10); stringPtr = SkipWS (stringPtr + symbolLength); symbolLength = SymbolLength (stringPtr); if (!isdigit (*stringPtr)) EXPECTING ("element count"); elementCount = strtoul (stringPtr, NULL, 10); stringPtr = SkipWS (stringPtr + symbolLength); ret = NewBalsaType (BalsaArrayType, NULL, elementCount * ABS (elementType->size)); ret->info.array.elementCount = elementCount; ret->info.array.elementType = elementType; ret->info.array.boundingType = boundingType; ret->info.array.lowIndex = lowIndex; } else if (SymbolEqual (symbolPtr, "builtin-type", symbolLength)) { ret = NewBalsaType (BalsaBuiltinType, NULL, 64); } else { stringPtr = symbolPtr; EXPECTING ("*-type"); } /* ( */ if (*stringPtr != ')') /* ( */ EXPECTING ("`)'"); stringPtr++; } else EXPECTING ("`('"); /* ) */ #undef EXPECTING if (type) *type = ret; return stringPtr; }
int LoadINI(INIFile *File,const char *FileName) { char S[256],SName[256],VName[256]; int J,Count; char *P; FILE *F; // Open file F=fopen(FileName,"rb"); if(!F) return(0); // Read file line by line for(Count=0;fgets(S,sizeof(S),F);) { // Skip white space P=SkipWS(S); // If a new section starts... if(*P=='[') { // Skip white space P=SkipWS(P+1); // Copy section name for(J=0;*P&&(*P!=']');SName[J++]=*P++); // Trim white space while(J&&(SName[J-1]<=' ')) --J; // Terminate section name SName[J]='\0'; } else if(SName[0]) { // // Variable (but only if we have a valid section name) // // Copy variable name for(J=0;*P&&(*P!='=');VName[J++]=*P++); // Trim white space while(J&&(VName[J-1]<=' ')) --J; // Terminate variable name VName[J]='\0'; // Only if we have got a variable name and an '=' sign... if(VName[0]&&(*P=='=')) { // Skip white space P=SkipWS(P+1); // Copy variable value for(J=0;*P;S[J++]=*P++); // Trim whitespace while(J&&(S[J-1]<=' ')) --J; // Terminate variable value S[J]='\0'; // If we have got a value, set it! INISetString(File,SName,VName,S); ++Count; } } } // Done reading file fclose(F); return(Count); }