/*oopsThatWasTheWrongChar(c)char c;{printf("ungetting '%c'\n", c);xoopsThatWasTheWrongChar(c);}*/ #define isAlphabetic(c) (alphabeticCharacterTable[c]) #define isNumeric(c) (numericCharacterTable[c]) #define isAlphaNumeric(c) (alphaNumericCharacterTable[c]) int yylex(void) { int result; result = lexer(); if (yydebug) { printf("lexer returns "); printToken(result); printf(", value=%d (0x%x)\n", yylval, yylval); } return(result); } int lexer(void) { char c; if ((c = skipWhitespaceAndComments()) == EOF) return(lexLiteral(c)); else return((*lexDispatchTable[c])(c)); } void initializeLexDispatchTable(void) { int c; for (c = 0; c < LEX_DISPATCH_TABLE_SIZE; c++) { if (isAlphabetic(c) || c=='$') lexDispatchTable[c] = lexIdentifier; else if (isNumeric(c)) lexDispatchTable[c] = lexNumber; else if (isMacrossLiteralCharacter(c)) lexDispatchTable[c] = lexLiteral; else if (c == '\'') lexDispatchTable[c] = lexCharacterConstant; else if (c == '"') lexDispatchTable[c] = lexStringConstant; else lexDispatchTable[c] = lexOperator; } } bool isMacrossLiteralCharacter(char c) { return(c==':' || c==',' || c=='@' || c=='#' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='\n' || c==EOF); } void snarfAlphanumericString(char c, char *buffer) { char *bufferPtr; bufferPtr = buffer; do { if (bufferPtr < &buffer[MAX_NAME_SIZE]) *bufferPtr++ = c; c = getNextChar(); } while (c!=EOF && isAlphaNumeric(c)); *bufferPtr = '\0'; oopsThatWasTheWrongChar(c); } char nameBuffer[MAX_NAME_SIZE+1]; int lexIdentifier(char c) { int hashValue; snarfAlphanumericString(c, nameBuffer); hashValue = hashString(nameBuffer); if (yylval = lookupOpcode(nameBuffer, hashValue)) return(Opcode); else if (yylval = lookupKeyword(nameBuffer, hashValue)) return(yylval); else if ((yylval = lookupConditionCode(nameBuffer, hashValue)) != (int)NOT_FOUND_COND) return(ConditionCode); else if (yylval = lookupMacroName(nameBuffer, hashValue)) return(MacroName); else { yylval = (int) saveString(nameBuffer); return(Identifier); } } char numberBuffer[MAX_NAME_SIZE+1]; int lexNumber(char c) { int base; int start; snarfAlphanumericString(c, numberBuffer); if (numberBuffer[0] != '0') { base = 10; start = 0; } else if (numberBuffer[1]=='b' || numberBuffer[1]=='B') { base = 2; start = 2; } else if (numberBuffer[1]=='q' || numberBuffer[1]=='Q') { base = 4; start = 2; } else if (numberBuffer[1]=='x' || numberBuffer[1]=='X') { base = 16; start = 2; } else { base = 8; start = 1; } yylval = fancyAtoI(&numberBuffer[start], base); return(Number); } int fancyAtoI(char *buffer, int base) { int value; int digit; char c; value = 0; while (*buffer != '\0') { if ((digit = digitValue(c = *buffer++)) >= base) { error(DIGIT_OUT_OF_RADIX_ERROR, c, base); return(0); } value = value*base + digit; } return(value); } int digitValue(char c) { if (isNumeric(c)) return(c - '0'); else return(toLowerCase(c) - 'a' + 10); } int lexLiteral(char c) { static bool passedEnd = FALSE; yylval = 0; if (c == '\n') { return(EOL); } else if (c == EOF) { if (passedEnd) { return(0); } else { passedEnd = TRUE; return(ENDFILE); } } else { return(c); } } int lexCharacterConstant(void) { char c; yylval = getStringCharacter(input); if (getNextChar() != '\'') { error(UNCLOSED_CHARACTER_CONSTANT_ERROR); while ((c = getNextChar())!='\'' && c!='\n' && c!=EOF) ; } return(Number); } bool escaped; /* true if last string character read was an escape code. */ int getStringCharacter(FILE *input) { char c; char *numberPtr; int result; escaped = FALSE; c = getNextChar(); if (c == '\\') { escaped = TRUE; c = getNextChar(); if (c == '^') return(controlCharacter(getNextChar())); else if ('0'<=c && c<='7') { numberPtr = numberBuffer; while ('0'<=c && c<='7') { *numberPtr++ = c; c = getNextChar(); } *numberPtr = '\0'; oopsThatWasTheWrongChar(c); result = fancyAtoI(numberBuffer, 8); if (result > 0377) error(OCTAL_CHARACTER_TOO_BIG_ERROR, result); return (result % 0377); } else return(escapeCodes[c]); } else return(c); }
/** * When return pressed, we return the selected unicode character * if it was not a control character. */ void UnicodeDialog::slotReturnPressed() { QString text = trimmedUnicodeNumber(unicodeNumber->text()); if (!controlCharacter(text)) { emit charSelected(unicodeChar->text()); writeChoices(); } emit accept(); }
void UnicodeDialog::updateOverviewChars(uint unicode) { QString left = ""; QString right = ""; uint i; for (i = 1; i <= 4; i++) { if (unicode > i && !controlCharacter(unicode - i)) { left = ' ' + left; left = QChar(unicode - i) + left; } } for (i = 1; i <= 8; i++) { if (unicode + i <= MAX_UNICODE_V1 && !controlCharacter(unicode + i)) { right += QChar(unicode + i); right += ' '; } } leftChars->setText(left); rightChars->setText(right); }
bool UnicodeDialog::controlCharacter(QString text) { bool isControlCharacter = false; QString t = text.toLower(); switch (inputMethod) { case InputHex: if (t.isEmpty() || (t.length() == 1 && !(t == "9" || t == "a" || t == "d")) || (t.length() == 2 && t.at(0) == QChar('1'))) { isControlCharacter = true; } break; case InputDec: bool ok; isControlCharacter = controlCharacter(text.toUInt(&ok, 16)); break; } return isControlCharacter; }
QString UnicodeDialog::unicodeInfo(QString unicode) { QString infoText(i18n("<small>(no character selected)</small>")); if (unicode.length() == 0) return infoText; QString u = trimmedUnicodeNumber(unicode).toLower(); if (controlCharacter(u)) { infoText = i18n("Control character. Cannot be inserted/printed. See <a href=\"http://en.wikipedia.org/wiki/Control_character\">Wikipedia:Control_character</a>"); } else if (u == "a") { infoText = i18n("Line Feed (newline character, \\\\n)"); } else if (u == "20") { infoText = i18n("Standard space character. (Other space characters: U+00a0, U+2000–200b, U+202f)"); } else if (u == "a0") { infoText = i18n("No-break space. &nbsp; in HTML. See U+2009 and U+0020."); } else if (u == "ab" || u == "bb" || u == "2039" || u == "203a") { infoText = i18n("<p><strong>«</strong> (u+00ab, <code>&lfquo;</code> in HTML) and <strong>»</strong> (u+00bb, <code>&rfquo;</code> in HTML) are called Guillemets or angle quotes. Usage in different countries: France (with non-breaking Space 0x00a0), Switzerland, Germany, Finland and Sweden.</p><p><strong>‹</strong> and <strong>›</strong> (U+2039/203a, <code>&lsaquo;/&rsaquo;</code>) are their single quote equivalents.</p><p>See <a href=\"http://en.wikipedia.org/wiki/Guillemets\">Wikipedia:Guillemets</a></p>"); } else if (u == "2002") { infoText = i18n("En Space (width of an n)"); } else if (u == "2003") { infoText = i18n("Em Space (width of an m)"); } else if (u == "2004") { infoText = i18n("Three-Per-Em Space. Width: 1/3 of one <em>em</em>"); } else if (u == "2005") { infoText = i18n("Four-Per-Em Space. Width: 1/4 of one <em>em</em>"); } else if (u == "2006") { infoText = i18n("Six-Per-Em Space. Width: 1/6 of one <em>em</em>"); } else if (u == "2007") { infoText = i18n("Figure space (non-breaking). Width of a digit if digits have fixed width in this font."); } else if (u == "2008") { infoText = i18n("Punctuation Space. Width the same as between a punctuation character and the next character."); } else if (u == "2009") { infoText = i18n("Thin space, in HTML also &thinsp;. See U+202f and <a href=\"http://en.wikipedia.org/wiki/Space_(punctuation)\">Wikipedia:Space_(punctuation)</a>"); } else if (u == "200a") { infoText = i18n("Hair Space. Thinner than U+2009."); } else if (u == "2019") { infoText = i18n("Punctuation Apostrophe. Should be used instead of U+0027. See <a href=\"http://en.wikipedia.org/wiki/Apostrophe\">Wikipedia:Apostrophe</a>"); } else if (u == "2013") { infoText = i18n("<p>An en Dash (dash of the width of an n).</p><p>Usage examples: In English language for value ranges (1878–1903), for relationships/connections (Zurich–Dublin). In the German language it is also used (with spaces!) for showing thoughts: “Es war – wie immer in den Ferien – ein regnerischer Tag.</p> <p>See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a></p>"); } else if (u == "2014") { infoText = i18n("<p>An em Dash (dash of the width of an m).</p><p>Usage examples: In English language to mark—like here—thoughts. Traditionally without spaces. </p><p>See <a href=\"http://en.wikipedia.org/wiki/Dash\">Wikipedia:Dash</a></p>"); } else if (u == "202f") { infoText = i18n("<p>Narrow no-break space. Has the same width as U+2009.</p><p>Usage: For units (spaces are marked with U+2423, ␣): 230␣V, −21␣°C, 50␣lb, <em>but</em> 90° (no space). In German for abbreviations (like: i. d. R. instead of i. d. R. with U+00a0).</p><p>See <a href=\"http://de.wikipedia.org/wiki/Schmales_Leerzeichen\">Wikipedia:de:Schmales_Leerzeichen</a></p>"); } else if (u == "2026") { infoText = i18n("Ellipsis: If text has been left o… See <a href=\"http://en.wikipedia.org/wiki/Ellipsis\">Wikipedia:Ellipsis</a>"); } else if (u == "2212") { infoText = i18n("Minus sign. For numbers: −42"); } else if (u == "2423") { infoText = i18n("Open box; stands for a space."); } else if (u == "2669") { infoText = i18n("Quarter note (Am.) or crochet (Brit.). See <a href=\"http://en.wikipedia.org/wiki/Quarter_note\">Wikipedia:Quarter_note</a>"); } else if (u == "266a" || u == "266b") { infoText = i18n("Eighth note (Am.) or quaver (Brit.). Half as long as a quarter note (U+2669). See <a href=\"http://en.wikipedia.org/wiki/Eighth_note\">Wikipedia:Eighth_note</a>"); } else if (u == "266c") { infoText = i18n("Sixteenth note (Am.) or semiquaver (Brit.). Half as long as an eighth note (U+266a). See <a href=\"http://en.wikipedia.org/wiki/Sixteenth_note\">Wikipedia:Sixteenth_note</a>"); } else if (u == "1D162") { infoText = i18n("Thirty-second note (Am.) or demisemiquaver (Brit.). Half as long as a sixteenth note (U+266b). See <a href=\"http://en.wikipedia.org/wiki/Thirty-second_note\">Wikipedia:Thirty-second_note</a>"); } else { infoText = i18n("<small>No additional information available for this character.</small>"); } return infoText; }