What I meant, was that there are some implicit defines in mingw (like __GCC) and vcX (like _MVC) but possibly also other unsupported? internal structures. As I stated earlier mingw should be win32 api compliant, but not for complicating matters. But as stated earlier we should also use a true MS VC compiler as true reference.
Anyway, I suspected as much re the legal
issues.
Take these into consideration, too.
Anyway, I avoided bleeding edge stuff like WOW64 for now. Still,
Signals.cpp is going to require some esoteric Structured Exception
Handling stuff and debug symbol table support. Nothing that hasn't been
around for a while, but rarely used by the typical Windows programmer.
Not an easy task. That's why I left it some code as an exercise in my first try...
The stack tracing code requires the header files dbghelp.h and psapi.h.
The SEH stuff is declared in windows.h; if your version has
SetUnhandledExceptionFilter and SetErrorMode you should be OK.
Thanks for the patch. It looks good except for the code copied from
Microsoft. That software is copyrighted by Microsoft and cannot be
entered into the LLVM code base without some kind of license. Was there
an MSDN license that came with this software? If so, could you please
send it to me?
Also, the formatting of that code needs to be adapted to LLVM coding
standards, like the rest of the file.
No, there isn't. It was originally published in Microsoft Systems
Journal. There's no license I can find in any of the files that
accompany the article. If publication in MSJ or MSDN doesn't make it
fair game, then I guess I'll have to rewrite it.
I suspect that it's not actually a problem: MS *wants* developers to copy
the code into their proprietary apps to make them better. However, some
reassurance of this is necessary: is there something in the front of the
magazine that specifies usage rights for the code or something like that?
I've only seen the article online. I cannot find anything that
explicitly grants permission, though my understanding is the same as
yours. So to be on the safe side, I'll rewrite it. I pretty much have
to do that anyway to make it conform to LLVM coding standards
And I now realize my code has concurrency issues. What, you ask? How
can a non-threaded program like LLVM have concurrency issues? Well, on
Windows any application can find itself growing extra threads. The
culprit in this case is the console handler. If you hit CTRL/C, a new
thread magically appears to execute the handler. So the globals that
hold the list of files and directories to be deleted might be modified
in one thread as the other iterates them. Very unlikely to occur, but
theoretically possible. Have to introduce a critical section.
Oh dear.. will an exception be thrown if the file cannot be deleted
because it's currently open? Have to handle that too if so...
Microsoft is quite strict and serious about its copyright, as should
everyone be (both open source and closed source). We should always err
on the side of caution in these matters. If the material to be added to
LLVM is copyrighted and there is no *explicit* license accompanying that
copyrighted material then we must assume there is *no* license. That's a
harsh stand, but these days I think its necessary. We don't want some
SCO-like bean counter 10 years from now saying "Hey, you stole our
code".
This version has been committed to CVS with one minor change:
I made the warning about caller calling LeaveCriticalSection a little
more prominent. Patch is here:
Here's my first take on Path.cpp. It has a few holes still but it ought
to be basically functional.
A few observations:
First, the Win32 version still has a lot of code in common with Unix.
This code should be pulled out into a common file.
Second, some of the functions leave me scratching me head. What purpose
does create_file serve? Is there really a need to create empty files?
(It also leaks an open file handle, BTW). I would expect set_file to
alter only the file name portion of the path and leave the directory
portion unchanged, and the opposite for set_directory. set_directory
obliterates the file name portion of the path (OK, I guess) but set_file
doesn't make any sense at all.
Here's my first take on Path.cpp. It has a few holes still but it ought
to be basically functional.
A few observations:
First, the Win32 version still has a lot of code in common with Unix.
This code should be pulled out into a common file.
truly generic code (common to all platforms) should go in
lib/System/Path.cpp. If you know of such things, feel free to send
patches. FYI: I'll reject anything that has a / in a string literal.
That's not portable to all systems. While it might work on 99.9% of unix
and some modern Win32 machines, it won't work on VMS or OS/390.
Second, some of the functions leave me scratching me head. What purpose
does create_file serve? Is there really a need to create empty files?
Yes. Lock files are done this way. However, I'm not sure if LLVM uses
them.
(It also leaks an open file handle, BTW).
Oops. I'll take a look.
I would expect set_file to
alter only the file name portion of the path and leave the directory
portion unchanged, and the opposite for set_directory. set_directory
obliterates the file name portion of the path (OK, I guess) but set_file
doesn't make any sense at all.
The Path class is intended to provide path construction, not path
editing. I don't see any need for path editing in LLVM. So, "set_file"
just sets the *entire* path to a single file name. I suppose it could
prefix it with ./ on Unix since that's what it means (i.e. the directory
part is the current directory. Set directory similarly sets the *entire*
path to a single directory name. The various append_* and elide_*
functions assist with path construction, in limited ways.
However, for some reason I haven't been able to determine, the lovely
trace you see above comes out only on Windows XP. On Windows 2000, it
can't get the symbol information for EXEs, though it does for DLLs. I
know this code worked on 2000 in the past, so it must be something that
broke with VC 7.1. Oh well.
(The GetCurrentDirectoryW is bogus, but the top of the stack usually is).
I did make some minor changes that I'll submit shortly.
Completed testing. Diffs for Path.cpp attached to fix bugs.
Some of them are probably present in the Unix version as well.
There are some uses of ThrowError when there is no error present in
errno to format. A throw statement should be used.
Path::is_valid uses realpath on Unix. The problem is that realpath
validates that all the directory components of the path actually exist
and are executable. There are two problems with this. First, Path.h
states that is_valid does syntactic validation only. Second, it is
impossible to create a series of nested directories with
create_directory(true) as such a path would be invalid according to
realpath and hence is_valid. I changed the Win32 version to only
perform syntactic validation.
Path::create_directory had other problems. The use of path::copy to
make a local copy of the path assumed there was a null terminator.
std::string doesn't use null termination. The parsing code to identify
the intermediate directories wasn't correct either.
My first implementation of create_file was incorrect because it
succeeded even if the file already existed. I fixed that, but creating
a file to serialize concurrent programs is a Unix paradigm that is not
appropriate for all platforms. On Windows the preferred way is to use a
mutex, which cleans up after itself if a program dies abnormally.