Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

dia2dfaml.cc

00001 /*
00002 *  Name:      dia2dfaml.cc
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   Translator for DIA XML format to DFAML
00005 *  Date:      $Date: 2003/10/06 12:45:11 $
00006 *  Revision:  $Revision: 1.2 $
00007 *
00008 *  Copyright (C) 1999-2002  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
00024 */
00025 
00026 #include <algorithm>
00027 #include <clocale>
00028 #include <ctime>
00029 #include <fstream>
00030 #include <iostream>
00031 #include <list>
00032 #include <mpcl/automaton/defs.hh>
00033 #include <mpcl/system/defs.hh>
00034 #include <mpcl/text/regex/matcher.hh>
00035 #include <mpcl/text/string.hh>
00036 #include <mpcl/util/prefs/config_processor.hh>
00037 #include <set>
00038 
00039 
00040 //
00041 //  L O C A L   T Y P E S
00042 //
00043 
00044 using mpcl::automaton::TIntegrityException;
00045 using mpcl::text::regex::TMatcher;
00046 using mpcl::text::Format;
00047 using mpcl::text::TString;
00048 using mpcl::util::collection::TMap;
00049 using mpcl::util::prefs::TConfigProcessor;
00050 using mpcl::system::GetErrorMessage;
00051 using std::pair;
00052 using std::set;
00053 
00054 typedef 
00055   pair<TString, TString>
00056   TConnectionPair;
00057 
00058 typedef
00059   pair<TString, TString>
00060   TIdStatePair;
00061 
00062 typedef
00063   TMap<TString, TConnectionPair>
00064   TMessageToConnectionMap;
00065 
00066 typedef
00067   set<TString>
00068   TStateSet;
00069 
00070 typedef
00071   TMap<TIdStatePair, TString>
00072   TStateToActionNameMap;
00073 
00074 
00075 //
00076 //  L O C A L   V A R I A B L E S
00077 //
00078 
00080 static const char*   _pkcVersion = "0.0.0";
00081 
00083 static TStateSet   _tFinalStateSet;
00084 
00086 static TStateSet   _tInitialStateSet;
00087 
00089 static TMessageToConnectionMap   _tMessageToConnectionMap;
00090 
00092 static TStateToActionNameMap   _tStateToActionNameMap;
00093 
00094 
00095 //
00096 //  L O C A L   F U N C T I O N S
00097 //
00098 
00105 static void _CheckIntegrity (void);
00106 
00112 static bool _ParseDiaString (TMatcher& rtSOURCE_MATCHER, TString& ryTARGET);
00113 
00115 static void 
00116 _ParseDiaClassAttribute ( TMatcher&      rtSOURCE_MATCHER         ,
00117                           TString&       ryTARGET_ATTRIBUTE_NAME  ,
00118                           TString&       ryTARGET_ATTRIBUTE_VALUE ,
00119                           const TString& rkySOURCE_OBJECT_ID      );
00120 
00122 static void
00123 _ParseDiaClassOperation ( TMatcher&      rtSOURCE_MATCHER        ,
00124                           TString&       ryTARGET_OPERATION_NAME ,
00125                           const TString& rkySOURCE_OBJECT_ID     );
00126 
00128 static bool _ParseEndDiaAttribute (TMatcher& rtSOURCE_MATCHER);
00129 
00138 static bool
00139 _ParseDiaAttribute ( TMatcher&      rtSOURCE_MATCHER    ,
00140                      TString&       ryTARGET_NAME       ,
00141                      TString&       ryTARGET_TYPE       ,
00142                      const TString& rkySOURCE_OBJECT_ID );
00143 
00151 static bool
00152 _ParseDiaConnections ( TMatcher& rtSOURCE_MATCHER ,
00153                        TString&  ryTARGET_FROM_ID ,
00154                        TString&  ryTARGET_TO_ID   );
00155 
00161 static void
00162 _ParseUmlMessage (TMatcher& rtSOURCE_MATCHER, const TString& rkySOURCE_OBJECT_ID);
00163 
00169 static void
00170 _ParseUmlClass (TMatcher& rtSOURCE_MATCHER, const TString& rkySOURCE_OBJECT_ID);
00171 
00173 static void _PrintUsage (void);
00174 
00176 static void _ResolveStates (void);
00177 
00179 static void _WriteActions (void);
00180 
00185 static void _WriteDfaml (const TString& rkySOURCE_DFAML_NAME);
00186 
00191 static void _WriteTransitions (const TString& rkySOURCE_STATE);
00192 
00193 
00194 //
00195 //  L O C A L   F U N C T I O N S
00196 //
00197 
00198 static void _CheckIntegrity (void)
00199 {
00200 
00201   std::list<TString>::const_iterator   I;
00202   TMessageToConnectionMap::iterator    J;
00203   std::list<TString>                   tReachableStateList;
00204 
00205   //
00206   //  Checks that only exists one and only one initial state.
00207   //
00208   switch (_tInitialStateSet.size())
00209   {
00210     case 0:
00211     {
00212       throw TIntegrityException ("no initial states", __FILE__, __LINE__);
00213     }
00214     case 1:
00215     {
00216       break;
00217     }
00218     default:
00219     {
00220       throw TIntegrityException ("too many initial states", __FILE__, __LINE__);
00221     }
00222   }
00223 
00224   //
00225   //  Checks that all states are reachable from initial state.
00226   //  Connections must be resolved before that.
00227   //
00228   tReachableStateList.push_back (*_tInitialStateSet.begin());
00229   for (I = tReachableStateList.begin(); ( I != tReachableStateList.end() ) ;++I)
00230   {
00231     for (J = _tMessageToConnectionMap.begin(); ( J != _tMessageToConnectionMap.end() ) ;++J)
00232     {
00233       //
00234       //  If the from-state is equal to the original state from reachable set.
00235       //
00236       if ( *I == J->second.first )
00237       {
00238         //
00239         //  If the to-state isn't included in the reachable state vector,
00240         //  then it inserts into it.
00241         //
00242         if ( find ( tReachableStateList.begin() ,
00243                     tReachableStateList.end()   ,
00244                     J->second.second            ) == tReachableStateList.end() )
00245         {
00246           tReachableStateList.push_back (J->second.second);
00247         }
00248       }
00249     }
00250   }
00251 
00252   //
00253   //  Checks that the cardinal of reachable states from original state,
00254   //  is the same that the cardinal of all states.
00255   //
00256   if ( tReachableStateList.size() != _tStateToActionNameMap.size() )
00257   {
00258     throw TIntegrityException ("there are states not reachable", __FILE__, __LINE__);
00259   }
00260 
00261 }  // _CheckIntegrity()
00262 
00263 
00264 static bool _ParseDiaString (TMatcher& rtSOURCE_MATCHER, TString& ryTARGET)
00265 {
00266 
00267   return rtSOURCE_MATCHER.scan ("<dia:string>{sep}*#%s#{sep}*</dia:string>{sep}*", &ryTARGET, NULL);
00268 
00269 }  // _ParseDiaString()
00270 
00271 
00272 static void _ParseDiaClassOperation ( TMatcher&      rtSOURCE_MATCHER        ,
00273                                       TString&       ryTARGET_OPERATION_NAME ,
00274                                       const TString& rkySOURCE_OBJECT_ID     )
00275 {
00276 
00277   TString   yNull;
00278   
00279   while ( _ParseDiaAttribute ( rtSOURCE_MATCHER        ,
00280                                ryTARGET_OPERATION_NAME ,
00281                                yNull                   ,
00282                                rkySOURCE_OBJECT_ID     ) );
00283 
00284 }  // _ParseDiaClassOperation()
00285 
00286 
00287 static void _ParseDiaClassAttribute ( TMatcher&      rtSOURCE_MATCHER         ,
00288                                       TString&       ryTARGET_ATTRIBUTE_NAME  ,
00289                                       TString&       ryTARGET_ATTRIBUTE_VALUE ,
00290                                       const TString& rkySOURCE_OBJECT_ID      )
00291 {
00292 
00293   while ( _ParseDiaAttribute ( rtSOURCE_MATCHER             ,
00294                                ryTARGET_ATTRIBUTE_NAME  ,
00295                                ryTARGET_ATTRIBUTE_VALUE , 
00296                                rkySOURCE_OBJECT_ID      ) );
00297 
00298 }  // _ParseDiaClassAttribute()
00299 
00300 
00301 static bool _ParseEndDiaAttribute (TMatcher& rtSOURCE_MATCHER)
00302 {
00303 
00304   return rtSOURCE_MATCHER.scan ("</dia:attribute>{sep}*", NULL);
00305   
00306 }  // _ParseEndDiaAttribute()
00307 
00308 
00309 static bool _ParseDiaAttribute ( TMatcher&      rtSOURCE_MATCHER    ,
00310                                  TString&       ryTARGET_NAME       ,
00311                                  TString&       ryTARGET_TYPE       ,
00312                                  const TString& rkySOURCE_OBJECT_ID )
00313 {
00314 
00315   int       iRet;
00316   TString   yActions;
00317   TString   yDiaAttributeName;
00318   TString   yDiaString;
00319   TString   yDiaOperation;
00320   TString   yNull;
00321 
00322   iRet = rtSOURCE_MATCHER.scan ("<dia:attribute name=%q>{sep}*", &yDiaAttributeName, NULL);
00323   if ( !iRet )
00324   {
00325     //
00326     //  Scans for an empty attribute.
00327     //
00328     iRet = rtSOURCE_MATCHER.scan ("<dia:attribute name=%q/>{sep}*", &yNull, NULL);
00329   }
00330   else 
00331   {
00332     if ( ( yDiaAttributeName == "name" ) ||
00333          ( yDiaAttributeName == "text" )  )
00334     {
00335       _ParseDiaString (rtSOURCE_MATCHER, yDiaString);
00336       ryTARGET_NAME = yDiaString;
00337       _ParseEndDiaAttribute (rtSOURCE_MATCHER);
00338     }
00339     else if ( yDiaAttributeName == "value" )
00340     {
00341       _ParseDiaString (rtSOURCE_MATCHER, yDiaString);
00342       ryTARGET_TYPE = yDiaString;
00343       _ParseEndDiaAttribute (rtSOURCE_MATCHER);
00344     }
00345     else if ( yDiaAttributeName == "operations" )
00346     {
00347       //
00348       //  Gets all actions for the current state.
00349       //
00350       yActions.erase();
00351       while ( rtSOURCE_MATCHER.scan ("<dia:composite type=\"umloperation\">{sep}*", NULL) )
00352       {
00353         _ParseDiaClassOperation (rtSOURCE_MATCHER, yDiaOperation, rkySOURCE_OBJECT_ID);
00354         rtSOURCE_MATCHER.scan ("</dia:composite>{sep}*", NULL);
00355         if ( !yActions.empty() )
00356         {
00357           yActions += ", ";
00358         }
00359         yActions += yDiaOperation;
00360       }
00361       _tStateToActionNameMap.bind (make_pair (rkySOURCE_OBJECT_ID, ryTARGET_NAME), yActions);
00362       _ParseEndDiaAttribute (rtSOURCE_MATCHER);
00363     }
00364     else if ( yDiaAttributeName == "attributes" )
00365     {
00366       TString   yAttributeName;
00367       TString   yAttributeValue;
00368       
00369       //
00370       //  Gets state type (initial or final) for the current state.
00371       //
00372       while ( rtSOURCE_MATCHER.scan ("<dia:composite type=\"umlattribute\">{sep}*", NULL) )
00373       {
00374         _ParseDiaClassAttribute (rtSOURCE_MATCHER, yAttributeName, yAttributeValue, rkySOURCE_OBJECT_ID);
00375         rtSOURCE_MATCHER.scan ("</dia:composite>{sep}*", NULL);
00376       }
00377       if ( yAttributeName == "type" )
00378       {
00379         if ( yAttributeValue == "final" )
00380         {
00381           _tFinalStateSet.insert (ryTARGET_NAME);
00382         }
00383         else if ( yAttributeValue == "initial" )
00384         {
00385           _tInitialStateSet.insert (ryTARGET_NAME);
00386         }
00387       }
00388       _ParseEndDiaAttribute (rtSOURCE_MATCHER);
00389     }
00390     else
00391     {
00392       //
00393       //  Remove un-useful DIA attributes.
00394       //
00395       while ( true )
00396       {
00397         if ( !rtSOURCE_MATCHER.scan ("<dia:%s val=%q/>{sep}*", NULL) )
00398         {
00399           if ( !rtSOURCE_MATCHER.scan ("<dia:string>%t</dia:string>{sep}*", NULL) )
00400           {
00401             if ( !rtSOURCE_MATCHER.scan ("<dia:string/>{sep}*", NULL) )
00402             {
00403               break;
00404             }
00405           }
00406         }
00407       }
00408     }
00409     _ParseEndDiaAttribute (rtSOURCE_MATCHER);
00410   }
00411   return iRet;
00412 
00413 }  // _ParseDiaAttribute()
00414 
00415 
00416 static bool _ParseDiaConnections ( TMatcher& rtSOURCE_MATCHER ,
00417                                    TString&  ryTARGET_FROM_ID ,
00418                                    TString&  ryTARGET_TO_ID   )
00419 {
00420 
00421   TString   yNull;
00422 
00423   return rtSOURCE_MATCHER.scan ( "<dia:connections>{sep}*"
00424                                  "<dia:connection handle=%q to=%q connection=%q/>{sep}*"
00425                                  "<dia:connection handle=%q to=%q connection=%q/>{sep}*"
00426                                  "</dia:connections>{sep}*"                              ,
00427                                  &yNull                                                  ,
00428                                  &ryTARGET_FROM_ID                                       ,
00429                                  &yNull                                                  ,
00430                                  &yNull                                                  ,
00431                                  &ryTARGET_TO_ID                                         ,
00432                                  &yNull                                                  ,
00433                                  NULL                                                    );
00434 
00435 }  // _ParseDiaConnections()
00436 
00437 
00438 static void _ParseUmlClass ( TMatcher&      rtSOURCE_MATCHER    ,
00439                              const TString& rkySOURCE_OBJECT_ID )
00440 {
00441 
00442   TStateToActionNameMap::const_iterator   I;
00443   TString                                 yDiaClassName;
00444   TString                                 yDiaClassType;
00445 
00446   while ( _ParseDiaAttribute (rtSOURCE_MATCHER, yDiaClassName, yDiaClassType, rkySOURCE_OBJECT_ID) );
00447   I = _tStateToActionNameMap.find (make_pair (rkySOURCE_OBJECT_ID, yDiaClassName));
00448   if ( I == _tStateToActionNameMap.end() )
00449   {
00450     _tStateToActionNameMap.bind (make_pair (rkySOURCE_OBJECT_ID, yDiaClassName), "");
00451   }
00452   rtSOURCE_MATCHER.scan ("</dia:object>{sep}*", NULL);
00453   
00454 }  // _ParseUmlClass()
00455 
00456 
00457 static void
00458 _ParseUmlMessage (TMatcher& rtSOURCE_MATCHER, const TString& rkySOURCE_OBJECT_ID)
00459 {
00460 
00461   TString   yDiaMessageName;
00462   TString   yFromId;
00463   TString   yNull;
00464   TString   yToId;
00465 
00466   for (;;)
00467   {
00468     if ( !_ParseDiaAttribute (rtSOURCE_MATCHER, yDiaMessageName, yNull, rkySOURCE_OBJECT_ID) )
00469     {
00470       if ( !_ParseDiaConnections (rtSOURCE_MATCHER, yFromId, yToId) )
00471       {
00472         break;
00473       }
00474       else
00475       {
00476         _tMessageToConnectionMap.bind (yDiaMessageName, make_pair (yFromId, yToId));
00477       }
00478     }
00479   }
00480   rtSOURCE_MATCHER.scan ("</dia:object>{sep}*", NULL);
00481 
00482 }  // _ParseUmlMessage()
00483 
00484 
00485 static void _ResolveStates (void)
00486 {
00487 
00488   TMessageToConnectionMap::iterator       I;
00489   TStateToActionNameMap::const_iterator   J;
00490   register short int                      K;
00491 
00492   for (I = _tMessageToConnectionMap.begin(); ( I != _tMessageToConnectionMap.end() ) ;++I)
00493   {
00494     J = _tStateToActionNameMap.begin();
00495     K = 0;
00496     for (; ( ( K < 2 ) && ( J != _tStateToActionNameMap.end() ) ) ;++J)
00497     {
00498       //
00499       //  Resolve FROM object identifier to a state name.
00500       //
00501       if ( I->second.first == J->first.first )
00502       {
00503         I->second.first = J->first.second;
00504         ++K;
00505       }
00506       //
00507       //  Resolve TO object identifier to a state name.
00508       //
00509       if ( I->second.second == J->first.first )
00510       {
00511         I->second.second = J->first.second;
00512         ++K;
00513       }
00514     }
00515   }
00516 
00517 }  // ResolveStates()
00518 
00519 
00520 static void _WriteActions (void)
00521 {
00522   
00523   TStateToActionNameMap::iterator   I;
00524 
00525   for (I = _tStateToActionNameMap.begin(); ( I != _tStateToActionNameMap.end() ) ;++I)
00526   {
00527     if ( !I->second.empty() )
00528     {
00529       std::cout << "    <action state=\"" << I->first.second
00530                 << "\" actions=\""        << I->second
00531                 << "\">\n";
00532     }
00533   }
00534 
00535 }  // _WriteTransitions()
00536 
00537 
00538 static void _WriteDfaml (const TString& rkySOURCE_DFAML_NAME)
00539 {
00540 
00541   using std::cout;
00542   using std::time_t;
00543 
00544   TStateToActionNameMap::const_iterator   I;
00545   char*                                   pcCurrentTime;
00546   time_t                                  tCurrentTime;
00547   TString                                 yDtdVersion;
00548   TString                                 yInitialState = *_tInitialStateSet.begin();
00549   
00550   //
00551   //  If there are no actions, then DTD version is 1.0, else is 2.0.
00552   //
00553   yDtdVersion = ( _tStateToActionNameMap.empty() ) ? "1.0" : "2.0";
00554 
00555   //
00556   //  Gets current date, and removes the last character '\n'
00557   //  from the string returned from std::ctime().
00558   //
00559   std::time (&tCurrentTime);
00560   pcCurrentTime                                      = std::ctime (&tCurrentTime);
00561   *(pcCurrentTime + std::strlen (pcCurrentTime) - 1) = '\0';
00562 
00563   //
00564   //  Writes header.
00565   //
00566   cout << Format ( "<!doctype dfaml public \"-//MPCL//DTD DFAML %s//EN\">\n"
00567                    "<dfaml name=\"%s\">\n"
00568                    "  <desc>Created with DIA2DFAML (DFAML %s) on %s.</desc>\n"
00569                    "  <transtbl initial=\"%s\">\n"                             ,
00570                    yDtdVersion.c_str()                                         ,
00571                    rkySOURCE_DFAML_NAME.c_str()                                ,
00572                    yDtdVersion.c_str()                                         ,
00573                    pcCurrentTime                                               ,
00574                    yInitialState.c_str()                                       );
00575 
00576   //
00577   //  Writes STATEs.
00578   //
00579   for (I = _tStateToActionNameMap.begin(); ( I != _tStateToActionNameMap.end() ) ;++I)
00580   {
00581     cout << "    <state name=\"" << I->first.second;
00582     
00583     //
00584     //  If this is a final state, then writes the corresponding attribute.
00585     //
00586     if ( _tFinalStateSet.find (I->first.second) == _tFinalStateSet.end() )
00587     {
00588       cout << "\">\n";
00589     }
00590     else
00591     {
00592       cout << "\" type=\"final\">\n";
00593     }
00594     _WriteTransitions (I->first.second);
00595     cout << "    </state>\n";
00596   }
00597   cout << "  </transtbl>\n";
00598 
00599   //
00600   //  Writes ACTLIST if any state has actions.
00601   //
00602   if ( !_tStateToActionNameMap.empty() )
00603   {
00604     cout << "  <actlist>\n";
00605     _WriteActions();
00606     cout << "  </actlist>\n";
00607   }
00608   cout << "</dfaml>\n";
00609 
00610 }  // _WriteDfaml()
00611 
00612 
00613 static void _WriteTransitions (const TString& rkySOURCE_STATE)
00614 {
00615   
00616   TMessageToConnectionMap::iterator   I;
00617   
00618   for (I = _tMessageToConnectionMap.begin(); ( I != _tMessageToConnectionMap.end() ) ;++I)
00619   {
00620     if ( I->second.first == rkySOURCE_STATE )
00621     {
00622       std::cout << "      <transit event=\"" << I->first 
00623                 << "\" next=\""              << I->second.second
00624                 << "\">\n";
00625     }
00626   }
00627   
00628 }  // _WriteTransitions()
00629 
00630 
00632 static void _PrintUsage (void)
00633 {
00634 
00635   std::cout << "Usage:  diadfaml [OPTION]... [{FILE, -}]\n\n"
00636             << "Overall Options:\n"
00637             << "  -n, --name=DFAML_NAME\n\n"
00638             << "Informative output:\n"
00639             << "  -h, --help\n"
00640             << "  -V, --version\n\n";
00641 
00642 }  // _PrintUsage()
00643 
00644 
00646 int main (int argc, const char* argv[])
00647 {
00648 
00649   using std::cerr;
00650   using std::cin;
00651   using std::cout;
00652   using std::endl;
00653   
00654   TMatcher                    tMatcher;
00655   TString                     yNull;
00656   TString                     yObjectId;
00657   TString                     yObjectType;
00658   TConfigProcessor            tConfig (argc, argv);
00659   int                         iExitCode      = 0;
00660   std::basic_istream<char>*   ptInputIstream = NULL;
00661   
00662   std::setlocale (LC_ALL, "");
00663   try
00664   {
00665     tConfig.addOption ("name",    "n", "generic_dfa");
00666     tConfig.addOption ("help",    "h");
00667     tConfig.addOption ("version", "V");
00668     tConfig.processOptions();
00669     if ( tConfig ["help"].isAtCmdLine() )
00670     {
00671       _PrintUsage();
00672     }
00673     else if ( tConfig ["version"].isAtCmdLine() )
00674     {
00675       cout << _pkcVersion << endl;
00676     }
00677     else
00678     {
00679       switch (tConfig.numberOfArguments())
00680       {
00681         case 0:
00682         {
00683           //
00684           //  Input is from standard input stream.
00685           //
00686           ptInputIstream = &cin;
00687           break;
00688         }
00689         case 1:
00690         {
00691           if ( tConfig.argumentValue (0) == "-" )
00692           {
00693             //
00694             //  Input is from standard input stream.
00695             //
00696             ptInputIstream = &cin;
00697           }
00698           else
00699           {
00700             //
00701             //  Input is from a file.
00702             //
00703             ptInputIstream = new std::basic_ifstream<char> (tConfig.argumentValue (0).c_str());
00704             if ( !ptInputIstream->good() )
00705             {
00706               throw mpcl::TNotFoundException (GetErrorMessage(), __FILE__, __LINE__);
00707             }
00708           }
00709           break;
00710         }
00711         default:
00712         {
00713           //
00714           //  Too many arguments.
00715           //
00716           throw TIntegrityException ("too many files", __FILE__, __LINE__);
00717         }
00718       }
00719       tMatcher.setInput (*ptInputIstream);
00720       tMatcher.define ("{sep}", "[[:space:]]");
00721       tMatcher.scan ( "%t<dia:layer name=\"Background\" visible=\"true\">{sep}*", NULL);
00722       while ( tMatcher.scan ( "<dia:object type=%q version=%q id=%q>{sep}*" ,
00723                               &yObjectType                                  ,
00724                               &yNull                                        ,
00725                               &yObjectId                                    ,
00726                               NULL                                          ) )
00727       {
00728         if ( yObjectType == "UML - Class" )
00729         {
00730           _ParseUmlClass (tMatcher, yObjectId);
00731         }
00732         else if ( yObjectType == "UML - Message" )
00733         {
00734           _ParseUmlMessage (tMatcher, yObjectId);
00735         }
00736         else
00737         {
00738           tMatcher.scan("%t</dia:object>{sep}*", NULL);
00739         }
00740       }
00741       //
00742       //  Resolves state identifiers to names.
00743       //
00744       _ResolveStates();
00745       _CheckIntegrity();
00746       _WriteDfaml (tConfig ["name"].getValue());
00747     }
00748   }
00749   catch (const mpcl::TException& rktEXCEPTION)
00750   {
00751     iExitCode = 3;
00752     cerr << rktEXCEPTION.what() << endl;
00753   }
00754   catch (const std::exception& rktEXCEPTION)
00755   {
00756     iExitCode = 2;
00757     cerr << rktEXCEPTION.what() << endl;
00758   }
00759   catch (...)
00760   {
00761     iExitCode = 1;
00762     cerr << mpcl::TException ("unhandled exception", NULL, __FILE__, __LINE__).what() << endl;
00763   }
00764 
00765   //
00766   //  Destroys dynamicly created objects.
00767   //
00768   if ( ptInputIstream && ( ptInputIstream != &cin ) )
00769   {
00770     delete ptInputIstream;
00771   }
00772   return iExitCode;
00773 
00774 }  // main()

Generated on Mon Oct 13 02:35:23 2003 for MPCL by doxygen1.2.18