LibOFX

- Main Page
- Namespaces
- Data Structures
- Files

- File List
- Globals

# ofx_preproc.cpp

Go to the documentation of this file.

    00001 /***************************************************************************
    00002           ofx_preproc.cpp
    00003                              -------------------
    00004     copyright            : (C) 2002 by Benoit Gr�oir
    00005     email                : benoitg@coeus.ca
    00006 ***************************************************************************/
    00012 /***************************************************************************
    00013  *                                                                         *
    00014  *   This program is free software; you can redistribute it and/or modify  *
    00015  *   it under the terms of the GNU General Public License as published by  *
    00016  *   the Free Software Foundation; either version 2 of the License, or     *
    00017  *   (at your option) any later version.                                   *
    00018  *                                                                         *
    00019  ***************************************************************************/
    00020 #include "../config.h"
    00021 #include <iostream>
    00022 #include <fstream>
    00023 #include <stdlib.h>
    00024 #include <stdio.h>
    00025 #include <string>
    00026 #include "ParserEventGeneratorKit.h"
    00027 #include "libofx.h"
    00028 #include "messages.hh"
    00029 #include "ofx_sgml.hh"
    00030 #include "ofc_sgml.hh"
    00031 #include "ofx_preproc.hh"
    00032 #include "ofx_utilities.hh"
    00033 #ifdef HAVE_ICONV
    00034 #include <iconv.h>
    00035 #endif
    00036
    00037 #ifdef OS_WIN32
    00038 # define DIRSEP "\\"
    00039 #else
    00040 # define DIRSEP "/"
    00041 #endif
    00042
    00043 #ifdef OS_WIN32
    00044 # include "win32.hh"
    00045 # include <windows.h> // for GetModuleFileName()
    00046 # undef ERROR
    00047 # undef DELETE
    00048 #endif
    00049
    00050 #define LIBOFX_DEFAULT_INPUT_ENCODING "CP1252"
    00051 #define LIBOFX_DEFAULT_OUTPUT_ENCODING "UTF-8"
    00052
    00053 using namespace std;
    00057 #ifdef MAKEFILE_DTD_PATH
    00058 const int DTD_SEARCH_PATH_NUM = 4;
    00059 #else
    00060 const int DTD_SEARCH_PATH_NUM = 3;
    00061 #endif
    00062
    00066 const char *DTD_SEARCH_PATH[DTD_SEARCH_PATH_NUM] =
    00067 {
    00068 #ifdef MAKEFILE_DTD_PATH
    00069   MAKEFILE_DTD_PATH ,
    00070 #endif
    00071   "/usr/local/share/libofx/dtd",
    00072   "/usr/share/libofx/dtd",
    00073   "~"
    00074 };
    00075 const unsigned int READ_BUFFER_SIZE = 1024;
    00076
    00081 int ofx_proc_file(LibofxContextPtr ctx, const char * p_filename)
    00082 {
    00083   LibofxContext *libofx_context;
    00084   bool ofx_start = false;
    00085   bool ofx_end = false;
    00086
    00087   ifstream input_file;
    00088   ofstream tmp_file;
    00089   char buffer[READ_BUFFER_SIZE];
    00090   char iconv_buffer[READ_BUFFER_SIZE * 2];
    00091   string s_buffer;
    00092   char *filenames[3];
    00093   char tmp_filename[256];
    00094   int tmp_file_fd;
    00095 #ifdef HAVE_ICONV
    00096   iconv_t conversion_descriptor;
    00097 #endif
    00098   libofx_context = (LibofxContext*)ctx;
    00099
    00100   if (p_filename != NULL && strcmp(p_filename, "") != 0)
    00101   {
    00102     message_out(DEBUG, string("ofx_proc_file():Opening file: ") + p_filename);
    00103
    00104     input_file.open(p_filename);
    00105     if (!input_file)
    00106     {
    00107       message_out(ERROR, "ofx_proc_file():Unable to open the input file " + string(p_filename));
    00108     }
    00109
    00110     mkTempFileName("libofxtmpXXXXXX", tmp_filename, sizeof(tmp_filename));
    00111
    00112     message_out(DEBUG, "ofx_proc_file(): Creating temp file: " + string(tmp_filename));
    00113     tmp_file_fd = mkstemp(tmp_filename);
    00114     if(tmp_file_fd)
    00115     {
    00116     tmp_file.open(tmp_filename);
    00117     if (!tmp_file)
    00118       {
    00119         message_out(ERROR, "ofx_proc_file():Unable to open the created temp file " + string(tmp_filename));
    00120         return -1;
    00121       }
    00122     }
    00123     else
    00124     {
    00125         message_out(ERROR, "ofx_proc_file():Unable to create a temp file at " + string(tmp_filename));
    00126         return -1;
    00127     }
    00128
    00129     if (input_file && tmp_file)
    00130     {
    00131       int header_separator_idx;
    00132       string header_name;
    00133       string header_value;
    00134       string ofx_encoding;
    00135       string ofx_charset;
    00136       do
    00137       {
    00138         input_file.getline(buffer, sizeof(buffer), '\n');
    00139         //cout<<buffer<<"\n";
    00140         s_buffer.assign(buffer);
    00141         //cout<<"input_file.gcount(): "<<input_file.gcount()<<" sizeof(buffer): "<<sizeof(buffer)<<endl;
    00142         if (input_file.gcount() < (sizeof(buffer) - 1))
    00143         {
    00144           s_buffer.append("\n");
    00145         }
    00146         else if ( !input_file.eof() && input_file.fail())
    00147         {
    00148           input_file.clear();
    00149         }
    00150         int ofx_start_idx;
    00151         if (ofx_start == false &&
    00152             (
    00153               (libofx_context->currentFileType() == OFX &&
    00154                ((ofx_start_idx = s_buffer.find("<OFX>")) !=
    00155                 string::npos || (ofx_start_idx = s_buffer.find("<ofx>")) != string::npos))
    00156               || (libofx_context->currentFileType() == OFC &&
    00157                   ((ofx_start_idx = s_buffer.find("<OFC>")) != string::npos ||
    00158                    (ofx_start_idx = s_buffer.find("<ofc>")) != string::npos))
    00159             )
    00160            )
    00161         {
    00162           ofx_start = true;
    00163           s_buffer.erase(0, ofx_start_idx); //Fix for really broken files that don't have a newline after the header.
    00164           message_out(DEBUG, "ofx_proc_file():<OFX> or <OFC> has been found");
    00165 #ifdef HAVE_ICONV
    00166           string fromcode;
    00167           string tocode;
    00168           if (ofx_encoding.compare("USASCII") == 0)
    00169           {
    00170             if (ofx_charset.compare("ISO-8859-1") == 0 || ofx_charset.compare("8859-1") == 0)
    00171             {
    00172               fromcode = "ISO-8859-1";
    00173             }
    00174             else if (ofx_charset.compare("1252") == 0)
    00175             {
    00176               fromcode = "CP1252";
    00177             }
    00178             else if (ofx_charset.compare("NONE") == 0)
    00179             {
    00180               fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
    00181             }
    00182             else
    00183             {
    00184               fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
    00185             }
    00186           }
    00187           else if (ofx_encoding.compare("UTF-8") == 0)
    00188           {
    00189             fromcode = "UTF-8";
    00190           }
    00191           else
    00192           {
    00193             fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
    00194           }
    00195           tocode = LIBOFX_DEFAULT_OUTPUT_ENCODING;
    00196           message_out(DEBUG, "ofx_proc_file(): Setting up iconv for fromcode: " + fromcode + ", tocode: " + tocode);
    00197           conversion_descriptor = iconv_open (tocode.c_str(), fromcode.c_str());
    00198 #endif
    00199         }
    00200         else
    00201         {
    00202           //We are still in the headers
    00203           if ((header_separator_idx = s_buffer.find(':')) != string::npos)
    00204           {
    00205             //Header processing
    00206             header_name.assign(s_buffer.substr(0, header_separator_idx));
    00207             header_value.assign(s_buffer.substr(header_separator_idx + 1));
    00208             while ( header_value[header_value.length() -1 ] == '\n' ||
    00209                     header_value[header_value.length() -1 ] == '\r' )
    00210               header_value.erase(header_value.length() - 1);
    00211             message_out(DEBUG, "ofx_proc_file():Header: " + header_name + " with value: " + header_value + " has been found");
    00212             if (header_name.compare("ENCODING") == 0)
    00213             {
    00214               ofx_encoding.assign(header_value);
    00215             }
    00216             if (header_name.compare("CHARSET") == 0)
    00217             {
    00218               ofx_charset.assign(header_value);
    00219             }
    00220           }
    00221         }
    00222
    00223         if (ofx_start == true && ofx_end == false)
    00224         {
    00225           s_buffer = sanitize_proprietary_tags(s_buffer);
    00226           //cout<< s_buffer<<"\n";
    00227 #ifdef HAVE_ICONV
    00228           memset(iconv_buffer, 0, READ_BUFFER_SIZE * 2);
    00229           size_t inbytesleft = strlen(s_buffer.c_str());
    00230           size_t outbytesleft = READ_BUFFER_SIZE * 2 - 1;
    00231 #ifdef OS_WIN32
    00232           const char * inchar = (const char *)s_buffer.c_str();
    00233 #else
    00234           char * inchar = (char *)s_buffer.c_str();
    00235 #endif
    00236           char * outchar = iconv_buffer;
    00237           int iconv_retval = iconv (conversion_descriptor,
    00238                                     &inchar, &inbytesleft,
    00239                                     &outchar, &outbytesleft);
    00240           if (iconv_retval == -1)
    00241           {
    00242             message_out(ERROR, "ofx_proc_file(): Conversion error");
    00243           }
    00244           s_buffer = iconv_buffer;
    00245 #endif
    00246           tmp_file.write(s_buffer.c_str(), s_buffer.length());
    00247         }
    00248
    00249         if (ofx_start == true &&
    00250             (
    00251               (libofx_context->currentFileType() == OFX &&
    00252                ((ofx_start_idx = s_buffer.find("</OFX>")) != string::npos ||
    00253                 (ofx_start_idx = s_buffer.find("</ofx>")) != string::npos))
    00254               || (libofx_context->currentFileType() == OFC &&
    00255                   ((ofx_start_idx = s_buffer.find("</OFC>")) != string::npos ||
    00256                    (ofx_start_idx = s_buffer.find("</ofc>")) != string::npos))
    00257             )
    00258            )
    00259         {
    00260           ofx_end = true;
    00261           message_out(DEBUG, "ofx_proc_file():</OFX> or </OFC>  has been found");
    00262         }
    00263
    00264       }
    00265       while (!input_file.eof() && !input_file.bad());
    00266     }
    00267     input_file.close();
    00268     tmp_file.close();
    00269 #ifdef HAVE_ICONV
    00270     iconv_close(conversion_descriptor);
    00271 #endif
    00272     char filename_openspdtd[255];
    00273     char filename_dtd[255];
    00274     char filename_ofx[255];
    00275     strncpy(filename_openspdtd, find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); //The opensp sgml dtd file
    00276     if (libofx_context->currentFileType() == OFX)
    00277     {
    00278       strncpy(filename_dtd, find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); //The ofx dtd file
    00279     }
    00280     else if (libofx_context->currentFileType() == OFC)
    00281     {
    00282       strncpy(filename_dtd, find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); //The ofc dtd file
    00283     }
    00284     else
    00285     {
    00286       message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser"));
    00287     }
    00288
    00289     if ((string)filename_dtd != "" && (string)filename_openspdtd != "")
    00290     {
    00291       strncpy(filename_ofx, tmp_filename, 255); //The processed ofx file
    00292       filenames[0] = filename_openspdtd;
    00293       filenames[1] = filename_dtd;
    00294       filenames[2] = filename_ofx;
    00295       if (libofx_context->currentFileType() == OFX)
    00296       {
    00297         ofx_proc_sgml(libofx_context, 3, filenames);
    00298       }
    00299       else if (libofx_context->currentFileType() == OFC)
    00300       {
    00301         ofc_proc_sgml(libofx_context, 3, filenames);
    00302       }
    00303       else
    00304       {
    00305         message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser"));
    00306       }
    00307       if (remove(tmp_filename) != 0)
    00308       {
    00309         message_out(ERROR, "ofx_proc_file(): Error deleting temporary file " + string(tmp_filename));
    00310       }
    00311     }
    00312     else
    00313     {
    00314       message_out(ERROR, "ofx_proc_file(): FATAL: Missing DTD, aborting");
    00315     }
    00316   }
    00317   else
    00318   {
    00319     message_out(ERROR, "ofx_proc_file():No input file specified");
    00320   }
    00321   return 0;
    00322 }
    00323
    00324
    00325
    00326 int libofx_proc_buffer(LibofxContextPtr ctx,
    00327                        const char *s, unsigned int size)
    00328 {
    00329   ofstream tmp_file;
    00330   string s_buffer;
    00331   char *filenames[3];
    00332   char tmp_filename[256];
    00333   int tmp_file_fd;
    00334   ssize_t pos;
    00335   LibofxContext *libofx_context;
    00336
    00337   libofx_context = (LibofxContext*)ctx;
    00338
    00339   if (size == 0)
    00340   {
    00341     message_out(ERROR,
    00342                 "ofx_proc_file(): bad size");
    00343     return -1;
    00344   }
    00345   s_buffer = string(s, size);
    00346
    00347   mkTempFileName("libofxtmpXXXXXX", tmp_filename, sizeof(tmp_filename));
    00348   message_out(DEBUG, "ofx_proc_file(): Creating temp file: " + string(tmp_filename));
    00349   tmp_file_fd = mkstemp(tmp_filename);
    00350   if(tmp_file_fd)
    00351   {
    00352   tmp_file.open(tmp_filename);
    00353   if (!tmp_file)
    00354     {
    00355       message_out(ERROR, "ofx_proc_file():Unable to open the created output file " + string(tmp_filename));
    00356       return -1;
    00357     }
    00358   }
    00359   else
    00360   {
    00361       message_out(ERROR, "ofx_proc_file():Unable to create a temp file at " + string(tmp_filename));
    00362       return -1;
    00363   }
    00364
    00365   if (libofx_context->currentFileType() == OFX)
    00366   {
    00367     pos = s_buffer.find("<OFX>");
    00368     if (pos == string::npos)
    00369       pos = s_buffer.find("<ofx>");
    00370   }
    00371   else if (libofx_context->currentFileType() == OFC)
    00372   {
    00373     pos = s_buffer.find("<OFC>");
    00374     if (pos == string::npos)
    00375       pos = s_buffer.find("<ofc>");
    00376   }
    00377   else
    00378   {
    00379     message_out(ERROR, "ofx_proc(): unknown file type");
    00380     return -1;
    00381   }
    00382   if (pos == string::npos || pos > s_buffer.size())
    00383   {
    00384     message_out(ERROR, "ofx_proc():<OFX> has not been found");
    00385     return -1;
    00386   }
    00387   else
    00388   {
    00389     // erase everything before the OFX tag
    00390     s_buffer.erase(0, pos);
    00391     message_out(DEBUG, "ofx_proc_file():<OF?> has been found");
    00392   }
    00393
    00394   if (libofx_context->currentFileType() == OFX)
    00395   {
    00396     pos = s_buffer.find("</OFX>");
    00397     if (pos == string::npos)
    00398       pos = s_buffer.find("</ofx>");
    00399   }
    00400   else if (libofx_context->currentFileType() == OFC)
    00401   {
    00402     pos = s_buffer.find("</OFC>");
    00403     if (pos == string::npos)
    00404       pos = s_buffer.find("</ofc>");
    00405   }
    00406   else
    00407   {
    00408     message_out(ERROR, "ofx_proc(): unknown file type");
    00409     return -1;
    00410   }
    00411
    00412   if (pos == string::npos || pos > s_buffer.size())
    00413   {
    00414     message_out(ERROR, "ofx_proc():</OF?> has not been found");
    00415     return -1;
    00416   }
    00417   else
    00418   {
    00419     // erase everything after the /OFX tag
    00420     if (s_buffer.size() > pos + 6)
    00421       s_buffer.erase(pos + 6);
    00422     message_out(DEBUG, "ofx_proc_file():<OFX> has been found");
    00423   }
    00424
    00425   s_buffer = sanitize_proprietary_tags(s_buffer);
    00426   tmp_file.write(s_buffer.c_str(), s_buffer.length());
    00427
    00428   tmp_file.close();
    00429
    00430   char filename_openspdtd[255];
    00431   char filename_dtd[255];
    00432   char filename_ofx[255];
    00433   strncpy(filename_openspdtd, find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); //The opensp sgml dtd file
    00434   if (libofx_context->currentFileType() == OFX)
    00435   {
    00436     strncpy(filename_dtd, find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); //The ofx dtd file
    00437   }
    00438   else if (libofx_context->currentFileType() == OFC)
    00439   {
    00440     strncpy(filename_dtd, find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); //The ofc dtd file
    00441   }
    00442   else
    00443   {
    00444     message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser"));
    00445   }
    00446
    00447   if ((string)filename_dtd != "" && (string)filename_openspdtd != "")
    00448   {
    00449     strncpy(filename_ofx, tmp_filename, 255); //The processed ofx file
    00450     filenames[0] = filename_openspdtd;
    00451     filenames[1] = filename_dtd;
    00452     filenames[2] = filename_ofx;
    00453     if (libofx_context->currentFileType() == OFX)
    00454     {
    00455       ofx_proc_sgml(libofx_context, 3, filenames);
    00456     }
    00457     else if (libofx_context->currentFileType() == OFC)
    00458     {
    00459       ofc_proc_sgml(libofx_context, 3, filenames);
    00460     }
    00461     else
    00462     {
    00463       message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser"));
    00464     }
    00465     if (remove(tmp_filename) != 0)
    00466     {
    00467       message_out(ERROR, "ofx_proc_file(): Error deleting temporary file " + string(tmp_filename));
    00468     }
    00469   }
    00470   else
    00471   {
    00472     message_out(ERROR, "ofx_proc_file(): FATAL: Missing DTD, aborting");
    00473   }
    00474
    00475   return 0;
    00476 }
    00477
    00478
    00479
    00480
    00481
    00482
    00487 string sanitize_proprietary_tags(string input_string)
    00488 {
    00489   unsigned int i;
    00490   size_t input_string_size;
    00491   bool strip = false;
    00492   bool tag_open = false;
    00493   int tag_open_idx = 0; //Are we within < > ?
    00494   bool closing_tag_open = false; //Are we within </ > ?
    00495   int orig_tag_open_idx = 0;
    00496   bool proprietary_tag = false; //Are we within a proprietary element?
    00497   bool proprietary_closing_tag = false;
    00498   int crop_end_idx = 0;
    00499   char buffer[READ_BUFFER_SIZE] = "";
    00500   char tagname[READ_BUFFER_SIZE] = "";
    00501   int tagname_idx = 0;
    00502   char close_tagname[READ_BUFFER_SIZE] = "";
    00503
    00504   for (i = 0; i < READ_BUFFER_SIZE; i++)
    00505   {
    00506     buffer[i] = 0;
    00507     tagname[i] = 0;
    00508     close_tagname[i] = 0;
    00509   }
    00510
    00511   input_string_size = input_string.size();
    00512
    00513   for (i = 0; i <= input_string_size; i++)
    00514   {
    00515     if (input_string.c_str()[i] == '<')
    00516     {
    00517       tag_open = true;
    00518       tag_open_idx = i;
    00519       if (proprietary_tag == true && input_string.c_str()[i+1] == '/')
    00520       {
    00521         //We are now in a closing tag
    00522         closing_tag_open = true;
    00523         //cout<<"Comparaison: "<<tagname<<"|"<<&(input_string.c_str()[i+2])<<"|"<<strlen(tagname)<<endl;
    00524         if (strncmp(tagname, &(input_string.c_str()[i+2]), strlen(tagname)) != 0)
    00525         {
    00526           //If it is the begining of an other tag
    00527           //cout<<"DIFFERENT!"<<endl;
    00528           crop_end_idx = i - 1;
    00529           strip = true;
    00530         }
    00531         else
    00532         {
    00533           //Otherwise, it is the start of the closing tag of the proprietary tag
    00534           proprietary_closing_tag = true;
    00535         }
    00536       }
    00537       else if (proprietary_tag == true)
    00538       {
    00539         //It is the start of a new tag, following a proprietary tag
    00540         crop_end_idx = i - 1;
    00541         strip = true;
    00542       }
    00543     }
    00544     else if (input_string.c_str()[i] == '>')
    00545     {
    00546       tag_open = false;
    00547       closing_tag_open = false;
    00548       tagname[tagname_idx] = 0;
    00549       tagname_idx = 0;
    00550       if (proprietary_closing_tag == true)
    00551       {
    00552         crop_end_idx = i;
    00553         strip = true;
    00554       }
    00555     }
    00556     else if (tag_open == true && closing_tag_open == false)
    00557     {
    00558       if (input_string.c_str()[i] == '.')
    00559       {
    00560         if (proprietary_tag != true)
    00561         {
    00562           orig_tag_open_idx = tag_open_idx;
    00563           proprietary_tag = true;
    00564         }
    00565       }
    00566       tagname[tagname_idx] = input_string.c_str()[i];
    00567       tagname_idx++;
    00568     }
    00569     //cerr <<i<<endl;
    00570     if (strip == true && orig_tag_open_idx < input_string.size())
    00571     {
    00572       input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
    00573       message_out(INFO, "sanitize_proprietary_tags() (end tag or new tag) removed: " + string(buffer));
    00574       input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
    00575       i = orig_tag_open_idx - 1;
    00576       proprietary_tag = false;
    00577       proprietary_closing_tag = false;
    00578       closing_tag_open = false;
    00579       tag_open = false;
    00580       strip = false;
    00581     }
    00582
    00583   }//end for
    00584   if (proprietary_tag == true && orig_tag_open_idx < input_string.size())
    00585   {
    00586     if (crop_end_idx == 0)   //no closing tag
    00587     {
    00588       crop_end_idx = input_string.size() - 1;
    00589     }
    00590     input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx);
    00591     message_out(INFO, "sanitize_proprietary_tags() (end of line) removed: " + string(buffer));
    00592     input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1);
    00593   }
    00594   return input_string;
    00595 }
    00596
    00597
    00598 #ifdef OS_WIN32
    00599 static std::string get_dtd_installation_directory()
    00600 {
    00601   // Partial implementation of
    00602   // http://developer.gnome.org/doc/API/2.0/glib/glib-Windows-Compatibility-Functions.html#g-win32-get-package-installation-directory
    00603   char ch_fn[MAX_PATH], *p;
    00604   std::string str_fn;
    00605
    00606   if (!GetModuleFileName(NULL, ch_fn, MAX_PATH)) return "";
    00607
    00608   if ((p = strrchr(ch_fn, '\\')) != NULL)
    00609     * p = '\0';
    00610
    00611   p = strrchr(ch_fn, '\\');
    00612   if (p && (_stricmp(p + 1, "bin") == 0 ||
    00613             _stricmp(p + 1, "lib") == 0))
    00614     *p = '\0';
    00615
    00616   str_fn = ch_fn;
    00617   str_fn += "\\share\\libofx\\dtd";
    00618
    00619   return str_fn;
    00620 }
    00621 #endif
    00622
    00623
    00636 string find_dtd(LibofxContextPtr ctx, string dtd_filename)
    00637 {
    00638   string dtd_path_filename;
    00639   char *env_dtd_path;
    00640
    00641   dtd_path_filename = reinterpret_cast<const LibofxContext*>(ctx)->dtdDir();
    00642   if (!dtd_path_filename.empty())
    00643   {
    00644     dtd_path_filename.append(dtd_filename);
    00645     ifstream dtd_file(dtd_path_filename.c_str());
    00646     if (dtd_file)
    00647     {
    00648       message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename);
    00649       return dtd_path_filename;
    00650     }
    00651   }
    00652
    00653 #ifdef OS_WIN32
    00654   dtd_path_filename = get_dtd_installation_directory();
    00655   if (!dtd_path_filename.empty())
    00656   {
    00657         dtd_path_filename.append(DIRSEP);
    00658     dtd_path_filename.append(dtd_filename);
    00659     ifstream dtd_file(dtd_path_filename.c_str());
    00660     if (dtd_file)
    00661     {
    00662       message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename);
    00663       return dtd_path_filename;
    00664     }
    00665   }
    00666 #endif
    00667   /* Search in environement variable OFX_DTD_PATH */
    00668   env_dtd_path = getenv("OFX_DTD_PATH");
    00669   if (env_dtd_path)
    00670   {
    00671     dtd_path_filename.append(env_dtd_path);
    00672     dtd_path_filename.append(DIRSEP);
    00673     dtd_path_filename.append(dtd_filename);
    00674     ifstream dtd_file(dtd_path_filename.c_str());
    00675     if (!dtd_file)
    00676     {
    00677       message_out(STATUS, "find_dtd():OFX_DTD_PATH env variable was was present, but unable to open the file " + dtd_path_filename);
    00678     }
    00679     else
    00680     {
    00681       message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename);
    00682       return dtd_path_filename;
    00683     }
    00684   }
    00685
    00686   for (int i = 0; i < DTD_SEARCH_PATH_NUM; i++)
    00687   {
    00688     dtd_path_filename = DTD_SEARCH_PATH[i];
    00689     dtd_path_filename.append(DIRSEP);
    00690     dtd_path_filename.append(dtd_filename);
    00691     ifstream dtd_file(dtd_path_filename.c_str());
    00692     if (!dtd_file)
    00693     {
    00694       message_out(DEBUG, "find_dtd():Unable to open the file " + dtd_path_filename);
    00695     }
    00696     else
    00697     {
    00698       message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename);
    00699       return dtd_path_filename;
    00700     }
    00701   }
    00702
    00703   message_out(ERROR, "find_dtd():Unable to find the DTD named " + dtd_filename);
    00704   return "";
    00705 }
    00706
    00707