예제 #1
0
void KstEquation::save(QTextStream &ts, const QString& indent) {
  QString l2 = indent + "  ";
  ts << indent << "<equationobject>" << endl;
  ts << l2 << "<tag>" << QStyleSheet::escape(tag().tagString()) << "</tag>" << endl;

  // Reparse the equation, then write it back out in text so that we can update
  // any vectors or scalars that had name changes, but we don't get affected by
  // the optimizer
  if (!_equation.isEmpty()) {
    QMutexLocker ml(&Equation::mutex());
    yy_scan_string(_equation.latin1());
    ParsedEquation = 0L;
    int rc = yyparse();
    Equation::Node *en = static_cast<Equation::Node*>(ParsedEquation);
    if (rc == 0 && en) {
      if (!en->takeVectors(VectorsUsed)) {
        KstDebug::self()->log(i18n("Equation [%1] failed to find its vectors when saving.  Resulting Kst file may have issues.").arg(_equation), KstDebug::Warning);
      }
      QString etext = en->text();
      ts << l2 << "<equation>" << QStyleSheet::escape(etext) << "</equation>" << endl;
    }
    delete en;
    ParsedEquation = 0L;
  }

  ts << l2 << "<xvector>" << QStyleSheet::escape((*_xInVector)->tag().tagString()) << "</xvector>" << endl;
  if (_doInterp) {
    ts << l2 << "<interpolate/>" << endl;
  }

  ts << indent << "</equationobject>" << endl;
}
예제 #2
0
void testText(const char *equation, const char *expect) {
  bool failure = false;
  QString txt;
  yy_scan_string(equation);
  int rc = yyparse();
  if (rc == 0) {
    vectorsUsed.clear();
    Equation::Node *eq = static_cast<Equation::Node*>(ParsedEquation);
    assert(eq);
    ParsedEquation = 0L;
    //eq->collectVectors(vectorsUsed);
    txt = eq->text();
    failure = txt != expect;
    delete eq;
  } else {
    // Parse error
    delete (Equation::Node*)ParsedEquation;
    ParsedEquation = 0L;
    failure = true;
  }

  if (failure) {
    if (!Equation::errorStack.isEmpty()) {
      printf("Failures on [%s] -------------------------\n", equation);
      for (QStringList::ConstIterator i = Equation::errorStack.constBegin(); i != Equation::errorStack.constEnd(); ++i) {
        printf("%s\n", (*i).latin1());
      }
      printf("------------------------------------------\n");
    } else {
      printf("Got [%s], expected [%s]\n", txt.latin1(), expect);
    }
    --rc;
  }
}
예제 #3
0
bool doTest(const char *equation, double x, double result, const double tol = 0.00000000001) {
  yy_scan_string(equation);
  int rc = yyparse();
  if (rc == 0) {
    vectorsUsed.clear();
    Equation::Node *eq = static_cast<Equation::Node*>(ParsedEquation);
    assert(eq);
    ParsedEquation = 0L;
    Equation::Context ctx;
    ctx.sampleCount = 2;
    ctx.noPoint = NOPOINT;
    ctx.x = x;
    ctx.xVector = xVector;
    if (xVector) {
      ctx.sampleCount = xVector->length();
    }
    Equation::FoldVisitor vis(&ctx, &eq);
    if (eq->isConst() && !dynamic_cast<Equation::Number*>(eq)) {
      if (!optimizerFailed) {
        optimizerFailed = true;
        ::rc--;
        printf("Optimizer bug: found an unoptimized const equation.  Optimizing for coverage purposes.\n");
      }
      double v = eq->value(&ctx);
      delete eq;
      eq = new Equation::Number(v);
    }
    KstScalarMap scm;
    KstStringMap stm;
    eq->collectObjects(vectorsUsed, scm, stm);

    //
    // do not use -1 in the call to eq->update( ... ) 
    //  as this will simply return without updating the plugin,
    //  unless an underlying data object was updated...
    //
    eq->update(0, &ctx);
    double v = eq->value(&ctx);
    delete eq;
    if (fabs(v - result) < tol || (result != result && v != v) || (result == INF && v == INF) || (result == -INF && v == -INF)) {
      return true;
    } else {
      printf("Result: %.16f\n", v);
      return false;
    }
  } else {
    // Parse error
    printf("Failures on [%s] -------------------------\n", equation);
    for (QStringList::ConstIterator i = Equation::errorStack.constBegin(); i != Equation::errorStack.constEnd(); ++i) {
      printf("%s\n", (*i).latin1());
    }
    printf("------------------------------------------\n");
    delete (Equation::Node*)ParsedEquation;
    ParsedEquation = 0L;
    return false;
  }
}
예제 #4
0
double Equation::interpret(const char *txt, bool *ok) {
  if (!txt || !*txt) {
    if (ok) {
      *ok = false;
    }
    return 0.0;
  }

  mutex().lock();
  yy_scan_string(txt);
  int rc = yyparse();
  if (rc == 0) {
    Equation::Node *eq = static_cast<Equation::Node*>(ParsedEquation);
    ParsedEquation = 0L;
    mutex().unlock();
    Equation::Context ctx;
    ctx.sampleCount = 2;
    ctx.noPoint = KST::NOPOINT;
    ctx.x = 0.0;
    ctx.xVector = 0L;
    Equation::FoldVisitor vis(&ctx, &eq);
    double v = eq->value(&ctx);
    delete eq;
    if (ok) {
      *ok = true;
    }
    return v;
  } else {
    ParsedEquation = 0L;
    mutex().unlock();
    if (ok) {
      *ok = false;
    }
    return 0.0;
  }
}