// // 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 [