Diff for /parser3/src/main/pa_globals.C between versions 1.178 and 1.213

version 1.178, 2005/11/30 14:56:16 version 1.213, 2023/09/26 20:49:10
Line 1 Line 1
 /** @file  /** @file
         Parser: globals.          Parser: globals.
   
         Copyright (c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
 */  */
   
 static const char * const IDENT_GLOBALS_C="$Date$";  
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   
 #ifdef XML  #ifdef XML
Line 15  static const char * const IDENT_GLOBALS_ Line 13  static const char * const IDENT_GLOBALS_
 #include "libxslt/xsltutils.h"  #include "libxslt/xsltutils.h"
 extern "C" {  extern "C" {
 #include "libexslt/exslt.h"  #include "libexslt/exslt.h"
 };  }
 #endif  #endif
   
 #include "pcre.h"  
   
 #include "pa_globals.h"  #include "pa_globals.h"
 #include "pa_string.h"  #include "pa_socks.h"
 #include "pa_sapi.h"  #include "pa_sapi.h"
 #include "pa_threads.h"  
 #include "pa_xml_io.h"  #include "pa_xml_io.h"
 #include "pa_common.h"  #include "pa_common.h"
   #include "pa_symbols.h"
   
 #include "pa_cache_managers.h"  #include "pa_cache_managers.h"
   
   #include "ltdl.h"
   #include "pcre.h"
   
   volatile const char * IDENT_PA_GLOBALS_C="$Id$" IDENT_PA_GLOBALS_H IDENT_PA_SAPI_H;
   
 // defines  // defines
   
 //#define PA_DEBUG_XML_GC_MEMORY  //#define PA_DEBUG_XML_GC_MEMORY
   
 //20051130 trying to remove this, author claims that fixed a lot there // 20040920 for now both workarounds needed. wait for new libxml/xsl versions  
 // // there is a problem with testcase, it's unstable.   
 // // see paf@six/bug20040920/cgi-bin/t for it-showed-bug-on-20040920-day  
 // #define PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY  
 // #define PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY  
   
 // globals  // globals
   
 short hex_value[0x100];  short hex_value[0x100] = {
             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 #ifdef XML            0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 GdomeDOMImplementation *domimpl;            0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 #endif            0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0,  0,  0,  0,  0,
             0, 10, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 static void setup_hex_value() {            0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         memset(hex_value, 0, sizeof(hex_value));            0, 10, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         hex_value['0'] = 0;       };
         hex_value['1'] = 1;       
         hex_value['2'] = 2;       
         hex_value['3'] = 3;       
         hex_value['4'] = 4;       
         hex_value['5'] = 5;       
         hex_value['6'] = 6;       
         hex_value['7'] = 7;       
         hex_value['8'] = 8;       
         hex_value['9'] = 9;  
         hex_value['A'] = 10;  
         hex_value['B'] = 11;  
         hex_value['C'] = 12;  
         hex_value['D'] = 13;  
         hex_value['E'] = 14;  
         hex_value['F'] = 15;  
         hex_value['a'] = 10;  
         hex_value['b'] = 11;  
         hex_value['c'] = 12;  
         hex_value['d'] = 13;  
         hex_value['e'] = 14;  
         hex_value['f'] = 15;  
 }  
   
   THREAD_LOCAL Request* thread_request=NULL; // every TLS should be referenced elsewhere, or GC will collect it
   
 Hash<pa_thread_t, Request*> thread_request;  
 void pa_register_thread_request(Request& r) {  void pa_register_thread_request(Request& r) {
         thread_request.put(pa_get_thread_id(), &r);          thread_request=&r;
 }  }
   
 /// retrives request set by pa_set_request function, useful in contextless places [slow]  /// retrives request set by pa_set_request function, useful in contextless places [slow]
 Request& pa_thread_request() {  Request& pa_thread_request() {
         return *thread_request.get(pa_get_thread_id());          if(!thread_request)
 }                  throw Exception(0, 0, "request is not initialized");
           return *thread_request;
 #ifdef PA_RELEASE_ASSERTS  
 void pa_release_assert(const char* str, const char* file, int line) {  
         SAPI::die("%s at %s:%d", str, file, line);   
 }  }
 #endif  
   
   
 #ifdef XML  #ifdef XML
Line 105  public: Line 75  public:
         }          }
 };  };
   
 static Hash<pa_thread_t, XML_Generic_error_info*> xml_generic_error_infos;  THREAD_LOCAL XML_Generic_error_info* xml_generic_error_info = NULL;
   
 static void xmlParserGenericErrorFunc(void *  /*ctx*/, const char* msg, ...) {   static void xmlParserGenericErrorFunc(void *  /*ctx*/, const char* msg, ...) { 
 //_asm int 3;  
         pa_thread_t thread_id=pa_get_thread_id();  
   
         XML_Generic_error_info* p;          XML_Generic_error_info* p;
         {          
                 SYNCHRONIZED;  // find+fill blocked          if(!(p=xml_generic_error_info)) // occupy empty one
                   p=xml_generic_error_info=new(PointerFreeGC) XML_Generic_error_info;
                 // first try to get existing for this thread_id  
                 p=xml_generic_error_infos.get(thread_id);  
                 if(!p) // occupy empty one  
                         xml_generic_error_infos.put(thread_id, (p=new(PointerFreeGC) XML_Generic_error_info));  
         }  
                                   
         va_list args;          va_list args;
         va_start(args, msg);          va_start(args, msg);
Line 128  static void xmlParserGenericErrorFunc(vo Line 90  static void xmlParserGenericErrorFunc(vo
 }  }
   
 bool xmlHaveGenericErrors() {  bool xmlHaveGenericErrors() {
         pa_thread_t thread_id=pa_get_thread_id();          return xml_generic_error_info!=0;
   
         SYNCHRONIZED;  // find blocked  
   
         return xml_generic_error_infos.get(thread_id)!=0;  
 }  }
   
 const char* xmlGenericErrors() {  const char* xmlGenericErrors() {
         pa_thread_t thread_id=pa_get_thread_id();          if(XML_Generic_error_info *p=xml_generic_error_info) {
                   xml_generic_error_info=0;
         SYNCHRONIZED;  // find+free blocked  
   
         if(XML_Generic_error_info *p=xml_generic_error_infos.get(thread_id)) {  
                 xml_generic_error_infos.remove(thread_id);  
                 return p->get();                  return p->get();
         }          }
   
         return 0; // no errors for our thread_id registered          return 0; // no errors for our thread_id registered
 }  }
   
 #endif  #endif // XML
   
 void pa_globals_destroy(void *) {  
         try {  
 #ifdef XML  
                 GdomeException exc;  
                 gdome_di_unref (domimpl, &exc);  
                 // uncomment SAPI::abort below if adding potential-throw code here  
 #endif  
         } catch(const Exception& e) {  
 //              SAPI::abort("pa_globals_destroy failed: %s", e.comment());  
         }  
 }  
   
   
 #ifdef XML  #ifdef XML
   
Line 171  static char *pa_GC_strdup(const char *s) Line 112  static char *pa_GC_strdup(const char *s)
   
         size_t size=strlen(s)+1;          size_t size=strlen(s)+1;
         char *result=(char *)GC_MALLOC_ATOMIC(size);          char *result=(char *)GC_MALLOC_ATOMIC(size);
   
         if(!result)          if(!result)
                 SAPI::abort("out of memory (while duplicating XML string [size=%d])", size);                  pa_fail_alloc("duplicate XML string",size);
   
         memcpy(result, s, size);          memcpy(result, s, size);
 #ifdef PA_DEBUG_XML_GC_MEMORY  #ifdef PA_DEBUG_XML_GC_MEMORY
Line 182  static char *pa_GC_strdup(const char *s) Line 124  static char *pa_GC_strdup(const char *s)
 }  }
   
 #ifdef PA_DEBUG_XML_GC_MEMORY  #ifdef PA_DEBUG_XML_GC_MEMORY
 void *pa_look_for[]={(void*)0x84ba980,(void*)0x8969460,(void*)0x0,(void*)0x0,  
                         (void*)0x0,(void*)0x0,(void*)0x0,(void*)0x0};  
 bool pa_looked(void*p) {  
         for(int i=0; i<8; i++)  
                 if(pa_look_for[i]==p) {  
                         __asm__("int $3");  
                         return true;  
                 }  
         if((((int)p)&~0xFF)==0x89a7700) {  
                 __asm__("int $3");  
                 return true;  
         }  
         return false;  
 }  
 static void* pa_gc_malloc_log(size_t size){  static void* pa_gc_malloc_log(size_t size){
         void *p=pa_gc_malloc(size);          void *p=GC_MALLOC(size);
         fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);          fprintf(stderr, "pa_gc_malloc_log(%d)=0x%p\n", size, p);
         if(pa_looked(p))  
                 fprintf(stderr,"catched debug malloc(%d)=0x%p\n", size, p);  
         return p;          return p;
                   
 }  }
   
 static void* pa_gc_malloc_atomic_log(size_t size){  static void* pa_gc_malloc_atomic_log(size_t size){
 #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY          void *p=GC_MALLOC_ATOMIC(size);
         void *p=pa_gc_malloc(size);  
         fprintf(stderr, "pa_gc_malloc_atomicFAKE_log(%d)=0x%p\n", size, p);  
 #else  
         void *p=pa_gc_malloc_atomic(size);  
         fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);          fprintf(stderr, "pa_gc_malloc_atomic_log(%d)=0x%p\n", size, p);
 #endif  
         if(pa_looked(p))  
                 fprintf(stderr,"catched debug malloc atomic(%d)=0x%p\n", size, p);  
         return p;          return p;
 }  }
   
 static void* pa_gc_realloc_log(void *ptr, size_t size){  static void* pa_gc_realloc_log(void *ptr, size_t size){
         void *p=pa_gc_realloc(ptr, size);          void *p=GC_REALLOC(ptr, size);
         fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);          fprintf(stderr, "pa_gc_realloc_log(0x%p, %d)=0x%p\n", ptr, size, p);
         if(pa_looked(p))  
                 fprintf(stderr,"catched debug realloc(%d)=0x%p\n", size, p);  
         return p;          return p;
 }  }
   
 static void pa_gc_free_log(void *p){  static void pa_gc_free_log(void *p){
 #ifdef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY  
         fprintf(stderr, "pa_gc_freeIGNORE_log(0x%p)\n", p);  
 #else  
         fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);          fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
 #endif          GC_FREE(p);
         if(pa_looked(p))  
                 fprintf(stderr,"catched debug free(0x%p)\n", p);  
 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY  
         pa_gc_free(p);  
 #endif  
 }  }
   
 #else  #else
   
 inline void *check(void *result, const char *where, size_t size) {  inline void *check(void *result, const char *where, size_t size) {
         if(!result)          if(!result)
                 SAPI::abort("out of memory (while %s [size=%d])", where, size);                  pa_fail_alloc(where, size);
   
         return result;          return result;
 }  }
   
 static void* pa_gc_malloc_nonull(size_t size) {   static void* pa_gc_malloc_nonull(size_t size) { 
         return check(pa_gc_malloc(size), "allocating XML compsite memory", size);          return check(GC_MALLOC(size), "allocate XML compsite memory", size);
 }  }
   
 static void* pa_gc_malloc_atomic_nonull(size_t size) {   static void* pa_gc_malloc_atomic_nonull(size_t size) { 
 #ifdef PA_WORKAROUND_BUGGY_MALLOCATOMIC_IN_LIBXML_GC_MEMORY          return check(GC_MALLOC_ATOMIC(size), "allocate XML atomic memory", size);
         return check(pa_gc_malloc(size), "allocating XML composite memory (asked atomic)", size);  
 #else  
         return check(pa_gc_malloc_atomic(size), "allocating XML atomic memory", size);  
 #endif  
 }  }
   
 static void* pa_gc_realloc_nonull(void* ptr, size_t size) {   static void* pa_gc_realloc_nonull(void* ptr, size_t size) { 
         return check(pa_gc_realloc(ptr, size), "reallocating XML memory", size);          return check(GC_REALLOC(ptr, size), "reallocate XML memory", size);
 }  }
   
 static void pa_gc_free_maybeignore(  static void pa_gc_free_maybeignore(void* ptr) {
         void*           GC_FREE(ptr);
 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY  
                 ptr  
 #endif  
         ) {  
 #ifndef PA_WORKAROUND_BUGGY_FREE_IN_LIBXML_GC_MEMORY  
         pa_gc_free(ptr);  
 #endif  
 }  }
   
 #endif  #endif
 #endif  
   #endif // XML
   
 void pa_CORD_oom_fn(void) {  void pa_CORD_oom_fn(void) {
         SAPI::abort("out of memory (while expanding string)");          pa_fail_alloc("expand string", 0);
 }  }
   
 /**  /**
Line 282  static void gc_substitute_memory_managem Line 188  static void gc_substitute_memory_managem
         // in libxml & libxslt          // in libxml & libxslt
 #ifdef XML  #ifdef XML
         // asking to use GC memory          // asking to use GC memory
 #if LIBXML_VERSION >= 20507  
 #ifdef PA_DEBUG_XML_GC_MEMORY  #ifdef PA_DEBUG_XML_GC_MEMORY
         xmlGcMemSetup(          xmlGcMemSetup(
                 /*xmlFreeFunc */pa_gc_free_log,                  /*xmlFreeFunc */pa_gc_free_log,
Line 299  static void gc_substitute_memory_managem Line 204  static void gc_substitute_memory_managem
                 /*xmlStrdupFunc */pa_GC_strdup);                  /*xmlStrdupFunc */pa_GC_strdup);
 #endif  #endif
   
 #else  
         xmlMemSetup(  
                 /*xmlFreeFunc */pa_gc_free_maybeignore,  
                 /*xmlMallocFunc */pa_gc_malloc,  
                 /*xmlReallocFunc */pa_gc_realloc,  
                 /*xmlStrdupFunc */pa_GC_strdup);  
 #endif  
   
 #endif  #endif
   
         // pcre          // pcre
         pcre_malloc=pa_gc_malloc;          pcre_malloc=pa_malloc;
         pcre_free=pa_gc_free;          pcre_free=pa_free;
   
   
         // cord          // cord
         CORD_oom_fn=pa_CORD_oom_fn;          CORD_oom_fn=pa_CORD_oom_fn;
Line 322  static void gc_substitute_memory_managem Line 218  static void gc_substitute_memory_managem
         @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);          @test hint on one should call this for each thread xmlSubstituteEntitiesDefault(1);
 */  */
 void pa_globals_init() {  void pa_globals_init() {
         // global variables   
         cache_managers=new Cache_managers;  
   
   #ifndef PA_DEBUG_DISABLE_GC
           // Dont collect unless explicitly requested. This is quicker (~30% ),
           // but less memory-efficient(~8%), so deciding for speed.
           GC_disable();
           // as we log allocation errors, we don't need default gc warnings (without timestamp and URI)
           GC_set_warn_proc(GC_ignore_warn_proc);
   #endif
   
           // init socks
           pa_socks_init();
   
           // global variables
           cache_managers=new Cache_managers;
   
         // in various libraries          // in various libraries
         gc_substitute_memory_management_functions();          gc_substitute_memory_management_functions();
   
         // hex value  #ifdef SYMBOLS_CACHING
         setup_hex_value();          // symbols cache
           Symbols::init();
   #endif
   
 #ifdef XML  #ifdef XML
         // initializing xml libs          // initializing xml libs
   
         /* First get a DOMImplementation reference */          // Register the EXSLT extensions and the test module
         domimpl = gdome_di_mkref ();  
         /*  
         * Register the EXSLT extensions and the test module  
         */  
         exsltRegisterAll();          exsltRegisterAll();
         xsltRegisterTestModule();          xsltRegisterTestModule();
         xmlDefaultSAXHandlerInit();          xmlDefaultSAXHandlerInit();
         /*  
         * disable CDATA from being built in the document tree          // disable CDATA from being built in the document tree
         */  
         // never added yet  xmlDefaultSAXHandler.cdataBlock = NULL;          // never added yet  xmlDefaultSAXHandler.cdataBlock = NULL;
                   
         /*          // Initialization function for the XML parser. This is not reentrant. 
          * Initialization function for the XML parser.          // Call once before processing in case of use in multithreaded programs.
          * This is not reentrant. Call once before processing in case of  
          * use in multithreaded programs.  
         */  
         xmlInitParser();          xmlInitParser();
   
         // 1. this is needed for proper parsing of stylesheets          // 1. this is needed for proper parsing of stylesheets
Line 371  void pa_globals_init() { Line 272  void pa_globals_init() {
         xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;          xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
   
         // validate each document after load/create (?)          // validate each document after load/create (?)
         //xmlDoValidityCheckingDefaultValue = 1;          // xmlDoValidityCheckingDefaultValue = 1;
   
 //regretfully this not only replaces entities on parse, but also on generate    xmlSubstituteEntitiesDefault(1);          // regretfully this not only replaces entities on parse, but also on generate   xmlSubstituteEntitiesDefault(1);
         // never switched this on xmlIndentTreeOutput=1;          // never switched this on xmlIndentTreeOutput=1;
   
         xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);          xmlSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
         xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);          xsltSetGenericErrorFunc(0, xmlParserGenericErrorFunc);
 //      FILE *f=fopen("y:\\xslt.log", "wt");  
   //      FILE *f=fopen("xslt.log", "wt");
 //      xsltSetGenericDebugFunc(f/*stderr*/, 0);  //      xsltSetGenericDebugFunc(f/*stderr*/, 0);
   
         pa_xml_io_init();          pa_xml_io_init();
 #endif  #endif
 }  }
   
   static bool is_dlinited=false;
   
 void pa_globals_done() {  void pa_globals_done() {
         delete cache_managers;  cache_managers=0;          delete cache_managers;
           cache_managers=0;
   
           if(is_dlinited)
                   lt_dlexit();
   
           pa_socks_done();
   }
   
   void pa_dlinit() {
           if(!is_dlinited){
                   if(lt_dlinit())
                           throw Exception(0,0,"preparation for dynamic library loading failed, %s", lt_dlerror());
                   is_dlinited=true;
           }
 }  }
   
 #ifdef _MSC_VER  #ifdef _MSC_VER
   
 #ifndef PA_DEBUG_DISABLE_GC  #define PREFIX "../../../../win32/"
 #       define GC_LIB "../../../../win32/gc"  
 #       ifdef _DEBUG  
 #               pragma comment(lib, GC_LIB "/Debug/gc.lib")  
 #       else  
 #               pragma comment(lib, GC_LIB "/Release/gc.lib")  
 #       endif  
   
   #ifdef _DEBUG
   #define CONFIGURATION "Debug"
   #else
   #define CONFIGURATION "Release"
 #endif  #endif
   
   #ifdef _WIN64
   #define PLATFORM_64 "x64/"
   #define PLATFORM_32 ""
   #else
   #define PLATFORM_64 ""
   #define PLATFORM_32 "win32/"
   #endif
   
   #pragma comment(lib, PREFIX "pcre/" PLATFORM_64 CONFIGURATION "/pcre.lib")
   
   #ifndef PA_DEBUG_DISABLE_GC
   
   #pragma comment(lib, PREFIX "gc/" PLATFORM_64 CONFIGURATION "/gc.lib")
   
   #endif // PA_DEBUG_DISABLE_GC
   
   
 #ifdef XML  #ifdef XML
 #       define GNOME_LIBS "../../../../win32/gnome"  
 #       pragma comment(lib, GNOME_LIBS "/glib/lib/libglib-1.3-11.lib")  
 #       ifdef _DEBUG  
   
 #               ifdef LIBXML_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/debug/lib/libxml2.lib")  
 #               endif  
   
 #               ifdef LIBXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libxslt.lib")  
 #               endif  
 #               ifdef LIBEXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/debug/lib/libexslt.lib")  
 #               endif  
   
 #               ifdef LIBGDOME_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/DebugStatic/libgdome.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/DebugDynamic/libgdome.lib")  
 #               endif  
   
 #else  #define GNOME_LIBS PREFIX "gnome"
   
 #               ifdef LIBXML_STATIC  #define LIB_XML PREFIX "gnome/libxml2-x.x.x/" PLATFORM_64 PLATFORM_32 CONFIGURATION "/lib/"
 #                       pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2_a.lib")  #define LIB_XSLT PREFIX "gnome/libxslt-x.x.x/" PLATFORM_64 PLATFORM_32 CONFIGURATION "/lib/"
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/release/lib/libxml2.lib")  
 #               endif  
   
 #               ifdef LIBXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libxslt.lib")  
 #               endif  
 #               ifdef LIBEXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/release/lib/libexslt.lib")  
 #               endif  
   
 #               ifdef LIBGDOME_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/ReleaseStatic/libgdome.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/ReleaseDynamic/libgdome.lib")  
 #               endif  
   
 #       endif  #ifdef XML_STATIC
   #pragma comment(lib, LIB_XML "libxml2_a.lib")
   #pragma comment(lib, LIB_XSLT "libxslt_a.lib")
   #pragma comment(lib, LIB_XSLT "libexslt_a.lib")
   #else
   #pragma comment(lib, LIB_XML "libxml2.lib")
   #pragma comment(lib, LIB_XSLT "libxslt.lib")
   #pragma comment(lib, LIB_XSLT "libexslt.lib")
 #endif  #endif
   
   #endif // XML
   
   // defines for VS2015 to link with gc/xml libs compiled in the previous VS versions
   #if _MSC_VER >= 1900
   #pragma comment(lib,"legacy_stdio_definitions.lib")
 #endif  #endif
   
   #endif // _MSC_VER

Removed from v.1.178  
changed lines
  Added in v.1.213


E-mail: