/* */
/* */
/* */
-/* (C) 1998-2008 Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 1998-2010, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
{ "__Y__", TOK_Y, TT_C89 | TT_C99 | TT_CC65 },
{ "__asm__", TOK_ASM, TT_C89 | TT_C99 | TT_CC65 },
{ "__attribute__", TOK_ATTRIBUTE, TT_C89 | TT_C99 | TT_CC65 },
+ { "__cdecl__", TOK_CDECL, TT_C89 | TT_C99 | TT_CC65 },
{ "__far__", TOK_FAR, TT_C89 | TT_C99 | TT_CC65 },
{ "__fastcall__", TOK_FASTCALL, TT_C89 | TT_C99 | TT_CC65 },
{ "__inline__", TOK_INLINE, TT_C89 | TT_C99 | TT_CC65 },
{ "auto", TOK_AUTO, TT_C89 | TT_C99 | TT_CC65 },
{ "break", TOK_BREAK, TT_C89 | TT_C99 | TT_CC65 },
{ "case", TOK_CASE, TT_C89 | TT_C99 | TT_CC65 },
+ { "cdecl", TOK_CDECL, TT_CC65 },
{ "char", TOK_CHAR, TT_C89 | TT_C99 | TT_CC65 },
{ "const", TOK_CONST, TT_C89 | TT_C99 | TT_CC65 },
{ "continue", TOK_CONTINUE, TT_C89 | TT_C99 | TT_CC65 },
int TokIsFuncSpec (const Token* T)
/* Return true if the token is a function specifier */
{
- return (T->Tok == TOK_INLINE) || (T->Tok == TOK_FASTCALL) ||
- (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR);
+ return (T->Tok == TOK_INLINE) ||
+ (T->Tok == TOK_FASTCALL) || (T->Tok == TOK_CDECL) ||
+ (T->Tok == TOK_NEAR) || (T->Tok == TOK_FAR);
}
static void StringConst (void)
/* Parse a quoted string */
{
- NextTok.IVal = GetLiteralPoolOffs ();
+ /* String buffer */
+ StrBuf S = AUTO_STRBUF_INITIALIZER;
+
+ /* Assume next token is a string constant */
NextTok.Tok = TOK_SCONST;
- /* Be sure to concatenate strings */
- while (CurC == '\"') {
+ /* Concatenate strings. If at least one of the concenated strings is a wide
+ * character literal, the whole string is a wide char literal, otherwise
+ * it's a normal string literal.
+ */
+ while (1) {
- /* Skip the quote char */
- NextChar ();
+ /* Check if this is a normal or a wide char string */
+ if (CurC == 'L' && NextC == '\"') {
+ /* Wide character literal */
+ NextTok.Tok = TOK_WCSCONST;
+ NextChar ();
+ NextChar ();
+ } else if (CurC == '\"') {
+ /* Skip the quote char */
+ NextChar ();
+ } else {
+ /* No string */
+ break;
+ }
- while (CurC != '\"') {
- if (CurC == '\0') {
- Error ("Unexpected newline");
- break;
- }
- AddLiteralChar (ParseChar ());
- }
+ /* Read until end of string */
+ while (CurC != '\"') {
+ if (CurC == '\0') {
+ Error ("Unexpected newline");
+ break;
+ }
+ SB_AppendChar (&S, ParseChar ());
+ }
- /* Skip closing quote char if there was one */
+ /* Skip closing quote char if there was one */
NextChar ();
/* Skip white space, read new input */
}
/* Terminate the string */
- AddLiteralChar ('\0');
+ SB_AppendChar (&S, '\0');
+
+ /* Add the whole string to the literal pool */
+ NextTok.SVal = AddLiteralStr (&S);
+
+ /* Free the buffer */
+ SB_Done (&S);
}
return;
}
+ /* Check for wide character literals */
+ if (CurC == 'L' && NextC == '\"') {
+ StringConst ();
+ return;
+ }
+
+ /* Check for keywords and identifiers */
if (IsSym (token)) {
/* Check for a keyword */
if (token[0] == '_' && token[1] == '_') {
/* Special symbols */
if (strcmp (token+2, "FILE__") == 0) {
- NextTok.IVal = AddLiteral (GetCurrentFile());
+ NextTok.SVal = AddLiteral (GetCurrentFile());
NextTok.Tok = TOK_SCONST;
return;
} else if (strcmp (token+2, "LINE__") == 0) {
} else if (strcmp (token+2, "func__") == 0) {
/* __func__ is only defined in functions */
if (CurrentFunc) {
- NextTok.IVal = AddLiteral (F_GetFuncName (CurrentFunc));
+ NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
NextTok.Tok = TOK_SCONST;
return;
}
NextToken ();
return 1;
} else {
- Error (ErrorMsg);
+ Error ("%s", ErrorMsg);
return 0;
}
}