On Tuesday November 6 2007 17:14, Rémi G. wrote: > Thank you for your answer ;) > > As you suggest to me, I report the bug in bugzilla here : > http://bugs.winehq.org/show_bug.cgi?id=10283 > > But before doing a regression test, I would like to try an old version > of Wine to be sure Outcast works with it. > > In order to install Wine 0.9, I try these commands (on ubuntu 7.10) : > > sudo apt-get install git ccache build-dep wine wine-dev > git clone git://source.winehq.org/git/wine.git wine-git > cd wine-git > > Then, to tell git I would like to install wine 0.9, I type this : > > git branch oldstuff wine-0.9 > git checkout oldstuff This is wrong. You need to execute: git-reset wine-0.9 git checkout -f If necessary use this command to destroy your unintentional changes in current source: git checkout -f > Then, I try to compile Wine 0.9.2 with the following lines : > > CC="ccache gcc" ./configure && make clean && make > ... > [compilation errors] > ... > So my questions are : > What could I do to avoid this? Short answer. To compile wine-0.9 execute the following from the root of the source directory (I assume that you have .diff files that are attached to this message there): git-reset wine-0.9 git checkout -f patch -p1 < 0.9-gdi-freetype-old.diff patch -p1 < 0.9-kernel-time.diff patch -p1 < 0.9-wrc-parser.diff ./configure && make depend && make At least on Debian Etch system I was able to compile wine-0.9 successfully. Try this first. Then install your game to clean WINE prefix, cd to its directory and run it. For example (I assume that you have your git repository with WINE source at /usr/src/wine-git/ ): export WINEPREFIX=~/.wine-tmp rm -rf ~/.wine-tmp/ /usr/src/wine-git/tools/wineprefixcreate cd /mnt/hdc/ /usr/src/wine-git/wine setup.exe cd ~/..wine-tmp/drive_c/Games/My_Game/ /usr/src/wine-git/wine game.exe If your game works with 0.9 then you can proceed with regression testing. Please note that you *may* need to repeat above commands so to start with clean WINE prefix directory each time during regression testing; in practice everything should work with the same WINE prefix directory in most cases so you most likely don't need to reinstall your game from scratch each time. Long answer: you may wonder how I did find necessary changes to compile wine-0.9 successfully on moder system? Below you can find detailed instructions on real world example. I recommend you to read these instructions carefully - this will help you to do the regression test between modern WINE and wine-0.9 without troubles. * * * REVERSE REGRESSION TESTING HOWTO Sometimes old programs doesn't compile on new systems. But what if you know that old program worked better than new one for particular task? This called regression. Fastest way to find the cause of regression is to do regression testing. But usual regression testing procedure will fail to work: you cannot compile and test old versions! Let's examine real-world example. We want to run regression test between wine-0.9 and wine-0.9.40. But we cannot compile wine-0.9 on modern system! That means we cannot do the regression test? No, we can! But we need to do reverse regression test first... What "reverse" does mean? It means that if program compiles (in this example WINE) - this is "bad" revision. If it doesn't compile - this is "good" revision. * * * 0) Lets start. This is preliminary optional step. System used by the author of this howto was Debain Etch at the time of writing. We know that 0.9 doesn't compile on it. Let's try to compile other old revisions - maybe they will work? For example: git-reset wine-0.9.10 git checkout -f Then try to compile: ./configure && make depend && make Great! Now we know that wine-0.9.10 can be successfully compiled on Debian Etch. So we now know that wine-0.9.10 compiles fine on Debian Etch but 0.9 doesn't. Good starting point. Actually this is optional step - we can use 0.9-0.9.40 history window as starting point too. But 0.9-0.9.10 is better because it allow us to find out the cause faster. * * * 1) First, we need to start git-bisect: git-bisect start Then we need to tell GIT that our current revision (0.9.10) is good: git-bisect bad wine-0.9.10 This is correct: we are using "git-bisect bad" for good revision because we are going to do reverse regression test. And we need to choose bad revision that we cannot compile: git-bisect good wine-0.9 * * * 2) Now try to compile: ./configure && make depend && make If at the end of compilation you see: Wine build complete. Then current revision is good and you need to execute (remember, we are doing reverse regression test so "bad" means good revision): make distclean; git-checkout -f && git-bisect bad Clean up commands "make distclean" and "git-checkout -f" are for sanity (without them sometimes strange things may happen). If you don't see "Wine build complete." then compilation was stopped because of errors. In this case you need to execute: make distclean; git-checkout -f && git-bisect good "good" means bad revision. Make sure that you are doing reverse regression test against one particular error at a time and ignore all other errors when choosing between "good" and "bad". Advice: when 2-20 revisions left it is easy to find that patch by using qgit program and SHA1 id of current revision. This may save you some time especially if you have slow computer. * * * 3) Go to step 2. Stop when you find lack of what patch is causing compile "current" errors and execute: git-bisect reset * * * When trying to compile 0.9 first compilation error will be: gcc -m32 -c -I. -I. -I../../include -I../../include -DINCLUDEDIR="\"/usr/local/include/wine\"" -Wall -pipe -fno-strict-aliasing -gstabs+ -Wdeclaration-after-statement -Wpointer-arith -O3 -mfpmath=387,sse -ffast-math -mmmx -msse -msse2 -msse3 -m3dnow -maccumulate-outgoing-args -minline-all-stringops -Wdisabled-optimization -Wall -o lex.yy.o lex.yy.c lex.yy.c:2610: error: expected ';', ',' or ')' before numeric constant make.bin[2]: *** [lex.yy.o] Error 1 make.bin[2]: *** Waiting for unfinished jobs.... Make sure to do reverse regression test against this error only and ignore all other possible errors (if any). If you followed above steps carefully you will find that this error is caused by lack of 69dcbaaf93a65820a28fe2485b6d15a90f423899 commit in 0.9. Using qgit it is easy to find this patch. Select it in the tree, press Ctrl+P to open separate window with patch content. Now press right mouse button and choose "Select All". Then press Ctrl+C to copy whole patch. With your favorite editor create file "0.9-wrc-parser.diff" and paste the patch into. Now go to step 0 and search for a cause of next problem. When you face with "expected ';', ',' or ')' before numeric constant" error again at step 2 execute: patch -p1 < 0.9-wrc-parser.diff make depend && make When you stop at next error or successfully complete compilation - follow corresponding instructions in step 2. I think you get the idea. Each iteration of reverse regression testing will give us yet another patch. At the end we have all patches necessary to compile ancient wine-0.9 on modern system. * * * There is some important notes. First, sometimes patches won't apply to old revisions. Usually this isn't big trouble. For example, I have incorporated following patches to a file "0.9-gdi-freetype.diff": 603d21cbc4fc8b915248cd3a6f90b02f721980c4 0458a5e38dcf7d03a0eedd1e63922c1eb4e37cb9 But we cannot apply this fix to 0.9 directly. How to solve this problem? Execute this to choose wine-0.9 revision first: git-reset wine-0.9 git checkout -f Then try to apply the patch: patch -p1 < 0.9-gdi-freetype.diff Fortunately, just 1 out of 6 hunks failed to apply. We now have freetype.c.rej. Open it. As you can see it is very easy to fix this by editing freetype.c accordingly. Save the result to "0.9-gdi-freetype-old.diff" by executing: git-diff > 0.9-gdi-freetype-old.diff * * * There is an alternative to reverse regression test: fix the code yourself. This may be even faster if you know exactly what's wrong, how to fix it and there is few lines to change. For example, this is exactly how I created patch "0.9-kernel-time.diff": by fixing the code manually (I just replaced old function TIME_ClockTimeToFileTime with newer version of it taken from recent time.c). However, if you don't know exact cause or there to many lines to change reverse regression testing is best and fastest option. * * * At the end of the whole process you should have four patches: "0.9-kernel-time.diff", "0.9-gdi-freetype.diff", "0.9-gdi-freetype-old.diff" and "0.9-wrc-parser.diff". As you remember, our original goal was to do regression test between 0.9.40 and 0.9. So what now? Just proceed with regression test as usual. When you get compile error just apply corresponding patch and try to compile again. It may be confusing to have multiple versions of patch to fix similar error ("0.9-gdi-freetype.diff" and "0.9-gdi-freetype-old.diff" in this case). But actually it isn't too hard to guess what you need. For example if you about 0.9.5 revision you need 0.9-gdi-freetype.diff", if you about 0.9 revision you need "0.9-gdi-freetype-old.diff". Of course it is possible to apply wrong version of patch by mistake. Just execute: git-checkout -f And then apply right patch(es). * * * Using above instructions it is possible to do regression test between recent version of WINE and ancient one. Everything should be very straightforward even for non-programmer. Just basic knowledge is needed. If you havn't basic knowledge just read man pages for commands you don't know. END OF REVERSE REGRESSION TESTING HOWTO This howto isn't stricly step-by-step guide and isn't perfectly written but I havn't time for writing better version. However, I think that above howto is understandable enough to be useful. If not (or you find any errors/typos) then tell me about this. > Should I remove wine first (binary .deb provided with ubuntu)? Simplest way to run WINE during regression testing is to just execute "./wine program.exe" from the root of the source directory where you are doing the regression test. In case if you stuck completely (or havn't enough personal/CPU time), you can consider to send your game via postal mail to someone who can try to do the regression testing for you. For example, I can try. When I complete regression testing I can return the game back to you if you want. It is obvious that you really should try to do the regression testing yourself first because it is a fastest way to find the cause of the bug. I will try to help you remotely if possible, just ask for help in case of any problem. Thank you for using WINE.
603d21cbc4fc8b915248cd3a6f90b02f721980c4 configure | 2 ++ configure.ac | 1 + dlls/gdi/freetype.c | 3 +++ include/config.h.in | 3 +++ 4 files changed, 9 insertions(+), 0 deletions(-) diff --git a/configure b/configure index c95d335..31005df 100755 --- a/configure +++ b/configure @@ -10042,6 +10042,7 @@ fi + for ac_header in ft2build.h \ freetype/freetype.h \ freetype/ftglyph.h \ @@ -10051,6 +10052,7 @@ for ac_header in ft2build.h \ freetype/ttnameid.h \ freetype/ftoutln.h \ freetype/ftwinfnt.h \ + freetype/ftmodapi.h \ freetype/internal/sfnt.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/configure.ac b/configure.ac index ca5eb8a..761f528 100644 --- a/configure.ac +++ b/configure.ac @@ -596,6 +596,7 @@ else freetype/ttnameid.h \ freetype/ftoutln.h \ freetype/ftwinfnt.h \ + freetype/ftmodapi.h \ freetype/internal/sfnt.h,,, [#if HAVE_FT2BUILD_H #include <ft2build.h> diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 3023ab3..314afd8 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -82,6 +82,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); #ifdef HAVE_FREETYPE_FTWINFNT_H #include <freetype/ftwinfnt.h> #endif +#ifdef HAVE_FREETYPE_FTMODAPI_H +#include <freetype/ftmodapi.h> +#endif #ifndef SONAME_LIBFREETYPE #define SONAME_LIBFREETYPE "libfreetype.so" diff --git a/include/config.h.in b/include/config.h.in index 51ecdc5..421a5eb 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -101,6 +101,9 @@ /* Define to 1 if you have the <freetype/ftglyph.h> header file. */ #undef HAVE_FREETYPE_FTGLYPH_H +/* Define to 1 if you have the <freetype/ftmodapi.h> header file. */ +#undef HAVE_FREETYPE_FTMODAPI_H + /* Define to 1 if you have the <freetype/ftnames.h> header file. */ #undef HAVE_FREETYPE_FTNAMES_H diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 41a1ded..1833355 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -87,6 +87,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); #define SONAME_LIBFREETYPE "libfreetype.so" #endif +#ifndef FT_MODULE_DRIVER_HAS_HINTER +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 +#endif + static FT_Library library = 0; typedef struct { @@ -119,6 +123,7 @@ MAKE_FUNCPTR(FT_Vector_Transform); static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*); static FT_Error (*pFT_Load_Sfnt_Table)(FT_Face,FT_ULong,FT_Long,FT_Byte*,FT_ULong*); static FT_ULong (*pFT_Get_First_Char)(FT_Face,FT_UInt*); +static FT_Error (*pFT_Module_Get_Flags)(FT_Module,FT_ULong*); #ifdef HAVE_FREETYPE_FTWINFNT_H MAKE_FUNCPTR(FT_Get_WinFNT_Header); #endif @@ -1496,6 +1501,7 @@ BOOL WineEngInit(void) pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0); pFT_Load_Sfnt_Table = wine_dlsym(ft_handle, "FT_Load_Sfnt_Table", NULL, 0); pFT_Get_First_Char = wine_dlsym(ft_handle, "FT_Get_First_Char", NULL, 0); + pFT_Module_Get_Flags = wine_dlsym(ft_handle, "FT_Module_Get_Flags", NULL, 0); #ifdef HAVE_FREETYPE_FTWINFNT_H pFT_Get_WinFNT_Header = wine_dlsym(ft_handle, "FT_Get_WinFNT_Header", NULL, 0); #endif @@ -3677,6 +3683,7 @@ DWORD WineEngGetFontData(GdiFont font, D /* If the FT_Load_Sfnt_Table function is there we'll use it */ if(pFT_Load_Sfnt_Table) err = pFT_Load_Sfnt_Table(ft_face, table, offset, buf, &len); +#ifdef HAVE_FREETYPE_INTERNAL_SFNT_H else { /* Do it the hard way */ TT_Face tt_face = (TT_Face) ft_face; SFNT_Interface *sfnt; @@ -3692,6 +3699,18 @@ DWORD WineEngGetFontData(GdiFont font, D } err = sfnt->load_any(tt_face, table, offset, buf, &len); } +#else + else { + static int msg; + if(!msg) { + MESSAGE("This version of Wine was compiled with freetype headers later than 2.2.0\n" + "but is being run with a freetype library without the FT_Load_Sfnt_Table function.\n" + "Please upgrade your freetype library.\n"); + msg++; + } + err = FT_Err_Unimplemented_Feature; + } +#endif if(err) { TRACE("Can't find table %08lx.\n", table); return GDI_ERROR; @@ -3757,8 +3776,21 @@ BOOL WINAPI FontIsLinked(HDC hdc) static BOOL is_hinting_enabled(void) { FT_Module mod = pFT_Get_Module(library, "truetype"); + + /* Use the >= 2.2.0 function if available */ + if(pFT_Module_Get_Flags) + { + FT_ULong flags; + pFT_Module_Get_Flags(mod, &flags); + return flags & FT_MODULE_DRIVER_HAS_HINTER; + } + + /* otherwise if we've been compiled with < 2.2.0 headers + use the internal macro */ +#ifdef FT_DRIVER_HAS_HINTER if(mod && FT_DRIVER_HAS_HINTER(mod)) return TRUE; +#endif return FALSE; }
diff --git a/dlls/kernel/time.c b/dlls/kernel/time.c index 9e38622..89db60e 100644 --- a/dlls/kernel/time.c +++ b/dlls/kernel/time.c @@ -518,8 +518,9 @@ VOID WINAPI GetSystemTimeAsFileTime( */ static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime) { + long clocksPerSec = sysconf(_SC_CLK_TCK); ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 ); - secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL ); + secs = RtlExtendedLargeIntegerDivide( secs, clocksPerSec, NULL ); filetime->dwLowDateTime = (DWORD)secs; filetime->dwHighDateTime = (DWORD)(secs >> 32); }
603d21cbc4fc8b915248cd3a6f90b02f721980c4 configure | 2 ++ configure.ac | 1 + dlls/gdi/freetype.c | 3 +++ include/config.h.in | 3 +++ 4 files changed, 9 insertions(+), 0 deletions(-) diff --git a/configure b/configure index c95d335..31005df 100755 --- a/configure +++ b/configure @@ -10042,6 +10042,7 @@ fi + for ac_header in ft2build.h \ freetype/freetype.h \ freetype/ftglyph.h \ @@ -10051,6 +10052,7 @@ for ac_header in ft2build.h \ freetype/ttnameid.h \ freetype/ftoutln.h \ freetype/ftwinfnt.h \ + freetype/ftmodapi.h \ freetype/internal/sfnt.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/configure.ac b/configure.ac index ca5eb8a..761f528 100644 --- a/configure.ac +++ b/configure.ac @@ -596,6 +596,7 @@ else freetype/ttnameid.h \ freetype/ftoutln.h \ freetype/ftwinfnt.h \ + freetype/ftmodapi.h \ freetype/internal/sfnt.h,,, [#if HAVE_FT2BUILD_H #include <ft2build.h> diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 3023ab3..314afd8 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -82,6 +82,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); #ifdef HAVE_FREETYPE_FTWINFNT_H #include <freetype/ftwinfnt.h> #endif +#ifdef HAVE_FREETYPE_FTMODAPI_H +#include <freetype/ftmodapi.h> +#endif #ifndef SONAME_LIBFREETYPE #define SONAME_LIBFREETYPE "libfreetype.so" diff --git a/include/config.h.in b/include/config.h.in index 51ecdc5..421a5eb 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -101,6 +101,9 @@ /* Define to 1 if you have the <freetype/ftglyph.h> header file. */ #undef HAVE_FREETYPE_FTGLYPH_H +/* Define to 1 if you have the <freetype/ftmodapi.h> header file. */ +#undef HAVE_FREETYPE_FTMODAPI_H + /* Define to 1 if you have the <freetype/ftnames.h> header file. */ #undef HAVE_FREETYPE_FTNAMES_H 0458a5e38dcf7d03a0eedd1e63922c1eb4e37cb9 dlls/gdi/freetype.c | 35 ++++++++++++++++++++++++++++++++++- 1 files changed, 34 insertions(+), 1 deletions(-) diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 314afd8..c4af124 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -90,6 +90,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(font); #define SONAME_LIBFREETYPE "libfreetype.so" #endif +#ifndef FT_MODULE_DRIVER_HAS_HINTER +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 +#endif + static FT_Library library = 0; typedef struct { @@ -122,6 +126,7 @@ MAKE_FUNCPTR(FT_Vector_Transform); static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*); static FT_Error (*pFT_Load_Sfnt_Table)(FT_Face,FT_ULong,FT_Long,FT_Byte*,FT_ULong*); static FT_ULong (*pFT_Get_First_Char)(FT_Face,FT_UInt*); +static FT_Error (*pFT_Module_Get_Flags)(FT_Module,FT_ULong*); #ifdef HAVE_FREETYPE_FTWINFNT_H MAKE_FUNCPTR(FT_Get_WinFNT_Header); #endif @@ -1499,6 +1504,7 @@ BOOL WineEngInit(void) pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0); pFT_Load_Sfnt_Table = wine_dlsym(ft_handle, "FT_Load_Sfnt_Table", NULL, 0); pFT_Get_First_Char = wine_dlsym(ft_handle, "FT_Get_First_Char", NULL, 0); + pFT_Module_Get_Flags = wine_dlsym(ft_handle, "FT_Module_Get_Flags", NULL, 0); #ifdef HAVE_FREETYPE_FTWINFNT_H pFT_Get_WinFNT_Header = wine_dlsym(ft_handle, "FT_Get_WinFNT_Header", NULL, 0); #endif @@ -3727,7 +3733,9 @@ DWORD WineEngGetFontData(GdiFont font, D if( !err && needed < len) len = needed; } err = pFT_Load_Sfnt_Table(ft_face, table, offset, buf, &len); - } else { /* Do it the hard way */ + } +#ifdef HAVE_FREETYPE_INTERNAL_SFNT_H + else { /* Do it the hard way */ TT_Face tt_face = (TT_Face) ft_face; SFNT_Interface *sfnt; if (FT_Version.major==2 && FT_Version.minor==0) @@ -3748,6 +3756,18 @@ DWORD WineEngGetFontData(GdiFont font, D } err = sfnt->load_any(tt_face, table, offset, buf, &len); } +#else + else { + static int msg; + if(!msg) { + MESSAGE("This version of Wine was compiled with freetype headers later than 2.2.0\n" + "but is being run with a freetype library without the FT_Load_Sfnt_Table function.\n" + "Please upgrade your freetype library.\n"); + msg++; + } + err = FT_Err_Unimplemented_Feature; + } +#endif if(err) { TRACE("Can't find table %08lx.\n", table); return GDI_ERROR; @@ -3813,8 +3833,21 @@ BOOL WINAPI FontIsLinked(HDC hdc) static BOOL is_hinting_enabled(void) { FT_Module mod = pFT_Get_Module(library, "truetype"); + + /* Use the >= 2.2.0 function if available */ + if(pFT_Module_Get_Flags) + { + FT_ULong flags; + pFT_Module_Get_Flags(mod, &flags); + return flags & FT_MODULE_DRIVER_HAS_HINTER; + } + + /* otherwise if we've been compiled with < 2.2.0 headers + use the internal macro */ +#ifdef FT_DRIVER_HAS_HINTER if(mod && FT_DRIVER_HAS_HINTER(mod)) return TRUE; +#endif return FALSE; }
69dcbaaf93a65820a28fe2485b6d15a90f423899 tools/wrc/parser.l | 110 ++++++++++++++++++++++++++-------------------------- 1 files changed, 55 insertions(+), 55 deletions(-) diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l index aea3fb8..9ad1751 100644 --- a/tools/wrc/parser.l +++ b/tools/wrc/parser.l @@ -68,11 +68,11 @@ */ /* Exclusive string handling */ -%x yystr +%x tkstr /* Exclusive unicode string handling */ -%x yylstr +%x tklstr /* Exclusive rcdata single quoted data handling */ -%x yyrcd +%x tkrcd /* Exclusive comment eating... */ %x comment /* Set when stripping c-junk */ @@ -428,102 +428,102 @@ static struct keyword *iskeyword(char *k * Wide string scanning */ L\" { - yy_push_state(yylstr); + yy_push_state(tklstr); wbufidx = 0; if(!win32) yywarning("16bit resource contains unicode strings\n"); } -<yylstr>\"{ws}+ | -<yylstr>\" { +<tklstr>\"{ws}+ | +<tklstr>\" { yy_pop_state(); yylval.str = get_buffered_wstring(); return tSTRING; } -<yylstr>\\[0-7]{1,6} { /* octal escape sequence */ +<tklstr>\\[0-7]{1,6} { /* octal escape sequence */ unsigned int result; result = strtoul(yytext+1, 0, 8); if ( result > 0xffff ) yyerror("Character constant out of range"); addwchar((WCHAR)result); } -<yylstr>\\x[0-9a-fA-F]{4} { /* hex escape sequence */ +<tklstr>\\x[0-9a-fA-F]{4} { /* hex escape sequence */ unsigned int result; result = strtoul(yytext+2, 0, 16); addwchar((WCHAR)result); } -<yylstr>\\x[0-9a-fA-F]{1,3} { yyerror("Invalid hex escape sequence '%s'", yytext); } - -<yylstr>\\[0-9]+ yyerror("Bad escape sequence"); -<yylstr>\\\n{ws}* line_number++; char_number = 1; /* backslash at EOL continues string after leading whitespace on next line */ -<yylstr>\\a addwchar('\a'); -<yylstr>\\b addwchar('\b'); -<yylstr>\\f addwchar('\f'); -<yylstr>\\n addwchar('\n'); -<yylstr>\\r addwchar('\r'); -<yylstr>\\t addwchar('\t'); -<yylstr>\\v addwchar('\v'); -<yylstr>\\. addwchar(yytext[1]); -<yylstr>\\\r\n addwchar(yytext[2]); line_number++; char_number = 1; -<yylstr>\"\" addwchar('\"'); /* "bla""bla" -> "bla\"bla" */ -<yylstr>\\\"\" addwchar('\"'); /* "bla\""bla" -> "bla\"bla" */ -<yylstr>\"{ws}+\" ; /* "bla" "bla" -> "blabla" */ -<yylstr>[^\\\n\"]+ { +<tklstr>\\x[0-9a-fA-F]{1,3} { yyerror("Invalid hex escape sequence '%s'", yytext); } + +<tklstr>\\[0-9]+ yyerror("Bad escape sequence"); +<tklstr>\\\n{ws}* line_number++; char_number = 1; /* backslash at EOL continues string after leading whitespace on next line */ +<tklstr>\\a addwchar('\a'); +<tklstr>\\b addwchar('\b'); +<tklstr>\\f addwchar('\f'); +<tklstr>\\n addwchar('\n'); +<tklstr>\\r addwchar('\r'); +<tklstr>\\t addwchar('\t'); +<tklstr>\\v addwchar('\v'); +<tklstr>\\. addwchar(yytext[1]); +<tklstr>\\\r\n addwchar(yytext[2]); line_number++; char_number = 1; +<tklstr>\"\" addwchar('\"'); /* "bla""bla" -> "bla\"bla" */ +<tklstr>\\\"\" addwchar('\"'); /* "bla\""bla" -> "bla\"bla" */ +<tklstr>\"{ws}+\" ; /* "bla" "bla" -> "blabla" */ +<tklstr>[^\\\n\"]+ { char *yptr = yytext; while(*yptr) /* FIXME: codepage translation */ addwchar(*yptr++ & 0xff); } -<yylstr>\n yyerror("Unterminated string"); +<tklstr>\n yyerror("Unterminated string"); /* * Normal string scanning */ -\" yy_push_state(yystr); cbufidx = 0; -<yystr>\"{ws}+ | -<yystr>\" { +\" yy_push_state(tkstr); cbufidx = 0; +<tkstr>\"{ws}+ | +<tkstr>\" { yy_pop_state(); yylval.str = get_buffered_cstring(); return tSTRING; } -<yystr>\\[0-7]{1,3} { /* octal escape sequence */ +<tkstr>\\[0-7]{1,3} { /* octal escape sequence */ int result; result = strtol(yytext+1, 0, 8); if ( result > 0xff ) yyerror("Character constant out of range"); addcchar((char)result); } -<yystr>\\x[0-9a-fA-F]{2} { /* hex escape sequence */ +<tkstr>\\x[0-9a-fA-F]{2} { /* hex escape sequence */ int result; result = strtol(yytext+2, 0, 16); addcchar((char)result); } -<yystr>\\x[0-9a-fA-F] { yyerror("Invalid hex escape sequence '%s'", yytext); } - -<yystr>\\[0-9]+ yyerror("Bad escape sequence"); -<yystr>\\\n{ws}* line_number++; char_number = 1; /* backslash at EOL continues string after leading whitespace on next line */ -<yystr>\\a addcchar('\a'); -<yystr>\\b addcchar('\b'); -<yystr>\\f addcchar('\f'); -<yystr>\\n addcchar('\n'); -<yystr>\\r addcchar('\r'); -<yystr>\\t addcchar('\t'); -<yystr>\\v addcchar('\v'); -<yystr>\\. addcchar(yytext[1]); -<yystr>\\\r\n addcchar(yytext[2]); line_number++; char_number = 1; -<yystr>[^\\\n\"]+ { +<tkstr>\\x[0-9a-fA-F] { yyerror("Invalid hex escape sequence '%s'", yytext); } + +<tkstr>\\[0-9]+ yyerror("Bad escape sequence"); +<tkstr>\\\n{ws}* line_number++; char_number = 1; /* backslash at EOL continues string after leading whitespace on next line */ +<tkstr>\\a addcchar('\a'); +<tkstr>\\b addcchar('\b'); +<tkstr>\\f addcchar('\f'); +<tkstr>\\n addcchar('\n'); +<tkstr>\\r addcchar('\r'); +<tkstr>\\t addcchar('\t'); +<tkstr>\\v addcchar('\v'); +<tkstr>\\. addcchar(yytext[1]); +<tkstr>\\\r\n addcchar(yytext[2]); line_number++; char_number = 1; +<tkstr>[^\\\n\"]+ { char *yptr = yytext; while(*yptr) addcchar(*yptr++); } -<yystr>\"\" addcchar('\"'); /* "bla""bla" -> "bla\"bla" */ -<yystr>\\\"\" addcchar('\"'); /* "bla\""bla" -> "bla\"bla" */ -<yystr>\"{ws}+\" ; /* "bla" "bla" -> "blabla" */ -<yystr>\n yyerror("Unterminated string"); +<tkstr>\"\" addcchar('\"'); /* "bla""bla" -> "bla\"bla" */ +<tkstr>\\\"\" addcchar('\"'); /* "bla\""bla" -> "bla\"bla" */ +<tkstr>\"{ws}+\" ; /* "bla" "bla" -> "blabla" */ +<tkstr>\n yyerror("Unterminated string"); /* * Raw data scanning */ -\' yy_push_state(yyrcd); cbufidx = 0; -<yyrcd>\' { +\' yy_push_state(tkrcd); cbufidx = 0; +<tkrcd>\' { yy_pop_state(); yylval.raw = new_raw_data(); yylval.raw->size = cbufidx; @@ -531,14 +531,14 @@ L\" { memcpy(yylval.raw->data, cbuffer, yylval.raw->size); return tRAWDATA; } -<yyrcd>[0-9a-fA-F]{2} { +<tkrcd>[0-9a-fA-F]{2} { int result; result = strtol(yytext, 0, 16); addcchar((char)result); } -<yyrcd>{ws}+ ; /* Ignore space */ -<yyrcd>\n line_number++; char_number = 1; -<yyrcd>. yyerror("Malformed data-line"); +<tkrcd>{ws}+ ; /* Ignore space */ +<tkrcd>\n line_number++; char_number = 1; +<tkrcd>. yyerror("Malformed data-line"); /* * Comment stripping
_______________________________________________ wine-users mailing list wine-users@xxxxxxxxxx http://www.winehq.org/mailman/listinfo/wine-users