pgsOperand pgsString::pgs_plus(const pgsVariable &rhs) const { if (rhs.is_string()) { return pnew pgsString(m_data + rhs.value()); } else { throw pgsArithmeticException(m_data, rhs.value()); } }
bool pgsRecord::newline() { // Insert a line m_record.Add(pgsVectorRecordLine()); // Initialize each column of the line with an empty string for (USHORT i = 0; i < count_columns(); i++) { m_record.Last().Add(pnew pgsString(wxT(""))); } return true; }
pgsOperand pgsRecord::get(const USHORT &line, const USHORT &column) const { if (line < count_lines() && column < count_columns()) { return m_record[line][column]; } else { return pnew pgsString(wxT("")); } }
pgsOperand pgsIdent::eval(pgsVarMap &vars) const { if (vars.find(m_name) != vars.end()) { return vars[m_name]; } else if (m_name == m_now) { time_t now = wxDateTime::GetTimeNow(); return pnew pgsNumber(wxString() << now); } else { return pnew pgsString(wxT("")); } }
pgsOperand pgsIdentRecord::eval(pgsVarMap &vars) const { // Check whether the variable is a record if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) { // Get the operand as a record const pgsRecord &rec = dynamic_cast<const pgsRecord &>(*vars[m_name]); // Evaluate parameters pgsOperand line(m_line->eval(vars)); if (line->is_integer()) { long aux_line; line->value().ToLong(&aux_line); if (m_column != 0) { pgsOperand column(m_column->eval(vars)); if (column->is_integer()) { long aux_column; column->value().ToLong(&aux_column); return rec.get(aux_line, aux_column); } else if (column->is_string()) { return rec.get(aux_line, rec.get_column(column->value())); } } else { return rec.get_line(aux_line); } } } return pnew pgsString(wxT("")); }
pgsString pgsRecord::string() const { return pgsString(value()); }
pgsVariable *pgsString::clone() const { return pnew pgsString(*this); }
pgsString pgsString::string() const { return pgsString(*this); }
pgsOperand pgsExecute::eval(pgsVarMap &vars) const { // Copy statement locally wxString stmt(m_query); // Build regular expressions wxRegEx identifier(wxT("([^\\])(@[a-zA-Z0-9_#@]+)")); wxRegEx escaped(wxT("\\\\(@|\\\\)")); // Backslash followed by @ or backslash wxASSERT(identifier.IsValid() && escaped.IsValid()); // Replace variables in statement while (identifier.Matches(stmt)) { wxString var = identifier.GetMatch(stmt, 2); wxString chr = identifier.GetMatch(stmt, 1); if (vars.find(var) != vars.end()) { wxString res = vars[var]->eval(vars)->value(); identifier.ReplaceFirst(&stmt, chr + pgsUtilities::escape_quotes(res)); } else { identifier.ReplaceFirst(&stmt, chr + wxT("\\\\") + var); } } escaped.ReplaceAll(&stmt, wxT("\\1")); // Perform operations only if we have a valid connection if (m_app != 0 && m_app->connection() != 0 && !m_app->TestDestroy()) { pgQueryThread thread(m_app->connection(), stmt); if (thread.Create() == wxTHREAD_NO_ERROR) { if (thread.Run() == wxTHREAD_NO_ERROR) { while (true) { if (m_app->TestDestroy()) // wxThread::TestDestroy() { thread.Delete(); break; } else if (thread.IsRunning()) { m_app->Yield(); m_app->Sleep(20); } else { thread.Wait(); break; } } if (thread.ReturnCode() != PGRES_COMMAND_OK && thread.ReturnCode() != PGRES_TUPLES_OK) { if (m_cout != 0) { m_app->LockOutput(); (*m_cout) << PGSOUTWARNING; wxString message(stmt + wxT("\n") + thread .GetMessagesAndClear().Strip(wxString::both)); wxRegEx multilf(wxT("(\n)+")); multilf.ReplaceAll(&message, wxT("\n")); message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTWARNING.Length())); (*m_cout) << message << wxT("\n"); m_app->UnlockOutput(); } } else if (!m_app->TestDestroy()) { if (m_cout != 0) { m_app->LockOutput(); (*m_cout) << PGSOUTQUERY; wxString message(thread.GetMessagesAndClear() .Strip(wxString::both)); if (!message.IsEmpty()) message = stmt + wxT("\n") + message; else message = stmt; wxRegEx multilf(wxT("(\n)+")); multilf.ReplaceAll(&message, wxT("\n")); message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTQUERY.Length())); (*m_cout) << message << wxT("\n"); m_app->UnlockOutput(); } pgsRecord *rec = 0; if (thread.DataValid()) { pgSet *set = thread.DataSet(); set->MoveFirst(); rec = pnew pgsRecord(set->NumCols()); wxArrayLong columns_int; // List of columns that contain integers wxArrayLong columns_real; // List of columns that contain reals for (long i = 0; i < set->NumCols(); i++) { rec->set_column_name(i, set->ColName(i)); wxString col_type = set->ColType(i); if (!col_type.CmpNoCase(wxT("bigint")) || !col_type.CmpNoCase(wxT("smallint")) || !col_type.CmpNoCase(wxT("integer"))) { columns_int.Add(i); } else if (!col_type.CmpNoCase(wxT("real")) || !col_type.CmpNoCase(wxT("double precision")) || !col_type.CmpNoCase(wxT("money")) || !col_type.CmpNoCase(wxT("numeric"))) { columns_real.Add(i); } } size_t line = 0; while (!set->Eof()) { for (long i = 0; i < set->NumCols(); i++) { wxString value = set->GetVal(i); if (columns_int.Index(i) != wxNOT_FOUND && pgsNumber::num_type(value) == pgsNumber::pgsTInt) { rec->insert(line, i, pnew pgsNumber(value, pgsInt)); } else if (columns_real.Index(i) != wxNOT_FOUND && pgsNumber::num_type(value) == pgsNumber::pgsTReal) { rec->insert(line, i, pnew pgsNumber(value, pgsReal)); } else { rec->insert(line, i, pnew pgsString(value)); } } set->MoveNext(); ++line; } } else { rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsNumber(wxT("1"))); } return rec; } } else { wxLogError(wxT("PGSCRIPT: Cannot run query thread for the query:\n%s"), m_query.c_str()); } } else { wxLogError(wxT("PGSCRIPT: Cannot create query thread for the query:\n%s"), m_query.c_str()); } } // This must return a record whatever happens return pnew pgsRecord(1); }
pgsOperand pgsString::pgs_not() const { wxString data = m_data.Strip(wxString::both); return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT("")); }
void pgsTestSuite::test_expression_record(void) { pgsVarMap vars; pgsStmtList * SL1 = 0; wxArrayString columns; SL1 = pnew pgsStmtList(pgsTestClass::get_cout()); { columns.Add(wxT("a")); columns.Add(wxT("b")); columns.Add(wxT("c")); columns.Add(wxT("d")); } // r := { a, b, c, d } { pgsStmt * S = 0; S = pnew pgsDeclareRecordStmt(wxT("r"), columns); SL1->insert_back(S); } // r[2][a] := 5 { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"), pnew pgsNumber(wxT("2")), pnew pgsString(wxT("a")), pnew pgsNumber(wxT("5")))); SL1->insert_back(S); } // r[1][b] := "abc" { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"), pnew pgsNumber(wxT("1")), pnew pgsString(wxT("b")), pnew pgsString(wxT("abc")))); SL1->insert_back(S); } // r[0][0] := 1 { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"), pnew pgsNumber(wxT("0")), pnew pgsNumber(wxT("0")), pnew pgsNumber(wxT("1")))); SL1->insert_back(S); } // w := r { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("w"), pnew pgsIdent(wxT("r")))); SL1->insert_back(S); } // p = (r != w) { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("p"), pnew pgsDifferent(pnew pgsIdent(wxT("r")), pnew pgsIdent(wxT("w"))))); SL1->insert_back(S); } // r.remove_line(1) { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsRemoveLine(wxT("r"), pnew pgsNumber(wxT("1")))); TS_ASSERT(pgsRemoveLine(wxT("r"), pnew pgsNumber(wxT("1"))) .value() == wxT("RMLINE(r[1])")); SL1->insert_back(S); } // q = (r != w) { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("q"), pnew pgsDifferent(pnew pgsIdent(wxT("r")), pnew pgsIdent(wxT("w"))))); SL1->insert_back(S); } // o = (r < w) { pgsStmt * S = 0; S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("o"), pnew pgsLower(pnew pgsIdent(wxT("r")), pnew pgsIdent(wxT("w"))))); SL1->insert_back(S); } SL1->eval(vars); // Test symbol table at the end of the execution TS_ASSERT(vars[wxT("p")]->value() == wxT("0")); TS_ASSERT(vars[wxT("q")]->value() == wxT("1")); TS_ASSERT(vars[wxT("o")]->value() == wxT("1")); pdelete(SL1); }
pgsOperand pgsTrim::eval(pgsVarMap &vars) const { return pnew pgsString(m_exp->eval(vars)->value().Strip(wxString::both)); }
pgsString pgsNumber::string() const { return pgsString(m_data); }
void pgsTestSuite::test_object_variable(void) { // A check is done when a pgsNumber is assigned to verify whether it is // a valid number. Default is an integer otherwise pgsReal must be // specified as second parameter of the constructor // pgsString does not perform any check but does not authorize arithmetic // on it even if it stores a number // Test string type { pgsString a(wxT("test")); TS_ASSERT(a.is_string() && !a.is_number() && !a.is_record()); pgsString b(wxT("123456.")); TS_ASSERT(b.is_string() && !b.is_number() && !b.is_record()); pgsString c(wxT("423432")); TS_ASSERT(c.is_string() && !c.is_number() && !c.is_record()); pgsString d(wxT("+.644e5")); TS_ASSERT(d.is_string() && !d.is_number() && !d.is_record()); pgsString e(wxT("0x0")); TS_ASSERT(e.is_string() && !e.is_number() && !e.is_record()); } // Test number type { pgsNumber a(wxT("123456."), pgsReal); TS_ASSERT(a.is_real() && !a.is_string() && !a.is_record()); pgsNumber b(wxT("423432")); TS_ASSERT(b.is_integer() && !b.is_string() && !b.is_record()); pgsNumber c(wxT("+.644e5"), pgsReal); TS_ASSERT(c.is_real() && !c.is_string() && !c.is_record()); } // Test integers { for (int i = 1; i <= 100; i++) { // [1] Generate a random integer as a string wxString str_rnd; for (int j = 0; j < i; j++) { char c = rand() % 9 + 48; str_rnd << c; } // [2] Allocate a number and test type properties pgsNumber exp(str_rnd); TS_ASSERT(exp.value() == str_rnd); TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record()); TS_ASSERT(exp.is_integer() && !exp.is_real()); // [3] Test copy constructor pgsNumber copy(exp); TS_ASSERT(copy.value() == exp.value() && copy.is_integer()); // [4] Test assignment operator exp = pgsNumber(wxT("1") + str_rnd, pgsReal); TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record()); TS_ASSERT(!exp.is_integer() && exp.is_real()); } } // Test reals { for (int i = 2; i <= 16; i++) { // [1] Generate a random real as a string wxString str_rnd; for (int j = 0; j < i / 2; j++) { char c = rand() % 9 + 48; str_rnd << c; } str_rnd << wxT("."); for (int j = 0; j < i / 2; j++) { char c = rand() % 9 + 48; str_rnd << c; } // [2] Allocate a number and test type properties pgsNumber exp(str_rnd, pgsReal); TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record()); TS_ASSERT(!exp.is_integer() && exp.is_real()); // [3] Test copy constructor pgsNumber copy(exp); TS_ASSERT(copy.value() == exp.value() && copy.is_real()); // [4] Test assignment operator exp = pgsNumber(wxT("1") + str_rnd, pgsReal); TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record()); TS_ASSERT(!exp.is_integer() && exp.is_real()); } } // Test real { pgsNumber exp(wxT("+1.5e-300000000000657788"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT("-1.e+0"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT("+.0e-1"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT("-0.0E5"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT("0."), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT(".1234567890098765432"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test string { pgsString exp(wxT(".")); TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string()); } // Test string { pgsString exp(wxT("")); TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string()); } // Test string { pgsString exp(wxT("e5")); TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string()); } // Test real { pgsNumber exp(wxT("0e0"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test real { pgsNumber exp(wxT("100000000000000000e1"), pgsReal); TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string()); } // Test string { pgsString exp(wxT("100000000000000000e")); TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string()); } // Test some operations { pgsVariable * a = pnew pgsNumber(wxT("123."), pgsReal); pgsVariable * b = pnew pgsNumber(wxT("2"), pgsInt); pgsVariable * c = pnew pgsString(wxT("0x1")); pgsVarMap vars; // 123. + 2 gives 125 pgsPlus * d = 0; d = pnew pgsPlus(a, b); // Deletes a and b pgsOperand v = d->eval(vars); TS_ASSERT(v->value() == wxT("125") && v->is_real()); // (123. + 2) + 0x1 gives the concatenation of the strings pgsPlus * e = 0; e = pnew pgsPlus(d, c); // Deletes d and c try { e->eval(vars); TS_ASSERT(false); } catch (const pgsArithmeticException &) { } // Test copy pgsPlus f(*e); // f is automatically deleted pdelete(e); // Deletes e } }
void pgsTestSuite::test_statement_stmt(void) { // Symbol table pgsVarMap vars; // Test Assignment Statement { pgsStmt * S1 = 0, * S2 = 0, * S3 = 0; // x := 0 S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"), pnew pgsNumber(wxT("0"), pgsInt))); S1->eval(vars); // y := 2 S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("y"), pnew pgsNumber(wxT("2"), pgsInt))); S2->eval(vars); // Check that assignments went fine TS_ASSERT(vars[wxT("x")]->value() == wxT("0")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); // x := 1 S3 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"), pnew pgsNumber(wxT("1"), pgsInt))); S3->eval(vars); TS_ASSERT(vars[wxT("x")]->value() == wxT("1")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); pdelete(S1); pdelete(S2); pdelete(S3); } // Test If Statement (if 0 then z := 0 else z := 1 fi) { pgsStmt * S1 = 0; pgsStmtList * SL1 = 0, * SL2 = 0; // z := 0 SL1 = pnew pgsStmtList(pgsTestClass::get_cout()); SL1->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), pnew pgsNumber(wxT("0"), pgsInt)))); // z := 1 SL2 = pnew pgsStmtList(pgsTestClass::get_cout()); SL2->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), pnew pgsNumber(wxT("1"), pgsInt)))); // if 0 then z := 0 else z := 1 fi S1 = pnew pgsIfStmt(pnew pgsNumber(wxT("0"), pgsInt), SL1, SL2); S1->eval(vars); TS_ASSERT(vars[wxT("x")]->value() == wxT("1")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); TS_ASSERT(vars[wxT("z")]->value() == wxT("1")); pdelete(S1); } // Test If Statement (if 1 then z := 0 else z := 1 fi) { pgsStmt * S1 = 0; pgsStmtList * SL1 = 0, * SL2 = 0; // z := 0 SL1 = pnew pgsStmtList(pgsTestClass::get_cout()); SL1->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), pnew pgsNumber(wxT("0"), pgsInt)))); // z := 1 SL2 = pnew pgsStmtList(pgsTestClass::get_cout()); SL2->insert_front(pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), pnew pgsNumber(wxT("1"), pgsInt)))); // if 1 then z := 0 else z := 1 fi S1 = pnew pgsIfStmt(pnew pgsNumber(wxT("1"), pgsInt), SL1, SL2); S1->eval(vars); TS_ASSERT(vars[wxT("x")]->value() == wxT("1")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); TS_ASSERT(vars[wxT("z")]->value() == wxT("0")); pdelete(S1); } // Test While Statement (while i do s := s + i; i := i-1 done) { pgsStmt * S1 = 0, * S2 = 0, * S3 = 0; pgsStmtList * SL1 = 0; // i := 3 pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsNumber(wxT("3"), pgsInt))).eval(vars); // s := 0 pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsNumber(wxT("0"), pgsInt))).eval(vars); TS_ASSERT(vars[wxT("x")]->value() == wxT("1")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); TS_ASSERT(vars[wxT("z")]->value() == wxT("0")); TS_ASSERT(vars[wxT("i")]->value() == wxT("3")); TS_ASSERT(vars[wxT("s")]->value() == wxT("0")); TS_ASSERT(vars.size() == 5); // i == 3 ? TS_ASSERT(pgsIdent(wxT("i")).eval(vars)->value() == wxT("3")); // s + i == 3 ? TS_ASSERT(pgsPlus(pnew pgsIdent(wxT("s")), pnew pgsIdent(wxT("i"))).eval(vars)->value() == wxT("3")); // s := s + i S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsPlus(pnew pgsIdent(wxT("s")), pnew pgsIdent(wxT("i"))))); // i := i-1 S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsMinus(pnew pgsIdent(wxT("i")), pnew pgsNumber(wxT("1"), pgsInt)))); SL1 = pnew pgsStmtList(pgsTestClass::get_cout()); SL1->insert_front(S2); SL1->insert_front(S1); // while i do s := s + i; i := i-1 done S3 = pnew pgsWhileStmt(pnew pgsIdent(wxT("i")), SL1); S3->eval(vars); pdelete(S3); TS_ASSERT(vars[wxT("x")]->value() == wxT("1")); TS_ASSERT(vars[wxT("y")]->value() == wxT("2")); TS_ASSERT(vars[wxT("z")]->value() == wxT("0")); TS_ASSERT(vars[wxT("i")]->value() == wxT("0")); TS_ASSERT(vars[wxT("s")]->value() == wxT("6")); TS_ASSERT(vars.size() == 5); } // Test While Statement // while i < 10 do // i := i + i; // if i > 5 then // break; // else // continue; // s := s + 1; // fi // done { pgsStmt * S1 = 0, * S2 = 0, * S3 = 0, * S4 = 0; pgsStmtList * SL1 = 0, * SL2 = 0; // i := 0 pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsNumber(wxT("0"), pgsInt))).eval(vars); // s := 5 pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsNumber(wxT("5"), pgsInt))).eval(vars); TS_ASSERT(vars[wxT("i")]->value() == wxT("0")); TS_ASSERT(vars[wxT("s")]->value() == wxT("5")); // i := i + 1 S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("i"), pnew pgsPlus(pnew pgsIdent(wxT("i")), pnew pgsNumber(wxT("1"), pgsInt)))); // s := s + 1 S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("s"), pnew pgsPlus(pnew pgsIdent(wxT("s")), pnew pgsNumber(wxT("1"), pgsInt)))); // s := s + 1; continue SL2 = pnew pgsStmtList(pgsTestClass::get_cout()); SL2->insert_back(pnew pgsContinueStmt()); SL2->insert_back(S2); // if i > 5 ... fi S3 = pnew pgsIfStmt(pnew pgsGreater(pnew pgsIdent(wxT("i")), pnew pgsNumber(wxT("5"))), pnew pgsBreakStmt(), SL2); // while ... done SL1 = pnew pgsStmtList(pgsTestClass::get_cout()); SL1->insert_back(S1); SL1->insert_back(S3); S4 = pnew pgsWhileStmt(pnew pgsLower(pnew pgsIdent(wxT("i")), pnew pgsNumber(wxT("10"))), SL1); S4->eval(vars); pdelete(S4); TS_ASSERT(vars[wxT("i")]->value() == wxT("6")); TS_ASSERT(vars[wxT("s")]->value() == wxT("5")); } // Test Assign Statement with a generator { pgsExpression * N0 = 0, * N1 = 0, * N2 = 0; pgsStmt * S1 = 0, * S2 = 0, * S3 = 0; // m := -10 pgsExpressionStmt(pnew pgsAssign(wxT("m"), pnew pgsNumber(wxT("-10")))).eval(vars); // integer(m, 10, true, now) N0 = pnew pgsGenInt(pnew pgsIdent(wxT("m")), pnew pgsNumber(wxT("10")), pnew pgsNumber(wxT("1")), pnew pgsNumber(wxString() << wxDateTime::GetTimeNow())); // string(1, 10, 2, now) N1 = pnew pgsGenString(pnew pgsNumber(wxT("1")), pnew pgsNumber(wxT("10")), pnew pgsNumber(wxT("2")), pnew pgsNumber(wxString() << wxDateTime::GetTimeNow())); // regex(a{2}[a-zA-Z]{10}c{3}, now) N2 = pnew pgsGenRegex(pnew pgsString(wxT("a{2}[a-zA-Z]{10}c{3}")), pnew pgsNumber(wxString() << wxDateTime::GetTimeNow())); // x := integer(m, 10, true, now) S1 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("x"), N0)); S1->eval(vars); // y := string(1, 10, 2, now) S2 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("y"), N1)); S2->eval(vars); // z := regex(a{2}[a-zA-Z]{10}c{3}, now) S3 = pnew pgsExpressionStmt(pnew pgsAssign(wxT("z"), N2)); S3->eval(vars); wxString result1, result2, result3; wxArrayString sav; for (int i = 0; i < 21; i++) { // Check that x result is unique (we wanted to generate a sequence) result1 = pgsIdent(wxT("x")).eval(vars)->value(); TS_ASSERT(sav.Index(result1) == wxNOT_FOUND); sav.Add(result1); // Check that y result is at least 3 characters (two words of 1 // character with a space in the middle) and less than 21 result2 = pgsIdent(wxT("y")).eval(vars)->value(); TS_ASSERT(result2.Length() >= 3 && result2.Length() <= 21); // Check the regex-based generators result3 = pgsIdent(wxT("z")).eval(vars)->value(); TS_ASSERT(result3.Length() == 15); TS_ASSERT(result3.StartsWith(wxT("aa")) && result3.EndsWith(wxT("ccc"))); } pdelete(S1); // Deletes N0 pdelete(S2); // Deletes N1 pdelete(S3); // Deletes N2 } // Test an unknown identifier { pgsExpression * E1; E1 = pnew pgsIdent(wxT("unknown")); TS_ASSERT(E1->eval(vars)->value() == wxT("")); pdelete(E1); } }
pgsRecord pgsString::record() const { pgsRecord *rec = 0; // Try to find the representation of a record in the string { wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)")); wxString data(m_data); wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(") << element << wxT(")[[:space:]]*([,][[:space:]]*(") << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE); // Find each line size_t line_nb = 0, nb_of_columns = 0; bool count_columns = true; while (regex1.Matches(data)) { // Process that line: find each element wxString line(regex1.GetMatch(data)); wxRegEx regex2(element); size_t column_nb = 0; while (regex2.Matches(line)) { if (count_columns == true) { ++nb_of_columns; } else { if (column_nb < nb_of_columns && rec != 0) { wxString value(regex2.GetMatch(line)); if (value.StartsWith(wxT("\"")) && value.EndsWith(wxT("\""))) { // This is a string value = value.Mid(1, value.Len() - 2); value.Replace(wxT("\\\""), wxT("\"")); value.Replace(wxT("\\\\"), wxT("\\")); rec->insert(line_nb, column_nb, pnew pgsString(value)); } else { // This is a number or a string pgsTypes type = pgsNumber::num_type(value); switch (type) { case pgsTInt: rec->insert(line_nb, column_nb, pnew pgsNumber(value, pgsInt)); break; case pgsTReal: rec->insert(line_nb, column_nb, pnew pgsNumber(value, pgsReal)); break; default: rec->insert(line_nb, column_nb, pnew pgsString(value)); break; } } } ++column_nb; } regex2.ReplaceFirst(&line, wxT("")); } // If it is the first loop we want to process this line a // second time because the first one was meant to count // the number of columns if (count_columns == true) { count_columns = false; rec = pnew pgsRecord(nb_of_columns); } else { regex1.ReplaceFirst(&data, wxT("")); ++line_nb; } } } // Process the case if (rec == 0) { rec = pnew pgsRecord(1); rec->insert(0, 0, this->clone()); } pgsRecord ret_val(*rec); pdelete(rec); return ret_val; }
void pgsTestSuite::test_operator_number(void) { // From a number with a string { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsVariable * var1 = 0; var1 = pnew pgsString(wxT("5")); // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); pgsOperand op(pnew pgsNumber(wxT("0"))); TS_ASSERT((!(*op))->value() == wxT("1")); // [16] Almost equal try { (*var0 &= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number (integer) with a real number { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100"), pgsInt); pgsVariable * var1 = 0; var1 = pnew pgsNumber(wxT("5"), pgsReal); // [2] Addition TS_ASSERT((*var0 + *var1)->value() == wxT("105")); // [3] Subtraction TS_ASSERT((*var0 - *var1)->value() == wxT("95")); // [4] Multiplication TS_ASSERT((*var0 * *var1)->value() == wxT("500")); // [5] Division TS_ASSERT((*var0 / *var1)->value() == wxT("20")); // [6] Modulo TS_ASSERT((*var0 % *var1)->value() == wxT("0")); // [9] Equal TS_ASSERT((*var0 == *var1)->value() == wxT("0")); // [10] Different TS_ASSERT((*var0 != *var1)->value() == wxT("1")); // [11] Lower TS_ASSERT((*var0 < *var1)->value() == wxT("0")); // [12] Greater TS_ASSERT((*var0 > *var1)->value() == wxT("1")); // [13] Lower or equal TS_ASSERT((*var0 <= *var1)->value() == wxT("0")); // [14] Greater or equal TS_ASSERT((*var0 >= *var1)->value() == wxT("1")); // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal TS_ASSERT((*var0 &= *var1)->value() == wxT("0")); // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a record { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsRecord * rec = 0; rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsString(wxT("5"))); pgsVariable * var1 = 0; var1 = rec; // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal try { (*var0 &= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a record { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsRecord * rec = 0; rec = pnew pgsRecord(1); rec->insert(0, 0, pnew pgsNumber(wxT("5"))); rec->insert(1, 0, pnew pgsNumber(wxT("1"))); pgsVariable * var1 = 0; var1 = rec; // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with a string generator { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsStringGen * gen = 0; gen = pnew pgsStringGen(10, 20); pgsVariable * var1 = 0; var1 = pnew pgsGenerator(pgsVariable::pgsTString, gen); // [2] Addition try { (*var0 + *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [3] Subtraction try { (*var0 - *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [4] Multiplication try { (*var0 * *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [5] Division try { (*var0 / *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [6] Modulo try { (*var0 % *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [9] Equal try { (*var0 == *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [10] Different try { (*var0 != *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [11] Lower try { (*var0 < *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [12] Greater try { (*var0 > *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [13] Lower or equal try { (*var0 <= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [14] Greater or equal try { (*var0 >= *var1); TS_ASSERT(false); } catch (const pgsException &) { } // [18] Delete variables pdelete(var0); pdelete(var1); } // From a number with an integer generator { // [1] Create variables pgsVariable * var0 = 0; var0 = pnew pgsNumber(wxT("100")); pgsIntegerGen * gen = 0; gen = pnew pgsIntegerGen(5, 5); pgsVariable * var1 = 0; var1 = pnew pgsGenerator(pgsVariable::pgsTInt, gen); // [2] Addition TS_ASSERT((*var0 + *var1)->value() == wxT("105")); // [3] Subtraction TS_ASSERT((*var0 - *var1)->value() == wxT("95")); // [4] Multiplication TS_ASSERT((*var0 * *var1)->value() == wxT("500")); // [5] Division TS_ASSERT((*var0 / *var1)->value() == wxT("20")); // [6] Modulo TS_ASSERT((*var0 % *var1)->value() == wxT("0")); // [9] Equal TS_ASSERT((*var0 == *var1)->value() == wxT("0")); // [10] Different TS_ASSERT((*var0 != *var1)->value() == wxT("1")); // [11] Lower TS_ASSERT((*var0 < *var1)->value() == wxT("0")); // [12] Greater TS_ASSERT((*var0 > *var1)->value() == wxT("1")); // [13] Lower or equal TS_ASSERT((*var0 <= *var1)->value() == wxT("0")); // [14] Greater or equal TS_ASSERT((*var0 >= *var1)->value() == wxT("1")); // [15] Not TS_ASSERT((!(*var0))->value() == wxT("0")); // [16] Almost equal TS_ASSERT((*var0 &= *var1)->value() == wxT("0")); // [17] Is true? TS_ASSERT(var0->pgs_is_true() == true); TS_ASSERT((!(*var0))->pgs_is_true() == false); // [18] Delete variables pdelete(var0); pdelete(var1); } }
pgsVariable * pgsContext::encoding() { pgsVariable * encoding = pnew pgsString(wxLocale::GetSystemEncodingName()); push_var(encoding); return encoding; }