20 #include "../config.h"    27 #include "ParserEventGeneratorKit.h"    51 #define LIBOFX_DEFAULT_INPUT_ENCODING "CP1252"    52 #define LIBOFX_DEFAULT_OUTPUT_ENCODING "UTF-8"    58 #ifdef MAKEFILE_DTD_PATH    69 #ifdef MAKEFILE_DTD_PATH    72   "/usr/local/share/libofx/dtd",
    73   "/usr/share/libofx/dtd",
    84   bool ofx_start = 
false;
    86   bool file_is_xml = 
false;
    87   bool used_iconv = 
false;
    91   char tmp_filename[256];
    94   iconv_t conversion_descriptor;
    98   if (p_filename != NULL && strcmp(p_filename, 
"") != 0)
   102     input_file.open(p_filename);
   105       message_out(
ERROR, 
"ofx_proc_file():Unable to open the input file " + 
string(p_filename));
   108     mkTempFileName(
"libofxtmpXXXXXX", tmp_filename, 
sizeof(tmp_filename));
   110     message_out(
DEBUG, 
"ofx_proc_file(): Creating temp file: " + 
string(tmp_filename));
   112     tmp_file_fd = mkstemp_win32(tmp_filename);
   114     tmp_file_fd = mkstemp(tmp_filename);
   118       tmp_file.open(tmp_filename);
   121         message_out(
ERROR, 
"ofx_proc_file():Unable to open the created temp file " + 
string(tmp_filename));
   127       message_out(
ERROR, 
"ofx_proc_file():Unable to create a temp file at " + 
string(tmp_filename));
   131     if (input_file && tmp_file)
   133       std::size_t header_separator_idx;
   142         input_file.get(buffer, 
'\n');
   144         s_buffer = buffer.str();
   148         if (!input_file.eof())
   151           if (input_file.fail()) 
   161           if (input_file.peek() == 
'\n')
   168         if (ofx_start == 
false && (s_buffer.find(
"<?xml") != string::npos))
   170           message_out(
DEBUG, 
"ofx_proc_file(): File is an actual XML file, iconv conversion will be skipped.");
   174         std::size_t ofx_start_idx;
   175         if (ofx_start == 
false)
   178             (libofx_context->currentFileType() == 
OFX &&
   179              ((ofx_start_idx = s_buffer.find(
"<OFX>")) != string::npos ||
   180               (ofx_start_idx = s_buffer.find(
"<ofx>")) != string::npos))
   182             (libofx_context->currentFileType() == 
OFC &&
   183              ((ofx_start_idx = s_buffer.find(
"<OFC>")) != string::npos ||
   184               (ofx_start_idx = s_buffer.find(
"<ofc>")) != string::npos))
   188             if (file_is_xml == 
false)
   190               s_buffer.erase(0, ofx_start_idx); 
   194             if (file_is_xml == 
true)
   196               static char sp_charset_fixed[] = 
"SP_CHARSET_FIXED=1";
   197               if (putenv(sp_charset_fixed) != 0)
   208               static char sp_encoding[] = 
"SP_ENCODING=ms-dos";
   209               if (putenv(sp_encoding) != 0)
   216               static char sp_charset_fixed[] = 
"SP_CHARSET_FIXED=1";
   217               if (putenv(sp_charset_fixed) != 0)
   221               static char sp_encoding[] = 
"SP_ENCODING=ms-dos"; 
   222               if (putenv(sp_encoding) != 0)
   229               if (ofx_encoding.compare(
"USASCII") == 0)
   231                 if (ofx_charset.compare(
"ISO-8859-1") == 0 || ofx_charset.compare(
"8859-1") == 0)
   234                   fromcode = 
"ISO-8859-1";
   236                 else if (ofx_charset.compare(
"1252") == 0 || ofx_charset.compare(
"CP1252") == 0)
   241                 else if (ofx_charset.compare(
"NONE") == 0)
   243                   fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
   247                   fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
   250               else if (ofx_encoding.compare(
"UTF-8") == 0 || ofx_encoding.compare(
"UNICODE") == 0)
   257                 fromcode = LIBOFX_DEFAULT_INPUT_ENCODING;
   259               tocode = LIBOFX_DEFAULT_OUTPUT_ENCODING;
   260               message_out(
DEBUG, 
"ofx_proc_file(): Setting up iconv for fromcode: " + fromcode + 
", tocode: " + tocode);
   261               conversion_descriptor = iconv_open (tocode.c_str(), fromcode.c_str());
   269             if ((header_separator_idx = s_buffer.find(
':')) != string::npos)
   272               header_name.assign(s_buffer.substr(0, header_separator_idx));
   273               header_value.assign(s_buffer.substr(header_separator_idx + 1));
   274               while ( header_value[header_value.length() - 1 ] == 
'\n' ||
   275                       header_value[header_value.length() - 1 ] == 
'\r' )
   276                 header_value.erase(header_value.length() - 1);
   277               message_out(
DEBUG, 
"ofx_proc_file():Header: " + header_name + 
" with value: " + header_value + 
" has been found");
   278               if (header_name.compare(
"ENCODING") == 0)
   280                 ofx_encoding.assign(header_value);
   282               if (header_name.compare(
"CHARSET") == 0)
   284                 ofx_charset.assign(header_value);
   290         if (file_is_xml == 
true || (ofx_start == 
true && ofx_end == 
false))
   292           if (ofx_start == 
true)
   299             if (s_buffer.empty())
   303           if (file_is_xml == 
false)
   306             size_t inbytesleft = s_buffer.size();
   307             size_t outbytesleft = inbytesleft * 2 - 1;
   308             char * iconv_buffer = (
char*) malloc (inbytesleft * 2);
   309             memset(iconv_buffer, 0, inbytesleft * 2);
   310 #if defined(__WIN32__) || defined(__sun) || defined(__NetBSD__)   311             const char * inchar = (
const char *)s_buffer.c_str();
   313             char * inchar = (
char *)s_buffer.c_str();
   315             char * outchar = iconv_buffer;
   316             int iconv_retval = iconv (conversion_descriptor,
   317                                       &inchar, &inbytesleft,
   318                                       &outchar, &outbytesleft);
   319             if (iconv_retval == -1)
   325             s_buffer = std::string(iconv_buffer, outchar - iconv_buffer);
   330           tmp_file << s_buffer << endl;
   333         if (ofx_start == 
true &&
   335               (libofx_context->currentFileType() == 
OFX &&
   336                ((ofx_start_idx = s_buffer.find(
"</OFX>")) != string::npos ||
   337                 (ofx_start_idx = s_buffer.find(
"</ofx>")) != string::npos))
   338               || (libofx_context->currentFileType() == 
OFC &&
   339                   ((ofx_start_idx = s_buffer.find(
"</OFC>")) != string::npos ||
   340                    (ofx_start_idx = s_buffer.find(
"</ofc>")) != string::npos))
   349       while (!input_file.eof() && !input_file.bad());
   354     if (used_iconv == 
true)
   356       iconv_close(conversion_descriptor);
   359     char filename_openspdtd[255];
   360     char filename_dtd[255];
   361     char filename_ofx[255];
   362     strncpy(filename_openspdtd, 
find_dtd(ctx, OPENSPDCL_FILENAME).c_str(), 255); 
   363     if (libofx_context->currentFileType() == 
OFX)
   365       strncpy(filename_dtd, 
find_dtd(ctx, OFX160DTD_FILENAME).c_str(), 255); 
   367     else if (libofx_context->currentFileType() == 
OFC)
   369       strncpy(filename_dtd, 
find_dtd(ctx, OFCDTD_FILENAME).c_str(), 255); 
   373       message_out(
ERROR, 
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
   376     if ((
string)filename_dtd != 
"" && (
string)filename_openspdtd != 
"")
   378       strncpy(filename_ofx, tmp_filename, 255); 
   379       filenames[0] = filename_openspdtd;
   380       filenames[1] = filename_dtd;
   381       filenames[2] = filename_ofx;
   382       if (libofx_context->currentFileType() == 
OFX)
   386       else if (libofx_context->currentFileType() == 
OFC)
   392         message_out(
ERROR, 
string(
"ofx_proc_file(): Error unknown file format for the OFX parser"));
   394       if (
remove(tmp_filename) != 0)
   396         message_out(
ERROR, 
"ofx_proc_file(): Error deleting temporary file " + 
string(tmp_filename));
   416 static string find_tag_open (
string& input_string, 
size_t& pos_start, 
size_t& pos_end)
   418   pos_start = input_string.find (
'<', pos_start);
   420   if (pos_start == string::npos)
   422     pos_end = string::npos;
   426   pos_end = input_string.find (
'>', pos_start + 1);
   427   if (pos_end != string::npos)
   428     pos_end = pos_end + 1;
   429   size_t tag_size = (pos_end - 1) - (pos_start + 1);
   430   return input_string.substr(pos_start + 1, tag_size);
   438 static void find_tag_close (
string& input_string, 
string& tag_name, 
size_t& pos)
   440   size_t start_idx = input_string.find (
"</" + tag_name + 
">", pos);
   442   if (start_idx == string::npos)
   446     string new_tag_name = find_tag_open (input_string, start_idx, end_idx);
   447     if (!new_tag_name.empty())
   449       message_out(
DEBUG, 
"find_tag_close() fell back to next open tag: " + new_tag_name);
   457       pos = input_string.length();
   462     pos = start_idx + tag_name.length() + 3;
   481   size_t last_known_good_pos = 0;
   482   size_t open_tag_start_pos = last_known_good_pos;
   483   size_t open_tag_end_pos;
   484   size_t close_tag_end_pos;
   486   string tag_name = find_tag_open(input_string, open_tag_start_pos, open_tag_end_pos);
   487   while (!tag_name.empty())
   490     if ((tag_name.find(
'.') != string::npos) ||   
   491         (tag_name == 
"CATEGORY"))                  
   493       close_tag_end_pos = open_tag_end_pos;
   494       find_tag_close (input_string, tag_name, close_tag_end_pos);
   495       size_t tag_size = close_tag_end_pos - open_tag_start_pos;
   496       string prop_tag = input_string.substr(open_tag_start_pos, tag_size);
   498       input_string.erase(open_tag_start_pos, tag_size);
   499       last_known_good_pos = open_tag_start_pos;
   503       last_known_good_pos = open_tag_end_pos;
   506     open_tag_start_pos = last_known_good_pos;
   507     if (last_known_good_pos != string::npos)
   508       tag_name = find_tag_open(input_string, open_tag_start_pos, open_tag_end_pos);
   515 static std::string get_dtd_installation_directory()
   519   char ch_fn[MAX_PATH], *p;
   522   if (!GetModuleFileName(NULL, ch_fn, MAX_PATH)) 
return "";
   524   if ((p = strrchr(ch_fn, 
'\\')) != NULL)
   527   p = strrchr(ch_fn, 
'\\');
   528   if (p && (_stricmp(p + 1, 
"bin") == 0 ||
   529             _stricmp(p + 1, 
"lib") == 0))
   533   str_fn += 
"\\share\\libofx\\dtd";
   552 std::string 
find_dtd(LibofxContextPtr ctx, 
const std::string& dtd_filename)
   554   string dtd_path_filename;
   557   dtd_path_filename = 
reinterpret_cast<const LibofxContext*
>(ctx)->dtdDir();
   558   if (!dtd_path_filename.empty())
   560     dtd_path_filename.append(dtd_filename);
   561     ifstream dtd_file(dtd_path_filename.c_str());
   565       return dtd_path_filename;
   570   dtd_path_filename = get_dtd_installation_directory();
   571   if (!dtd_path_filename.empty())
   573     dtd_path_filename.append(DIRSEP);
   574     dtd_path_filename.append(dtd_filename);
   575     ifstream dtd_file(dtd_path_filename.c_str());
   579       return dtd_path_filename;
   584   env_dtd_path = getenv(
"OFX_DTD_PATH");
   587     dtd_path_filename.append(env_dtd_path);
   588     dtd_path_filename.append(DIRSEP);
   589     dtd_path_filename.append(dtd_filename);
   590     ifstream dtd_file(dtd_path_filename.c_str());
   593       message_out(
STATUS, 
"find_dtd():OFX_DTD_PATH env variable was was present, but unable to open the file " + dtd_path_filename);
   598       return dtd_path_filename;
   605     dtd_path_filename.append(DIRSEP);
   606     dtd_path_filename.append(dtd_filename);
   607     ifstream dtd_file(dtd_path_filename.c_str());
   610       message_out(
DEBUG, 
"find_dtd():Unable to open the file " + dtd_path_filename);
   615       return dtd_path_filename;
   620   dtd_path_filename = 
"";
   621   dtd_path_filename.append(
"..");
   622   dtd_path_filename.append(DIRSEP);
   623   dtd_path_filename.append(
"dtd");
   624   dtd_path_filename.append(DIRSEP);
   625   dtd_path_filename.append(dtd_filename);
   626   ifstream dtd_file(dtd_path_filename.c_str());
   629     message_out(
DEBUG, 
"find_dtd(): Unable to open the file " + dtd_path_filename + 
", most likely we are not in the source tree.");
   634     return dtd_path_filename;
   638   message_out(
ERROR, 
"find_dtd():Unable to find the DTD named " + dtd_filename);
 string sanitize_proprietary_tags(string input_string)
Removes proprietary tags and comments. 
Various simple functions for type conversion & al. 
int ofc_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s) 
int message_out(OfxMsgType error_type, const string message)
Message output function. 
Preprocessing of the OFX files before parsing. 
OFX/SGML parsing functionnality. 
const int DTD_SEARCH_PATH_NUM
The number of different paths to search for DTDs. 
std::string find_dtd(LibofxContextPtr ctx, const std::string &dtd_filename)
Find the appropriate DTD for the file version. 
Message IO functionality. 
OFX/SGML parsing functionnality. 
const char * DTD_SEARCH_PATH[DTD_SEARCH_PATH_NUM]
The list of paths to search for the DTDs. 
int ofx_proc_sgml(LibofxContext *libofx_context, int argc, char *const *argv)
Parses a DTD and OFX file(s) 
int ofx_proc_file(LibofxContextPtr ctx, const char *p_filename)
File pre-processing of OFX AND for OFC files.