]> git.mxchange.org Git - flightgear.git/blobdiff - src/ATC/transmissionlist.cxx
The most important part is that it fixes possible
[flightgear.git] / src / ATC / transmissionlist.cxx
index 8d354cc718cdf86edef1f9b9ca7b9885a97cb154..2f138edc90d670856e2dda4bd14e843f0301031e 100644 (file)
-// transmissionlist.cxx -- transmission management class\r
-//\r
-// Written by Alexander Kappes, started March 2002.\r
-// Based on navlist.cxx by Curtis Olson, started April 2000.\r
-//\r
-// Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org\r
-//\r
-// This program is free software; you can redistribute it and/or\r
-// modify it under the terms of the GNU General Public License as\r
-// published by the Free Software Foundation; either version 2 of the\r
-// License, or (at your option) any later version.\r
-//\r
-// This program is distributed in the hope that it will be useful, but\r
-// WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
-// General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU General Public License\r
-// along with this program; if not, write to the Free Software\r
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
-//\r
-// $Id$\r
-\r
-\r
-#ifdef HAVE_CONFIG_H\r
-#  include <config.h>\r
-#endif\r
-\r
-#include <simgear/debug/logstream.hxx>\r
-#include <simgear/misc/sgstream.hxx>\r
-#include <simgear/math/sg_geodesy.hxx>\r
-\r
-#include "transmissionlist.hxx"\r
-\r
-#include <GUI/gui.h>\r
-\r
-static puDialogBox  *ATCMenuBox = 0;\r
-static puFrame      *ATCMenuFrame = 0;\r
-static puText       *ATCMenuBoxMessage = 0;\r
-\r
-FGTransmissionList *current_transmissionlist;\r
-\r
-\r
-// Constructor\r
-FGTransmissionList::FGTransmissionList( void ) {\r
-}\r
-\r
-\r
-// Destructor\r
-FGTransmissionList::~FGTransmissionList( void ) {\r
-}\r
-\r
-/*\r
-// ============================================================================\r
-// init menu window\r
-// ============================================================================\r
-void mkATCMenuInit (void)\r
-{\r
-  int dx = 400;\r
-  int dy = 100;\r
-  int y = (fgGetInt("/sim/startup/ysize") - 10 - dy);\r
-  ATCMenuBox = new puDialogBox (10, y);\r
-  {\r
-    ATCMenuFrame = new puFrame (0,0,400,100);\r
-    ATCMenuBoxMessage  =  new puText         (10, 70);\r
-    ATCMenuBoxMessage  -> setLabel           ("");\r
-  }\r
-  fgSetBool("/sim/atc/menu",false);\r
-  fgSetBool("/sim/atc/opt1",false);\r
-  fgSetBool("/sim/atc/opt2",false);\r
-  fgSetBool("/sim/atc/opt3",false);\r
-  fgSetBool("/sim/atc/opt4",false);\r
-  fgSetBool("/sim/atc/opt5",false);\r
-  fgSetBool("/sim/atc/opt6",false);\r
-  fgSetBool("/sim/atc/opt7",false);\r
-  fgSetBool("/sim/atc/opt8",false);\r
-  fgSetBool("/sim/atc/opt9",false);\r
-  fgSetBool("/sim/atc/opt0",false);\r
-}\r
-\r
-// ATC Menu Message Box\r
-void mkATCMenu ( const char *txt )\r
-{\r
-  ATCMenuBoxMessage  =  new puText   (10, 70);\r
-  ATCMenuBoxMessage->setLabel( txt );\r
-\r
-  FG_PUSH_PUI_DIALOG( ATCMenuBox );\r
-}\r
-*/\r
-\r
-// load default.transmissions\r
-bool FGTransmissionList::init( SGPath path ) {\r
-    FGTransmission a;\r
-\r
-    transmissionlist_station.erase( transmissionlist_station.begin(), transmissionlist_station.end() );\r
-\r
-    sg_gzifstream in( path.str() );\r
-    if ( !in.is_open() ) {\r
-        SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );\r
-        exit(-1);\r
-    }\r
-\r
-    // read in each line of the file\r
-\r
-    // in >> skipeol;\r
-    // in >> skipcomment;\r
-\r
-#ifdef __MWERKS__\r
-\r
-    char c = 0;\r
-    while ( in.get(c) && c != '\0' ) {\r
-        in.putback(c);\r
-        in >> a;\r
-       if ( a.get_type() != '[' ) {\r
-           transmissionlist_code[a.get_station()].push_back(a);\r
-       }\r
-        in >> skipcomment;\r
-    }\r
-\r
-#else\r
-\r
-    double min = 100000;\r
-    double max = 0;\r
-\r
-    while ( ! in.eof() ) {\r
-        in >> a;\r
-       transmissionlist_station[a.get_station()].push_back(a);\r
-       \r
-        in >> skipcomment;\r
-\r
-       if ( a.get_station() < min ) {\r
-         min = a.get_station();\r
-       }\r
-       if ( a.get_station() > max ) {\r
-         max = a.get_station();\r
-       }\r
-       cout << a.get_station() << " " << a.get_code().c1 << " " << a.get_code().c2 << " "\r
-            << a.get_code().c3 << " " << a.get_transtext() \r
-            << " " << a.get_menutext() << endl;\r
-    }\r
-    \r
-#endif\r
-\r
-    // init ATC menu\r
-    fgSetBool("/sim/atc/menu",false);\r
-\r
-    return true;\r
-}\r
-\r
-// query the database for the specified station type; \r
-// for station see FlightGear/ATC/default.transmissions\r
-bool FGTransmissionList::query_station( const int &station, FGTransmission *t,\r
-                                       int max_trans, int &num_trans ) \r
-{\r
-  transmission_list_type     tmissions = transmissionlist_station[station];\r
-  transmission_list_iterator current   = tmissions.begin();\r
-  transmission_list_iterator last      = tmissions.end();\r
-\r
-  for ( ; current != last ; ++current ) {\r
-    if (num_trans < max_trans) {\r
-      t[num_trans] = *current;\r
-      num_trans += 1;\r
-    }\r
-    else {\r
-      cout << "Transmissionlist error: Too many transmissions" << endl; \r
-    }\r
-  }\r
-\r
-  if ( num_trans != 0 ) return true;\r
-  else {\r
-    cout << "No transmission with station " << station << "found." << endl;\r
-    string empty;\r
-    return false;\r
-  }\r
-}\r
-\r
-string FGTransmissionList::gen_text(const int &station, const TransCode code, \r
-                                   const TransPar &tpars, const bool ttext )\r
-{\r
-  const int cmax = 100;\r
-  string message;\r
-  char tag[4];\r
-  char crej = '@';\r
-  char mes[cmax];\r
-  char dum[cmax];\r
-  char buf[10];\r
-  char *pos;\r
-  int len;\r
-  FGTransmission t;\r
-\r
-  //  if (current_transmissionlist->query_station( station, &t ) ) {  \r
-  transmission_list_type     tmissions = transmissionlist_station[station];\r
-  transmission_list_iterator current   = tmissions.begin();\r
-  transmission_list_iterator last      = tmissions.end();\r
-  \r
-  for ( ; current != last ; ++current ) {\r
-    if ( current->get_code().c1 == code.c1 &&  \r
-        current->get_code().c2 == code.c2 &&\r
-        current->get_code().c3 == code.c3 ) {\r
-      \r
-      if ( ttext ) message = current->get_transtext();\r
-      else message = current->get_menutext();\r
-      strcpy( &mes[0], message.c_str() ); \r
-      \r
-      while ( strchr(&mes[0], crej) != NULL  ) {\r
-       pos = strchr( &mes[0], crej );\r
-       bcopy(pos, &tag, 3);\r
-       tag[3] = '\0';\r
-       int i;\r
-       len = 0;\r
-       for ( i=0; i<cmax; i++ ) {\r
-         if ( mes[i] == crej ) {\r
-           len = i; \r
-           break;\r
-         }\r
-       }\r
-       strncpy( &dum[0], &mes[0], len );\r
-       dum[len] = '\0';\r
-       \r
-       if ( strcmp ( tag, "@ST" ) == 0 )\r
-         strcat( &dum[0], tpars.station.c_str() );\r
-       else if ( strcmp ( tag, "@AP" ) == 0 )\r
-         strcat( &dum[0], tpars.airport.c_str() );\r
-       else if ( strcmp ( tag, "@CS" ) == 0 ) \r
-         strcat( &dum[0], tpars.callsign.c_str() );\r
-       else if ( strcmp ( tag, "@TD" ) == 0 ) {\r
-         if ( tpars.tdir == 1 ) {\r
-           char buf[] = "left";\r
-           strcat( &dum[0], &buf[0] );\r
-         }\r
-         else {\r
-           char buf[] = "right";\r
-           strcat( &dum[0], &buf[0] );\r
-         }\r
-       }\r
-       else if ( strcmp ( tag, "@HE" ) == 0 ) {\r
-         char buf[10];\r
-         sprintf( buf, "%i", (int)(tpars.heading) );\r
-         strcat( &dum[0], &buf[0] );\r
-       }\r
-       else if ( strcmp ( tag, "@VD" ) == 0 ) {\r
-         if ( tpars.VDir == 1 ) {\r
-           char buf[] = "Descent and maintain";\r
-           strcat( &dum[0], &buf[0] );\r
-         }\r
-         else if ( tpars.VDir == 2 ) {\r
-           char buf[] = "Maintain";\r
-           strcat( &dum[0], &buf[0] );\r
-         }\r
-         else if ( tpars.VDir == 3 ) {\r
-           char buf[] = "Climb and maintain";\r
-           strcat( &dum[0], &buf[0] );\r
-         }  \r
-       }\r
-       else if ( strcmp ( tag, "@AL" ) == 0 ) {\r
-         char buf[10];\r
-         sprintf( buf, "%i", (int)(tpars.alt) );\r
-         strcat( &dum[0], &buf[0] );\r
-       }\r
-       else if ( strcmp ( tag, "@MI" ) == 0 ) {\r
-         char buf[10];\r
-         sprintf( buf, "%3.1f", tpars.miles );\r
-         strcat( &dum[0], &buf[0] );\r
-       }\r
-       else if ( strcmp ( tag, "@FR" ) == 0 ) {\r
-         char buf[10];\r
-         sprintf( buf, "%6.2f", tpars.freq );\r
-         strcat( &dum[0], &buf[0] );\r
-       }\r
-       else if ( strcmp ( tag, "@RW" ) == 0 )\r
-         strcat( &dum[0], tpars.runway.c_str() );\r
-       else {\r
-         cout << "Tag " << tag << " not found" << endl;\r
-         break;\r
-       }\r
-       strcat( &dum[0], &mes[len+3] );\r
-       strcpy( &mes[0], &dum[0] );\r
-      }\r
-\r
-      //cout << mes  << endl;  \r
-      break;\r
-    }\r
-  }\r
-  if ( mes != "" ) return mes;\r
-  else return "No transmission found";\r
-}\r
-\r
-\r
+// transmissionlist.cxx -- transmission management class
+//
+// Written by Alexander Kappes, started March 2002.
+// Based on navlist.cxx by Curtis Olson, started April 2000.
+//
+// Copyright (C) 2000  Curtis L. Olson - http://www.flightgear.org/~curt
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>   // bcopy()
+#else
+#  include <string.h>    // MSVC doesn't have strings.h
+#endif
+
+
+#include <simgear/debug/logstream.hxx>
+#include <simgear/misc/sgstream.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+
+#include "transmissionlist.hxx"
+
+#include <GUI/gui.h>
+
+
+FGTransmissionList *current_transmissionlist;
+
+
+FGTransmissionList::FGTransmissionList( void ) {
+}
+
+
+FGTransmissionList::~FGTransmissionList( void ) {
+}
+
+
+// load default.transmissions
+bool FGTransmissionList::init( const SGPath& path ) {
+    FGTransmission a;
+
+    transmissionlist_station.erase( transmissionlist_station.begin(), transmissionlist_station.end() );
+
+    sg_gzifstream in( path.str() );
+    if ( !in.is_open() ) {
+        SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << path.str() );
+        exit(-1);
+    }
+
+    // read in each line of the file
+
+    // in >> skipeol;
+    // in >> skipcomment;
+
+#ifdef __MWERKS__
+
+    char c = 0;
+    while ( in.get(c) && c != '\0' ) {
+        in.putback(c);
+        in >> a;
+       if ( a.get_type() != '[' ) {
+           transmissionlist_code[a.get_station()].push_back(a);
+       }
+        in >> skipcomment;
+    }
+
+#else
+
+    double min = 100000;
+    double max = 0;
+
+    while ( ! in.eof() ) {
+        in >> a;
+        transmissionlist_station[a.get_station()].push_back(a);
+
+        in >> skipcomment;
+
+        if ( a.get_station() < min ) {
+            min = a.get_station();
+        }
+        if ( a.get_station() > max ) {
+            max = a.get_station();
+        }
+
+        /*
+        cout << a.get_station() << " " << a.get_code().c1 << " " << a.get_code().c2 << " "
+             << a.get_code().c3 << " " << a.get_transtext() 
+             << " " << a.get_menutext() << endl;
+        */
+    }
+#endif
+
+    // init ATC menu
+    fgSetBool("/sim/atc/menu",false);
+
+    return true;
+}
+
+// query the database for the specified station type; 
+// for station see FlightGear/ATC/default.transmissions
+bool FGTransmissionList::query_station( const atc_type &station, FGTransmission *t,
+                                       int max_trans, int &num_trans ) 
+{
+  transmission_list_type     tmissions = transmissionlist_station[station];
+  transmission_list_iterator current   = tmissions.begin();
+  transmission_list_iterator last      = tmissions.end();
+
+  for ( ; current != last ; ++current ) {
+    if (num_trans < max_trans) {
+      t[num_trans] = *current;
+      num_trans += 1;
+    }
+    else {
+      cout << "Transmissionlist error: Too many transmissions" << endl; 
+    }
+  }
+
+  if ( num_trans != 0 ) return true;
+  else {
+    cout << "No transmission with station " << station << "found." << endl;
+    string empty;
+    return false;
+  }
+}
+
+string FGTransmissionList::gen_text(const atc_type &station, const TransCode code, 
+                                    const TransPar &tpars, const bool ttext )
+{
+       const int cmax = 300;
+       string message;
+       char tag[4];
+       char crej = '@';
+       char mes[cmax];
+       char dum[cmax];
+       //char buf[10];
+       char *pos;
+       int len;
+       FGTransmission t;
+       
+       //  if (current_transmissionlist->query_station( station, &t ) ) { 
+       transmission_list_type     tmissions = transmissionlist_station[station];
+       transmission_list_iterator current   = tmissions.begin();
+       transmission_list_iterator last      = tmissions.end();
+       
+       for ( ; current != last ; ++current ) {
+               if ( current->get_code().c1 == code.c1 &&  
+                       current->get_code().c2 == code.c2 &&
+                   current->get_code().c3 == code.c3 ) {
+                       
+                       if ( ttext ) message = current->get_transtext();
+                       else message = current->get_menutext();
+                       strcpy( &mes[0], message.c_str() ); 
+                       
+                       // Replace all the '@' parameters with the actual text.
+                       int check = 0;  // If mes gets overflowed the while loop can go infinite
+                       while ( strchr(&mes[0], crej) != NULL  ) {      // ie. loop until no more occurances of crej ('@') found
+                               pos = strchr( &mes[0], crej );
+                               memmove(&tag[0], pos, 3);
+                               tag[3] = '\0';
+                               int i;
+                               len = 0;
+                               for ( i=0; i<cmax; i++ ) {
+                                       if ( mes[i] == crej ) {
+                                               len = i; 
+                                               break;
+                                       }
+                               }
+                               strncpy( &dum[0], &mes[0], len );
+                               dum[len] = '\0';
+                               
+                               if ( strcmp ( tag, "@ST" ) == 0 )
+                                       strcat( &dum[0], tpars.station.c_str() );
+                               else if ( strcmp ( tag, "@AP" ) == 0 )
+                                       strcat( &dum[0], tpars.airport.c_str() );
+                               else if ( strcmp ( tag, "@CS" ) == 0 ) 
+                                       strcat( &dum[0], tpars.callsign.c_str() );
+                               else if ( strcmp ( tag, "@TD" ) == 0 ) {
+                                       if ( tpars.tdir == 1 ) {
+                                               char buf[] = "left";
+                                               strcat( &dum[0], &buf[0] );
+                                       }
+                                       else {
+                                               char buf[] = "right";
+                                               strcat( &dum[0], &buf[0] );
+                                       }
+                               }
+                               else if ( strcmp ( tag, "@HE" ) == 0 ) {
+                                       char buf[10];
+                                       sprintf( buf, "%i", (int)(tpars.heading) );
+                                       strcat( &dum[0], &buf[0] );
+                               }
+                               else if ( strcmp ( tag, "@VD" ) == 0 ) {
+                                       if ( tpars.VDir == 1 ) {
+                                               char buf[] = "Descend and maintain";
+                                               strcat( &dum[0], &buf[0] );
+                                       }
+                                       else if ( tpars.VDir == 2 ) {
+                                               char buf[] = "Maintain";
+                                               strcat( &dum[0], &buf[0] );
+                                       }
+                                       else if ( tpars.VDir == 3 ) {
+                                               char buf[] = "Climb and maintain";
+                                               strcat( &dum[0], &buf[0] );
+                                       }  
+                               }
+                               else if ( strcmp ( tag, "@AL" ) == 0 ) {
+                                       char buf[10];
+                                       sprintf( buf, "%i", (int)(tpars.alt) );
+                                       strcat( &dum[0], &buf[0] );
+                               }
+                               else if ( strcmp ( tag, "@MI" ) == 0 ) {
+                                       char buf[10];
+                                       sprintf( buf, "%3.1f", tpars.miles );
+                                       strcat( &dum[0], &buf[0] );
+                               }
+                               else if ( strcmp ( tag, "@FR" ) == 0 ) {
+                                       char buf[10];
+                                       sprintf( buf, "%6.2f", tpars.freq );
+                                       strcat( &dum[0], &buf[0] );
+                               }
+                               else if ( strcmp ( tag, "@RW" ) == 0 )
+                                       strcat( &dum[0], tpars.runway.c_str() );
+                               else {
+                                       cout << "Tag " << tag << " not found" << endl;
+                                       break;
+                               }
+                               strcat( &dum[0], &mes[len+3] );
+                               strcpy( &mes[0], &dum[0] );
+                               
+                               ++check;
+                               if(check > 10) {
+                                       SG_LOG(SG_ATC, SG_WARN, "WARNING: Possibly endless loop terminated in FGTransmissionlist::gen_text(...)"); 
+                                       break;
+                               }
+                       }
+                       
+                       //cout << mes  << endl;  
+                       break;
+               }
+       }
+       if ( mes != "" ) return mes;
+       else return "No transmission found";
+}
+
+