[Debian-astro-commits] [gyoto] 88/221: New API: FactoryMessenger::parseArray(). Use it instead of direct calls to strtod everywhere.

Thibaut Jean-Claude Paumard thibaut at moszumanska.debian.org
Fri May 22 20:52:36 UTC 2015


This is an automated email from the git hooks/post-receive script.

thibaut pushed a commit to branch master
in repository gyoto.

commit 40cf1c2b9b65942fafa02259209aa92d29c2791b
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date:   Tue Nov 18 15:38:23 2014 +0100

    New API: FactoryMessenger::parseArray(). Use it instead of direct calls to strtod everywhere.
---
 include/GyotoFactoryMessenger.h | 10 ++++++++++
 lib/Factory.C                   | 25 +++++++++++++++++++++++++
 lib/FixedStar.C                 |  4 ++--
 lib/NumericalMetricLorene.C     |  8 +++++---
 lib/PolishDoughnut.C            | 16 ++++++++++------
 lib/Screen.C                    | 16 +++++++++++-----
 lib/UniformSpectrometer.C       |  8 ++++----
 lib/Worldline.C                 |  9 ++++++---
 8 files changed, 73 insertions(+), 23 deletions(-)

diff --git a/include/GyotoFactoryMessenger.h b/include/GyotoFactoryMessenger.h
index 514701c..7ec704c 100644
--- a/include/GyotoFactoryMessenger.h
+++ b/include/GyotoFactoryMessenger.h
@@ -456,6 +456,16 @@ class Gyoto::FactoryMessenger {
   FactoryMessenger* makeChild(std::string name);
   ///< Create child FactoryMessenger
 
+  /**
+   * \brief Parse string into array
+   *
+   * Parse at most max_tokens tokens from string src into
+   * pre-allocated array dst. Returns the number of tokens actually
+   * found (interpreted using atof). dst must be at least of size
+   * max_tokens.
+   */
+  static size_t parseArray(std::string src, double dst[], size_t max_tokens);
+
 };
 
 #endif
diff --git a/lib/Factory.C b/lib/Factory.C
index 6b5af59..080ab1c 100644
--- a/lib/Factory.C
+++ b/lib/Factory.C
@@ -928,6 +928,31 @@ void FactoryMessenger::setParameter(std::string name, double val[], size_t n,
   employer_ -> setParameter(name, val, n, element_, child);
 }
 
+size_t FactoryMessenger::parseArray(std::string content, double val[], size_t max_tokens)
+{
+  char const * const delim = " \t\n" ;
+  char const * const c_content=content.c_str();
+  size_t len=strlen(c_content);
+  if (len==0) return 0;
+
+  size_t n=0;
+  char * const tc = new char[len+1];
+  memcpy(tc, c_content, len+1);
+  char * sub = strtok(tc, delim);
+
+  while (sub && n<max_tokens) {
+    val[n++] = Gyoto::atof(sub);
+    cerr << "#"<< n << ": " << sub << " -> " << val[n-1] << endl;
+    sub = strtok(NULL, delim);
+  }
+  
+  if (sub) n=max_tokens+1;
+
+  delete [] tc;
+
+  return n;
+}
+
 std::string FactoryMessenger::fullPath(std::string fname) {
   return employer_ -> fullPath(fname);
 }
diff --git a/lib/FixedStar.C b/lib/FixedStar.C
index 82ec0e0..1501bad 100644
--- a/lib/FixedStar.C
+++ b/lib/FixedStar.C
@@ -165,9 +165,9 @@ void FixedStar::setPos(const double p[3])
 
 int FixedStar::setParameter(string name, string content, string unit) {
   if (name=="Position") {
-    char* tc = const_cast<char*>(content.c_str());
     double pos[3];
-    for (int i=0;i<3;++i) pos[i] = strtod(tc, &tc);
+    if (FactoryMessenger::parseArray(content, pos, 3) != 3)
+      throwError("FixedStar \"Position\" element requires exactly 3 tokens");
     setPos(pos);
   } else if (name=="Rotating") {
     rotating(true);
diff --git a/lib/NumericalMetricLorene.C b/lib/NumericalMetricLorene.C
index 75dfcad..952d055 100644
--- a/lib/NumericalMetricLorene.C
+++ b/lib/NumericalMetricLorene.C
@@ -1624,9 +1624,11 @@ void  NumericalMetricLorene::setParameter(string name,
   else if (name=="Horizon") horizon_=atof(content.c_str());
   else if (name=="RefineIntegStep"){
     refine_=1;
-    char * tc = const_cast<char*>(content.c_str());
-    r_refine_  = strtod(tc, &tc);
-    h0_refine_ = strtod(tc, &tc);
+    double parms[2];
+    if (FactoryMessenger::parseArray(content, parms, 2) != 2)
+      throwError("NumericalMetricLorene \"RefineIntegStep\" requires exactly 2 tokens");
+    r_refine_  = parms[0];
+    h0_refine_ = parms[1];
   }
   else  Generic::setParameter(name, content, unit);
 }
diff --git a/lib/PolishDoughnut.C b/lib/PolishDoughnut.C
index 4d2e320..1fe8816 100644
--- a/lib/PolishDoughnut.C
+++ b/lib/PolishDoughnut.C
@@ -1638,14 +1638,18 @@ int PolishDoughnut::setParameter(string name, string content, string unit) {
   else if (name=="Komissarov") komissarov_=1;
   else if (name=="KomissarovAngleAveraged") {komissarov_=1;angle_averaged_=1;}
   else if (name=="NonThermalDeltaExpo") {nonthermal_=1; 
-    char * tc = const_cast<char*>(content.c_str());
-    deltaPL_=strtod(tc,&tc); 
-    expoPL_=strtod(tc,&tc); 
+    double parms[2];
+    if (FactoryMessenger::parseArray(content, parms, 2) != 2)
+      throwError("PolishDoughnut \"NonThermalDeltaExpo\" requires exactly 2 tokens");
+    deltaPL_= parms[0];
+    expoPL_ = parms[1]; 
   }
   else if (name=="ADAF") {adaf_ = 1;
-    char * tc = const_cast<char*>(content.c_str());
-    ADAFtemperature_=strtod(tc,&tc); 
-    ADAFdensity_=strtod(tc,&tc); 
+    double parms[2];
+    if (FactoryMessenger::parseArray(content, parms, 2) != 2)
+      throwError("PolishDoughnut \"ADAF\" requires exactly 2 tokens");
+    ADAFtemperature_ = parms[0];
+    ADAFdensity_     = parms[1]; 
   }
   else return Standard::setParameter(name, content, unit);
   return 0;
diff --git a/lib/Screen.C b/lib/Screen.C
index 1bef1fc..096b0a1 100644
--- a/lib/Screen.C
+++ b/lib/Screen.C
@@ -1163,7 +1163,9 @@ SmartPointer<Screen> Screen::Subcontractor(FactoryMessenger* fmp) {
     GYOTO_ENDIF_DEBUG
 #   endif
     if      (name=="Time")     {tobs_tmp = atof(tc); tunit=unit; tobs_found=1;}
-    else if (name=="Position") {for (int i=0;i<4;++i) pos[i] = strtod(tc, &tc);
+    else if (name=="Position") {
+      if (FactoryMessenger::parseArray(content, pos, 4) != 4)
+	throwError("Screen \"Position\" requires exactly 4 tokens");
       scr -> setObserverPos (pos); 
     }
     else if (name=="KeplerianObserver" || name=="ZAMO") {
@@ -1171,22 +1173,26 @@ SmartPointer<Screen> Screen::Subcontractor(FactoryMessenger* fmp) {
     }
     else if (name=="FourVelocity") {
       fourvel_found=1;
-      for (int i=0;i<4;++i) pos[i] = strtod(tc, &tc);
+      if (FactoryMessenger::parseArray(content, pos, 4) != 4)
+	throwError("Screen \"FourVelocity\" requires exactly 4 tokens");
       scr -> setFourVel (pos); 
     }
     else if (name=="ScreenVector1") {
       screen1_found=1;
-      for (int i=0;i<4;++i) pos[i] = strtod(tc, &tc);
+      if (FactoryMessenger::parseArray(content, pos, 4) != 4)
+	throwError("Screen \"ScreenVector*\" require exactly 4 tokens");
       scr -> setScreen1 (pos); 
     }
     else if (name=="ScreenVector2") {
       screen2_found=1;
-      for (int i=0;i<4;++i) pos[i] = strtod(tc, &tc);
+      if (FactoryMessenger::parseArray(content, pos, 4) != 4)
+	throwError("Screen \"ScreenVector*\" require exactly 4 tokens");
       scr -> setScreen2 (pos); 
     }
     else if (name=="ScreenVector3") {
       screen3_found=1;
-      for (int i=0;i<4;++i) pos[i] = strtod(tc, &tc);
+      if (FactoryMessenger::parseArray(content, pos, 4) != 4)
+	throwError("Screen \"ScreenVector*\" require exactly 4 tokens");
       scr -> setScreen3 (pos); 
     }
     else if (name=="Distance")    
diff --git a/lib/UniformSpectrometer.C b/lib/UniformSpectrometer.C
index 92ca5ca..f876385 100644
--- a/lib/UniformSpectrometer.C
+++ b/lib/UniformSpectrometer.C
@@ -209,10 +209,9 @@ void Gyoto::Spectrometer::Uniform::setParameters(FactoryMessenger* fmp) {
   string unit = fmp -> getSelfAttribute( "unit" );
 
   string content = fmp -> getFullContent();
-  char * tc = const_cast<char*>(content.c_str());
   double band[2];
-  band[0]=strtod(tc, &tc);
-  band[1]=strtod(tc, &tc);
+  if (FactoryMessenger::parseArray(content, band, 2) != 2)
+    throwError("Spectromecter::Uniform requires exactly 2 tokens");
 
   setBand(band, unit, skind);
   nSamples(nsamples);
@@ -226,7 +225,8 @@ int Spectrometer::Uniform::setParameter(string name,
   double band[2];
   char* tc = const_cast<char*>(content.c_str());
   if (name=="Band") {
-    for (int i=0;i<2;++i) band[i] = strtod(tc, &tc);
+    if (FactoryMessenger::parseArray(content, band, 2) != 2)
+      throwError("Spectromecter::Uniform \"Band\" requires exactly 2 tokens");
     setBand(band, unit);
   } else if (name=="Kind") {
     kind(content);
diff --git a/lib/Worldline.C b/lib/Worldline.C
index 5d7c289..83bbb7c 100644
--- a/lib/Worldline.C
+++ b/lib/Worldline.C
@@ -331,17 +331,20 @@ int Worldline::setParameter(std::string name,
   double coord[8];
   char* tc = const_cast<char*>(content.c_str());
   if (name=="InitialCoordinate" || name=="InitCoord") {
-    for (int i=0;i<8;++i) coord[i] = strtod(tc, &tc);
+    if (FactoryMessenger::parseArray(content, coord, 8) != 8)
+      throwError("Worldline \"InitialCoordinate\" requires exactly 8 tokens");
     setInitCoord(coord);
   } else if (name=="Position") {
-    for (int i=0;i<4;++i) coord[i] = strtod(tc, &tc);
+    if (FactoryMessenger::parseArray(content, coord, 4) != 4)
+      throwError("Worldline \"Position\" requires exactly 4 tokens");
     if (init_vel_) {
       setInitCoord(coord, init_vel_);
       delete[] init_vel_; init_vel_=NULL;
     } else setPosition(coord);
     wait_pos_ = 0;
   } else if (name=="Velocity") {
-    for (int i=0;i<3;++i) coord[i] = strtod(tc, &tc);
+    if (FactoryMessenger::parseArray(content, coord, 3) != 3)
+      throwError("Worldline \"Velocity\" requires exactly 3 tokens");
     if (wait_pos_) {
       if (init_vel_) delete [] init_vel_;
       init_vel_ = new double[3];

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git



More information about the Debian-astro-commits mailing list