Nuno Lucas escreveu: > On 2/15/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> > wrote: > [...] >> 4) Map errno to [Get|Set]LastError() with preprocessor macros. >> #define errno GetLastError() >> #define __set_errno(X) SetLastError((DWORD)X) >> #define ENOMEM ERROR_OUTOFMEMORY >> (...) > [...] >> Conclusion: >> >> I like 4 the best, and I am going to give it a try. >> >> Any opinions/comments/requests-for-clarification/war_stories >> would be much appreciated. > > You forgot one solution: > > 5) Win32 for WindowsCE doesn't have errno, just like it doesn't have > any getcwd() and co. If the user is porting code with mingw32ce which > uses this, either use it's own replacements or use cegcc. >
> I'm with 5. For me, mingw32ce is the thin wrapper around the WinCE > Win32 API, so don't try to add functionality that doesn't exist > already on the standard SDK. > I don't see a problem in adding stuff to mingwex, as long as it doesn't *change* what the runtime does. Eg: There is no fdopen on coredll, but there is an _wfdopen. How many implementations of fdopen can the user pull off? So, instead of forcing everyone that encounters an fdopen call to port it himself, we have it in libmingwex.a. Notice that this is a static lib. No dll dependency. If the user still doesn't like our fdopen, just reimplement it, and the linker won't even bother with our version. This is a very different attitude from cegcc. On cegcc, we *reimplement* most of the c runtime (crt). In cegcc, when you call fopen, you are calling the newlib version of fopen, although there is an fopen in coredll.dll (we are ignoring it). Another example, and I could keep going on: in cegcc, we have our own malloc. So allocating memory in a cegcc app, passing the pointer into a dll build with mingw32ce/msvc, and freeing it there, will surely crash. So, all the extensions we have / will have on mingw32ce, will not reimplement (minus really needed exceptions) what already exists on coredll. The resulting app is still a "native" WinCE app. I suggest everyone to take a look at wince ports of stuff like ruby, sshd, python, <insert favorite package here>, and you will see the same code over and over again. If we have it on the base package, there is only one place to have it done, and one place to fixed if it is broken. Having to keep local patches for a lot of libs, and/or convincing that maintainers of those apps/libs to accept twists into their package because WinCE is such a broken dev env, is a worse solution IMHO. I guess this brokenness is in my humble opinion the reason you don't see more stuff ported to wince, and the free developers base for wince stuff is so low. > The possible exception may be the implementation of the minimum > required to build a minimal C++ standard library, but I would not > worry about iostreams and such (anyone using iostreams on WinCE, > instead of using the lower level API is probably going in the wrong > direction anyway). > Why? What is wrong with iostreams? > Also, many things weren't available on earlier WinCE versions that are > now on recent versions, so there's the risk of implementing too much > and make the programs not compatible for the future. > I don't see how. If something we have will be added to wince proper, we just adapt to it. As long as the existing functions from coredll.dll don't change their meaning, there won't be any incompatibility. And we all know MSFT does have a commitment to backwards compatibility. > And, most of the missing "standard" C runtime functions are > implemented in the MFC libraries, so a latter support for MFC > applications compiled with mingw32ce could become messy if we do too > much now. > That doesn't case sense at all. MFC is a c++ lib, with a very different API from the std c functions, so how would it become messy? > I don't mind having a separate helper library for mingw32ce but, for > me, anyone using errno with mingw32ce will always get into trouble > latter (there's no way to correctly map the errno errors with the > GetLastError() results). > I was until this week of the very same opinion. If was after at porting a bunch of packages, that I realized that 99% of the time, it does map well, and that most ports do it the wrong way. Look at the VLC mingw errno.h. They went around it by having an errno.h, and declaring a 'static int errno'. That is another solution I forgot adding to the list, so here goes: 6) declare an errno.h with a 'static int errno'. This is broken, because every object (.o) will have its own instance of errno, thus, what you get is that errno will not work across objects. eg: errno.h: static int errno; file1.c: #include <errno.h> int function1() { errno = 1; } file2.c: #include <errno.h> errno = 0; function1(); if (errno != 0) { /* will never be hit. */} I have another solution, that looks promising. 7) Have an int errno that maps to [Get|Set]LastError, and enables use as an lvalue. This solution works across dlls, without a shared dll, has minimum code impact, but, depends on SEH. I tried using the same trick as in src/newlib/newlib/libc/sys/wince/crt0.S to have SEH with mingw32ce, but failed, so I though I would test it first in MSVC. Here is the code. #include <windows.h> #define ERRNO_HELPER_ADDR 0xfeed int* _errno (void) { return (int*)ERRNO_HELPER_ADDR; } #define errno (*_errno ()) int _errno_handler (DWORD excp_code, struct _EXCEPTION_POINTERS *ExceptionPointers) { PEXCEPTION_RECORD ExceptionRecord = ExceptionPointers->ExceptionRecord; PCONTEXT ContextRecord = ExceptionPointers->ContextRecord; if (ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION) return EXCEPTION_CONTINUE_SEARCH; DWORD Cmd = *(DWORD *)ExceptionRecord->ExceptionAddress; switch (Cmd&0xfff00000) { case 0xe5900000: { DWORD DataAddr; int Src, Dst, Off; DWORD *Regs = (DWORD*)&ContextRecord->R0; Src = (Cmd >> 16) & 0xf; Dst = (Cmd >> 12) & 0xf; Off = Cmd & 0xfff; DataAddr = Regs[Src] + Off; if (DataAddr != ERRNO_HELPER_ADDR) return EXCEPTION_CONTINUE_SEARCH; Regs[Dst] = GetLastError (); break; } case 0xe5800000: { DWORD DataAddr; int Src, Dst, Off; DWORD *Regs = (DWORD*)&ContextRecord->R0; Dst = (Cmd >> 16) & 0xf; Src = (Cmd >> 12) & 0xf; Off = Cmd & 0xfff; DataAddr = Regs[Dst] + Off; if (DataAddr != ERRNO_HELPER_ADDR) return EXCEPTION_CONTINUE_SEARCH; SetLastError (Regs[Src]); break; } default: { #if 0 printf("Unhandled command:%x\n", Cmd); #endif return EXCEPTION_CONTINUE_SEARCH; } } ContextRecord->Pc += 4; // skip faulty instruction return EXCEPTION_CONTINUE_EXECUTION; } int WINAPI WinMain2(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { printf ("GetLastError (%d): %d\r\n", __LINE__, GetLastError ()); errno = 1; printf ("GetLastError (%d): %d\r\n", __LINE__, GetLastError ()); errno = 0; printf ("GetLastError (%d): %d\r\n", __LINE__, GetLastError ()); errno = 20; printf ("GetLastError (%d): %d\r\n", __LINE__, GetLastError ()); errno = 10; printf ("errno (%d): %d\r\n", __LINE__, errno); volatile int a = errno; SetLastError (30); printf ("errno (%d): %d\r\n", __LINE__, errno); return 0; } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { __try { return WinMain2 (hInstance, hPrevInstance, lpCmdLine, nCmdShow); } __except (_errno_handler (GetExceptionCode (), GetExceptionInformation ())) {} return 1; } I woke up on the middle of the night with this solution banging on my head, so I could resist to test it. It works. Back to bed now. Cheers, Pedro Alves ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Cegcc-devel mailing list Cegcc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cegcc-devel