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 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