]> git.saurik.com Git - wxWidgets.git/commitdiff
1. ReadMailcap/MimeTypes returna bool error code
authorVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Mar 1999 17:39:47 +0000 (17:39 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Tue, 23 Mar 1999 17:39:47 +0000 (17:39 +0000)
2. 'fallback' flag added to ReadMailcap
3, subtle (and very rare) bug with mailcap entries order corrected

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1962 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/mimetype.tex
include/wx/mimetype.h
src/common/mimetype.cpp

index 94c7191bb774f3c96cb4d5ca5a57d15381e47a51..bd7275d5b9b53db15ab65151d7fe0c4984f759c1 100644 (file)
@@ -15,7 +15,7 @@ initialization is needed.
 (system-wide) and .mailcap and .mime.types in the current user's home directory:
 all of these files are searched for and loaded if found by default. However,
 additional functions 
 (system-wide) and .mailcap and .mime.types in the current user's home directory:
 all of these files are searched for and loaded if found by default. However,
 additional functions 
-\helpref{wxMimeTypesManager::ReadMailcap}{wxmimetypesmanagerreadmailcap} and
+\helpref{wxMimeTypesManager::ReadMailcap}{wxmimetypesmanagerreadmailcap} and 
 \helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are
 provided to load additional files.
 
 \helpref{wxMimeTypesManager::ReadMimeTypes}{wxmimetypesmanagerreadmimetypes} are
 provided to load additional files.
 
@@ -123,17 +123,29 @@ necessary to convert the strings to the same case before calling it.
 
 \membersection{wxMimeTypesManager::ReadMailcap}\label{wxmimetypesmanagerreadmailcap}
 
 
 \membersection{wxMimeTypesManager::ReadMailcap}\label{wxmimetypesmanagerreadmailcap}
 
-\func{void}{ReadMailcap}{\param{const wxString\&}{ filename}}
+\func{bool}{ReadMailcap}{\param{const wxString\&}{ filename}, \param{bool}{ fallback = FALSE}}
 
 Load additional file containing information about MIME types and associated
 information in mailcap format. See metamail(1) and mailcap(5) for more
 information.
 
 
 Load additional file containing information about MIME types and associated
 information in mailcap format. See metamail(1) and mailcap(5) for more
 information.
 
+{\it fallback} parameter may be used to load additional mailcap files without
+overriding the settings found in the standard files: normally, entries from
+files loaded with ReadMailcap will override the entries from files loaded
+previously (and the standard ones are loaded in the very beginning), but this
+will not happen if this parameter is set to TRUE (default is FALSE).
+
+The return value is TRUE if there were no errors in the file or FALSE
+otherwise.
+
 \membersection{wxMimeTypesManager::ReadMimeTypes}\label{wxmimetypesmanagerreadmimetypes}
 
 \membersection{wxMimeTypesManager::ReadMimeTypes}\label{wxmimetypesmanagerreadmimetypes}
 
-\func{void}{ReadMimeTypes}{\param{const wxString\&}{ filename}}
+\func{bool}{ReadMimeTypes}{\param{const wxString\&}{ filename}}
 
 Load additional file containing information about MIME types and associated
 information in mime.types file format. See metamail(1) and mailcap(5) for more
 information.
 
 
 Load additional file containing information about MIME types and associated
 information in mime.types file format. See metamail(1) and mailcap(5) for more
 information.
 
+The return value is TRUE if there were no errors in the file or FALSE
+otherwise.
+
index 18680f3afc89b4b47bd2579448a87f54eaf09958..d30eb3c70d1f3874cec5366f6f2eb630a8a01670 100644 (file)
@@ -131,12 +131,18 @@ public:
         // get file type from MIME type (in format <category>/<format>)
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
         // get file type from MIME type (in format <category>/<format>)
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
-    // other operations
+    // other operations: return TRUE if there were no errors or FALSE if there
+    // were some unreckognized entries (the good entries are always read anyhow)
         // read in additional file (the standard ones are read automatically)
         // in mailcap format (see mimetype.cpp for description)
         // read in additional file (the standard ones are read automatically)
         // in mailcap format (see mimetype.cpp for description)
-    void ReadMailcap(const wxString& filename);
+        //
+        // 'fallback' parameter may be set to TRUE to avoid overriding the
+        // settings from other, previously parsed, files by this one: normally,
+        // the files read most recently would override the older files, but with
+        // fallback == TRUE this won't happen
+    bool ReadMailcap(const wxString& filename, bool fallback = FALSE);
         // read in additional file in mime.types format
         // read in additional file in mime.types format
-    void ReadMimeTypes(const wxString& filename);
+    bool ReadMimeTypes(const wxString& filename);
 
     // dtor (not virtual, shouldn't be derived from)
     ~wxMimeTypesManager();
 
     // dtor (not virtual, shouldn't be derived from)
     ~wxMimeTypesManager();
index cc3415d7e126745a725ed4cc8289b56d0daefd8f..ce234a392fffe3a3930c9ec1768b05710decf961 100644 (file)
@@ -124,8 +124,8 @@ public:
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
     // this are NOPs under Windows
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
     // this are NOPs under Windows
-    void ReadMailcap(const wxString& filename) { }
-    void ReadMimeTypes(const wxString& filename) { }
+    bool ReadMailcap(const wxString& filename, bool fallback = TRUE) { }
+    bool ReadMimeTypes(const wxString& filename) { }
 };
 
 #else  // Unix
 };
 
 #else  // Unix
@@ -220,9 +220,27 @@ public:
     // operations
         // prepend this element to the list
     void Prepend(MailCapEntry *next) { m_next = next; }
     // operations
         // prepend this element to the list
     void Prepend(MailCapEntry *next) { m_next = next; }
-        // append to the list
+        // insert into the list at given position
+    void Insert(MailCapEntry *next, size_t pos)
+    {
+        // FIXME slooow...
+        MailCapEntry *cur;
+        size_t n = 0;
+        for ( cur = next; cur != NULL; cur = cur->m_next, n++ ) {
+            if ( n == pos )
+                break;
+        }
+
+        wxASSERT_MSG( n == pos, "invalid position in MailCapEntry::Insert" );
+
+        m_next = cur->m_next;
+        cur->m_next = this;
+    }
+        // append this element to the list
     void Append(MailCapEntry *next)
     {
     void Append(MailCapEntry *next)
     {
+        wxCHECK_RET( next != NULL, "Append()ing to what?" );
+
         // FIXME slooow...
         MailCapEntry *cur;
         for ( cur = next; cur->m_next != NULL; cur = cur->m_next )
         // FIXME slooow...
         MailCapEntry *cur;
         for ( cur = next; cur->m_next != NULL; cur = cur->m_next )
@@ -230,9 +248,7 @@ public:
 
         cur->m_next = this;
 
 
         cur->m_next = this;
 
-        // we initialize it in the ctor and there is no reason to both Prepend()
-        // and Append() one and the same entry
-        wxASSERT( m_next == NULL );
+        wxASSERT_MSG( !m_next, "Append()ing element already in the list?" );
     }
 
 private:
     }
 
 private:
@@ -252,15 +268,15 @@ friend class wxFileTypeImpl; // give it access to m_aXXX variables
 
 public:
     // ctor loads all info into memory for quicker access later on
 
 public:
     // ctor loads all info into memory for quicker access later on
-    // @@ it would be nice to load them all, but parse on demand only...
+    // TODO it would be nice to load them all, but parse on demand only...
     wxMimeTypesManagerImpl();
 
     // implement containing class functions
     wxFileType *GetFileTypeFromExtension(const wxString& ext);
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
     wxMimeTypesManagerImpl();
 
     // implement containing class functions
     wxFileType *GetFileTypeFromExtension(const wxString& ext);
     wxFileType *GetFileTypeFromMimeType(const wxString& mimeType);
 
-    void ReadMailcap(const wxString& filename);
-    void ReadMimeTypes(const wxString& filename);
+    bool ReadMailcap(const wxString& filename, bool fallback = FALSE);
+    bool ReadMimeTypes(const wxString& filename);
 
     // accessors
         // get the string containing space separated extensions for the given
 
     // accessors
         // get the string containing space separated extensions for the given
@@ -286,7 +302,7 @@ public:
     bool GetMimeType(wxString *mimeType) const
         { *mimeType = m_manager->m_aTypes[m_index]; return TRUE; }
     bool GetIcon(wxIcon * WXUNUSED(icon)) const
     bool GetMimeType(wxString *mimeType) const
         { *mimeType = m_manager->m_aTypes[m_index]; return TRUE; }
     bool GetIcon(wxIcon * WXUNUSED(icon)) const
-        { return FALSE; }   // @@ maybe with Gnome/KDE integration...
+        { return FALSE; }   // TODO maybe with Gnome/KDE integration...
     bool GetDescription(wxString *desc) const
         { *desc = m_manager->m_aDescriptions[m_index]; return TRUE; }
 
     bool GetDescription(wxString *desc) const
         { *desc = m_manager->m_aDescriptions[m_index]; return TRUE; }
 
@@ -492,14 +508,14 @@ wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
     return m_impl->GetFileTypeFromMimeType(mimeType);
 }
 
     return m_impl->GetFileTypeFromMimeType(mimeType);
 }
 
-void wxMimeTypesManager::ReadMailcap(const wxString& filename)
+bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
 {
 {
-    m_impl->ReadMailcap(filename);
+    return m_impl->ReadMailcap(filename, fallback);
 }
 
 }
 
-void wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
+bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
 {
 {
-    m_impl->ReadMimeTypes(filename);
+    return m_impl->ReadMimeTypes(filename);
 }
 
 // ============================================================================
 }
 
 // ============================================================================
@@ -520,9 +536,9 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
         // it's the default value of the key
         if ( key.QueryValue("", *command) ) {
             // transform it from '%1' to '%s' style format string
         // it's the default value of the key
         if ( key.QueryValue("", *command) ) {
             // transform it from '%1' to '%s' style format string
-            // @@ we don't make any attempt to verify that the string is valid,
-            //    i.e. doesn't contain %2, or second %1 or .... But we do make
-            //    sure that we return a string with _exactly_ one '%s'!
+            // NB: we don't make any attempt to verify that the string is valid,
+            //     i.e. doesn't contain %2, or second %1 or .... But we do make
+            //     sure that we return a string with _exactly_ one '%s'!
             size_t len = command->Len();
             for ( size_t n = 0; n < len; n++ ) {
                 if ( command->GetChar(n) == '%' &&
             size_t len = command->Len();
             for ( size_t n = 0; n < len; n++ ) {
                 if ( command->GetChar(n) == '%' &&
@@ -535,7 +551,7 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
             }
 
             // we didn't find any '%1'!
             }
 
             // we didn't find any '%1'!
-            // @@@ hack: append the filename at the end, hope that it will do
+            // HACK: append the filename at the end, hope that it will do
             *command << " %s";
 
             return TRUE;
             *command << " %s";
 
             return TRUE;
@@ -546,7 +562,7 @@ bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
     return FALSE;
 }
 
     return FALSE;
 }
 
-// @@ this function is half implemented
+// TODO this function is half implemented
 bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
 {
     if ( m_ext.IsEmpty() ) {
 bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
 {
     if ( m_ext.IsEmpty() ) {
@@ -676,8 +692,8 @@ wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& ext)
 wxFileType *
 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
 {
 wxFileType *
 wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
 {
-    // @@@ I don't know of any official documentation which mentions this
-    //     location, but as a matter of fact IE uses it, so why not we?
+    // HACK I don't know of any official documentation which mentions this
+    //      location, but as a matter of fact IE uses it, so why not we?
     static const char *szMimeDbase = "MIME\\Database\\Content Type\\";
 
     wxString strKey = szMimeDbase;
     static const char *szMimeDbase = "MIME\\Database\\Content Type\\";
 
     wxString strKey = szMimeDbase;
@@ -706,7 +722,7 @@ wxFileTypeImpl::GetEntry(const wxFileType::MessageParameters& params) const
     wxString command;
     MailCapEntry *entry = m_manager->m_aEntries[m_index];
     while ( entry != NULL ) {
     wxString command;
     MailCapEntry *entry = m_manager->m_aEntries[m_index];
     while ( entry != NULL ) {
-        // notice that an empty command would always succeed (@@ is it ok?)
+        // notice that an empty command would always succeed (it's ok)
         command = wxFileType::ExpandCommand(entry->GetTestCmd(), params);
 
         if ( command.IsEmpty() || (system(command) == 0) ) {
         command = wxFileType::ExpandCommand(entry->GetTestCmd(), params);
 
         if ( command.IsEmpty() || (system(command) == 0) ) {
@@ -887,13 +903,13 @@ wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
     }
 }
 
     }
 }
 
-void wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
+bool wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
 {
     wxLogTrace("--- Parsing mime.types file '%s' ---", strFileName.c_str());
 
     wxTextFile file(strFileName);
     if ( !file.Open() )
 {
     wxLogTrace("--- Parsing mime.types file '%s' ---", strFileName.c_str());
 
     wxTextFile file(strFileName);
     if ( !file.Open() )
-        return;
+        return FALSE;
 
     // the information we extract
     wxString strMimeType, strDesc, strExtensions;
 
     // the information we extract
     wxString strMimeType, strDesc, strExtensions;
@@ -1050,18 +1066,26 @@ void wxMimeTypesManagerImpl::ReadMimeTypes(const wxString& strFileName)
     wxASSERT( m_aTypes.Count() == m_aEntries.Count() &&
               m_aTypes.Count() == m_aExtensions.Count() &&
               m_aTypes.Count() == m_aDescriptions.Count() );
     wxASSERT( m_aTypes.Count() == m_aEntries.Count() &&
               m_aTypes.Count() == m_aExtensions.Count() &&
               m_aTypes.Count() == m_aDescriptions.Count() );
+
+    return TRUE;
 }
 
 }
 
-void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
+bool wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName,
+                                         bool fallback)
 {
     wxLogTrace("--- Parsing mailcap file '%s' ---", strFileName.c_str());
 
     wxTextFile file(strFileName);
     if ( !file.Open() )
 {
     wxLogTrace("--- Parsing mailcap file '%s' ---", strFileName.c_str());
 
     wxTextFile file(strFileName);
     if ( !file.Open() )
-        return;
+        return FALSE;
 
 
-    // see the comments near the end of function for the reason we need this
+    // see the comments near the end of function for the reason we need these
+    // variables (search for the next occurence of them)
+        // indices of MIME types (in m_aTypes) we already found in this file
     wxArrayInt aEntryIndices;
     wxArrayInt aEntryIndices;
+        // aLastIndices[n] is the index of last element in
+        // m_aEntries[aEntryIndices[n]] from this file
+    wxArrayInt aLastIndices;
 
     size_t nLineCount = file.GetLineCount();
     for ( size_t nLine = 0; nLine < nLineCount; nLine++ ) {
 
     size_t nLineCount = file.GetLineCount();
     for ( size_t nLine = 0; nLine < nLineCount; nLine++ ) {
@@ -1256,26 +1280,51 @@ void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
                 m_aDescriptions.Add(strDesc);
             }
             else {
                 m_aDescriptions.Add(strDesc);
             }
             else {
-                // modify the existing entry: the entry in one and the same file
-                // are read in top-to-bottom order, i.e. the entries read first
-                // should be tried before the entries below. However, the files
-                // read later should override the settings in the files read
-                // before, thus we Append() the new entry to the list if it has
-                // already occured in _this_ file, but Prepend() it if it
-                // occured in some of the previous ones.
-                if ( aEntryIndices.Index(nIndex) == wxNOT_FOUND ) {
-                    // first time in this file
-                    aEntryIndices.Add(nIndex);
-                    entry->Prepend(m_aEntries[nIndex]);
-                    m_aEntries[nIndex] = entry;
+                // modify the existing entry: the entries in one and the same
+                // file are read in top-to-bottom order, i.e. the entries read
+                // first should be tried before the entries below. However,
+                // the files read later should override the settings in the
+                // files read before (except if fallback is TRUE), thus we
+                // Insert() the new entry to the list if it has already
+                // occured in _this_ file, but Prepend() it if it occured in
+                // some of the previous ones and Append() to it in the
+                // fallback case
+
+                if ( fallback ) {
+                    // 'fallback' parameter prevents the entries from this
+                    // file from overriding the other ones - always append
+                    MailCapEntry *entryOld = m_aEntries[nIndex];
+                    if ( entryOld )
+                        entry->Append(entryOld);
+                    else
+                        m_aEntries[nIndex] = entry;
                 }
                 else {
                 }
                 else {
-                    // not the first time in _this_ file
-                    entry->Append(m_aEntries[nIndex]);
+                    int entryIndex = aEntryIndices.Index(nIndex);
+                    if ( entryIndex == wxNOT_FOUND ) {
+                        // first time in this file
+                        aEntryIndices.Add(nIndex);
+                        aLastIndices.Add(0);
+
+                        entry->Prepend(m_aEntries[nIndex]);
+                        m_aEntries[nIndex] = entry;
+                    }
+                    else {
+                        // not the first time in _this_ file
+                        size_t nEntryIndex = (size_t)entryIndex;
+                        MailCapEntry *entryOld = m_aEntries[nIndex];
+                        if ( entryOld )
+                            entry->Insert(entryOld, aLastIndices[nEntryIndex]);
+                        else
+                            m_aEntries[nIndex] = entry;
+
+                        // the indices were shifted by 1
+                        aLastIndices[nEntryIndex]++;
+                    }
                 }
 
                 if ( !strDesc.IsEmpty() ) {
                 }
 
                 if ( !strDesc.IsEmpty() ) {
-                    // @@ replace the old one - what else can we do??
+                    // replace the old one - what else can we do??
                     m_aDescriptions[nIndex] = strDesc;
                 }
             }
                     m_aDescriptions[nIndex] = strDesc;
                 }
             }
@@ -1286,6 +1335,8 @@ void wxMimeTypesManagerImpl::ReadMailcap(const wxString& strFileName)
                   m_aTypes.Count() == m_aExtensions.Count() &&
                   m_aTypes.Count() == m_aDescriptions.Count() );
     }
                   m_aTypes.Count() == m_aExtensions.Count() &&
                   m_aTypes.Count() == m_aDescriptions.Count() );
     }
+
+    return TRUE;
 }
 
 #endif // OS type
 }
 
 #endif // OS type