stringparsing.c
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· C语言 代码 · 共 883 行 · 第 1/2 页
C
883 行
return( str );}staticchar *skipSpace(unsigned char *str, unsigned char *str_end){ assert(str != 0); assert(str_end != 0); while( (str < str_end) && isspace(*str) ) { str++; } return( str );}staticint parseString_private(parseErrorInfo *pe, parsedString *subString, stringScript *script, void **values, int op, va_list args){ char *str, *str_end, *str_ptr = 0, *term_ptr, *new_pos = 0; int values_pos = 0, len, retval = 1; stringScript *script_pos = script; parseValue pv; parseStack ps;#ifdef VA_LIST_IS_ARRAY /* Use temporary copy of args on platforms where va_list * is an array. * * We sometimes need to pass the address of a va_list to * another function. C Standard mandates array types in * prototypes to be silently coerced into pointers to base * objects. If va_list is an array, this results in the * receiving function expecting a pointer to a va_list array * member, but getting a pointer to a pointer instead when * we pass &args. * * Copying the va_list into a temporary buffer, and copying * it back 'undoes' the coercion. * * A longer explanation was posted by Graeme Peterson on the * GDB mailing list on 2002-04-15. */ va_list tmp_args; VA_LIST_COPY (tmp_args, args);#endif assert(subString != 0); str = subString->data; str_end = subString->data + subString->len; pv.type = SPO_Noop; ps.top = &ps.frames[0]; ps.top->op = SPO_Noop; ps.depth = 0; if( script ) { op = script_pos->op; } while( retval && (ps.depth >= 0) ) { switch( op ) { case SPO_End: if( ps.top->op == SPO_Do ) VA_LIST_COPY(args, ps.top->args); else popFrame(&ps); script_pos++; break; case SPO_Expect: if( script ) { str_ptr = script_pos->args[0]; script_pos = STRING_SCRIPT_NEXT(script_pos, 1); } else { str_ptr = va_arg(args, char *); } if( (str = strstr(str, str_ptr)) && (str < str_end) ) { retval = storeValue(pe, &pv, str, 1); str += strlen(str_ptr); } else { pe->position = str_end; pe->op = op; pe->args[0] = str_ptr; retval = 0; } break; case SPO_ExpectSpace: str = skipChars(str, str_end); retval = storeValue(pe, &pv, str, 1); str = skipSpace(str, str_end); script_pos++; break; case SPO_Character: case SPO_Byte: case SPO_HexByte: case SPO_Short: case SPO_HexShort: case SPO_Integer: case SPO_LongInteger: case SPO_HexInteger: case SPO_HexLongInteger: case SPO_Float: case SPO_Double: case SPO_Count: case SPO_String: case SPO_NonEmptyString: pv.type = op; pv.value = str; if( values ) pv.storage.p = values[values_pos++]; else pv.storage.p = va_arg(args, void *); script_pos++; break; case SPO_OneOf: if( script ) { str_ptr = script_pos->args[0]; script_pos = STRING_SCRIPT_NEXT(script_pos, 1); } else { str_ptr = va_arg(args, char *); } if( (new_pos = strpbrk(str, str_ptr)) && (new_pos < str_end) ) { retval = storeValue(pe, &pv, new_pos, 1); retval = retval && pushFrame(pe, &ps, op, script_pos, values_pos, args); str = new_pos; } else {#ifdef VA_LIST_IS_ARRAY VA_LIST_COPY (args, tmp_args);#endif skipBlock(script, values, &script_pos, &values_pos, &args); } break; case SPO_Do: ps.top->pv = pv; retval = pushFrame(pe, &ps, op, script_pos, values_pos, args); script_pos++; break; case SPO_While: if( script ) { str_ptr = script_pos->args[0]; term_ptr = script_pos->args[1]; script_pos = STRING_SCRIPT_NEXT(script_pos, 2); } else { str_ptr = va_arg(args, char *); term_ptr = va_arg(args, char *); } if( (new_pos = strstr(str, str_ptr)) && (new_pos < str_end) ) { retval = storeValue(pe, &ps.top->prev->pv, new_pos, 0); retval = retval && storeValue(pe, &pv, new_pos, 1); str = new_pos + strlen(str_ptr); } else if( ((term_ptr[0] == '\0') ? (new_pos = str_end) : (new_pos = strstr(str, term_ptr))) && (new_pos <= str_end) ) { retval = storeValue(pe, &pv, new_pos, 1); str = new_pos + strlen(term_ptr); ps.top->op = SPO_Noop; } else { pe->position = str_end; pe->op = op; pe->args[0] = str_ptr; pe->args[1] = term_ptr; retval = 0; } break; case SPO_SkipSpace: str = skipSpace(str, str_end); break; case SPO_WhileSpace: new_pos = skipChars(str, str_end); retval = storeValue(pe, &pv, new_pos, 1); str = skipSpace(new_pos, str_end); if( str == str_end ) { ps.top->op = SPO_Noop; } script_pos++; break; case SPO_Cond: if( script ) { str_ptr = script_pos->args[0]; script_pos = STRING_SCRIPT_NEXT(script_pos, 1); } else { str_ptr = va_arg(args, char *); } len = strlen(str_ptr); new_pos = str; if( ((pv.type == SPO_Noop) && !strncmp(str, str_ptr, len)) || ((pv.type != SPO_Noop) && (new_pos = strstr(str, str_ptr)) && (new_pos < str_end)) ) { if( ps.top->op == SPO_OneOf ) { ps.top->op = SPO_Noop; } else { retval = storeValue(pe, &pv, new_pos, 1); } retval = retval && pushFrame(pe, &ps, op, script_pos, values_pos, args); str = new_pos + len; } else {#ifdef VA_LIST_IS_ARRAY VA_LIST_COPY (args, tmp_args);#endif skipBlock(script, values, &script_pos, &values_pos, &args); } break; case SPO_Handle: { int (*handler)(void *arg); void *v_ptr; if( script ) { handler = (int (*)(void *)) script_pos->args[0]; v_ptr = script_pos->args[1]; script_pos = STRING_SCRIPT_NEXT(script_pos, 2); } else { handler = (int (*)(void *)) va_arg(args, void *); v_ptr = va_arg(args, void *); } if( !(retval = handler(v_ptr)) ) { pe->position = str; pe->op = op; pe->args[0] = handler; pe->args[1] = v_ptr; } } break; case SPO_NotEmpty: if( str < str_end ) { retval = pushFrame(pe, &ps, op, script_pos, values_pos, args); } else {#ifdef VA_LIST_IS_ARRAY VA_LIST_COPY (args, tmp_args);#endif skipBlock(script, values, &script_pos, &values_pos, &args); } script_pos++; break; default: assert(0); break; } if( script ) op = script_pos->op; else op = va_arg(args, int); } if( retval && (str < str_end) ) { if( pv.type == SPO_Noop ) { pe->position = str; pe->op = SPO_Noop; retval = 0; } else { retval = storeValue(pe, &pv, str_end, 1); } } cutFrames(&ps); return( retval );}int parseString(char *str, int op, ...){ parseErrorInfo pe; parsedString ps; va_list args; int retval; assert(str != 0); va_start(args, op); ps.data = str; ps.len = strlen(str); retval = parseString_private(&pe, &ps, NULL, NULL, op, args); va_end(args); return( retval );}int parseString_error(parseErrorInfo *pe, char *str, int op, ...){ parsedString ps; va_list args; int retval; assert(str != 0); va_start(args, op); ps.data = str; ps.len = strlen(str); retval = parseString_private(pe, &ps, NULL, NULL, op, args); va_end(args); return( retval );}int parseSubString(parsedString *ps, int op, ...){ parseErrorInfo pe; va_list args; int retval; assert(ps != 0); va_start(args, op); retval = parseString_private(&pe, ps, NULL, NULL, op, args); va_end(args); return( retval );}int parseString_script(char *str, stringScript *ss, ...){ parseErrorInfo pe; parsedString ps; va_list args; int retval; va_start(args, ss); ps.data = str; ps.len = strlen(str); retval = parseString_private(&pe, &ps, ss, NULL, SPO_Noop, args); va_end(args); return( retval );}int parseString_script_values(char *str, stringScript *ss, void **values){ parseErrorInfo pe; parsedString ps; int retval; va_list * args; args = KCALLOC(1, sizeof(args)); ps.data = str; ps.len = strlen(str); retval = parseString_private(&pe, &ps, ss, values, SPO_Noop, *args); KFREE(args); return( retval );}char *promoteParsedString(parsedString *ps){ char *retval; if( (retval = spMalloc(ps->len + 1)) ) { strncpy(retval, ps->data, ps->len); retval[ps->len] = '\0'; } return( retval );}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?