// // aegis - project change supervisor // Copyright (C) 1994-1996, 1999, 2001-2008 Peter Miller // // 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 3 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, see // . // #include #include #include #include #include #include #include #include #include #include #include #include size_t rpt_func_print__ncolumns; size_t rpt_func_print__ncolumns_max; output::pointer *rpt_func_print__column; col::pointer rpt_func_print__colp; rpt_func_print::~rpt_func_print() { } rpt_func_print::rpt_func_print() { } rpt_func::pointer rpt_func_print::create() { return pointer(new rpt_func_print()); } const char * rpt_func_print::name() const { return "print"; } bool rpt_func_print::optimizable() const { return false; } bool rpt_func_print::verify(const rpt_expr::pointer &ep) const { trace(("%s\n", __PRETTY_FUNCTION__)); if (!rpt_func_print__ncolumns) { trace(("no columns defined yet\n")); return false; } // // you may not print with more arguments // than columns defined // assert(ep); bool ok = (ep->get_nchildren() <= rpt_func_print__ncolumns); trace(("==> %d\n", ok)); return ok; } rpt_value::pointer rpt_func_print::run(const rpt_expr::pointer &ep, size_t argc, rpt_value::pointer *argv) const { trace(("%s\n", __PRETTY_FUNCTION__)); if (argc > (size_t)rpt_func_print__ncolumns) { sub_context_ty sc; sc.var_set_charstar("Function", "print"); sc.var_set_long("Number1", (long)argc); sc.var_set_long("Number2", (long)rpt_func_print__ncolumns); nstring s ( sc.subst_intl ( i18n("$function: too many arguments ($number1 given, " "only $number2 used)") ) ); return rpt_value_error::create(ep->get_pos(), s); } // // turn each argument into a string // rpt_value::pointer *argv2 = new rpt_value::pointer [argc]; for (size_t j = 0; j < argc; ++j) { trace(("j = %d of %d\n", (int)j, (int)argc)); rpt_value::pointer vp = rpt_value::stringize(argv[j]); trace(("mark\n")); rpt_value_string *rvsp = dynamic_cast(vp.get()); if (rvsp) { trace(("ok\n")); argv2[j] = vp; continue; } delete [] argv2; // // ...and complain bitterly // trace(("erk\n")); sub_context_ty sc; sc.var_set_charstar("Function", "print"); sc.var_set_long("Number", (long)j + 1); sc.var_set_charstar("Name", argv[j]->name()); nstring s ( sc.subst_intl ( i18n("$function: argument $number: unable to print $name value") ) ); return rpt_value_error::create(ep->get_pos(), s); } // // now that we know they are all stringizable, print the line out // for (size_t j = 0; j < argc; ++j) { trace(("j = %d of %d\n", (int)j, (int)argc)); rpt_value::pointer vp = argv2[j]; rpt_value_string *rvsp = dynamic_cast(vp.get()); assert(rvsp); if (rpt_func_print__column[j]) { rpt_func_print__column[j]->fputs(rvsp->query()); } } delete [] argv2; // // Emit the line. // // The os_become bracketing is because we would write to the // file at this point, and some operating systems will barf if // we have the wrong uid. // trace(("emit\n")); os_become_orig(); rpt_func_print__colp->eoln(); os_become_undo(); trace(("bye bye\n")); return rpt_value_void::create(); }