//
// aegis - project change supervisor
// Copyright (C) 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct table_ty
{
const char *name;
const char *description;
void (*func)(string_ty *, long, output::pointer );
};
static table_ty table[] =
{
{
"Change_Files",
"Internal change file state. See aefstate(5) for structure.",
xml_change_fstate,
},
{
"Change_State",
"Internal change state. See aecstate(5) for structure.",
xml_change_cstate,
},
{
"Project",
"List of projects. See aegstate(5) for structure.",
xml_project_list,
},
{
"Project_Change_State",
"Internal project change state. See aecstate(5) for structure.",
xml_project_cstate,
},
{
"Project_Config_File",
"The project config file. See aepconf(5) for structure.",
xml_change_pconf,
},
{
"Project_Files",
"Internal project file state. See aefstate(5) for structure.",
xml_project_fstate,
},
{
"Project_State",
"Internal project state. See aepstate(5) for structure.",
xml_project_pstate,
},
{
"User_Config_File",
"The user config file. See aeuconf(5) for structure.",
xml_user_uconf,
},
};
static int
ends_with(string_ty *haystack, const char *needle)
{
size_t needle_length;
needle_length = strlen(needle);
return
(
haystack->str_length > needle_length
&&
(
0
==
memcmp
(
haystack->str_text + haystack->str_length - needle_length,
needle,
needle_length
)
)
);
}
static void
via_table(const char *listname, string_ty *project_name, long change_number,
string_ty *outfile)
{
output::pointer op;
sub_context_ty *scp;
string_ty *s1;
string_ty *s2;
size_t nhit = 0;
table_ty *hit[SIZEOF(table)];
for (table_ty *tp = table; tp < ENDOF(table); ++tp)
{
if (arglex_compare(tp->name, listname, 0))
hit[nhit++] = tp;
}
switch (nhit)
{
case 0:
scp = sub_context_new();
sub_var_set_charstar(scp, "Name", listname);
fatal_intl(scp, i18n("no $name list"));
// NOTREACHED
sub_context_delete(scp);
case 1:
os_become_orig();
if (outfile && ends_with(outfile, ".gz"))
{
op = output_file::binary_open(outfile);
op = output_gzip::create(op);
}
else if
(
outfile
&&
(ends_with(outfile, ".bz") || ends_with(outfile, ".bz2"))
)
{
op = output_file::binary_open(outfile);
op = output_bzip2::create(op);
}
else
op = output_file::text_open(outfile);
os_become_undo();
hit[0]->func(project_name, change_number, op);
op.reset();
break;
default:
s1 = str_from_c(hit[0]->name);
for (size_t j = 1; j < nhit; ++j)
{
s2 = str_format("%s, %s", s1->str_text, hit[j]->name);
str_free(s1);
s1 = s2;
}
scp = sub_context_new();
sub_var_set_charstar(scp, "Name", listname);
sub_var_set_string(scp, "Name_List", s1);
str_free(s1);
sub_var_optional(scp, "Name_List");
fatal_intl(scp, i18n("list $name ambiguous"));
// NOTREACHED
sub_context_delete(scp);
break;
}
}
static void
xml_usage(void)
{
const char *progname = progname_get();
fprintf(stderr, "usage: %s [