//
// aegis - project change supervisor
// Copyright (C) 1999, 2002-2006, 2008 Peter Miller
// Copyright (C) 2007 Walter Franzini
//
// 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 // for assert
#include
#include
#include
#include
#include
#include
#include
fstate_src_ty *
change_file_find(change::pointer cp, const nstring &file_name,
view_path_ty as_view_path)
{
trace(("change_file_find(cp = %8.8lX, file_name = \"%s\", "
"as_view_path = %s)\n{\n", (long)cp, file_name.c_str(),
view_path_ename(as_view_path)));
fstate_src_ty *result = 0;
bool xpar = false;
bool top_level = !change_is_a_branch(cp);
//
// In order to make Aegis time safe we need to exclude files
// created in the future with respect to the change cp points to.
//
// There is no need to set the limit if as_view_path ==
// view_path_first because we only need to consult the change
// record without looking in up to parent branches.
//
// There is no need to set the limit if the change is not
// completed.
//
time_t limit = cp->time_limit_get();
trace_time(limit);
//
// To avoid memory exaustion problems we handle all change_ty
// pointers in the same manner (change_free) so we need to take a
// copy also of cp.
//
change::pointer cp2 = change_copy(cp);
for (;;)
{
fstate_src_ty *fsp;
trace(("project \"%s\": change %ld\n",
project_name_get(cp2->pp)->str_text, cp2->number));
if (cp2->bogus)
goto next;
if (as_view_path != view_path_first && change_pfstate_get(cp2))
{
assert(cp2->pfstate_stp);
fsp =
(fstate_src_ty *)
symtab_query(cp2->pfstate_stp, file_name.get_ref());
}
else
{
change_fstate_get(cp2);
assert(cp2->fstate_stp);
fsp =
(fstate_src_ty *)symtab_query(cp2->fstate_stp, file_name.get_ref());
}
if (fsp)
{
trace(("%s \"%s\" %s\n", file_action_ename(fsp->action),
fsp->file_name->str_text,
(fsp->edit && fsp->edit->revision ?
fsp->edit->revision->str_text : "")));
//
// If there is a top-level transparent file,
// it hides the next instance of the file.
//
if (xpar)
{
result = 0;
xpar = 0;
goto next;
}
//
// If we already have a "hit" for this file, ignore any
// deeper records.
//
if (result)
break;
switch (as_view_path)
{
case view_path_first:
//
// This means that transparent and removed files
// are returned. No project file union, either.
//
break;
case view_path_none:
//
// This means that transparent files are returned
// as transparent, no processing or filtering of
// the list is performed.
//
break;
case view_path_simple:
case view_path_extreme:
switch (fsp->action)
{
case file_action_transparent:
//
// These cases both mean that transparent files
// are resolved (the underlying file is shown).
//
if (top_level)
xpar = true;
goto next;
case file_action_remove:
//
// For now, we keep removed files.
//
break;
case file_action_create:
case file_action_modify:
case file_action_insulate:
#ifndef DEBUG
default:
#endif
// should be file_action_remove
assert(!fsp->deleted_by);
if (fsp->deleted_by)
break;
// should be file_action_transparent
assert(!fsp->about_to_be_created_by);
if (fsp->about_to_be_created_by)
goto next;
// should be file_action_transparent
assert(!fsp->about_to_be_copied_by);
if (fsp->about_to_be_copied_by)
goto next;
break;
}
break;
}
result = fsp;
}
next:
if (as_view_path == view_path_first)
break;
if (cp2->number == TRUNK_CHANGE_NUMBER)
break;
if
(
limit != TIME_NOT_SET
&&
change_pfstate_get(cp2)
&&
cp2->pp->is_a_trunk()
)
break;
change::pointer next_change = view_path_next_change(cp2, limit);
change_free(cp2);
cp2 = next_change;
top_level = false;
}
if
(
result
&&
as_view_path == view_path_extreme
&&
result->action == file_action_remove
)
result = 0;
trace(("return %8.8lX;\n", (long)result));
trace(("}\n"));
return result;
}
fstate_src_ty *
change_file_find(change::pointer cp, string_ty *file_name,
view_path_ty as_view_path)
{
return change_file_find(cp, nstring(file_name), as_view_path);
}