// // aegis - project change supervisor // Copyright (C) 2001, 2003-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 // // NAME // sub_source - the source substitution // // SYNOPSIS // string_ty *sub_source(wstring_list_ty *arg); // // DESCRIPTION // The sub_source function implements the source substitution. // The source substitution is replaced by the path of the source file, // depending on wether it is in the baseline or the change. // If the file named in the argument is in the change, // the name will be left unchanged, // but if the file is in the baseline, an absolute path will resiult. // If the change is being integrated, it will always be left untouched. // // Requires exactly one argument. // // ARGUMENTS // arg - list of arguments, including the function name as [0] // // RETURNS // a pointer to a string in dynamic memory; // or NULL on error, setting suberr appropriately. // wstring sub_source(sub_context_ty *scp, const wstring_list &arg) { trace(("sub_source()\n{\n")); // // Find the change. If there is no change, it is also valid in // the baseline context. // bool absolute = false; change::pointer cp = sub_context_change_get(scp); if (!cp) { project_ty *pp = sub_context_project_get(scp); if (!pp) { scp->error_set(i18n("not valid in current context")); trace(("return NULL;\n")); trace(("}\n")); return wstring(); } cp = pp->change_get(); } // // make sure we like the arguments. // switch (arg.size()) { default: scp->error_set(i18n("requires one argument")); trace(("return NULL;\n")); trace(("}\n")); return wstring(); case 2: break; case 3: { nstring s = arg[2].to_nstring(); if (arglex_compare("Relative", s.c_str(), 0)) { break; } if (arglex_compare("Absolute", s.c_str(), 0)) { absolute = true; break; } scp->error_set ( i18n("second argument must be \"Absolute\" or \"Relative\"") ); trace(("return NULL;\n")); trace(("}\n")); return wstring(); } } // // make sure we are in an appropriate state // cstate_ty *cstate_data = cp->cstate_get(); if (cstate_data->state == cstate_state_awaiting_development) { scp->error_set(i18n("not valid in current context")); trace(("return NULL;\n")); trace(("}\n")); return wstring(); } // // find the file's path // nstring fn = arg[1].to_nstring(); nstring s(change_file_source(cp, fn.get_ref())); if (s.empty()) { scp->error_set(i18n("source file unknown")); trace(("return NULL;\n")); trace(("}\n")); return wstring(); } // // To turn absolute paths into relative ones, we need to see if // the file is in the first element of the search path. // if (!absolute) { string_list_ty search_path; if (cstate_data->state == cstate_state_completed) project_search_path_get(cp->pp, &search_path, 0); else change_search_path_get(cp, &search_path, 0); nstring s2(os_below_dir(nstring(search_path.string[0]), s)); if (!s2.empty()) { s = fn; } } // // build the result // wstring result(s); trace(("return %8.8lX;\n", (long)result.get_ref())); trace(("}\n")); return result; }