diff --git a/GCC/gcc/cp/xml.c b/GCC/gcc/cp/xml.c index da89ee3..392ce50 100644 --- a/GCC/gcc/cp/xml.c +++ b/GCC/gcc/cp/xml.c @@ -76,7 +76,7 @@ # define XML_PRE_3_4_TREE_VIA_PUBLIC #endif -#define GCC_XML_C_VERSION "$Revision: 1.114 $" +#define GCC_XML_C_VERSION "$Revision: 1.115 $" /*--------------------------------------------------------------------------*/ /* Data structures for the actual XML dump. */ @@ -1504,6 +1504,46 @@ xml_document_add_attribute_bits(xml_document_element_p element) xml_document_attribute_use_optional, 0); } +/*--------------------------------------------------------------------------*/ +/* Print the XML attribute befriending="..." for a function or class. */ +static void +xml_print_befriending_attribute (xml_dump_info_p xdi, tree befriending) +{ + int have_befriending = 0; + tree frnd; + for (frnd = befriending ; frnd && !have_befriending ; + frnd = TREE_CHAIN (frnd)) + { + if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) + { + have_befriending = 1; + } + } + if(have_befriending) + { + const char* sep = ""; + fprintf (xdi->file, " befriending=\""); + for (frnd = befriending ; frnd ; frnd = TREE_CHAIN (frnd)) + { + if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) + { + fprintf (xdi->file, + "%s_%d", sep, xml_add_node (xdi, TREE_VALUE (frnd), 0)); + sep = " "; + } + } + fprintf (xdi->file, "\""); + } +} + +static void +xml_document_add_attribute_befriending(xml_document_element_p element) +{ + xml_document_add_attribute(element, "befriending", + xml_document_attribute_type_idrefs, + xml_document_attribute_use_optional, 0); +} + /*--------------------------------------------------------------------------*/ /* Print XML empty tag describing an unimplemented TREE_CODE that has been encountered. */ @@ -1888,6 +1928,7 @@ xml_output_function_decl (xml_dump_info_p xdi, tree fd, xml_dump_node_p dn) xml_print_inline_attribute (xdi, fd); xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(fd), TYPE_ATTRIBUTES(TREE_TYPE(fd))); + xml_print_befriending_attribute (xdi, DECL_BEFRIENDING_CLASSES (fd)); /* Prepare to iterator through argument list. */ arg = DECL_ARGUMENTS (fd); @@ -1979,6 +2020,7 @@ xml_document_add_element_function_helper (xml_document_info_p xdi, xml_document_add_attribute_extern(e); xml_document_add_attribute_inline(e); xml_document_add_attribute_attributes(e); + xml_document_add_attribute_befriending(e); if(allow_arguments) { xml_document_add_element_argument (xdi, e); @@ -2148,6 +2190,7 @@ xml_output_record_type (xml_dump_info_p xdi, tree rt, xml_dump_node_p dn) xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(rt), 0); xml_print_size_attribute (xdi, rt); xml_print_align_attribute (xdi, rt); + xml_print_befriending_attribute (xdi, CLASSTYPE_BEFRIENDING_CLASSES (rt)); if (dn->complete && COMPLETE_TYPE_P (rt)) { @@ -2337,6 +2380,7 @@ xml_document_add_element_record_type_helper (xml_document_info_p xdi, xml_document_add_attribute_attributes(e); xml_document_add_attribute_size(e); xml_document_add_attribute_align(e); + xml_document_add_attribute_befriending(e); xml_document_add_attribute(e, "members", xml_document_attribute_type_idrefs, xml_document_attribute_use_optional, 0); diff --git a/GCC_XML/KWSys/CMakeLists.txt b/GCC_XML/KWSys/CMakeLists.txt index 1b5495b..673f4a9 100644 --- a/GCC_XML/KWSys/CMakeLists.txt +++ b/GCC_XML/KWSys/CMakeLists.txt @@ -395,17 +395,17 @@ ELSE(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) ENDIF(KWSYS_STL_HAS_ALLOCATOR_TEMPLATE) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_ALLOCATOR_OBJECTS "Checking whether stl containers support allocator objects." DIRECT) -IF(KWSYS_IOS_USE_ANSI) +IF(KWSYS_IOS_USE_ANSI AND NOT WATCOM) # ANSI streams always have string operators. SET(KWSYS_STL_STRING_HAVE_OSTREAM 1) SET(KWSYS_STL_STRING_HAVE_ISTREAM 1) -ELSE(KWSYS_IOS_USE_ANSI) +ELSE(KWSYS_IOS_USE_ANSI AND NOT WATCOM) # There may not be string operators for old streams. KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM "Checking whether stl string has ostream operator<<" DIRECT) KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM "Checking whether stl string has istream operator>>" DIRECT) -ENDIF(KWSYS_IOS_USE_ANSI) +ENDIF(KWSYS_IOS_USE_ANSI AND NOT WATCOM) SET(KWSYS_PLATFORM_CXX_TEST_DEFINES) KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_NULL_TEMPLATE_ARGS @@ -872,9 +872,13 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ENDFOREACH(test) # C++ tests - SET(KWSYS_CXX_TESTS - testAutoPtr - testHashSTL + IF(NOT WATCOM) + SET(KWSYS_CXX_TESTS + testAutoPtr + testHashSTL + ) + ENDIF(NOT WATCOM) + SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testRegistry testIOS testSystemTools diff --git a/GCC_XML/KWSys/DynamicLoader.cxx b/GCC_XML/KWSys/DynamicLoader.cxx index 25c20dc..1fdc985 100644 --- a/GCC_XML/KWSys/DynamicLoader.cxx +++ b/GCC_XML/KWSys/DynamicLoader.cxx @@ -31,21 +31,6 @@ // (default) Each part of the ifdef contains a complete implementation for // the static methods of DynamicLoader. -namespace KWSYS_NAMESPACE -{ - -//---------------------------------------------------------------------------- -DynamicLoader::DynamicLoader() -{ -} - -//---------------------------------------------------------------------------- -DynamicLoader::~DynamicLoader() -{ -} - -} - // --------------------------------------------------------------- // 1. Implementation for HPUX machines #ifdef __hpux @@ -251,13 +236,35 @@ int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib) DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( DynamicLoader::LibraryHandle lib, const char* sym) { + // TODO: The calling convention affects the name of the symbol. We + // should have a tool to help get the symbol with the desired + // calling convention. Currently we assume cdecl. + // + // Borland: + // __cdecl = "_func" (default) + // __fastcall = "@_func" + // __stdcall = "func" + // + // Watcom: + // __cdecl = "_func" + // __fastcall = "@_func@X" + // __stdcall = "_func@X" + // __watcall = "func_" (default) + // + // MSVC: + // __cdecl = "func" (default) + // __fastcall = "@_func@X" + // __stdcall = "_func@X" + // + // Note that the "@X" part of the name above is the total size (in + // bytes) of the arguments on the stack. void *result; -#ifdef __BORLANDC__ - // Need to prepend symbols with '_' on borland compilers +#if defined(__BORLANDC__) || defined(__WATCOMC__) + // Need to prepend symbols with '_' size_t len = strlen(sym); char *rsym = new char[len + 1 + 1]; strcpy(rsym, "_"); - strcat(rsym+1, sym); + strcat(rsym, sym); #else const char *rsym = sym; #endif @@ -268,11 +275,15 @@ DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress( #else result = (void*)GetProcAddress(lib, rsym); #endif -#ifdef __BORLANDC__ +#if defined(__BORLANDC__) || defined(__WATCOMC__) delete[] rsym; #endif // Hack to cast pointer-to-data to pointer-to-function. +#ifdef __WATCOMC__ + return *(DynamicLoader::SymbolPointer*)(&result); +#else return *reinterpret_cast(&result); +#endif } //---------------------------------------------------------------------------- diff --git a/GCC_XML/KWSys/DynamicLoader.hxx.in b/GCC_XML/KWSys/DynamicLoader.hxx.in index 419aba8..5910c52 100644 --- a/GCC_XML/KWSys/DynamicLoader.hxx.in +++ b/GCC_XML/KWSys/DynamicLoader.hxx.in @@ -76,9 +76,6 @@ public: // Return type from DynamicLoader::GetSymbolAddress. typedef void (*SymbolPointer)(); - DynamicLoader(); - ~DynamicLoader(); - /** Load a dynamic library into the current process. * The returned LibraryHandle can be used to access the symbols in the * library. */ diff --git a/GCC_XML/KWSys/EncodeExecutable.c b/GCC_XML/KWSys/EncodeExecutable.c index e2ae360..5acdbce 100644 --- a/GCC_XML/KWSys/EncodeExecutable.c +++ b/GCC_XML/KWSys/EncodeExecutable.c @@ -52,6 +52,21 @@ int main(int argc, char* argv[]) fprintf(ofp, "#include \"kwsysPrivate.h\"\n"); fprintf(ofp, "#include KWSYS_HEADER(Configure.h)\n\n"); fprintf(ofp, "#include \n\n"); + fprintf(ofp, "#if defined(_WIN32)\n"); + fprintf(ofp, "# include \n"); + fprintf(ofp, "#else\n"); + fprintf(ofp, "# include \n"); + fprintf(ofp, "#endif\n"); + fprintf(ofp, "\n"); + fprintf(ofp, "static void kwsys_unlink(const char* fname)\n"); + fprintf(ofp, "{\n"); + fprintf(ofp, "#if defined(__WATCOMC__)\n"); + fprintf(ofp, " unlink(fname);\n"); + fprintf(ofp, "#else\n"); + fprintf(ofp, " _unlink(fname);\n"); + fprintf(ofp, "#endif\n"); + fprintf(ofp, "}\n"); + fprintf(ofp, "\n"); /* Split file up in 1024-byte chunks. */ while((n = (int)fread(buffer, 1, 1024, ifp)) > 0) @@ -78,9 +93,6 @@ int main(int argc, char* argv[]) fprintf(ofp, "extern %s_EXPORT int %sEncodedWriteArray%s(const char* fname)\n", argv[3], argv[3], argv[4]); fprintf(ofp, "{\n"); - fprintf(ofp, "#ifdef __WATCOMC__\n"); - fprintf(ofp, "#define _unlink unlink\n"); - fprintf(ofp, "#endif\n"); fprintf(ofp, " FILE* ofp = fopen(fname, \"wb\");\n"); fprintf(ofp, " if(!ofp) { return 0; }\n"); for(i=0; i < count; ++i) @@ -91,7 +103,7 @@ int main(int argc, char* argv[]) argv[4], i, argv[4], i, argv[4], i); fprintf(ofp, " {\n"); fprintf(ofp, " fclose(ofp);\n"); - fprintf(ofp, " _unlink(fname);\n"); + fprintf(ofp, " kwsys_unlink(fname);\n"); fprintf(ofp, " return 0;\n"); fprintf(ofp, " }\n"); } diff --git a/GCC_XML/KWSys/ProcessUNIX.c b/GCC_XML/KWSys/ProcessUNIX.c index c217d07..9c5915f 100644 --- a/GCC_XML/KWSys/ProcessUNIX.c +++ b/GCC_XML/KWSys/ProcessUNIX.c @@ -100,8 +100,8 @@ static inline void kwsysProcess_usleep(unsigned int msec) # define KWSYSPE_USE_SELECT 1 #endif -/* BeOS does not have siginfo on its signal handlers. */ -#if !defined(__BEOS__) +/* Some platforms do not have siginfo on their signal handlers. */ +#if defined(SA_SIGINFO) && !defined(__BEOS__) # define KWSYSPE_USE_SIGINFO 1 #endif @@ -2227,6 +2227,12 @@ static void kwsysProcessRestoreDefaultSignalHandlers(void) #endif } +/*--------------------------------------------------------------------------*/ +static void kwsysProcessExit(void) +{ + _exit(0); +} + /*--------------------------------------------------------------------------*/ static pid_t kwsysProcessFork(kwsysProcess* cp, kwsysProcessCreateInformation* si) @@ -2257,7 +2263,7 @@ static pid_t kwsysProcessFork(kwsysProcess* cp, (errno == EINTR)); /* Exit without cleanup. The parent holds all resources. */ - _exit(0); + kwsysProcessExit(); return 0; /* Never reached, but avoids SunCC warning. */ } } @@ -2306,8 +2312,13 @@ static void kwsysProcessKill(pid_t process_id) DIR* procdir; #endif - /* Suspend the process to be sure it will not create more children. */ - kill(process_id, SIGSTOP); + /* Kill the process now to make sure it does not create more + children. Do not reap it yet so we can identify its existing + children. There is a small race condition here. If the child + forks after we begin looking for children below but before it + receives this kill signal we might miss a child. Also we might + not be able to catch up to a fork bomb. */ + kill(process_id, SIGKILL); /* Kill all children if we can find them. */ #if defined(__linux__) || defined(__CYGWIN__) @@ -2395,9 +2406,6 @@ static void kwsysProcessKill(pid_t process_id) } #endif } - - /* Kill the process. */ - kill(process_id, SIGKILL); } /*--------------------------------------------------------------------------*/ diff --git a/GCC_XML/KWSys/ProcessWin32.c b/GCC_XML/KWSys/ProcessWin32.c index fa58d89..43bcff5 100644 --- a/GCC_XML/KWSys/ProcessWin32.c +++ b/GCC_XML/KWSys/ProcessWin32.c @@ -77,6 +77,22 @@ Q190351 and Q150956. /* The maximum amount to read from a pipe at a time. */ #define KWSYSPE_PIPE_BUFFER_SIZE 1024 +/* Debug output macro. */ +#if 0 +# define KWSYSPE_DEBUG(x) \ +( \ + (void*)cp == (void*)0x00226DE0? \ + ( \ + fprintf(stderr, "%d/%p/%d ", (int)GetCurrentProcessId(), cp, __LINE__), \ + fprintf x, \ + fflush(stderr), \ + 1 \ + ) : (1) \ +) +#else +# define KWSYSPE_DEBUG(x) (void)1 +#endif + #define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x) typedef LARGE_INTEGER kwsysProcessTime; @@ -1238,6 +1254,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, done with the data. */ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { + KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); cp->CurrentIndex = KWSYSPE_PIPE_COUNT; } @@ -1282,6 +1299,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, inform the wakeup thread it is done with this process. */ kwsysProcessCleanupHandle(&cp->Pipe[cp->CurrentIndex].Read); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Waker.Go, 1, 0); + KWSYSPE_DEBUG((stderr, "wakeup %d\n", cp->CurrentIndex)); --cp->PipesLeft; } else if(data && length) @@ -1337,6 +1355,7 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length, else { /* The process timeout has expired. Kill the child now. */ + KWSYSPE_DEBUG((stderr, "killing child because timeout expired\n")); kwsysProcess_Kill(cp); cp->TimeoutExpired = 1; cp->Killed = 0; @@ -1372,10 +1391,13 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) } } + KWSYSPE_DEBUG((stderr, "no more data\n")); + /* When the last pipe closes in WaitForData, the loop terminates without releasing the pipe's thread. Release it now. */ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { + KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); cp->CurrentIndex = KWSYSPE_PIPE_COUNT; } @@ -1383,7 +1405,9 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout) /* Wait for all pipe threads to reset. */ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) { + KWSYSPE_DEBUG((stderr, "waiting reader reset %d\n", i)); WaitForSingleObject(cp->Pipe[i].Reader.Reset, INFINITE); + KWSYSPE_DEBUG((stderr, "waiting waker reset %d\n", i)); WaitForSingleObject(cp->Pipe[i].Waker.Reset, INFINITE); } @@ -1434,15 +1458,18 @@ void kwsysProcess_Kill(kwsysProcess* cp) if(!cp || cp->State != kwsysProcess_State_Executing || cp->TimeoutExpired || cp->Killed) { + KWSYSPE_DEBUG((stderr, "kill: child not executing\n")); return; } /* Disable the reading threads. */ + KWSYSPE_DEBUG((stderr, "kill: disabling pipe threads\n")); kwsysProcessDisablePipeThreads(cp); /* Skip actually killing the child if it has already terminated. */ if(cp->Terminated) { + KWSYSPE_DEBUG((stderr, "kill: child already terminated\n")); return; } @@ -1498,8 +1525,11 @@ DWORD WINAPI kwsysProcessPipeThreadRead(LPVOID ptd) void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td) { /* Wait for space in the thread's buffer. */ - while((WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed)) + while((KWSYSPE_DEBUG((stderr, "wait for read %d\n", td->Index)), + WaitForSingleObject(td->Reader.Go, INFINITE), !td->Closed)) { + KWSYSPE_DEBUG((stderr, "reading %d\n", td->Index)); + /* Read data from the pipe. This may block until data are available. */ if(!ReadFile(td->Read, td->DataBuffer, KWSYSPE_PIPE_BUFFER_SIZE, &td->DataLength, 0)) @@ -1511,11 +1541,16 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td) /* The pipe closed. There are no more data to read. */ td->Closed = 1; + KWSYSPE_DEBUG((stderr, "read closed %d\n", td->Index)); } + KWSYSPE_DEBUG((stderr, "read %d\n", td->Index)); + /* Wait for our turn to be handled by the main thread. */ WaitForSingleObject(cp->SharedIndexMutex, INFINITE); + KWSYSPE_DEBUG((stderr, "reporting read %d\n", td->Index)); + /* Tell the main thread we have something to report. */ cp->SharedIndex = td->Index; ReleaseSemaphore(cp->Full, 1, 0); @@ -1523,6 +1558,7 @@ void kwsysProcessPipeThreadReadPipe(kwsysProcess* cp, kwsysProcessPipeData* td) /* We were signalled to exit with our buffer empty. Reset the mutex for a new process. */ + KWSYSPE_DEBUG((stderr, "self releasing reader %d\n", td->Index)); ReleaseSemaphore(td->Reader.Go, 1, 0); } @@ -1560,13 +1596,17 @@ void kwsysProcessPipeThreadWakePipe(kwsysProcess* cp, kwsysProcessPipeData* td) (void)cp; /* Wait for a possible wake command. */ + KWSYSPE_DEBUG((stderr, "wait for wake %d\n", td->Index)); WaitForSingleObject(td->Waker.Go, INFINITE); + KWSYSPE_DEBUG((stderr, "waking %d\n", td->Index)); /* If the pipe is not closed, we need to wake up the reading thread. */ if(!td->Closed) { DWORD dummy; + KWSYSPE_DEBUG((stderr, "waker %d writing byte\n", td->Index)); WriteFile(td->Write, "", 1, &dummy, 0); + KWSYSPE_DEBUG((stderr, "waker %d wrote byte\n", td->Index)); } } @@ -1910,6 +1950,15 @@ void kwsysProcessDestroy(kwsysProcess* cp, int event) can detect end-of-data. */ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) { + /* TODO: If the child created its own child (our grandchild) + which inherited a copy of the pipe write-end then the pipe + may not close and we will still need the waker write pipe. + However we still want to be able to detect end-of-data in the + normal case. The reader thread will have to switch to using + PeekNamedPipe to read the last bit of data from the pipe + without blocking. This is equivalent to using a non-blocking + read on posix. */ + KWSYSPE_DEBUG((stderr, "closing wakeup write %d\n", i)); kwsysProcessCleanupHandle(&cp->Pipe[i].Write); } } @@ -2842,6 +2891,7 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) /* If data were just reported data, release the pipe's thread. */ if(cp->CurrentIndex < KWSYSPE_PIPE_COUNT) { + KWSYSPE_DEBUG((stderr, "releasing reader %d\n", cp->CurrentIndex)); ReleaseSemaphore(cp->Pipe[cp->CurrentIndex].Reader.Go, 1, 0); cp->CurrentIndex = KWSYSPE_PIPE_COUNT; } @@ -2862,6 +2912,7 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) below. */ if(cp->Pipe[i].Read) { + KWSYSPE_DEBUG((stderr, "releasing waker %d\n", i)); ReleaseSemaphore(cp->Pipe[i].Waker.Go, 1, 0); } } @@ -2871,9 +2922,11 @@ static void kwsysProcessDisablePipeThreads(kwsysProcess* cp) { /* The waking threads will cause all reading threads to report. Wait for the next one and save its index. */ + KWSYSPE_DEBUG((stderr, "waiting for reader\n")); WaitForSingleObject(cp->Full, INFINITE); cp->CurrentIndex = cp->SharedIndex; ReleaseSemaphore(cp->SharedIndexMutex, 1, 0); + KWSYSPE_DEBUG((stderr, "got reader %d\n", cp->CurrentIndex)); /* We are done reading this pipe. Close its read handle. */ cp->Pipe[cp->CurrentIndex].Closed = 1; diff --git a/GCC_XML/KWSys/String.hxx.in b/GCC_XML/KWSys/String.hxx.in index 6f449bb..5157fb6 100644 --- a/GCC_XML/KWSys/String.hxx.in +++ b/GCC_XML/KWSys/String.hxx.in @@ -54,6 +54,14 @@ public: stl_string(s, pos, n) {} }; // End Class: String +#if defined(__WATCOMC__) +inline bool operator<(String const& l, String const& r) + { + return (static_cast<@KWSYS_NAMESPACE@_stl::string const&>(l) < + static_cast<@KWSYS_NAMESPACE@_stl::string const&>(r)); + } +#endif + } // namespace @KWSYS_NAMESPACE@ #endif diff --git a/GCC_XML/KWSys/System.c b/GCC_XML/KWSys/System.c index fdf2b28..c400674 100644 --- a/GCC_XML/KWSys/System.c +++ b/GCC_XML/KWSys/System.c @@ -50,6 +50,15 @@ just NOT quote them and let the listfile author deal with it. */ +/* +TODO: For windows echo: + +To display a pipe (|) or redirection character (< or >) when using the +echo command, use a caret character immediately before the pipe or +redirection character (for example, ^>, ^<, or ^| ). If you need to +use the caret character itself (^), use two in a row (^^). +*/ + /*--------------------------------------------------------------------------*/ static int kwsysSystem_Shell__CharIsWhitespace(char c) { @@ -60,7 +69,9 @@ static int kwsysSystem_Shell__CharIsWhitespace(char c) static int kwsysSystem_Shell__CharNeedsQuotesOnUnix(char c) { return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') || - (c == '&') || (c == '$') || (c == '(') || (c == ')')); + (c == '&') || (c == '$') || (c == '(') || (c == ')') || + (c == '~') || (c == '<') || (c == '>') || (c == '|') || + (c == '*') || (c == '^') || (c == '\\')); } /*--------------------------------------------------------------------------*/ @@ -157,6 +168,7 @@ static int kwsysSystem_Shell__ArgumentNeedsQuotes(const char* in, int isUnix, int flags) { /* Scan the string for characters that require quoting. */ + { const char* c; for(c=in; *c; ++c) { @@ -189,6 +201,18 @@ static int kwsysSystem_Shell__ArgumentNeedsQuotes(const char* in, int isUnix, return 1; } } + } + + /* On Windows some single character arguments need quotes. */ + if(!isUnix && *in && !*(in+1)) + { + char c = *in; + if((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) + { + return 1; + } + } + return 0; } @@ -287,6 +311,17 @@ static int kwsysSystem_Shell__GetArgumentSize(const char* in, ++size; } } + else if(*c == '%') + { + if((flags & kwsysSystem_Shell_Flag_VSIDE) || + ((flags & kwsysSystem_Shell_Flag_Make) && + (flags & kwsysSystem_Shell_Flag_MinGWMake))) + { + /* In the VS IDE or MinGW make a percent is written %% so we + need one extra characters. */ + size += 1; + } + } } /* Check whether the argument needs surrounding quotes. */ @@ -432,6 +467,22 @@ static char* kwsysSystem_Shell__GetArgument(const char* in, char* out, *out++ = '#'; } } + else if(*c == '%') + { + if((flags & kwsysSystem_Shell_Flag_VSIDE) || + ((flags & kwsysSystem_Shell_Flag_Make) && + (flags & kwsysSystem_Shell_Flag_MinGWMake))) + { + /* In the VS IDE or MinGW make a percent is written %%. */ + *out++ = '%'; + *out++ = '%'; + } + else + { + /* Otherwise a percent is written just %. */ + *out++ = '%'; + } + } else { /* Store this character. */ diff --git a/GCC_XML/KWSys/System.h.in b/GCC_XML/KWSys/System.h.in index 1a51c3a..5967f4d 100644 --- a/GCC_XML/KWSys/System.h.in +++ b/GCC_XML/KWSys/System.h.in @@ -33,6 +33,7 @@ #define kwsysSystem_Shell_Flag_VSIDE kwsys_ns(System_Shell_Flag_VSIDE) #define kwsysSystem_Shell_Flag_EchoWindows kwsys_ns(System_Shell_Flag_EchoWindows) #define kwsysSystem_Shell_Flag_WatcomWMake kwsys_ns(System_Shell_Flag_WatcomWMake) +#define kwsysSystem_Shell_Flag_MinGWMake kwsys_ns(System_Shell_Flag_MinGWMake) #define kwsysSystem_Shell_Flag_AllowMakeVariables kwsys_ns(System_Shell_Flag_AllowMakeVariables) #if defined(__cplusplus) @@ -86,12 +87,15 @@ enum kwsysSystem_Shell_Flag_e /** The target shell is in a Watcom WMake makefile. */ kwsysSystem_Shell_Flag_WatcomWMake = (1<<3), + /** The target shell is in a MinGW Make makefile. */ + kwsysSystem_Shell_Flag_MinGWMake = (1<<4), + /** Make variable reference syntax $(MAKEVAR) should not be escaped to allow a build tool to replace it. Replacement values containing spaces, quotes, backslashes, or other non-alphanumeric characters that have significance to some makes or shells produce undefined behavior. */ - kwsysSystem_Shell_Flag_AllowMakeVariables = (1<<4) + kwsysSystem_Shell_Flag_AllowMakeVariables = (1<<5) }; #if defined(__cplusplus) @@ -112,6 +116,7 @@ enum kwsysSystem_Shell_Flag_e # undef kwsysSystem_Shell_Flag_VSIDE # undef kwsysSystem_Shell_Flag_EchoWindows # undef kwsysSystem_Shell_Flag_WatcomWMake +# undef kwsysSystem_Shell_Flag_MinGWMake # undef kwsysSystem_Shell_Flag_AllowMakeVariables #endif diff --git a/GCC_XML/KWSys/SystemTools.cxx b/GCC_XML/KWSys/SystemTools.cxx index 1359bc3..613cbd2 100644 --- a/GCC_XML/KWSys/SystemTools.cxx +++ b/GCC_XML/KWSys/SystemTools.cxx @@ -154,6 +154,11 @@ inline const char* Getcwd(char* buf, unsigned int len) fprintf(stderr, "No current working directory.\n"); abort(); } + // make sure the drive letter is capital + if(strlen(buf) > 1 && buf[1] == ':') + { + buf[0] = toupper(buf[0]); + } return ret; } inline int Chdir(const char* dir) @@ -2875,6 +2880,11 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const char* p) { return p; } + // make sure drive letter is always upper case + if(longPath.size() > 1 && longPath[1] == ':') + { + longPath[0] = toupper(longPath[0]); + } return longPath; #endif } diff --git a/GCC_XML/KWSys/kwsysPlatformTestsCXX.cxx b/GCC_XML/KWSys/kwsysPlatformTestsCXX.cxx index ccc46fe..93d7d22 100644 --- a/GCC_XML/KWSys/kwsysPlatformTestsCXX.cxx +++ b/GCC_XML/KWSys/kwsysPlatformTestsCXX.cxx @@ -46,6 +46,9 @@ int main() { return 0; } #ifdef TEST_KWSYS_IOS_USE_SSTREAM #include +#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ == 96 +# error "GCC 2.96 stringstream is buggy" +#endif int main() { std::ostringstream ostr; diff --git a/GCC_XML/KWSys/kwsys_ios_sstream.h.in b/GCC_XML/KWSys/kwsys_ios_sstream.h.in index 241dfcd..b99ceeb 100644 --- a/GCC_XML/KWSys/kwsys_ios_sstream.h.in +++ b/GCC_XML/KWSys/kwsys_ios_sstream.h.in @@ -95,6 +95,8 @@ public: // Visual Studio 6 has a strstream::pcount, but this is not rdbuf()->pcount() #if (@KWSYS_NAMESPACE@_IOS_USE_STRSTREA_H) && defined(_MSC_VER) && (_MSC_VER == 1200) int count = this->pcount(); +#elif defined(__WATCOMC__) + int count = this->rdbuf()->out_waiting(); #else int count = this->rdbuf()->pcount(); #endif @@ -151,6 +153,10 @@ private: # pragma warning (push) # pragma warning (disable: 4097) /* typedef-name used as synonym for class */ #endif +#if defined(__WATCOMC__) +// W728: class modifiers for 'A' conflict with class modifiers for 'B' +# pragma warning 728 10 +#endif class istringstream: private kwsys_stl::string, public istrstream { @@ -167,11 +173,18 @@ public: this->~istringstream(); new (this) istringstream(s); } + void clear(int flags) + { + this->IStrStream::clear(flags); + } private: istringstream(const istringstream&); void operator=(const istringstream&); }; +#if defined(__WATCOMC__) +# pragma warning 728 9 +#endif #if defined(_MSC_VER) # pragma warning (pop) #endif diff --git a/GCC_XML/KWSys/kwsys_stl_string.hxx.in b/GCC_XML/KWSys/kwsys_stl_string.hxx.in index c94b989..a81c9b9 100644 --- a/GCC_XML/KWSys/kwsys_stl_string.hxx.in +++ b/GCC_XML/KWSys/kwsys_stl_string.hxx.in @@ -29,6 +29,13 @@ # define @KWSYS_NAMESPACE@_STL_STRING_ISTREAM_DEFINED # include // isspace # include <@KWSYS_NAMESPACE@/ios/iostream> +# if defined(__WATCOMC__) +namespace @KWSYS_NAMESPACE@ +{ +struct ios_istream_hack: public kwsys_ios::istream +{ void eatwhite() { this->@KWSYS_NAMESPACE@_ios::istream::eatwhite(); } }; +} +# endif inline @KWSYS_NAMESPACE@_ios::istream& operator>>(@KWSYS_NAMESPACE@_ios::istream& is, @KWSYS_NAMESPACE@_stl::string& s) @@ -43,8 +50,12 @@ operator>>(@KWSYS_NAMESPACE@_ios::istream& is, s.erase(); // Skip leading whitespace. +#if defined(__WATCOMC__) + static_cast<@KWSYS_NAMESPACE@::ios_istream_hack&>(is).eatwhite(); +#else is.eatwhite(); - istream& okay = is; +#endif + @KWSYS_NAMESPACE@_ios::istream& okay = is; if(okay) { @@ -65,7 +76,7 @@ operator>>(@KWSYS_NAMESPACE@_ios::istream& is, // Set flags for resulting state. if(is.peek() == EOF) { state |= @KWSYS_NAMESPACE@_ios::ios::eofbit; } - if(success) { state |= @KWSYS_NAMESPACE@_ios::ios::failbit; } + if(!success) { state |= @KWSYS_NAMESPACE@_ios::ios::failbit; } } // Set the final result state. diff --git a/GCC_XML/KWSys/testIOS.cxx b/GCC_XML/KWSys/testIOS.cxx index 632b5c2..e4e0a2d 100644 --- a/GCC_XML/KWSys/testIOS.cxx +++ b/GCC_XML/KWSys/testIOS.cxx @@ -6,6 +6,7 @@ // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. #if 0 +# include "kwsys_stl_string.hxx.in" # include "kwsys_stl_vector.h.in" # include "kwsys_ios_sstream.h.in" # include "kwsys_ios_iostream.h.in" @@ -14,7 +15,109 @@ int testIOS(int, char*[]) { kwsys_ios::ostringstream ostr; - ostr << "Hello, World!"; - kwsys_ios::cout << ostr.str() << kwsys_ios::endl; + ostr << "hello"; + if(ostr.str() != "hello") + { + kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl; + return 1; + } + kwsys_ios::istringstream istr(" 10 20 str "); + kwsys_stl::string s; + int x; + if(istr >> x) + { + if(x != 10) + { + kwsys_ios::cerr << "x != 10" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl; + return 1; + } + if(istr >> x) + { + if(x != 20) + { + kwsys_ios::cerr << "x != 20" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl; + return 1; + } + if(istr >> s) + { + if(s != "str") + { + kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl; + return 1; + } + if(istr >> s) + { + kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl; + return 1; + } + else + { + // Clear the failure. + istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit); + istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit); + } + istr.str("30"); + if(istr >> x) + { + if(x != 30) + { + kwsys_ios::cerr << "x != 30" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl; + return 1; + } + + kwsys_ios::stringstream sstr; + sstr << "40 str2"; + if(sstr >> x) + { + if(x != 40) + { + kwsys_ios::cerr << "x != 40" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl; + return 1; + } + if(sstr >> s) + { + if(s != "str2") + { + kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl; + return 1; + } + } + else + { + kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl; + return 1; + } + + kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl; return 0; } diff --git a/GCC_XML/xml.c b/GCC_XML/xml.c index da89ee3..392ce50 100644 --- a/GCC_XML/xml.c +++ b/GCC_XML/xml.c @@ -76,7 +76,7 @@ # define XML_PRE_3_4_TREE_VIA_PUBLIC #endif -#define GCC_XML_C_VERSION "$Revision: 1.114 $" +#define GCC_XML_C_VERSION "$Revision: 1.115 $" /*--------------------------------------------------------------------------*/ /* Data structures for the actual XML dump. */ @@ -1504,6 +1504,46 @@ xml_document_add_attribute_bits(xml_document_element_p element) xml_document_attribute_use_optional, 0); } +/*--------------------------------------------------------------------------*/ +/* Print the XML attribute befriending="..." for a function or class. */ +static void +xml_print_befriending_attribute (xml_dump_info_p xdi, tree befriending) +{ + int have_befriending = 0; + tree frnd; + for (frnd = befriending ; frnd && !have_befriending ; + frnd = TREE_CHAIN (frnd)) + { + if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) + { + have_befriending = 1; + } + } + if(have_befriending) + { + const char* sep = ""; + fprintf (xdi->file, " befriending=\""); + for (frnd = befriending ; frnd ; frnd = TREE_CHAIN (frnd)) + { + if(TREE_CODE (TREE_VALUE (frnd)) != TEMPLATE_DECL) + { + fprintf (xdi->file, + "%s_%d", sep, xml_add_node (xdi, TREE_VALUE (frnd), 0)); + sep = " "; + } + } + fprintf (xdi->file, "\""); + } +} + +static void +xml_document_add_attribute_befriending(xml_document_element_p element) +{ + xml_document_add_attribute(element, "befriending", + xml_document_attribute_type_idrefs, + xml_document_attribute_use_optional, 0); +} + /*--------------------------------------------------------------------------*/ /* Print XML empty tag describing an unimplemented TREE_CODE that has been encountered. */ @@ -1888,6 +1928,7 @@ xml_output_function_decl (xml_dump_info_p xdi, tree fd, xml_dump_node_p dn) xml_print_inline_attribute (xdi, fd); xml_print_attributes_attribute (xdi, GCC_XML_DECL_ATTRIBUTES(fd), TYPE_ATTRIBUTES(TREE_TYPE(fd))); + xml_print_befriending_attribute (xdi, DECL_BEFRIENDING_CLASSES (fd)); /* Prepare to iterator through argument list. */ arg = DECL_ARGUMENTS (fd); @@ -1979,6 +2020,7 @@ xml_document_add_element_function_helper (xml_document_info_p xdi, xml_document_add_attribute_extern(e); xml_document_add_attribute_inline(e); xml_document_add_attribute_attributes(e); + xml_document_add_attribute_befriending(e); if(allow_arguments) { xml_document_add_element_argument (xdi, e); @@ -2148,6 +2190,7 @@ xml_output_record_type (xml_dump_info_p xdi, tree rt, xml_dump_node_p dn) xml_print_attributes_attribute (xdi, TYPE_ATTRIBUTES(rt), 0); xml_print_size_attribute (xdi, rt); xml_print_align_attribute (xdi, rt); + xml_print_befriending_attribute (xdi, CLASSTYPE_BEFRIENDING_CLASSES (rt)); if (dn->complete && COMPLETE_TYPE_P (rt)) { @@ -2337,6 +2380,7 @@ xml_document_add_element_record_type_helper (xml_document_info_p xdi, xml_document_add_attribute_attributes(e); xml_document_add_attribute_size(e); xml_document_add_attribute_align(e); + xml_document_add_attribute_befriending(e); xml_document_add_attribute(e, "members", xml_document_attribute_type_idrefs, xml_document_attribute_use_optional, 0);