//
// 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
static void
destructor(format_ty *)
{
}
static int
is_a_candidate(format_ty *, string_ty *filename)
{
return
(
filename->str_length > 2
&&
filename->str_text[filename->str_length - 2] == ','
&&
filename->str_text[filename->str_length - 1] == 'v'
);
}
static string_ty *
sanitize(format_ty *, string_ty *filename, int last_part)
{
static string_ty *rcs = 0;
static string_ty *cvs = 0;
static string_ty *attic = 0;
if (!rcs)
{
rcs = str_from_c("RCS");
cvs = str_from_c("CVS");
attic = str_from_c("Attic");
}
//
// Break the filename into path elements.
//
string_list_ty sl;
sl.split(filename, "/");
//
// Get rid of path elements named "RCS" or "CVS" or "Attic".
//
string_list_ty sl2;
for (size_t j = 0; j < sl.nstrings; ++j)
{
string_ty *s;
s = sl.string[j];
if (!str_equal(s, rcs) && !str_equal(s, cvs) && !str_equal(s, attic))
sl2.push_back(s);
}
if (last_part)
{
//
// Remove the ",v" from the end of the last path element.
//
if (sl2.nstrings)
{
string_ty *s;
s = sl2.string[sl2.nstrings - 1];
if
(
s->str_length >= 2
&&
s->str_text[s->str_length - 2] == ','
&&
s->str_text[s->str_length - 1] == 'v'
)
{
sl2.string[sl2.nstrings - 1] =
str_n_from_c(s->str_text, s->str_length - 2);
str_free(s);
}
}
}
//
// Rebuild the filename from the remaining path elements.
//
return sl2.unsplit("/");
}
static format_version_ty *
read_versions(format_ty *, string_ty *physical, string_ty *logical)
{
return rcs_parse(physical, logical);
}
static string_ty *
history_put(format_ty *)
{
return
str_from_c
(
"ci -u -d -M -m${quote ($version) ${change description}} "
"-t/dev/null ${quote $input} ${quote $history,v}; "
"rcs -U ${quote $history,v}"
);
}
static string_ty *
history_get(format_ty *)
{
return
str_from_c
(
"co -r${quote $edit} -p ${quote $history,v} > ${quote $output}"
);
}
static string_ty *
history_query(format_ty *)
{
return
str_from_c
(
"rlog -r ${quote $history,v} | awk '/^revision/ {print $$2}'"
);
}
static string_ty *
diff(format_ty *)
{
//
// I'd prefer to say "diff -U10", but we can't rely on GNU
// Diff being installed everywhere. It's a risk even using
// a context diff, because not all non-GNU diff progs have -c.
//
return
str_from_c
(
"set +e; "
CONF_DIFF " "
#ifdef HAVE_GNU_DIFF
"-U10 --text "
#else
"-c "
#endif
"${quote $original} ${quote $input} > ${quote $output}; "
"test $? -le 1"
);
}
static string_ty *
merge(format_ty *)
{
return
str_from_c
(
"set +e; "
"merge -p -L baseline -L C$c ${quote $mostrecent} "
"${quote $original} ${quote $input} > ${quote $output}; "
"test $? -le 1"
);
}
static void
unlock(format_ty *, string_ty *filename)
{
int flags;
string_ty *cmd;
string_ty *qfn;
//
// -b means resume working from the trunk, not a branch
// -e means get rid of any access list
// -ko means no keyword expansion
// -M means do not send mail
// -q means operate quietly
// -U means set locking to non-strict
//
// There doesn't seem to be an option to get rid of all locks.
//
qfn = str_quote_shell(filename);
cmd = str_format("rcs -b -e -M -q -U %s", qfn->str_text);
str_free(qfn);
flags = OS_EXEC_FLAG_ERROK;
os_execute(cmd, flags, os_curdir());
str_free(cmd);
}
static format_vtable_ty vtbl =
{
sizeof(format_ty),
destructor,
is_a_candidate,
sanitize,
read_versions,
history_put,
history_get,
history_query,
diff,
merge,
unlock,
};
format_ty *
format_rcs_new()
{
return format_new(&vtbl);
}