Diff for /parser3/src/main/pa_globals.C between versions 1.167 and 1.217

version 1.167, 2004/02/11 09:18:24 version 1.217, 2024/12/23 16:59:17
Line 1 Line 1
 /** @file  /** @file
         Parser: globals.          Parser: globals.
   
         Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)          Copyright (c) 2001-2024 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 "pa_vregex.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
   
 // 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 XML  #ifdef XML
   
 class XML_Generic_error_info {  class XML_Generic_error_info {
 public:  public:/*internal, actually*/
         char buf[MAX_STRING*5];          char buf[MAX_STRING*5];
         size_t used;          size_t used;
 public:  public:
         XML_Generic_error_info() {          XML_Generic_error_info() {
                 reset();  
         }  
         void reset() {   
                 buf[used=0]=0;                  buf[used=0]=0;
         }          }
         const char* get_and_reset() {          const char* get() {
                 if(used) {                  return used? buf: 0;
                         char* result=pa_strdup(buf, used);  
                         reset();  
                         return result;  
                 } else  
                         return 0;                 
         }          }
 };  };
   
 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;          XML_Generic_error_info* p;
         pa_thread_t thread_id=pa_get_thread_id();          
           if(!(p=xml_generic_error_info)) // occupy empty one
         // infinitely looking for free slot to fill it                  p=xml_generic_error_info=new(PointerFreeGC) XML_Generic_error_info;
         while(true) {  
                 SYNCHRONIZED;  // find+fill blocked  
   
                 // first try to get existing for this thread_id  
                 XML_Generic_error_info *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);
                 p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);          p->used+=vsnprintf(p->buf+p->used, sizeof(p->buf)-p->used, msg, args);
                 va_end(args);          va_end(args);
   
                 break;  
         }  
 }  }
   
 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                  return p->get();
           }
         if(XML_Generic_error_info *p=xml_generic_error_infos.get(thread_id))  
                 return p->get_and_reset();  
   
         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 165  static char *pa_GC_strdup(const char *s) Line 111  static char *pa_GC_strdup(const char *s)
                 return 0;                  return 0;
   
         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
           fprintf(stderr, "pa_GC_strdup(%p=%s, length=%d)=0x%p\n", s, s, size, result);
   #endif
         return result;          return result;
 }  }
   
 #ifdef PA_DEBUG_XML_GC_MEMORY  #ifdef PA_DEBUG_XML_GC_MEMORY
 void *pa_look_for[]={(void*)0x8abe000,(void*)0x0,(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)  
                         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){
         void *p=pa_gc_malloc_atomic(size);          void *p=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);
 //      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_ignore(void *){}  
 static void pa_gc_free_log(void *p){  static void pa_gc_free_log(void *p){
         fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);          fprintf(stderr, "pa_gc_free_log(0x%p)\n", p);
 //      if(pa_looked(p))          GC_FREE(p);
 //              fprintf(stderr,"catched debug free(0x%p)\n", p);  
         pa_gc_free(p);  
 }  }
   
 #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) { 
         return check(pa_gc_malloc_atomic(size), "allocating XML atomic memory", size);          return check(GC_MALLOC_ATOMIC(size), "allocate XML atomic memory", size);
 }  }
   
 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(void* ptr) {
           GC_FREE(ptr);
 }  }
   
 #endif  #endif
   
   #endif // XML
   
   #ifdef HAVE_PCRE2
   pcre2_general_context* VRegex::fgen_ctxt;
   
   static void* pa_pcre_malloc(size_t size, void *){
           return pa_malloc(size);
   }
   
   static void pa_pcre_free(void *ptr, void *){
           pa_free(ptr);
   }
 #endif  #endif
   
   
 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 243  static void gc_substitute_memory_managem Line 201  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 253  static void gc_substitute_memory_managem Line 210  static void gc_substitute_memory_managem
                 /*xmlStrdupFunc */pa_GC_strdup);                  /*xmlStrdupFunc */pa_GC_strdup);
 #else  #else
         xmlGcMemSetup(          xmlGcMemSetup(
                 /*xmlFreeFunc */pa_gc_free,                  /*xmlFreeFunc */pa_gc_free_maybeignore,
                 /*xmlMallocFunc */pa_gc_malloc_nonull,                  /*xmlMallocFunc */pa_gc_malloc_nonull,
                 /*xmlMallocFunc */pa_gc_malloc_atomic_nonull,                  /*xmlMallocFunc */pa_gc_malloc_atomic_nonull,
                 /*xmlReallocFunc */pa_gc_realloc_nonull,                  /*xmlReallocFunc */pa_gc_realloc_nonull,
                 /*xmlStrdupFunc */pa_GC_strdup);                  /*xmlStrdupFunc */pa_GC_strdup);
 #endif  #endif
   
 #else  
         xmlMemSetup(  
                 /*xmlFreeFunc */pa_gc_free,  
                 /*xmlMallocFunc */pa_gc_malloc,  
                 /*xmlReallocFunc */pa_gc_realloc,  
                 /*xmlStrdupFunc */pa_GC_strdup);  
 #endif  
   
 #endif  #endif
   
         // pcre          // pcre
         pcre_malloc=pa_gc_malloc;  #ifdef HAVE_PCRE2
         pcre_free=pa_gc_free;          VRegex::fgen_ctxt=pcre2_general_context_create(pa_pcre_malloc, pa_pcre_free, NULL);
   #else
           pcre_malloc=pa_malloc;
           pcre_free=pa_free;
   #endif
   
         // cord          // cord
         CORD_oom_fn=pa_CORD_oom_fn;          CORD_oom_fn=pa_CORD_oom_fn;
Line 283  static void gc_substitute_memory_managem Line 235  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 332  void pa_globals_init() { Line 289  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
   
           // init *_class variables
           methoded_array();
   }
   
   static bool is_dlinited=false;
   
   void pa_globals_done() {
           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/binaries-debug/libxml2_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxml2-x.x.x/win32/binaries-debug/libxml2.lib")  
 #               endif  
   
 #               ifdef LIBXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-debug/libxslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-debug/libxslt.lib")  
 #               endif  
 #               ifdef LIBEXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-debug/libexslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-debug/libexslt.lib")  
 #               endif  
   
 #               ifdef LIBGDOME_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_DebugStatic/libgdome.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_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/binaries-release/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/binaries-release/libxml2.lib")  
 #               endif  
   
 #               ifdef LIBXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-release/libxslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-release/libxslt.lib")  
 #               endif  
 #               ifdef LIBEXSLT_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-release/libexslt_a.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/libxslt-x.x.x/win32/binaries-release/libexslt.lib")  
 #               endif  
   
 #               ifdef LIBGDOME_STATIC  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_ReleaseStatic/libgdome.lib")  
 #               else  
 #                       pragma comment(lib, GNOME_LIBS "/gdome2-x.x.x/win32/dsp/libgdome_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.167  
changed lines
  Added in v.1.217


E-mail: