LibOFX
|
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 //Only "ISO-8859-1" is actually a legal value, but since the banks follows the spec SO well... 00173 fromcode = "ISO-8859-1"; 00174 } 00175 else if (ofx_charset.compare("1252") == 0 || ofx_charset.compare("CP1252") == 0) 00176 { 00177 //Only "1252" is actually a legal value, but since the banks follows the spec SO well... 00178 fromcode = "CP1252"; 00179 } 00180 else if (ofx_charset.compare("NONE") == 0) 00181 { 00182 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING; 00183 } 00184 else 00185 { 00186 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING; 00187 } 00188 } 00189 else if (ofx_encoding.compare("UTF-8") == 0 || ofx_encoding.compare("UNICODE") == 0) 00190 { 00191 //While "UNICODE" isn't a legal value, some cyrilic files do specify it as such... 00192 fromcode = "UTF-8"; 00193 } 00194 else 00195 { 00196 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING; 00197 } 00198 tocode = LIBOFX_DEFAULT_OUTPUT_ENCODING; 00199 message_out(DEBUG, "ofx_proc_file(): Setting up iconv for fromcode: " + fromcode + ", tocode: " + tocode); 00200 conversion_descriptor = iconv_open (tocode.c_str(), fromcode.c_str()); 00201 #endif 00202 } 00203 else 00204 { 00205 //We are still in the headers 00206 if ((header_separator_idx = s_buffer.find(':')) != string::npos) 00207 { 00208 //Header processing 00209 header_name.assign(s_buffer.substr(0, header_separator_idx)); 00210 header_value.assign(s_buffer.substr(header_separator_idx + 1)); 00211 while ( header_value[header_value.length() -1 ] == '\n' || 00212 header_value[header_value.length() -1 ] == '\r' ) 00213 header_value.erase(header_value.length() - 1); 00214 message_out(DEBUG, "ofx_proc_file():Header: " + header_name + " with value: " + header_value + " has been found"); 00215 if (header_name.compare("ENCODING") == 0) 00216 { 00217 ofx_encoding.assign(header_value); 00218 } 00219 if (header_name.compare("CHARSET") == 0) 00220 { 00221 ofx_charset.assign(header_value); 00222 } 00223 } 00224 } 00225 00226 if (ofx_start == true && ofx_end == false) 00227 { 00228 s_buffer = sanitize_proprietary_tags(s_buffer); 00229 //cout<< s_buffer<<"\n"; 00230 #ifdef HAVE_ICONV 00231 memset(iconv_buffer, 0, READ_BUFFER_SIZE * 2); 00232 size_t inbytesleft = strlen(s_buffer.c_str()); 00233 size_t outbytesleft = READ_BUFFER_SIZE * 2 - 1; 00234 #ifdef OS_WIN32 00235 const char * inchar = (const char *)s_buffer.c_str(); 00236 #else 00237 char * inchar = (char *)s_buffer.c_str(); 00238 #endif 00239 char * outchar = iconv_buffer; 00240 int iconv_retval = iconv (conversion_descriptor, 00241 &inchar, &inbytesleft, 00242 &outchar, &outbytesleft); 00243 if (iconv_retval == -1) 00244 { 00245 message_out(ERROR, "ofx_proc_file(): Conversion error"); 00246 } 00247 s_buffer = iconv_buffer; 00248 #endif 00249 tmp_file.write(s_buffer.c_str(), s_buffer.length()); 00250 } 00251 00252 if (ofx_start == true && 00253 ( 00254 (libofx_context->currentFileType() == OFX && 00255 ((ofx_start_idx = s_buffer.find("</OFX>")) != string::npos || 00256 (ofx_start_idx = s_buffer.find("</ofx>")) != string::npos)) 00257 || (libofx_context->currentFileType() == OFC && 00258 ((ofx_start_idx = s_buffer.find("</OFC>")) != string::npos || 00259 (ofx_start_idx = s_buffer.find("</ofc>")) != string::npos)) 00260 ) 00261 ) 00262 { 00263 ofx_end = true; 00264 message_out(DEBUG, "ofx_proc_file():</OFX> or </OFC> has been found"); 00265 } 00266 00267 } 00268 while (!input_file.eof() && !input_file.bad()); 00269 } 00270 input_file.close(); 00271 tmp_file.close(); 00272 #ifdef HAVE_ICONV 00273 iconv_close(conversion_descriptor); 00274 #endif 00275 char filename_openspdtd[255]; 00276 char filename_dtd[255]; 00277 char filename_ofx[255]; 00278 strncpy(filename_openspdtd, find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); //The opensp sgml dtd file 00279 if (libofx_context->currentFileType() == OFX) 00280 { 00281 strncpy(filename_dtd, find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); //The ofx dtd file 00282 } 00283 else if (libofx_context->currentFileType() == OFC) 00284 { 00285 strncpy(filename_dtd, find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); //The ofc dtd file 00286 } 00287 else 00288 { 00289 message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser")); 00290 } 00291 00292 if ((string)filename_dtd != "" && (string)filename_openspdtd != "") 00293 { 00294 strncpy(filename_ofx, tmp_filename, 255); //The processed ofx file 00295 filenames[0] = filename_openspdtd; 00296 filenames[1] = filename_dtd; 00297 filenames[2] = filename_ofx; 00298 if (libofx_context->currentFileType() == OFX) 00299 { 00300 ofx_proc_sgml(libofx_context, 3, filenames); 00301 } 00302 else if (libofx_context->currentFileType() == OFC) 00303 { 00304 ofc_proc_sgml(libofx_context, 3, filenames); 00305 } 00306 else 00307 { 00308 message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser")); 00309 } 00310 if (remove(tmp_filename) != 0) 00311 { 00312 message_out(ERROR, "ofx_proc_file(): Error deleting temporary file " + string(tmp_filename)); 00313 } 00314 } 00315 else 00316 { 00317 message_out(ERROR, "ofx_proc_file(): FATAL: Missing DTD, aborting"); 00318 } 00319 } 00320 else 00321 { 00322 message_out(ERROR, "ofx_proc_file():No input file specified"); 00323 } 00324 return 0; 00325 } 00326 00327 00328 00329 int libofx_proc_buffer(LibofxContextPtr ctx, 00330 const char *s, unsigned int size) 00331 { 00332 ofstream tmp_file; 00333 string s_buffer; 00334 char *filenames[3]; 00335 char tmp_filename[256]; 00336 int tmp_file_fd; 00337 ssize_t pos; 00338 LibofxContext *libofx_context; 00339 00340 libofx_context = (LibofxContext*)ctx; 00341 00342 if (size == 0) 00343 { 00344 message_out(ERROR, 00345 "ofx_proc_file(): bad size"); 00346 return -1; 00347 } 00348 s_buffer = string(s, size); 00349 00350 mkTempFileName("libofxtmpXXXXXX", tmp_filename, sizeof(tmp_filename)); 00351 message_out(DEBUG, "ofx_proc_file(): Creating temp file: " + string(tmp_filename)); 00352 tmp_file_fd = mkstemp(tmp_filename); 00353 if (tmp_file_fd) 00354 { 00355 tmp_file.open(tmp_filename); 00356 if (!tmp_file) 00357 { 00358 message_out(ERROR, "ofx_proc_file():Unable to open the created output file " + string(tmp_filename)); 00359 return -1; 00360 } 00361 } 00362 else 00363 { 00364 message_out(ERROR, "ofx_proc_file():Unable to create a temp file at " + string(tmp_filename)); 00365 return -1; 00366 } 00367 00368 if (libofx_context->currentFileType() == OFX) 00369 { 00370 pos = s_buffer.find("<OFX>"); 00371 if (pos == string::npos) 00372 pos = s_buffer.find("<ofx>"); 00373 } 00374 else if (libofx_context->currentFileType() == OFC) 00375 { 00376 pos = s_buffer.find("<OFC>"); 00377 if (pos == string::npos) 00378 pos = s_buffer.find("<ofc>"); 00379 } 00380 else 00381 { 00382 message_out(ERROR, "ofx_proc(): unknown file type"); 00383 return -1; 00384 } 00385 if (pos == string::npos || pos > s_buffer.size()) 00386 { 00387 message_out(ERROR, "ofx_proc():<OFX> has not been found"); 00388 return -1; 00389 } 00390 else 00391 { 00392 // erase everything before the OFX tag 00393 s_buffer.erase(0, pos); 00394 message_out(DEBUG, "ofx_proc_file():<OF?> has been found"); 00395 } 00396 00397 if (libofx_context->currentFileType() == OFX) 00398 { 00399 pos = s_buffer.find("</OFX>"); 00400 if (pos == string::npos) 00401 pos = s_buffer.find("</ofx>"); 00402 } 00403 else if (libofx_context->currentFileType() == OFC) 00404 { 00405 pos = s_buffer.find("</OFC>"); 00406 if (pos == string::npos) 00407 pos = s_buffer.find("</ofc>"); 00408 } 00409 else 00410 { 00411 message_out(ERROR, "ofx_proc(): unknown file type"); 00412 return -1; 00413 } 00414 00415 if (pos == string::npos || pos > s_buffer.size()) 00416 { 00417 message_out(ERROR, "ofx_proc():</OF?> has not been found"); 00418 return -1; 00419 } 00420 else 00421 { 00422 // erase everything after the /OFX tag 00423 if (s_buffer.size() > pos + 6) 00424 s_buffer.erase(pos + 6); 00425 message_out(DEBUG, "ofx_proc_file():<OFX> has been found"); 00426 } 00427 00428 s_buffer = sanitize_proprietary_tags(s_buffer); 00429 tmp_file.write(s_buffer.c_str(), s_buffer.length()); 00430 00431 tmp_file.close(); 00432 00433 char filename_openspdtd[255]; 00434 char filename_dtd[255]; 00435 char filename_ofx[255]; 00436 strncpy(filename_openspdtd, find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); //The opensp sgml dtd file 00437 if (libofx_context->currentFileType() == OFX) 00438 { 00439 strncpy(filename_dtd, find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); //The ofx dtd file 00440 } 00441 else if (libofx_context->currentFileType() == OFC) 00442 { 00443 strncpy(filename_dtd, find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); //The ofc dtd file 00444 } 00445 else 00446 { 00447 message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser")); 00448 } 00449 00450 if ((string)filename_dtd != "" && (string)filename_openspdtd != "") 00451 { 00452 strncpy(filename_ofx, tmp_filename, 255); //The processed ofx file 00453 filenames[0] = filename_openspdtd; 00454 filenames[1] = filename_dtd; 00455 filenames[2] = filename_ofx; 00456 if (libofx_context->currentFileType() == OFX) 00457 { 00458 ofx_proc_sgml(libofx_context, 3, filenames); 00459 } 00460 else if (libofx_context->currentFileType() == OFC) 00461 { 00462 ofc_proc_sgml(libofx_context, 3, filenames); 00463 } 00464 else 00465 { 00466 message_out(ERROR, string("ofx_proc_file(): Error unknown file format for the OFX parser")); 00467 } 00468 if (remove(tmp_filename) != 0) 00469 { 00470 message_out(ERROR, "ofx_proc_file(): Error deleting temporary file " + string(tmp_filename)); 00471 } 00472 } 00473 else 00474 { 00475 message_out(ERROR, "ofx_proc_file(): FATAL: Missing DTD, aborting"); 00476 } 00477 00478 return 0; 00479 } 00480 00481 00482 00483 00484 00485 00490 string sanitize_proprietary_tags(string input_string) 00491 { 00492 unsigned int i; 00493 size_t input_string_size; 00494 bool strip = false; 00495 bool tag_open = false; 00496 int tag_open_idx = 0; //Are we within < > ? 00497 bool closing_tag_open = false; //Are we within </ > ? 00498 int orig_tag_open_idx = 0; 00499 bool proprietary_tag = false; //Are we within a proprietary element? 00500 bool proprietary_closing_tag = false; 00501 int crop_end_idx = 0; 00502 char buffer[READ_BUFFER_SIZE] = ""; 00503 char tagname[READ_BUFFER_SIZE] = ""; 00504 int tagname_idx = 0; 00505 char close_tagname[READ_BUFFER_SIZE] = ""; 00506 00507 for (i = 0; i < READ_BUFFER_SIZE; i++) 00508 { 00509 buffer[i] = 0; 00510 tagname[i] = 0; 00511 close_tagname[i] = 0; 00512 } 00513 00514 input_string_size = input_string.size(); 00515 00516 for (i = 0; i <= input_string_size; i++) 00517 { 00518 if (input_string.c_str()[i] == '<') 00519 { 00520 tag_open = true; 00521 tag_open_idx = i; 00522 if (proprietary_tag == true && input_string.c_str()[i+1] == '/') 00523 { 00524 //We are now in a closing tag 00525 closing_tag_open = true; 00526 //cout<<"Comparaison: "<<tagname<<"|"<<&(input_string.c_str()[i+2])<<"|"<<strlen(tagname)<<endl; 00527 if (strncmp(tagname, &(input_string.c_str()[i+2]), strlen(tagname)) != 0) 00528 { 00529 //If it is the begining of an other tag 00530 //cout<<"DIFFERENT!"<<endl; 00531 crop_end_idx = i - 1; 00532 strip = true; 00533 } 00534 else 00535 { 00536 //Otherwise, it is the start of the closing tag of the proprietary tag 00537 proprietary_closing_tag = true; 00538 } 00539 } 00540 else if (proprietary_tag == true) 00541 { 00542 //It is the start of a new tag, following a proprietary tag 00543 crop_end_idx = i - 1; 00544 strip = true; 00545 } 00546 } 00547 else if (input_string.c_str()[i] == '>') 00548 { 00549 tag_open = false; 00550 closing_tag_open = false; 00551 tagname[tagname_idx] = 0; 00552 tagname_idx = 0; 00553 if (proprietary_closing_tag == true) 00554 { 00555 crop_end_idx = i; 00556 strip = true; 00557 } 00558 } 00559 else if (tag_open == true && closing_tag_open == false) 00560 { 00561 if (input_string.c_str()[i] == '.') 00562 { 00563 if (proprietary_tag != true) 00564 { 00565 orig_tag_open_idx = tag_open_idx; 00566 proprietary_tag = true; 00567 } 00568 } 00569 tagname[tagname_idx] = input_string.c_str()[i]; 00570 tagname_idx++; 00571 } 00572 //cerr <<i<<endl; 00573 if (strip == true && orig_tag_open_idx < input_string.size()) 00574 { 00575 input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx); 00576 message_out(INFO, "sanitize_proprietary_tags() (end tag or new tag) removed: " + string(buffer)); 00577 input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1); 00578 i = orig_tag_open_idx - 1; 00579 proprietary_tag = false; 00580 proprietary_closing_tag = false; 00581 closing_tag_open = false; 00582 tag_open = false; 00583 strip = false; 00584 } 00585 00586 }//end for 00587 if (proprietary_tag == true && orig_tag_open_idx < input_string.size()) 00588 { 00589 if (crop_end_idx == 0) //no closing tag 00590 { 00591 crop_end_idx = input_string.size() - 1; 00592 } 00593 input_string.copy(buffer, (crop_end_idx - orig_tag_open_idx) + 1, orig_tag_open_idx); 00594 message_out(INFO, "sanitize_proprietary_tags() (end of line) removed: " + string(buffer)); 00595 input_string.erase(orig_tag_open_idx, (crop_end_idx - orig_tag_open_idx) + 1); 00596 } 00597 return input_string; 00598 } 00599 00600 00601 #ifdef OS_WIN32 00602 static std::string get_dtd_installation_directory() 00603 { 00604 // Partial implementation of 00605 // http://developer.gnome.org/doc/API/2.0/glib/glib-Windows-Compatibility-Functions.html#g-win32-get-package-installation-directory 00606 char ch_fn[MAX_PATH], *p; 00607 std::string str_fn; 00608 00609 if (!GetModuleFileName(NULL, ch_fn, MAX_PATH)) return ""; 00610 00611 if ((p = strrchr(ch_fn, '\\')) != NULL) 00612 * p = '\0'; 00613 00614 p = strrchr(ch_fn, '\\'); 00615 if (p && (_stricmp(p + 1, "bin") == 0 || 00616 _stricmp(p + 1, "lib") == 0)) 00617 *p = '\0'; 00618 00619 str_fn = ch_fn; 00620 str_fn += "\\share\\libofx\\dtd"; 00621 00622 return str_fn; 00623 } 00624 #endif 00625 00626 00639 string find_dtd(LibofxContextPtr ctx, string dtd_filename) 00640 { 00641 string dtd_path_filename; 00642 char *env_dtd_path; 00643 00644 dtd_path_filename = reinterpret_cast<const LibofxContext*>(ctx)->dtdDir(); 00645 if (!dtd_path_filename.empty()) 00646 { 00647 dtd_path_filename.append(dtd_filename); 00648 ifstream dtd_file(dtd_path_filename.c_str()); 00649 if (dtd_file) 00650 { 00651 message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename); 00652 return dtd_path_filename; 00653 } 00654 } 00655 00656 #ifdef OS_WIN32 00657 dtd_path_filename = get_dtd_installation_directory(); 00658 if (!dtd_path_filename.empty()) 00659 { 00660 dtd_path_filename.append(DIRSEP); 00661 dtd_path_filename.append(dtd_filename); 00662 ifstream dtd_file(dtd_path_filename.c_str()); 00663 if (dtd_file) 00664 { 00665 message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename); 00666 return dtd_path_filename; 00667 } 00668 } 00669 #endif 00670 /* Search in environement variable OFX_DTD_PATH */ 00671 env_dtd_path = getenv("OFX_DTD_PATH"); 00672 if (env_dtd_path) 00673 { 00674 dtd_path_filename.append(env_dtd_path); 00675 dtd_path_filename.append(DIRSEP); 00676 dtd_path_filename.append(dtd_filename); 00677 ifstream dtd_file(dtd_path_filename.c_str()); 00678 if (!dtd_file) 00679 { 00680 message_out(STATUS, "find_dtd():OFX_DTD_PATH env variable was was present, but unable to open the file " + dtd_path_filename); 00681 } 00682 else 00683 { 00684 message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename); 00685 return dtd_path_filename; 00686 } 00687 } 00688 00689 for (int i = 0; i < DTD_SEARCH_PATH_NUM; i++) 00690 { 00691 dtd_path_filename = DTD_SEARCH_PATH[i]; 00692 dtd_path_filename.append(DIRSEP); 00693 dtd_path_filename.append(dtd_filename); 00694 ifstream dtd_file(dtd_path_filename.c_str()); 00695 if (!dtd_file) 00696 { 00697 message_out(DEBUG, "find_dtd():Unable to open the file " + dtd_path_filename); 00698 } 00699 else 00700 { 00701 message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename); 00702 return dtd_path_filename; 00703 } 00704 } 00705 00706 /* Last resort, look in source tree relative path (useful for development) */ 00707 dtd_path_filename = ""; 00708 dtd_path_filename.append(".."); 00709 dtd_path_filename.append(DIRSEP); 00710 dtd_path_filename.append("dtd"); 00711 dtd_path_filename.append(DIRSEP); 00712 dtd_path_filename.append(dtd_filename); 00713 ifstream dtd_file(dtd_path_filename.c_str()); 00714 if (!dtd_file) 00715 { 00716 message_out(DEBUG, "find_dtd(): Unable to open the file " + dtd_path_filename + ", most likely we are not in the source tree."); 00717 } 00718 else 00719 { 00720 message_out(STATUS, "find_dtd():DTD found: " + dtd_path_filename); 00721 return dtd_path_filename; 00722 } 00723 00724 00725 message_out(ERROR, "find_dtd():Unable to find the DTD named " + dtd_filename); 00726 return ""; 00727 } 00728 00729