*/ REBINT Check_Error(REBVAL *val) /* ** Process a loop exceptions. Pass in the TOS value, returns: ** ** 2 - if break/return, change val to that set by break ** 1 - if break ** -1 - if continue, change val to unset ** 0 - if not break or continue ** else: error if not an ERROR value ** ***********************************************************************/ { // It's UNSET, not an error: if (!IS_ERROR(val)) Trap0(RE_NO_RETURN); //!!! change to special msg // If it's a BREAK, check for /return value: if (IS_BREAK(val)) { if (VAL_ERR_VALUE(val)) { *val = *VAL_ERR_VALUE(val); return 2; } else { SET_UNSET(val); return 1; } } if (IS_CONTINUE(val)) { SET_UNSET(val); return -1; } return 0; // Else: Let all other errors return as values. }
void handleScanCode(unsigned char scanCode) { if (!checkSpecialKey(scanCode)) { if (!IS_BREAK(scanCode)) { char c = translateSc(CLEAR_BREAK_BIT(scanCode)); signal_keyPressed(c); } } }
void SimpleJsonParser::parse( SimpleJsonTokenizer& tokenizer ) { #define IS_BREAK( t, b ) (t[0] == b && t[1] == '\0') enum ParseState { SCAN=1, ARRAY, PAIR, PAIR_COLON, RVALUE, RVALUE_SEPARATOR }; ParseState state = SCAN; char tag_name[MAXTAGNAMELEN+1]; CString array_index; reset(); push( this ); while ( tokenizer.hasToken() ) { LPSTR token = tokenizer.nextToken(); switch ( state ) { case SCAN: if ( IS_BREAK( token, '[' ) ) { // Start of array setType( JSONARRAY ); state = RVALUE; break; } else if ( IS_BREAK( token, '{' ) ) { // Start of object setType( JSONOBJECT ); state = PAIR; break; } throw std::exception( "Parser expected opening object or array" ); case PAIR: // Check for empty object if ( IS_BREAK( token, '}' ) && top()->getType() == JSONOBJECT && top()->valueCount() == 0 ) { pop(); state = RVALUE_SEPARATOR; break; } strcpy_s( tag_name, strip_quotes( token ) ); state = PAIR_COLON; break; case PAIR_COLON: if ( !IS_BREAK( token, ':' ) ) throw std::exception( "Parser expecting colon seperator" ); state = RVALUE; break; case RVALUE: { if ( IS_BREAK( token, ']' ) ) { // Empty array if ( top()->getType() != JSONARRAY ) throw std::exception( "Unexpected array closing bracket" ); pop(); state = RVALUE_SEPARATOR; break; } JsonNode* node = top(); if ( node->getType() == JSONARRAY ) { tag_name[0] = '\0'; } else if ( node->has_key( tag_name ) ) { CString error; error.Format( "Duplicate JSON tag name '%s'", tag_name ); throw std::exception( (LPCSTR)error ); } if ( IS_BREAK( token, '[' ) ) { push( node->setValue( JSONARRAY, tag_name ) ); state = RVALUE; break; } if ( IS_BREAK( token, '{' )) { push( node->setValue( JSONOBJECT, tag_name ) ); state = PAIR; break; } // Add a constant to current node container if ( node->getType() != JSONOBJECT && node->getType() != JSONARRAY) throw std::exception( "Parser expecting container JSON node" ); node->setValue( strip_quotes( token ), tag_name ); state = RVALUE_SEPARATOR; break; } case RVALUE_SEPARATOR: { JsonNode* node = m_nodeStack[m_stack_ptr-1]; if ( IS_BREAK( token, ',' ) ) { state = node->getType() == JSONARRAY ? RVALUE : PAIR; break; } if ( IS_BREAK( token, '}' ) && node->getType() == JSONOBJECT ) { pop(); break; } if ( IS_BREAK( token, ']' ) && node->getType() == JSONARRAY ) { if ( !node->validateArray( ) ) { CString error; error.Format( "Mixed object types in '%s'", node->getTagName() ); throw std::exception( (LPCSTR)error ); } pop(); break; } throw std::exception( "Parser expecting object or array seperator" ); } } } if ( stackSize() > 0 ) throw std::exception( "Unclosed JSON objects detected" ); }