/*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);
}
예제 #2
0
/**
 * 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();
}
예제 #3
0
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);

}
예제 #4
0
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;
}
예제 #5
0
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&#x2013;200b, U+202f)");
    } else if (u == "a0") {
        infoText = i18n("No-break space. &amp;nbsp; in HTML. See U+2009 and U+0020.");
    } else if (u == "ab" || u == "bb" || u == "2039" || u == "203a") {
        infoText = i18n("<p><strong>&laquo;</strong> (u+00ab, <code>&amp;lfquo;</code> in HTML) and <strong>&raquo;</strong> (u+00bb, <code>&amp;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>&lsaquo;</strong> and <strong>&rsaquo;</strong> (U+2039/203a, <code>&amp;lsaquo;/&amp;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 &amp;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&#x2013;1903), for relationships/connections (Zurich&#x2013;Dublin). In the German language it is also used (with spaces!) for showing thoughts: &ldquo;Es war &#x2013; wie immer in den Ferien &#x2013; 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&#x2014;like here&#x2014;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, &#x2423;): 230&#x2423;V, &#x2212;21&#x2423;&deg;C, 50&#x2423;lb, <em>but</em> 90&deg; (no space). In German for abbreviations (like: i.&#x202f;d.&#x202f;R. instead of i.&#xa0;d.&#xa0;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&#x2026; See <a href=\"http://en.wikipedia.org/wiki/Ellipsis\">Wikipedia:Ellipsis</a>");
    } else if (u == "2212") {
        infoText = i18n("Minus sign. For numbers: &#x2212;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;
}