extern exprNode
exprNode_stringLiteral (/*@only@*/ cstring p_t, /*@only@*/ fileloc p_loc) /*@*/ ;
+extern /*@only@*/ exprNode
+ exprNode_wideStringLiteral (/*@only@*/ cstring p_t, /*@only@*/ fileloc p_loc) /*@*/ ;
+
/*
** No surrounding quotes.
*/
extern ctype ctype_makeNFParamsFunction (ctype p_base, /*@only@*/ uentryList p_p) /*@*/ ;
extern ctype ctype_makePointer (ctype p_c);
extern ctype ctype_makeRawFunction (ctype p_base, /*@only@*/ uentryList p_p);
+extern ctype ctype_makeWideString (void) /*@modifies internalState@*/ ;
+extern bool ctype_isWideString (ctype p_c) /*@*/ ;
extern ctype ctype_newBase (ctype p_c, ctype p_p) /*@*/ ;
extern ctype ctype_realType (ctype p_c) /*@*/ ;
static int ninput (void);
static char processChar (void);
static double processFloat (void);
-static /*@only@*/ exprNode processString (void);
+static /*@only@*/ exprNode processString (void) ;
+static /*@only@*/ exprNode processWideString (void) ;
static long processDec (void);
static long processHex (void);
static long processOctal (void);
"static" { setTokLength (6); RETURN_TOK (QSTATIC); }
\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
-L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
+L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processWideString ()); }
"out" { return (processSpec (QOUT)); }
"in" { return (processSpec (QIN)); }
"partial" { return (processSpec (QPARTIAL)); }
return (res);
}
+/*
+** process a wide character string L"...."
+*/
+
+static /*@only@*/ exprNode processWideString ()
+{
+ exprNode res;
+ fileloc loc;
+ char *nl = strchr (yytext, '\n');
+ cstring ns;
+
+ llassert (*yytext == 'L');
+ yytext++;
+
+ ns = cstring_fromCharsNew (yytext);
+
+ if (nl == NULL)
+ {
+ loc = fileloc_copy (g_currentloc);
+ addColumn (cstring_length (ns));
+ }
+ else
+ {
+ char *lastnl = nl;
+
+ loc = fileloc_copy (g_currentloc);
+
+ context_incLineno ();
+
+ while ((nl = strchr ((nl + 1), '\n')) != NULL)
+ {
+ context_incLineno ();
+ lastnl = nl;
+ }
+ }
+
+ res = exprNode_wideStringLiteral (ns, loc);
+ return (res);
+}
+
static
char processChar ()
{
}
}
+/*
+** wchar_t *
+*/
+
+ctype
+ctype_makeWideString ()
+{
+ static ctype res = ctype_unknown;
+
+ if (ctype_isUnknown (res))
+ {
+ ctype wchart;
+
+ if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
+ {
+ wchart = uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t")));
+ }
+ else
+ {
+ wchart = ctype_char;
+ }
+
+ res = ctype_makePointer (wchart);
+ }
+
+ return res;
+}
+
+bool
+ctype_isWideString (ctype c)
+{
+ if (ctype_isPointer (c))
+ {
+ ctype ct = ctype_baseArrayPtr (c);
+
+ if (usymtab_existsType (cstring_makeLiteralTemp ("wchar_t")))
+ {
+ return (ct == uentry_getAbstractType (usymtab_lookup (cstring_makeLiteralTemp ("wchar_t"))));
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
ctype
ctype_getReturnType (ctype c)
{
return (e); /* s released */
}
+/*@only@*/ exprNode
+exprNode_wideStringLiteral (/*@only@*/ cstring t, /*@only@*/ fileloc loc)
+{
+ exprNode res = exprNode_stringLiteral (t, loc);
+ res->typ = ctype_makeWideString ();
+
+ return res;
+}
+
/*@only@*/ exprNode
exprNode_stringLiteral (/*@only@*/ cstring t, /*@only@*/ fileloc loc)
{
}
else
{
- sizet = ctype_ulint;
+ sizet = ctype_ulint;
}
}
return sizet;
break;
case XPR_STRINGLITERAL:
- ret = message ("\"%s\"", exprData_getLiteral (data));
+ if (ctype_isWideString (e->typ))
+ {
+ ret = message ("L\"%s\"", exprData_getLiteral (data));
+ }
+ else
+ {
+ ret = message ("\"%s\"", exprData_getLiteral (data));
+ }
break;
case XPR_NUMLIT:
#!/bin/sh
-etags *.y Headers/* *.c *.l *.i || echo "Error creating TAGS file (ignoring)"
+etags *.y *.l *.c *.i Headers/* || echo "Error creating TAGS file (ignoring)"
postnotnull preds prefixes printflike rc refcounts release repexpose \
returned sharing slovaknames specclauses special stack staticarray strings \
structassign typequals ud ulstypes union unioninit unreachable unsignedcompare \
- unused ullint utypes void
+ unused ullint utypes void widestrings
UNITEXPECTS = $(addsuffix .expect, $(UNITTESTS))
INTEGTESTS = db1 db2 db3
void:
${SPLINTRN} void.c -expect 2
+###
+### 2001-12-30: Problems with wide character strings reported by Nelson Beebe
+###
+
+.PHONY: widestrings
+widestrings:
+ ${SPLINTRN} widestrings.c -expect 2
+
###
### New since 2.5q:
###
postnotnull preds prefixes printflike rc refcounts release repexpose \
returned sharing slovaknames specclauses special stack staticarray strings \
structassign typequals ud ulstypes union unioninit unreachable unsignedcompare \
- unused ullint utypes void
+ unused ullint utypes void widestrings
UNITEXPECTS = $(addsuffix .expect, $(UNITTESTS))
void:
${SPLINTRN} void.c -expect 2
+###
+### 2001-12-30: Problems with wide character strings reported by Nelson Beebe
+###
+
+.PHONY: widestrings
+widestrings:
+ ${SPLINTRN} widestrings.c -expect 2
+
###
### New since 2.5q:
###
--- /dev/null
+/* Provided by Nelson Beebe */
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+int main(void)
+{
+ (void)wprintf(L"English: Hello, world!\n");
+ (void)printf(L"English: Hello, world!\n"); /* error */
+ (void)wprintf("English: Hello, world!\n"); /* error */
+
+ (void)wprintf(L"Russian: Ð^×аÑ^ÀегиÑ^ÁÑ^ÂÑ^ÀиÑ^ÀÑ^ÃйÑ^ÂеÑ^ÁÑ^Ì Ñ^ÁейÑ^ÇаÑ^Á на Ð^ÔеÑ^ÁÑ^ÏÑ^ÂÑ^ÃÑ^Î Ð^ÜеждÑ^ÃнаÑ^ÀоднÑ^ÃÑ^Î Ð^ÚонÑ^ÄеÑ^ÀенÑ^ÆиÑ^Î...\n");
+ (void)wprintf(L"Greek: Σὲ γνÏ^ÉÏ^ÁίζÏ^É á¼^ÀÏ^Àὸ Ï^Äὴν κόÏ^Èη...\n");
+ (void)wprintf(L"Georgian: á^Ã^Òá^Ã^×á^îá^Ã^Ýá^Ã^Õá^Ã^× á^Ã^Ðá^îá^Ã^Úá^Ã^Ðá^Ã^Õá^Ã^Ô á^Ã^Òá^Ã^Ðá^Ã^Øá^Ã^Ðá^à á^Ã^Ýá^Ã^× á^à á^Ã^Ôá^Ã^Òá^Ã^Øá^áá^âá^à á^Ã^Ðá^êá^Ã^Øá^Ã^Ð Unicode-á^Ã^Øá^á á^Ã^Ûá^Ã^Ôá^Ã^Ðá^Ã^×á^Ã^Ô á^áá^Ã^Ðá^Ã^Ôá^à á^Ã^×á^Ã^Ðá^èá^Ã^Ýá^à á^Ã^Øá^áá^Ã^Ý\n");
+ return (EXIT_SUCCESS);
+}
+
--- /dev/null
+
+widestrings.c: (in function main)
+widestrings.c:9:16: Function printf expects arg 1 to be char * gets wchar_t *:
+ L"English: Hello, world!\n"
+widestrings.c:10:17: Function wprintf expects arg 1 to be wchar_t * gets char
+ *: "English: Hello, world!\n"
+
+Finished checking --- 2 code warnings, as expected