/********************************************************************************************** * * ReadProcessingInstruction * * ProcessingInstruction = '<?' QualifiedName ( Whitespace (Character)* ) ? '?>' ; * *********************************************************************************************/ XMLScanner::TOKEN XMLScanner::ReadProcessingInstruction () { QualfiedName targer = ReadQualifiedName (); if (isWhitespace (current)) { while (ReadCharacter ()) { if (current == '?') { ReadCharacter (); if (current == '>') { ReadCharacter (); return TOKEN_PROCESSING_INSTRUCTION; } else { output.Append ('?'); output.Append (current); continue; } } else { output.Append (current); } } throw UnexpectedEndException (); } else { throw UnexpectedCharacterException (); } }
/********************************************************************************************** * * ReadReference * * Reference = EntityReference | CharacterReference ; * * CharacterReference = "&#" [0-9]+ ";" | "&#x" [0-9a-fA-F]+ ";" ; * * EntityReference = "<" | "&" | ">" | """ | "'" ; * *********************************************************************************************/ void XMLParser::ReadReference () { if (current == '&') ReadCharacter (); else throw InvalidStateException (); if (current == '#') { if (current == 'x') { /* hexadecimal encoded unicode character. */ while (ReadCharacter ()) { // TODO ... if (current == ';') break; } } else { /* decimal encoded unicode character. */ do { // TODO ... if (current == ';') break; } while (ReadCharacter ()); } } else { /* named entity */ do { // TODO ... if (current == ';') break; } while (ReadCharacter ()); } }
/****************************************************************************** * read float * checks for positive and negative float * checks for a valid range of numbers *****************************************************************************/ int ReadFloat(float *f) { int c; int minus = 0; float d = 0.0f; *f = 0.0f; if ((c = ReadCharacter()) == EOF) return 0; if (c == '-') minus = 1; else if (c != '+') UngetCharacter(c); c = ReadCharacter(); if ((c < '0' || c > '9') && c != '.') { UngetCharacter(c); return 0; } UngetCharacter(c); while((c = ReadCharacter()) != EOF) { if (c == '.') { if (d == 0.0f) { d = 1.0f; continue; } else { UngetCharacter(c); return 1; } } if (c >= '0' && c <= '9') { if (d == 0.0f) *f = *f * 10.0f + (float)(c - '0'); else *f += (float)(c - '0') / (d *= 10.0f); continue; } UngetCharacter(c); if (d != 1.0f) { if (minus) *f = -*f; return 1; } else return 0; } if (d != 1.0f) { if (minus) *f = -*f; return 1; } else return 0; }
/****************************************************************************** * read signed integer * used in the coaster definition file *****************************************************************************/ int ReadSignedInt(int *i) { int c, minus = 0; if ((c = ReadCharacter()) == EOF) { PrintError("Integer expected"); return 0; } switch(c) { case '-': minus = 1; break; case '+': break; default : UngetCharacter(c); } if (!ReadInteger(i)) { PrintError("Integer expected"); return 0; } if (minus) *i = -*i; return 1; }
/********************************************************************************************** * * ReadCDATASection * * CDATASection = '<![CDATA[' Character * ']]>' ; * *********************************************************************************************/ void XMLScanner::ReadCDATASection () { if (current == '[') { ReadCharacter (); if (current == 'C') { ReadCharacter (); if (current == 'D') { ReadCharacter (); if (current == 'A') { ReadCharacter (); if (current == 'T') { ReadCharacter (); if (current == 'A') { ReadCharacter (); if (current == '[') { /* CDATA section content */ while (ReadCharacter ()) { if (current == ']') { ReadCharacter (); if (current == ']') { ReadCharacter (); if (current == '>') { ReadCharacter (); return ; } else { output.Append (']'); output.Append (']'); output.Append (current); } } else { output.Append (']'); output.Append (current); } } else { output.Append (current); } } throw UnexpectedEndException (); } } } } } } } throw UnexpectedCharacterException (); }
/****************************************************************************** * skip comment * comment will start with '#' *****************************************************************************/ void SkipComment() { int c; SkipWhitespace(); if ((c = ReadCharacter()) == EOF) return; while(c == LF || c=='#') { if (c == '#') { c = ReadCharacter(); while(c != EOF && c != LF) c = ReadCharacter(); } SkipWhitespace(); c = ReadCharacter(); } UngetCharacter(c); }
/********************************************************************************************** * * ReadQualifiedName * * QualifiedName = Name ? ":" ? Name ; * * Name = NameStartCharacter ( NameCharacter )* ; * * NameStartCharacter = "_" | [A-Z] | [a-z] ; * * NameCharacter = NameStartCharacter | "-" | "." | [0-9] ; * *********************************************************************************************/ QualifiedName XMLParser::ReadQualifiedName () { static const int name_charachters [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; bool first = true; bool valid = true; std::string specifier; std::string name; do { if (valid && current == ':') { if (specifier == "") { specifier = output.toString (); output.Reset (); } else { valid = false; } } else if (current == '\x20' || current == '\x9' || current == '\xD' || current == '\xA') { Position end = position; if (!valid) throw InvalidNameException (); if (first ) throw UnexpectedTokenException (); return QualifiedName (specifier, name); } else if ('\0' <= current && current < '\x7f' && name_characters [(int) current] == 1) { if ((first && '9' < current) || !first) { first = false; output.AppendIgnoreCase (current); } else { valid = false; } } else { valid = false; continue; } } while (ReadCharacter ()); return UnexpectedEndException (); }
/****************************************************************************** * skip whitespace *****************************************************************************/ void SkipWhitespace() { int c; while((c = ReadCharacter()) != EOF) { if (c != ' ' && c != '\t') { UngetCharacter(c); return; } } }
// This puts "<!" into destinationForReadCharacters if it is not NULL, then // reads in characters from xmlStream until the next "]]>", placing // them all into destinationForReadCharacters if it is not NULL. It throws // an exception if it fails to read in "]]>". inline void RestrictedXmlParser::ReadCdata( std::ostream* destinationForReadCharacters ) { if( destinationForReadCharacters != NULL ) { (*destinationForReadCharacters) << "<!["; } while( ReadToNextHalt( ']', NULL, destinationForReadCharacters ) && ReadCharacter( destinationForReadCharacters ) && ( currentCharacter == ']' ) && ReadCharacter( destinationForReadCharacters ) ) { if( currentCharacter == '>' ) { return; } } throw std::runtime_error( "Failed to close <[...]]> structure!" ); }
// This puts characters from xmlStream into destinationWithoutHalt if it is // not NULL and destinationIncludingHalt if it is not NULL (if both are // NULL, the characters are discarded) until it reads in the first instance // of haltCharacter (which is put into destinationIncludingHalt but not // into destinationWithoutHalt). inline bool RestrictedXmlParser::ReadToNextHalt( char const haltCharacter, std::ostream* destinationWithoutHalt, std::ostream* destinationIncludingHalt ) { while( ReadCharacter( destinationIncludingHalt ) && ( currentCharacter != haltCharacter ) ) { if( destinationWithoutHalt != NULL ) { (*destinationWithoutHalt) << currentCharacter; } } return ( currentCharacter == haltCharacter ); }
/********************************************************************************************** * * ReadLiteral * * Literal = '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" ; * *********************************************************************************************/ XMLScanner::TOKEN XMLParser::ReadLiteral () { char quote = '\0'; if (current == '\"' || current == '\'') { quote = current; output.Reset (); } while (ReadCharacter ()) { if (current == quote) { ReadCharacter (); break; } else if (current == '<') { throw UnexpectedCharacterException (); } else if (current == '&') { ReadReference (); } else { output.Append (current); } } return Literal (output.toString ()); }
/****************************************************************************** * read a section SECTION * construct the section SECTION character by character *****************************************************************************/ int ReadSectionName(char *str, int length) { int c; int i = 0; str[i] = 0; if ((c = ReadCharacter()) == EOF) return 0; UngetCharacter(c); if (c < 'a' || c > 'z') return 0; while((c = ReadCharacter()) != EOF) { if (c >= 'a' && c <= 'z') { if (i < length - 1) str[i++] = c; else str[i] = 0; continue; } str[i] = 0; UngetCharacter(c); return 1; } str[i] = 0; return 1; }
/****************************************************************************** * rean an integer * validate the range of the integer *****************************************************************************/ int ReadInteger(int *i) { int c; *i = 0; if ((c = ReadCharacter()) == EOF) return 0; if (c < '0' || c > '9') { UngetCharacter(c); return 0; } UngetCharacter(c); while((c = ReadCharacter()) != EOF) { if (c >= '0' && c <= '9') { *i = *i * 10 + c - '0'; continue; } UngetCharacter(c); return 1; } return 1; }
// This puts characters from xmlStream into destinationWithoutHalt if it is // not NULL and destinationIncludingHalt if it is not NULL (if both are // NULL, the characters are discarded) until it reads in the first instance // of any of the characters in haltCharacters (which is put into // destinationIncludingHalt but not into destinationWithoutHalt). inline bool RestrictedXmlParser::ReadToNextHalt( std::string const& haltCharacters, std::ostream* destinationWithoutHalt, std::ostream* destinationIncludingHalt ) { while( ReadCharacter( destinationIncludingHalt ) && !(ParsingUtilities::CharacterIsInString( currentCharacter, haltCharacters )) ) { if( destinationWithoutHalt != NULL ) { (*destinationWithoutHalt) << currentCharacter; } } return ParsingUtilities::CharacterIsInString( currentCharacter, haltCharacters ); }
/****************************************************************************** * read separator * separator can be ';' or ',' *****************************************************************************/ int ReadSeparator() { int c; SkipWhitespace(); c = ReadCharacter(); if (c == ';' || c==',') { SkipWhitespace(); return 1; } else { UngetCharacter(c); PrintError("Separator expected"); return 0; } }
// This reads characters from xmlStream into currentChar until the first // non-whitespace character is read in, returning true unless the stream // ended without any non-whitespace character being read in. If // destinationForReadCharacters is not NULL, all read characters (including // the first non-whitespace character) are put into it. inline bool RestrictedXmlParser::SkipWhitespace( std::ostream* destinationForReadCharacters ) { // If the name is followed by whitespace, we keep going to the first // non-whitespace character, discarding all the whitespace characters // along the way. while( ParsingUtilities::CharacterIsInString( currentCharacter, AllowedWhitespaceChars() ) ) { // If we run out of characters from the stream before finding a // non-whitespace character, we return false. Evaluating the // conditional does work. if( !(ReadCharacter( destinationForReadCharacters )) ) { return false; } } return true; }
// This puts "<?" into destinationForReadCharacters if it is not NULL, then // reads in characters from xmlStream until the next "?>", placing // them all into destinationForReadCharacters if it is not NULL. It throws // an exception if it fails to read in "?>". inline void RestrictedXmlParser::CloseQuestionMark( std::ostream* destinationForReadCharacters ) { if( destinationForReadCharacters != NULL ) { (*destinationForReadCharacters) << "<?"; } while( ReadToNextHalt( '?', NULL, destinationForReadCharacters ) && ReadCharacter( destinationForReadCharacters ) ) { if( currentCharacter == '>' ) { return; } } throw std::runtime_error( "Failed to close processing instruction!" ); }
// This returns true if the attribute was correctly formed, assuming that // the first character of the attribute name is already in nameStream, // putting the rest of the name into nameStream and the value into // valueStream (without the quote marks), and all read characters into // tagRecord if it is not NULL. bool TryToReadValidAttribute( std::ostream& nameStream, std::ostream& valueStream, std::ostream* tagRecord ) { return ( ReadToNextHalt( ( AllowedWhitespaceChars() + "=" ), &nameStream, tagRecord ) && SkipWhitespace( tagRecord ) && ( currentCharacter == '=' ) && ReadCharacter( tagRecord ) && SkipWhitespace( tagRecord ) && ( ( currentCharacter == '\'' ) || ( currentCharacter == '\"' ) ) && ReadToNextHalt( currentCharacter, &valueStream, tagRecord ) ); }
bool StyleSheetParser::FindToken(String& buffer, const char* tokens, bool remove_token) { buffer.Clear(); char character; while (ReadCharacter(character)) { if (strchr(tokens, character) != NULL) { if (remove_token) parse_buffer_pos++; return true; } else { buffer.Append(character); parse_buffer_pos++; } } return false; }
// This reads xmlStream until the end of the start or empty-element tag is // reached, parsing attributes along the way into attributeDestination, // throwing an exception if it does not reach the end of the tag without // the stream ending or finding malformed XML. All the characters of the // tag get put into tagRecord if it is not NULL. inline void RestrictedXmlParser::CloseStartTag( AttributeMap* attributeDestination, std::ostream* tagRecord ) { if( !(SkipWhitespace( tagRecord )) ) { throw std::runtime_error( "Could not find end of start tag!" ); } // Now currentChar is the end of the start tag ('>'), or the first // character of the end of an empty element tag ('/' in "/>") (or the // tag is malformed with a '/' out of place), or is the first character // of an attribute name. if( TagIsStillOpen( tagRecord ) ) { ParseAttribute( attributeDestination, tagRecord ); if( !(ReadCharacter( tagRecord )) ) { throw std::runtime_error( "Could not find end of start tag!" ); } CloseStartTag( attributeDestination, tagRecord ); } }
// This returns false if currentCharacter is '>' or if it is '/' and the // next character is '>', first setting currentElementIsEmpty // appropriately. It throws an exception if currentCharacter is '/' and is // not followed immediately by '>'. It returns true otherwise. inline bool RestrictedXmlParser::TagIsStillOpen( std::ostream* tagRecord ) { if( currentCharacter == '>' ) { currentElementIsEmpty = false; return false; } else if( currentCharacter == '/' ) { if( ReadCharacter( tagRecord ) && ( currentCharacter == '>' ) ) { currentElementIsEmpty = true; return false; } else { throw std::runtime_error( "Attribute name cannot begin with \'/\'" ); } } return true; }
/********************************************************************************************** * * ReadComment * * Comment = '<!--' ((Character - '-') | ('-' (Character - '-')))* '-->' ; * *********************************************************************************************/ void XMLScanner::ReadComment () { if (current == '-') { ReadCharacter (); if (current == '-') { ReadCharacter (); while (ReadCharacter ()) { if (current == '-') { ReadCharacter (); if (current == '-') { ReadCharacter (); if (current == '>') { ReadCharacter (); return ; } else { // TODO : Warning : Illegal sequence '--' inside comment } } } } throw UnexpectedEndException (); } } throw UnexpectedCharacterException (); }
/* // GetTextLine // // Gets a line of text from the source file without # directive // processing, or processing past a EOL. // // Returns 1 on success, 0 on error */ static int GetTextLine( SOURCEFILE *ps, char *Dst, int MaxLen, int *pLength, int *pEOF ) { int c; int idx; int commentFlag,quoteFlag; /* Remove leading white space */ do { c = ReadCharacter( ps ); } while( c==' ' || c==0x9 || c==0xa ); /* // Process line watching for comments and quotes */ idx=0; commentFlag=0; quoteFlag=0; for(;;) { /* Process quotes and comments */ if( c=='"' ) quoteFlag^=1; if( quoteFlag ) commentFlag=0; if( (commentFlag && c=='/') || (!quoteFlag && c==';') ) { if( c=='/' && idx>0 ) idx--; while( c!=0 && c!=-1 && c!=0xa ) c = ReadCharacter( ps ); break; } if( c=='/' ) commentFlag=1; else commentFlag=0; /* If this character terminated the line, break now */ if( c==0 || c==-1 || c==0xa ) break; /* We didn't consume this charater */ if( idx<(MaxLen-1) ) Dst[idx++]=c; else { Report(ps,REP_ERROR,"Line too long"); return(0); } c = ReadCharacter( ps ); } /* Back off white space */ while( idx>0 && (Dst[idx-1]==' ' || Dst[idx-1]==0x9) ) idx--; /* Null terminate the output */ Dst[idx] = 0; if( quoteFlag ) Report(ps,REP_ERROR,"Open Quotes"); if( pLength ) *pLength = idx; if( pEOF ) { if( idx || c!=-1 ) *pEOF=0; else *pEOF=1; } return(1); }
bool StyleSheetParser::ReadProperties(PropertyDictionary& properties) { int rule_line_number = line_number; String name; String value; enum ParseState { NAME, VALUE, QUOTE }; ParseState state = NAME; char character; char previous_character = 0; while (ReadCharacter(character)) { parse_buffer_pos++; switch (state) { case NAME: { if (character == ';') { name = StringUtilities::StripWhitespace(name); if (!name.Empty()) { Log::Message(Log::LT_WARNING, "Found name with no value parsing property declaration '%s' at %s:%d", name.CString(), stream_file_name.CString(), line_number); name.Clear(); } } else if (character == '}') { name = StringUtilities::StripWhitespace(name); if (!StringUtilities::StripWhitespace(name).Empty()) Log::Message(Log::LT_WARNING, "End of rule encountered while parsing property declaration '%s' at %s:%d", name.CString(), stream_file_name.CString(), line_number); return true; } else if (character == ':') { name = StringUtilities::StripWhitespace(name); state = VALUE; } else name.Append(character); } break; case VALUE: { if (character == ';') { value = StringUtilities::StripWhitespace(value); if (!StyleSheetSpecification::ParsePropertyDeclaration(properties, name, value, stream_file_name, rule_line_number)) Log::Message(Log::LT_WARNING, "Syntax error parsing property declaration '%s: %s;' in %s: %d.", name.CString(), value.CString(), stream_file_name.CString(), line_number); name.Clear(); value.Clear(); state = NAME; } else if (character == '}') { Log::Message(Log::LT_WARNING, "End of rule encountered while parsing property declaration '%s: %s;' in %s: %d.", name.CString(), value.CString(), stream_file_name.CString(), line_number); return true; } else { value.Append(character); if (character == '"') state = QUOTE; } } break; case QUOTE: { value.Append(character); if (character == '"' && previous_character != '/') state = VALUE; } break; } previous_character = character; } if (!name.Empty() || !value.Empty()) Log::Message(Log::LT_WARNING, "Invalid property declaration at %s:%d", stream_file_name.CString(), line_number); return true; }
/********************************************************************************************** * * Whitespaces * * Whitespaces = (#x20 | #x9 | #xD | #xA)+ ; * *********************************************************************************************/ void XMLParser::SkipWhitespaces () { do { if (current != '\x20' && current != '\x9' && current != '\xD' && current != '\xA') break; } while (ReadCharacter ()); }
/********************************************************************************************** * NextToken *********************************************************************************************/ XMLScanner::TOKEN XMLScanner::NextToken () { if (state == STATE_STREAM_END) return TOKEN_STREAM_END; do { switch (state) { /* Content */ case STATE_CONTENT: switch (current) { /* Element tag */ case '<' : state = STATE_ELEMENT_TAG; if (! output.isEmpty ()) { // TODO : check for whitespace only elements ... return TOKEN_CHARACTER_DATA; } break; case '&' : ReadReference (); break; case ']' : /* checks for invalid CDATA section end */ ReadCharacter (); if (current == ']') { ReadCharacter (); if (current == '>') { ReadCharacter (); throw IllegalCharacterException (); } else { output.Append (']'); output.Append (']'); output.Append (current); } } else { output.Append (']'); output.Append (current); } break; default : output.Append (current); break; } break; /* Element Tag */ case STATE_ELEMENT_START_OPENING: if (current == '!') { ReadCharacter (); state = STATE_SPECIAL_ELEMENT; } else if (current == '?') { ReadCharacter (); state = STATE_CONTENT; return ReadProcessingInstruction (); } else if (current == '/') { ReadCharacter (); state = STATE_ELEMENT_END_NAME; return TOKEN_ELEMENT_END_TAG; } else if (isNameFirst (current)) { state = STATE_ELEMENT_START_NAME; return TOKEN_ELEMENT_START_OPENING; } else { throw UnexpectedCharacterException (previous); } break; /* Special elements (comments and CDATA sections etc ...) */ /* '<!' ... */ case STATE_SPECIAL_ELEMENT: if (current == '-') { ReadComment (); } else if (current == '[') { ReadCDATASection (); } else { throw UnsupportedFeatureException (position); } state = STATE_CONTENT; break; /* Element start name target */ /* '<' ... */ case STATE_ELEMENT_START_NAME: if (isNameFirst (current)) { state = STATE_ELEMENT_ATTRIBUTES_START; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; /* Element start name target */ /* '</' ... */ case STATE_ELEMENT_END_NAME: if (isNameFirst (current)) { state = STATE_ELEMENT_END_TAG; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; /* Attributes */ case STATE_ATTRIBUTES_START: if (isWhitespace (current)) { state = STATE_ATTRIBUTES; } else if (current == '/') { state = STATE_ELEMENT_END_CLOSING; } else if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_START_CLOSING; } else { throw UnexpectedCharacterException (previous); } break; /* '<' QualifiedName ... */ case STATE_ATTRIBUTES : if (isWhitespace (current)) { break; } else if (isNameFirst (current)) { state = STATE_ATTRIBUTE_EQUAL; return ReadQualifiedName (); } else { throw UnexpectedCharacterException (previous); } break; case STATE_ELEMENT_END_CLOSING: if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_END_CLOSING; } else { throw UnexpectedCharacterException (previous); } break; case STATE_ATTRIBUTE_EQUAL: if (current == '\'' || current == '\"') { state = STATE_ATTRIBUTES_START; return ReadLiteral (); } break; case STATE_ELEMENT_END_TAG: if (current == '>') { state = STATE_CONTENT; return TOKEN_ELEMENT_END_TAG_CLOSING; } break; } } while (ReadCharacter ()); /* Stream end */ return TOKEN_STREAM_END; }
void Mouse(int btn, int state, int x, int y) { if (stat.turnedON) { if (btn == GLUT_LEFT_BUTTON && (x > 15 && x<70) && (y>455 && y<505) && state == GLUT_DOWN) { ReadCharacter('0'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>90 && x<145) && (y>455 && y<505) && state == GLUT_DOWN) { if (stat.decimalOperation == 0) { if (stat.currentOperand == 0) { stat.operandLength++; if (stat.operandLength > 10) { return; } operand1Str[opr1Index++] = '.'; stat.decimalOperation = 1; } else if (stat.currentOperand == 1) { stat.operandLength++; if (stat.operandLength > 10) { return; } operand2Str[opr2Index++] = '.'; stat.decimalOperation = 1; } totalExp[expIndex++] = '.'; } else if (stat.decimalOperation == 1) return; glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x > 15 && x<70) && (y>380 && y<430) && state == GLUT_DOWN) { ReadCharacter('1'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>90 && x<145) && (y>380 && y<430) && state == GLUT_DOWN) { ReadCharacter('2'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>165 && x<220) && (y>380 && y<430) && state == GLUT_DOWN) { ReadCharacter('3'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>15 && x<70) && (y>305 && y<355) && state == GLUT_DOWN) { ReadCharacter('4'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>90 && x<145) && (y>305 && y<355) && state == GLUT_DOWN) { ReadCharacter('5'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>165 && x<220) && (y>305 && y<355) && state == GLUT_DOWN) { ReadCharacter('6'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>15 && x<70) && (y>230 && y<280) && state == GLUT_DOWN) { ReadCharacter('7'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>90 && x<145) && (y>230 && y<280) && state == GLUT_DOWN) { ReadCharacter('8'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>165 && x<220) && (y>230 && y<280) && state == GLUT_DOWN) { ReadCharacter('9'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>240 && x<295) && (y>455 && y<505) && state == GLUT_DOWN) { ReadOperator('+'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>240 && x<295) && (y>380 && y<430) && state == GLUT_DOWN) { ReadOperator('-'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>240 && x<295) && (y>305 && y<355) && state == GLUT_DOWN) { ReadOperator('*'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>240 && x<295) && (y>230 && y<280) && state == GLUT_DOWN) { ReadOperator('/'); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x > 165 && x<295) && (y>155 && y<205) && state == GLUT_DOWN) { //AC is clicked ClearEverything(); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>165 && x<220) && (y>455 && y < 505) && state == GLUT_DOWN) { // = is clicked CalculateResult(); glutPostRedisplay(); } else if (btn == GLUT_LEFT_BUTTON && (x>90 && x<145) && (y>155 && y<205) && state == GLUT_DOWN) { exit(0); } } else if (btn == GLUT_LEFT_BUTTON && (x>15 && x<70) && (y>155 && y<205) && state == GLUT_DOWN) { stat.turnedON = 1; glutPostRedisplay(); } }
void Keys(unsigned char key, int x, int y) { if (stat.turnedON) { switch (key) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ReadCharacter(key); break; case '.': if (stat.decimalOperation == 0) { if (stat.currentOperand == 0) { stat.operandLength++; if (stat.operandLength > 10) { return; } operand1Str[opr1Index++] = '.'; stat.decimalOperation = 1; } else if (stat.currentOperand == 1) { stat.operandLength++; if (stat.operandLength > 10) { return; } operand2Str[opr2Index++] = '.'; stat.decimalOperation = 1; } totalExp[expIndex++] = '.'; } else if (stat.decimalOperation == 1) return; break; case '+': ReadOperator('+'); break; case '-': ReadOperator('-'); break; case '*': ReadOperator('*'); break; case '/': ReadOperator('/'); break; case '=': case 13: //ASCII value of return key CalculateResult(); break; case 27: //ASCII value of Escape key ClearEverything(); break; default: printf("Invalid Character Chosen\n"); return; break; } glutPostRedisplay(); } else return; }