home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume27
/
aegis-2.1
/
part06
< prev
next >
Wrap
Text File
|
1993-09-24
|
157KB
|
6,695 lines
Newsgroups: comp.sources.unix
From: pmiller@bmr.gov.au (Peter Miller)
Subject: v27i041: aegis - project change supervisor (V2.1), Part06/19
References: <1.748951883.12788@gw.home.vix.com>
Sender: unix-sources-moderator@gw.home.vix.com
Approved: vixie@gw.home.vix.com
Submitted-By: pmiller@bmr.gov.au (Peter Miller)
Posting-Number: Volume 27, Issue 41
Archive-Name: aegis-2.1/part06
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 6 (of 19)."
# Contents: aegis/aena.c aegis/aend.c aegis/aeni.c aegis/aenrv.c
# aegis/aera.c aegis/aerd.c aegis/aeri.c aegis/aerrv.c aegis/lex.c
# common/trace.c doc/c1.3.so doc/c2.4.so doc/c4.2.so
# fmtgen/type_list.c man1/aegis.1 test/00/t0005a.sh
# test/00/t0008a.sh test/00/t0017a.sh
# Wrapped by vixie@gw.home.vix.com on Sat Sep 25 03:00:35 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'aegis/aena.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aena.c'\"
else
echo shar: Extracting \"'aegis/aena.c'\" \(8357 characters\)
sed "s/^X//" >'aegis/aena.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement new administrator
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <aena.h>
X#include <ael.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void new_administrator_usage _((void));
X
Xstatic void
Xnew_administrator_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -New_Administrator [ <option>... ] <username>...\n", progname);
X fprintf(stderr, " %s -New_Administrator -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Administrator -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void new_administrator_help _((void));
X
Xstatic void
Xnew_administrator_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -New_Administrator - add a new administrator to a",
X" project",
X"",
X"SYNOPSIS",
X" %s -New_Administrator <user-name>... [ <option>... ]",
X" %s -New_Administrator -List [ <option>... ]",
X" %s -New_Administrator -Help",
X"",
X"DESCRIPTION",
X" The %s -New_Administrator command is used to add a new",
X" administrator to a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aena '%s -na \\!* -v'",
X" sh$ aena(){%s -na $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administrator of the project.",
X" It is an error if any of the named users have a uid of",
X" less than 100.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), new_administrator_usage);
X}
X
X
Xstatic void new_administrator_list _((void));
X
Xstatic void
Xnew_administrator_list()
X{
X string_ty *project_name;
X
X trace(("new_administrator_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(new_administrator_usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X new_administrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_administrators(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void new_administrator_main _((void));
X
Xstatic void
Xnew_administrator_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("new_administrator_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(new_administrator_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X new_administrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X /*
X * make sure the user isn't already there
X */
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (project_administrator_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is already an administrator",
X user_name(candidate)
X );
X }
X
X /*
X * make sure the user exists
X * (should we check s/he is in the project's group?)
X * this is to avoid security holes
X */
X if (!user_uid_check(user_name(candidate)))
X {
X fatal
X (
X "user \"%s\" is too privileged",
X user_name(candidate)->str_text
X );
X }
X
X /*
X * add it to the list
X */
X project_administrator_add(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is now an administrator",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xnew_administrator()
X{
X trace(("new_administrator()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X new_administrator_main();
X break;
X
X case arglex_token_help:
X new_administrator_help();
X break;
X
X case arglex_token_list:
X new_administrator_list();
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 8357 -ne `wc -c <'aegis/aena.c'`; then
echo shar: \"'aegis/aena.c'\" unpacked with wrong size!
fi
# end of 'aegis/aena.c'
fi
if test -f 'aegis/aend.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aend.c'\"
else
echo shar: Extracting \"'aegis/aend.c'\" \(8112 characters\)
sed "s/^X//" >'aegis/aend.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement new developer
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <ael.h>
X#include <aend.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void new_developer_usage _((void));
X
Xstatic void
Xnew_developer_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -New_Developer <username>... [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Developer -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Developer -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void new_developer_help _((void));
X
Xstatic void
Xnew_developer_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -New_Developer - add new developers to a project",
X"",
X"SYNOPSIS",
X" %s -New_Developer <username>... [ <option>... ]",
X" %s -New_Developer -List [ <option>... ]",
X" %s -New_Developer -Help",
X"",
X"DESCRIPTION",
X" The %s -New_Developer command is used to add new",
X" developers to a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aend '%s -nd \\!* -v'",
X" sh$ aend(){%s -nd $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administrator of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), new_developer_usage);
X}
X
X
Xstatic void new_developer_list _((void (*)(void)));
X
Xstatic void
Xnew_developer_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("new_developer_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_developers(project_name, 0);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void new_developer_main _((void));
X
Xstatic void
Xnew_developer_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("new_developer_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(new_developer_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X new_developer_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X /*
X * make sure the user isn't already there
X */
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (project_developer_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is already a developer",
X user_name(candidate)
X );
X }
X
X /*
X * make sure the user exists
X * (should we chech s/he is in the project's group?)
X * this is to avoid security holes
X */
X if (!user_uid_check(user_name(candidate)))
X {
X fatal
X (
X "user \"%s\" is too privileged",
X user_name(candidate)->str_text
X );
X }
X
X /*
X * add it to the list
X */
X project_developer_add(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is now a developer",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xnew_developer()
X{
X trace(("new_developer()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X new_developer_main();
X break;
X
X case arglex_token_help:
X new_developer_help();
X break;
X
X case arglex_token_list:
X new_developer_list(new_developer_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 8112 -ne `wc -c <'aegis/aend.c'`; then
echo shar: \"'aegis/aend.c'\" unpacked with wrong size!
fi
# end of 'aegis/aend.c'
fi
if test -f 'aegis/aeni.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aeni.c'\"
else
echo shar: Extracting \"'aegis/aeni.c'\" \(8195 characters\)
sed "s/^X//" >'aegis/aeni.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement new integrator
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <aeni.h>
X#include <ael.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void new_integrator_usage _((void));
X
Xstatic void
Xnew_integrator_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -New_Integrator <username>... [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Integrator -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Integrator -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void new_integrator_help _((void));
X
Xstatic void
Xnew_integrator_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -New_Integrator - add new integrators to a project",
X"",
X"SYNOPSIS",
X" %s -New_Integrator <user-name>... [ <option>... ]",
X" %s -New_Integrator -List [ <option>... ]",
X" %s -New_Integrator -Help",
X"",
X"DESCRIPTION",
X" The %s -New_Integrator command is used to add new",
X" integrators to a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aeni '%s -ni \\!* -v'",
X" sh$ aeni(){%s -ni $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administrator of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), new_integrator_usage);
X}
X
X
Xstatic void new_integrator_list _((void (*)(void)));
X
Xstatic void
Xnew_integrator_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("new_integrator_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_integrators(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void new_integrator_main _((void));
X
Xstatic void
Xnew_integrator_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("new_integrator_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(new_integrator_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X new_integrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X /*
X * make sure the user isn't already there
X */
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (project_integrator_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is already an integrator",
X user_name(candidate)
X );
X }
X
X /*
X * make sure the user exists
X * (should we check s/he is in the project's group?)
X * this is to avoid security holes
X */
X if (!user_uid_check(user_name(candidate)))
X {
X fatal
X (
X "user \"%s\" is too privileged",
X user_name(candidate)->str_text
X );
X }
X
X /*
X * add it to the list
X */
X project_integrator_add(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is now an integrator",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xnew_integrator()
X{
X trace(("new_integrator()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X new_integrator_main();
X break;
X
X case arglex_token_help:
X new_integrator_help();
X break;
X
X case arglex_token_list:
X new_integrator_list(new_integrator_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 8195 -ne `wc -c <'aegis/aeni.c'`; then
echo shar: \"'aegis/aeni.c'\" unpacked with wrong size!
fi
# end of 'aegis/aeni.c'
fi
if test -f 'aegis/aenrv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aenrv.c'\"
else
echo shar: Extracting \"'aegis/aenrv.c'\" \(8124 characters\)
sed "s/^X//" >'aegis/aenrv.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement new reviewer
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <ael.h>
X#include <aenrv.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void new_reviewer_usage _((void));
X
Xstatic void
Xnew_reviewer_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -New_Reviewer <username>... [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Reviewer -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -New_Reviewer -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void new_reviewer_help _((void));
X
Xstatic void
Xnew_reviewer_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -New_ReViewer - add new reviewers to a project",
X"",
X"SYNOPSIS",
X" %s -New_ReViewer <user-name>... [ <option>... ]",
X" %s -New_ReViewer -List [ <option>... ]",
X" %s -New_ReViewer -Help",
X"",
X"DESCRIPTION",
X" The %s -New_ReViewer command is used to add new reviewers",
X" to a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more information",
X" about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of suitable",
X" subjects for this command. The list may be more",
X" general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to produce",
X" the bare minimum of information. It is usually",
X" useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces output",
X" on errors. When used with the -List option this",
X" option causes column headings to be added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aenrv '%s -nrv \\!* -v'",
X" sh$ aenrv(){%s -nrv $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an administrator",
X" of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any error.",
X" The %s command will only exit with a status of 0 if there",
X" are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), new_reviewer_usage);
X}
X
X
Xstatic void new_reviewer_list _((void (*)(void)));
X
Xstatic void
Xnew_reviewer_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("new_reviewer_list()\n{\n"/*}*/));
X project_name = 0;
X arglex();
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_reviewers(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void new_reviewer_main _((void));
X
Xstatic void
Xnew_reviewer_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("new_reviewer_main()\n{\n"/*}*/));
X project_name = 0;
X wl_zero(&wl);
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(new_reviewer_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X new_reviewer_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X /*
X * make sure the user isn't already there
X */
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (project_reviewer_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is already a reviewer",
X user_name(candidate)
X );
X }
X
X /*
X * make sure the user exists
X * (should we check s/he is in the project's group?)
X * this is to avoid security holes
X */
X if (!user_uid_check(user_name(candidate)))
X {
X fatal
X (
X "user \"%s\" is too privileged",
X user_name(candidate)->str_text
X );
X }
X
X /*
X * add them to the list
X */
X project_reviewer_add(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is now a reviewer",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xnew_reviewer()
X{
X trace(("new_reviewer()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X new_reviewer_main();
X break;
X
X case arglex_token_help:
X new_reviewer_help();
X break;
X
X case arglex_token_list:
X new_reviewer_list(new_reviewer_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 8124 -ne `wc -c <'aegis/aenrv.c'`; then
echo shar: \"'aegis/aenrv.c'\" unpacked with wrong size!
fi
# end of 'aegis/aenrv.c'
fi
if test -f 'aegis/aera.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aera.c'\"
else
echo shar: Extracting \"'aegis/aera.c'\" \(8302 characters\)
sed "s/^X//" >'aegis/aera.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement remove administrator
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <aera.h>
X#include <ael.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void remove_administrator_usage _((void));
X
Xstatic void
Xremove_administrator_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -Remove_Administrator [ <option>... ] <username>...\n", progname);
X fprintf(stderr, " %s -Remove_Administrator -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -Remove_Administrator -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void remove_administrator_help _((void));
X
Xstatic void
Xremove_administrator_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -Remove_Administrator - remove administrators from",
X" a project",
X"",
X"SYNOPSIS",
X" %s -Remove_Administrator user-name ... [ option... ]",
X" %s -Remove_Administrator -List [ option... ]",
X" %s -Remove_Administrator -Help",
X"",
X"DESCRIPTION",
X" The %s -Remove_Administrator command is used to remove",
X" administrators from a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, if",
X" the user is only working on changes within a single",
X" project, the project name defaults to that project;",
X" if the user is currently working on changes to more",
X" than one project, or is not working on changes to",
X" any project, the user's $HOME/.%src file is",
X" examined for a default project field (see aeuconf(5)",
X" for more information).",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aera '%s -ra \\!* -v'",
X" sh$ aera(){%s -ra $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administrator of the project.",
X"",
X" It is an error if an attempt is made to remove the last",
X" administrator from the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), remove_administrator_usage);
X}
X
X
Xstatic void remove_administrator_list _((void));
X
Xstatic void
Xremove_administrator_list()
X{
X string_ty *project_name;
X
X trace(("remove_administrator_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(remove_administrator_usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X remove_administrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_administrators(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void remove_administrator_main _((void));
X
Xstatic void
Xremove_administrator_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("remove_administrator_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(remove_administrator_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X remove_administrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check the users are actually administrators
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (!project_administrator_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(candidate)
X );
X }
X project_administrator_delete(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * make sure there will always be at least one administrator
X */
X if (pstate_data->administrator->length <= 0)
X {
X project_fatal
X (
X pp,
X "must have at least one administrator at all times"
X );
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is no longer an administrator",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xremove_administrator()
X{
X trace(("remove_administrator()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X remove_administrator_main();
X break;
X
X case arglex_token_help:
X remove_administrator_help();
X break;
X
X case arglex_token_list:
X remove_administrator_list();
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 8302 -ne `wc -c <'aegis/aera.c'`; then
echo shar: \"'aegis/aera.c'\" unpacked with wrong size!
fi
# end of 'aegis/aera.c'
fi
if test -f 'aegis/aerd.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aerd.c'\"
else
echo shar: Extracting \"'aegis/aerd.c'\" \(7837 characters\)
sed "s/^X//" >'aegis/aerd.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement remove developer
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <ael.h>
X#include <aerd.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void remove_developer_usage _((void));
X
Xstatic void
Xremove_developer_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -Remove_Developer [ <option>... ] <username>...\n", progname);
X fprintf(stderr, " %s -Remove_Developer -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -Remove_Developer -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void remove_developer_help _((void));
X
Xstatic void
Xremove_developer_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -Remove_Developer - remove developers from a",
X" project",
X"",
X"SYNOPSIS",
X" %s -Remove_Developer <user-name>... [ <option>... ]",
X" %s -Remove_Developer -List [ <option>... ]",
X" %s -Remove_Developer -Help",
X"",
X"DESCRIPTION",
X" The %s -Remove_Developer command is used to remove",
X" developers from a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aerd '%s -rd \\!* -v'",
X" sh$ aerd(){%s -rd $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administrator of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), remove_developer_usage);
X}
X
X
Xstatic void remove_developer_list _((void (*)(void)));
X
Xstatic void
Xremove_developer_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("remove_developer_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_developers(project_name, 0);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void remove_developer_main _((void));
X
Xstatic void
Xremove_developer_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("remove_developer_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(remove_developer_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X remove_developer_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (!project_developer_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not a developer",
X user_name(candidate)
X );
X }
X project_developer_delete(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is no longer a developer",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xremove_developer()
X{
X trace(("remove_developer()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X remove_developer_main();
X break;
X
X case arglex_token_help:
X remove_developer_help();
X break;
X
X case arglex_token_list:
X remove_developer_list(remove_developer_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 7837 -ne `wc -c <'aegis/aerd.c'`; then
echo shar: \"'aegis/aerd.c'\" unpacked with wrong size!
fi
# end of 'aegis/aerd.c'
fi
if test -f 'aegis/aeri.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aeri.c'\"
else
echo shar: Extracting \"'aegis/aeri.c'\" \(7902 characters\)
sed "s/^X//" >'aegis/aeri.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement remove administrator
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <ael.h>
X#include <aeri.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void remove_integrator_usage _((void));
X
Xstatic void
Xremove_integrator_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -Remove_Integrator [ <option>... ] <username>...\n", progname);
X fprintf(stderr, " %s -Remove_Integrator -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -Remove_Integrator -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void remove_integrator_help _((void));
X
Xstatic void
Xremove_integrator_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -Remove_Integrator - remove integrators from a",
X" project",
X"",
X"SYNOPSIS",
X" %s -Remove_Integrator <user-name>... [ <option>... ]",
X" %s -Remove_Integrator -List [ <option>... ]",
X" %s -Remove_Integrator -Help",
X"",
X"DESCRIPTION",
X" The %s -Remove_Integrator command is used to remove",
X" integrators from a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more",
X" information about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of",
X" suitable subjects for this command. The list may",
X" be more general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, if",
X" the user is only working on changes within a single",
X" project, the project name defaults to that project;",
X" if the user is currently working on changes to more",
X" than one project, or is not working on changes to",
X" any project, the user's $HOME/.%src file is",
X" examined for a default project field (see aeuconf(5)",
X" for more information).",
X"",
X" -TERse",
X" This option may be used to cause listings to",
X" produce the bare minimum of information. It is",
X" usually useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces",
X" output on errors. When used with the -List",
X" option this option causes column headings to be",
X" added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aeri '%s -ri \\!* -v'",
X" sh$ aeri(){%s -ri $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an",
X" administratot of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any",
X" error. The %s command will only exit with a status of",
X" 0 if there are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), remove_integrator_usage);
X}
X
X
Xstatic void remove_integrator_list _((void (*)(void)));
X
Xstatic void
Xremove_integrator_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("remove_integrator_list()\n{\n"/*}*/));
X arglex();
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_integrators(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void remove_integrator_main _((void));
X
Xstatic void
Xremove_integrator_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("remove_integrator_main()\n{\n"/*}*/));
X wl_zero(&wl);
X project_name = 0;
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(remove_integrator_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X remove_integrator_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (!project_integrator_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an integrator",
X user_name(candidate)
X );
X }
X project_integrator_delete(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is no longer an integrator",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xremove_integrator()
X{
X trace(("remove_integrator()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X remove_integrator_main();
X break;
X
X case arglex_token_help:
X remove_integrator_help();
X break;
X
X case arglex_token_list:
X remove_integrator_list(remove_integrator_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 7902 -ne `wc -c <'aegis/aeri.c'`; then
echo shar: \"'aegis/aeri.c'\" unpacked with wrong size!
fi
# end of 'aegis/aeri.c'
fi
if test -f 'aegis/aerrv.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/aerrv.c'\"
else
echo shar: Extracting \"'aegis/aerrv.c'\" \(7843 characters\)
sed "s/^X//" >'aegis/aerrv.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to implement remove reviewer
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X
X#include <ael.h>
X#include <aerrv.h>
X#include <arglex2.h>
X#include <commit.h>
X#include <error.h>
X#include <help.h>
X#include <lock.h>
X#include <option.h>
X#include <os.h>
X#include <project.h>
X#include <trace.h>
X#include <user.h>
X#include <word.h>
X
X
Xstatic void remove_reviewer_usage _((void));
X
Xstatic void
Xremove_reviewer_usage()
X{
X char *progname;
X
X progname = option_progname_get();
X fprintf(stderr, "usage: %s -Remove_Reviewer [ <option>... ] <username>...\n", progname);
X fprintf(stderr, " %s -Remove_Reviewer -List [ <option>... ]\n", progname);
X fprintf(stderr, " %s -Remove_Reviewer -Help\n", progname);
X quit(1);
X}
X
X
Xstatic void remove_reviewer_help _((void));
X
Xstatic void
Xremove_reviewer_help()
X{
X static char *text[] =
X {
X"NAME",
X" %s -Remove_ReViewer - remove reviewers from a project",
X"",
X"SYNOPSIS",
X" %s -Remove_ReViewer <user-name>... [ <option>... ]",
X" %s -Remove_ReViewer -List [ <option>... ]",
X" %s -Remove_ReViewer -Help",
X"",
X"DESCRIPTION",
X" The %s -Remove_ReViewer command is used to remove",
X" reviewers from a project.",
X"",
X"OPTIONS",
X" The following options are understood:",
X"",
X" -Help",
X" This option may be used to obtain more information",
X" about how to use the %s program.",
X"",
X" -List",
X" This option may be used to obtain a list of suitable",
X" subjects for this command. The list may be more",
X" general than expected.",
X"",
X" -Project <name>",
X" This option may be used to select the project of",
X" interest. When no -Project option is specified, the",
X" AEGIS_PROJECT environment variable is consulted. If",
X" that does not exist, the user's $HOME/.aegisrc file",
X" is examined for a default project field (see",
X" aeuconf(5) for more information). If that does not",
X" exist, when the user is only working on changes",
X" within a single project, the project name defaults",
X" to that project. Otherwise, it is an error.",
X"",
X" -TERse",
X" This option may be used to cause listings to produce",
X" the bare minimum of information. It is usually",
X" useful for shell scripts.",
X"",
X" -Verbose",
X" This option may be used to cause %s to produce",
X" more output. By default %s only produces output",
X" on errors. When used with the -List option this",
X" option causes column headings to be added.",
X"",
X" All options may be abbreviated; the abbreviation is",
X" documented as the upper case letters, all lower case",
X" letters and underscores (_) are optional. You must use",
X" consecutive sequences of optional letters.",
X"",
X" All options are case insensitive, you may type them in",
X" upper case or lower case or a combination of both, case",
X" is not important.",
X"",
X" For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
X" are all interpreted to mean the -Project option. The",
X" argument \"-prj\" will not be understood, because",
X" consecutive optional characters were not supplied.",
X"",
X" Options and other command line arguments may be mixed",
X" arbitrarily on the command line, after the function",
X" selectors.",
X"",
X" The GNU long option names are understood. Since all",
X" option names for aegis are long, this means ignoring the",
X" extra leading '-'. The \"--option=value\" convention is",
X" also understood.",
X"",
X"RECOMMENDED ALIAS",
X" The recommended alias for this command is",
X" csh%% alias aerrv '%s -rrv \\!* -v'",
X" sh$ aerrv(){%s -rrv $* -v}",
X"",
X"ERRORS",
X" It is an error if the current user is not an administrator",
X" of the project.",
X"",
X"EXIT STATUS",
X" The %s command will exit with a status of 1 on any error.",
X" The %s command will only exit with a status of 0 if there",
X" are no errors.",
X"",
X"COPYRIGHT",
X" %C",
X"",
X"AUTHOR",
X" %A",
X };
X
X help(text, SIZEOF(text), remove_reviewer_usage);
X}
X
X
Xstatic void remove_reviewer_list _((void (*)(void)));
X
Xstatic void
Xremove_reviewer_list(usage)
X void (*usage)_((void));
X{
X string_ty *project_name;
X
X trace(("remove_reviewer_list()\n{\n"/*}*/));
X project_name = 0;
X arglex();
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(usage);
X continue;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X list_reviewers(project_name, 0);
X if (project_name)
X str_free(project_name);
X trace((/*{*/"}\n"));
X}
X
X
Xstatic void remove_reviewer_main _((void));
X
Xstatic void
Xremove_reviewer_main()
X{
X wlist wl;
X string_ty *s1;
X pstate pstate_data;
X int j;
X string_ty *project_name;
X project_ty *pp;
X user_ty *up;
X
X trace(("remove_reviewer_main()\n{\n"/*}*/));
X project_name = 0;
X wl_zero(&wl);
X while (arglex_token != arglex_token_eoln)
X {
X switch (arglex_token)
X {
X default:
X generic_argument(remove_reviewer_usage);
X continue;
X
X case arglex_token_string:
X s1 = str_from_c(arglex_value.alv_string);
X if (wl_member(&wl, s1))
X fatal("user \"%s\" named more than once", s1->str_text);
X wl_append(&wl, s1);
X str_free(s1);
X break;
X
X case arglex_token_project:
X if (arglex() != arglex_token_string)
X remove_reviewer_usage();
X if (project_name)
X fatal("duplicate -Project option");
X project_name = str_from_c(arglex_value.alv_string);
X break;
X }
X arglex();
X }
X if (!wl.wl_nwords)
X fatal("no users named");
X
X /*
X * locate project data
X */
X if (!project_name)
X project_name = user_default_project();
X pp = project_alloc(project_name);
X str_free(project_name);
X project_bind_existing(pp);
X
X /*
X * locate user data
X */
X up = user_executing(pp);
X
X /*
X * lock the project for change
X */
X project_pstate_lock_prepare(pp);
X lock_take();
X pstate_data = project_pstate_get(pp);
X
X /*
X * check they are allowed to do this
X */
X if (!project_administrator_query(pp, user_name(up)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not an administrator",
X user_name(up)
X );
X }
X
X /*
X * check they they are OK users
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X user_ty *candidate;
X
X candidate = user_symbolic(pp, wl.wl_word[j]);
X if (!project_reviewer_query(pp, user_name(candidate)))
X {
X project_fatal
X (
X pp,
X "user \"%S\" is not a reviewer",
X user_name(candidate)
X );
X }
X project_reviewer_delete(pp, user_name(candidate));
X user_free(candidate);
X }
X
X /*
X * write out and release lock
X */
X project_pstate_write(pp);
X commit();
X lock_release();
X
X /*
X * verbose success message
X */
X for (j = 0; j < wl.wl_nwords; ++j)
X {
X project_verbose
X (
X pp,
X "user \"%S\" is no longer a reviewer",
X wl.wl_word[j]
X );
X }
X project_free(pp);
X user_free(up);
X trace((/*{*/"}\n"));
X}
X
X
Xvoid
Xremove_reviewer()
X{
X trace(("remove_reviewer()\n{\n"/*}*/));
X switch (arglex())
X {
X default:
X remove_reviewer_main();
X break;
X
X case arglex_token_help:
X remove_reviewer_help();
X break;
X
X case arglex_token_list:
X remove_reviewer_list(remove_reviewer_usage);
X break;
X }
X trace((/*{*/"}\n"));
X}
END_OF_FILE
if test 7843 -ne `wc -c <'aegis/aerrv.c'`; then
echo shar: \"'aegis/aerrv.c'\" unpacked with wrong size!
fi
# end of 'aegis/aerrv.c'
fi
if test -f 'aegis/lex.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'aegis/lex.c'\"
else
echo shar: Extracting \"'aegis/lex.c'\" \(7951 characters\)
sed "s/^X//" >'aegis/lex.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions to perform lexical analysis on aegis' data files
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <errno.h>
X
X#include <error.h>
X#include <glue.h>
X#include <lex.h>
X#include <s-v-arg.h>
X#include <str.h>
X#include <gram.gen.h> /* must be after <str.h> */
X
X
Xstatic FILE *fp;
Xstatic int line_number;
Xstatic int line_number_start;
Xstatic char *file_name;
Xstatic int error_count;
Xextern gram_STYPE gram_lval;
Xstatic char buffer[1 << 14];
X
X
Xvoid
Xlex_open(s)
X char *s;
X{
X fp = glue_fopen(s, "r");
X if (!fp)
X nfatal("open \"%s\"", s);
X file_name = s;
X line_number = 1;
X error_count = 0;
X}
X
X
Xvoid
Xlex_close()
X{
X glue_fclose(fp);
X fp = 0;
X if (error_count)
X fatal("%s: incorrect format", file_name);
X file_name = 0;
X}
X
X
Xstatic int lex_getc _((void));
X
Xstatic int
Xlex_getc()
X{
X int c;
X
X c = glue_fgetc(fp);
X switch (c)
X {
X case EOF:
X if (glue_ferror(fp))
X {
X nerror("%s", file_name);
X ++error_count;
X }
X break;
X
X case '\n':
X ++line_number;
X break;
X
X default:
X if (c < ' ' || c > '~')
X gram_error("illegal '\\%o' character", c);
X break;
X
X case '\t':
X case '\f':
X break;
X }
X return c;
X}
X
X
Xstatic void lex_getc_undo _((int));
X
Xstatic void
Xlex_getc_undo(c)
X int c;
X{
X switch (c)
X {
X case EOF:
X break;
X
X case '\n':
X --line_number;
X /* fall through... */
X
X default:
X glue_ungetc(c, fp);
X break;
X }
X}
X
X
Xint
Xgram_lex()
X{
X int c;
X char *cp;
X
X for (;;)
X {
X c = lex_getc();
X switch (c)
X {
X case ' ':
X case '\t':
X case '\f':
X case '\n':
X break;
X
X case '0':
X gram_lval.lv_integer = 0;
X c = lex_getc();
X if (c == 'x' || c == 'X')
X {
X int ndigits;
X int n;
X
X ndigits = 0;
X n = 0;
X for (;;)
X {
X ++ndigits;
X c = lex_getc();
X switch (c)
X {
X case '0': case '1': case '2': case '3':
X case '4': case '5': case '6': case '7':
X case '8': case '9':
X n = 16 * n + c - '0';
X continue;
X
X case 'A': case 'B': case 'C': case 'D':
X case 'E': case 'F':
X n = 16 * n + c - 'A' + 10;
X continue;
X
X case 'a': case 'b': case 'c': case 'd':
X case 'e': case 'f':
X n = 16 * n + c - 'a' + 10;
X continue;
X
X default:
X --ndigits;
X lex_getc_undo(c);
X break;
X }
X break;
X }
X if (!ndigits)
X {
X gram_error("malformed hex constant");
X gram_lval.lv_integer = 0;
X return INTEGER;
X }
X gram_lval.lv_integer = n;
X return INTEGER;
X }
X for (;;)
X {
X gram_lval.lv_integer =
X 8 * gram_lval.lv_integer + c - '0';
X c = lex_getc();
X switch (c)
X {
X case '0': case '1': case '2': case '3':
X case '4': case '5': case '6': case '7':
X continue;
X
X default:
X lex_getc_undo(c);
X break;
X }
X break;
X }
X return INTEGER;
X
X case '1': case '2': case '3': case '4':
X case '5': case '6': case '7': case '8': case '9':
X gram_lval.lv_integer = 0;
X for (;;)
X {
X gram_lval.lv_integer =
X 10 * gram_lval.lv_integer + c - '0';
X c = lex_getc();
X switch (c)
X {
X case '0': case '1': case '2': case '3':
X case '4': case '5': case '6': case '7':
X case '8': case '9':
X continue;
X
X default:
X lex_getc_undo(c);
X break;
X }
X break;
X }
X return INTEGER;
X
X case '"':
X line_number_start = line_number;
X cp = buffer;
X for (;;)
X {
X c = lex_getc();
X if (c == EOF)
X {
X str_eof:
X line_number = line_number_start;
X gram_error("end-of-file within string");
X break;
X }
X if (c == '\n')
X {
X line_number = line_number_start;
X gram_error("end-of-line within string");
X break;
X }
X if (c == '"')
X break;
X if (c == '\\')
X {
X c = lex_getc();
X switch (c)
X {
X default:
X gram_error("unknown '\\%c' escape", c);
X break;
X
X case '\n':
X break;
X
X case EOF:
X goto str_eof;
X
X case 'b':
X *cp++ = '\b';
X break;
X
X case 'n':
X *cp++ = '\n';
X break;
X
X case 'r':
X *cp++ = '\r';
X break;
X
X case 't':
X *cp++ = '\t';
X break;
X
X case 'f':
X *cp++ = '\f';
X break;
X
X case '"':
X case '\\':
X *cp++ = c;
X break;
X
X case '0': case '1': case '2': case '3':
X case '4': case '5': case '6': case '7':
X {
X int n;
X int v;
X
X v = 0;
X for (n = 0; n < 3; ++n)
X {
X v = v * 8 + c - '0';
X c = lex_getc();
X switch (c)
X {
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X continue;
X
X default:
X lex_getc_undo(c);
X break;
X }
X break;
X }
X *cp++ = v;
X }
X break;
X }
X }
X else
X *cp++ = c;
X }
X *cp = 0;
X gram_lval.lv_string = str_from_c(buffer);
X return STRING;
X
X case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
X case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
X case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
X case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
X case 'Y': case 'Z': case '_':
X case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
X case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
X case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
X case 's': case 't': case 'u': case 'v': case 'w': case 'x':
X case 'y': case 'z':
X cp = buffer;
X for (;;)
X {
X *cp++ = c;
X c = lex_getc();
X switch (c)
X {
X case '0': case '1': case '2': case '3':
X case '4': case '5': case '6': case '7':
X case '8': case '9':
X case 'A': case 'B': case 'C': case 'D':
X case 'E': case 'F': case 'G': case 'H':
X case 'I': case 'J': case 'K': case 'L':
X case 'M': case 'N': case 'O': case 'P':
X case 'Q': case 'R': case 'S': case 'T':
X case 'U': case 'V': case 'W': case 'X':
X case 'Y': case 'Z': case '_':
X case 'a': case 'b': case 'c': case 'd':
X case 'e': case 'f': case 'g': case 'h':
X case 'i': case 'j': case 'k': case 'l':
X case 'm': case 'n': case 'o': case 'p':
X case 'q': case 'r': case 's': case 't':
X case 'u': case 'v': case 'w': case 'x':
X case 'y': case 'z':
X continue;
X
X default:
X lex_getc_undo(c);
X break;
X }
X *cp = 0;
X break;
X }
X gram_lval.lv_string = str_from_c(buffer);
X return NAME;
X
X case '/':
X line_number_start = line_number;
X c = lex_getc();
X if (c != '*')
X {
X lex_getc_undo(c);
X return '/';
X }
X for (;;)
X {
X for (;;)
X {
X c = lex_getc();
X if (c == EOF)
X {
X bad_comment:
X line_number = line_number_start;
X gram_error("end-of-file within comment");
X quit(1);
X }
X if (c == '*')
X break;
X }
X for (;;)
X {
X c = lex_getc();
X if (c == EOF)
X goto bad_comment;
X if (c != '*')
X break;
X }
X if (c == '/')
X break;
X }
X break;
X
X default:
X return c;
X }
X }
X}
X
X
Xvoid
Xgram_error(s sva_last)
X char *s;
X sva_last_decl
X{
X va_list ap;
X
X sva_init(ap, s);
X vsprintf(buffer, s, ap);
X va_end(ap);
X error("%s: %d: %s", file_name, line_number, buffer);
X if (++error_count >= 20)
X fatal("%s: too many errors, bye!", file_name);
X}
END_OF_FILE
if test 7951 -ne `wc -c <'aegis/lex.c'`; then
echo shar: \"'aegis/lex.c'\" unpacked with wrong size!
fi
# end of 'aegis/lex.c'
fi
if test -f 'common/trace.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'common/trace.c'\"
else
echo shar: Extracting \"'common/trace.c'\" \(7721 characters\)
sed "s/^X//" >'common/trace.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: functions for execution trace
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <stddef.h>
X
X#include <error.h>
X#include <mem.h>
X#include <option.h>
X#include <s-v-arg.h>
X#include <str.h>
X#include <trace.h>
X
X
X#define INDENT 2
X
Xtypedef struct known_ty known_ty;
Xstruct known_ty
X{
X string_ty *filename;
X int flag;
X int *flag_p;
X known_ty *next;
X};
X
Xstatic string_ty *file_name;
Xstatic int line_number;
Xstatic int page_width;
Xstatic known_ty *known;
Xstatic int depth;
X
X
Xstatic string_ty *basename _((char *));
X
Xstatic string_ty *
Xbasename(file)
X char *file;
X{
X char *cp1;
X char *cp2;
X
X cp1 = strrchr(file, '/');
X if (cp1)
X ++cp1;
X else
X cp1 = file;
X cp2 = strrchr(cp1, '.');
X if (!cp2)
X cp2 = cp1 + strlen(cp1);
X if (cp2 > cp1 + 6)
X return str_n_from_c(cp1, 6);
X return str_n_from_c(cp1, cp2 - cp1);
X}
X
X
Xint
Xtrace_pretest(file, result)
X char *file;
X int *result;
X{
X string_ty *s;
X known_ty *kp;
X
X s = basename(file);
X for (kp = known; kp; kp = kp->next)
X {
X if (str_equal(s, kp->filename))
X {
X str_free(s);
X break;
X }
X }
X if (!kp)
X {
X kp = (known_ty *)mem_alloc(sizeof(known_ty));
X kp->filename = s;
X kp->next = known;
X kp->flag = 2; /* disabled */
X known = kp;
X }
X kp->flag_p = result;
X *result = kp->flag;
X return *result;
X}
X
X
Xvoid
Xtrace_where(file, line)
X char *file;
X int line;
X{
X string_ty *s;
X
X /*
X * take new name fist, because will probably be same as last
X * thus saving a free and a malloc (which are slow)
X */
X s = basename(file);
X if (file_name)
X str_free(file_name);
X file_name = s;
X line_number = line;
X}
X
X
Xstatic void trace_putchar _((int));
X
Xstatic void
Xtrace_putchar(c)
X int c;
X{
X static char buffer[MAX_PAGE_WIDTH + 2];
X static char *cp;
X static int in_col;
X static int out_col;
X
X if (!page_width)
X {
X /* don't use last column, many terminals are dumb */
X page_width = option_page_width_get() - 1;
X /* allow for progname, filename and line number (8 each) */
X page_width -= 24;
X if (page_width < 16)
X page_width = 16;
X }
X if (!cp)
X {
X strcpy(buffer, option_progname_get());
X cp = buffer + strlen(buffer);
X if (cp > buffer + 6)
X cp = buffer + 6;
X *cp++ = ':';
X *cp++ = '\t';
X strcpy(cp, file_name->str_text);
X cp += file_name->str_length;
X *cp++ = ':';
X *cp++ = '\t';
X sprintf(cp, "%d:\t", line_number);
X cp += strlen(cp);
X in_col = 0;
X out_col = 0;
X }
X switch (c)
X {
X case '\n':
X *cp++ = '\n';
X *cp = 0;
X fflush(stdout);
X fputs(buffer, stderr);
X fflush(stderr);
X if (ferror(stderr))
X nfatal("(stderr)");
X cp = 0;
X break;
X
X case ' ':
X if (out_col)
X ++in_col;
X break;
X
X case '\t':
X if (out_col)
X in_col = (in_col/INDENT + 1) * INDENT;
X break;
X
X case /*{*/'}':
X case /*(*/')':
X case /*[*/']':
X if (depth > 0)
X --depth;
X /* fall through */
X
X default:
X if (!out_col)
X {
X if (c != '#')
X /* modulo so never too long */
X in_col = (INDENT * depth) % page_width;
X else
X in_col = 0;
X }
X if (in_col >= page_width)
X {
X trace_putchar('\n');
X trace_putchar(c);
X return;
X }
X while (((out_col + 8) & -8) <= in_col && out_col + 1 < in_col)
X {
X *cp++ = '\t';
X out_col = (out_col + 8) & -8;
X }
X while (out_col < in_col)
X {
X *cp++ = ' ';
X ++out_col;
X }
X if (c == '{'/*}*/ || c == '('/*)*/ || c == '['/*]*/)
X ++depth;
X *cp++ = c;
X in_col++;
X out_col++;
X break;
X }
X}
X
X
Xvoid
Xtrace_printf(s sva_last)
X char *s;
X sva_last_decl
X{
X char buffer[MAX_PAGE_WIDTH];
X va_list ap;
X
X sva_init(ap, s);
X vsprintf(buffer, s, ap);
X va_end(ap);
X for (s = buffer; *s; ++s)
X trace_putchar(*s);
X}
X
X
Xvoid
Xtrace_enable(file)
X char *file;
X{
X string_ty *s;
X known_ty *kp;
X
X s = basename(file);
X for (kp = known; kp; kp = kp->next)
X {
X if (str_equal(s, kp->filename))
X {
X str_free(s);
X break;
X }
X }
X if (!kp)
X {
X kp = (known_ty *)mem_alloc(sizeof(known_ty));
X kp->filename = s;
X kp->flag_p = 0;
X kp->next = known;
X known = kp;
X }
X kp->flag = 3; /* enabled */
X if (kp->flag_p)
X *kp->flag_p = kp->flag;
X}
X
X
Xvoid
Xtrace_char_real(name, vp)
X char *name;
X char *vp;
X{
X trace_printf("%s = '", name);
X if (*vp < ' ' || *vp > '~' || strchr("(){}[]", *vp))
X {
X char *s;
X
X s = strchr("\bb\nn\tt\rr\ff", *vp);
X if (s)
X {
X trace_putchar('\\');
X trace_putchar(s[1]);
X }
X else
X trace_printf("\\%03o", (unsigned char)*vp);
X }
X else
X {
X if (strchr("'\\", *vp))
X trace_putchar('\\');
X trace_putchar(*vp);
X }
X trace_printf("'; /* 0x%02X, %d */\n", (unsigned char)*vp, *vp);
X}
X
X
Xvoid
Xtrace_char_unsigned_real(name, vp)
X char *name;
X unsigned char *vp;
X{
X trace_printf("%s = '", name);
X if (*vp < ' ' || *vp > '~' || strchr("(){}[]", *vp))
X {
X char *s;
X
X s = strchr("\bb\nn\tt\rr\ff", *vp);
X if (s)
X {
X trace_putchar('\\');
X trace_putchar(s[1]);
X }
X else
X trace_printf("\\%03o", *vp);
X }
X else
X {
X if (strchr("'\\", *vp))
X trace_putchar('\\');
X trace_putchar(*vp);
X }
X trace_printf("'; /* 0x%02X, %d */\n", *vp, *vp);
X}
X
X
Xvoid
Xtrace_int_real(name, vp)
X char *name;
X int *vp;
X{
X trace_printf("%s = %d;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_int_unsigned_real(name, vp)
X char *name;
X unsigned int *vp;
X{
X trace_printf("%s = %u;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_long_real(name, vp)
X char *name;
X long *vp;
X{
X trace_printf("%s = %ld;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_long_unsigned_real(name, vp)
X char *name;
X unsigned long *vp;
X{
X trace_printf("%s = %lu;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_pointer_real(name, vptrptr)
X char *name;
X void *vptrptr;
X{
X void **ptr_ptr = vptrptr;
X void *ptr;
X
X ptr = *ptr_ptr;
X if (!ptr)
X trace_printf("%s = NULL;\n", name);
X else
X trace_printf("%s = 0x%08lX;\n", name, ptr);
X}
X
X
Xvoid
Xtrace_short_real(name, vp)
X char *name;
X short *vp;
X{
X trace_printf("%s = %hd;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_short_unsigned_real(name, vp)
X char *name;
X unsigned short *vp;
X{
X trace_printf("%s = %hu;\n", name, *vp);
X}
X
X
Xvoid
Xtrace_string_real(name, vp)
X char *name;
X char *vp;
X{
X char *s;
X long count;
X
X trace_printf("%s = ", name);
X if (!vp)
X {
X trace_printf("NULL;\n");
X return;
X }
X trace_printf("\"");
X count = 0;
X for (s = vp; *s; ++s)
X {
X switch (*s)
X {
X case '('/*)*/:
X case '['/*]*/:
X case '{'/*}*/:
X ++count;
X break;
X
X case /*(*/')':
X case /*[*/']':
X case /*{*/'}':
X --count;
X break;
X }
X }
X if (count > 0)
X count = -count;
X else
X count = 0;
X for (s = vp; *s; ++s)
X {
X int c;
X
X c = *s;
X if (c < ' ' || c > '~')
X {
X char *cp;
X
X cp = strchr("\bb\ff\nn\rr\tt", c);
X if (cp)
X trace_printf("\\%c", cp[1]);
X else
X {
X escape:
X trace_printf("\\%03o", (unsigned char)c);
X }
X }
X else
X {
X switch (c)
X {
X case '('/*)*/:
X case '['/*]*/:
X case '{'/*}*/:
X ++count;
X if (count <= 0)
X goto escape;
X break;
X
X case /*(*/')':
X case /*[*/']':
X case /*{*/'}':
X --count;
X if (count < 0)
X goto escape;
X break;
X
X case '\\':
X case '"':
X trace_printf("\\");
X break;
X }
X trace_printf("%c", c);
X }
X }
X trace_printf("\";\n");
X}
X
X
Xvoid
Xtrace_indent_reset()
X{
X depth = 0;
X}
END_OF_FILE
if test 7721 -ne `wc -c <'common/trace.c'`; then
echo shar: \"'common/trace.c'\" unpacked with wrong size!
fi
# end of 'common/trace.c'
fi
if test -f 'doc/c1.3.so' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/c1.3.so'\"
else
echo shar: Extracting \"'doc/c1.3.so'\" \(7810 characters\)
sed "s/^X//" >'doc/c1.3.so' <<'END_OF_FILE'
X.\"
X.\" aegis - project change supervisor
X.\" Copyright (C) 1991, 1992, 1993 Peter Miller.
X.\" All rights reserved.
X.\"
X.\" This program is free software; you can redistribute it and/or modify
X.\" it under the terms of the GNU General Public License as published by
X.\" the Free Software Foundation; either version 2 of the License, or
X.\" (at your option) any later version.
X.\"
X.\" This program is distributed in the hope that it will be useful,
X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X.\" GNU General Public License for more details.
X.\"
X.\" You should have received a copy of the GNU General Public License
X.\" along with this program; if not, write to the Free Software
X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X.\"
X.\" MANIFEST: User Guide, How Aegis Works, When (not) to use Aegis
X.\"
X.bp
X.nh 2 "When (not) to use Aegis"
X.LP
XThe aegis program is not a silver bullet;
Xit will not solve all of your problems.
XAegis is suitable for some kinds of projects,
Xuseful for others,
Xand useless for a few.
X.LP
XThe most difficult thing about the aegis program is that it takes
Xmanagement buy-in.
XIt takes effort to convince many people that the model
Xused by aegis has benefits,
Xand you need management backing you up when some person
Xcomes along with a way of developing software "without the extra work" imposed
Xby the model used by aegis program.
X.LP
XThere is extra up-front work: writing tests.
XThe win is that the tests hang around forever,
Xcatching minor and major slips before they become
Xembarrassing "features" in a released product.
XPrevention is cheaper than cure in this case,
Xthe tests save work down the track.
X.LP
XAll of the "extra work" of writing tests is a long-term win,
Xwhere old problems never again reappear.
XAll of the "extra work" of reviewing changes means that another pair of eyes
Xsights the code and finds potential problems before they manifest
Xthemselves in shipped product.
XAll of the "extra work" of integration ensures that the baseline always works,
Xand is always self-consistent.
XAll of the "extra work" of having a baseline and separate
Xdevelopment directories allows multiple parallel development,
Xwith no inter-developer interference;
Xand the baseline always works, it is never in an "in-between" state.
XIn each case,
Xnot doing this "extra work" is a false economy.
X.LP
XThe existence of these tests, though,
Xis what determines which projects are most suited to aegis and which are not.
XIt should be noted that suitability is a continuous scale,
Xnot black-and-white.
XWith effort and resources,
Xalmost anything fits.
X.nh 3 "Projects for which Aegis is Most Suitable"
X.LP
XProjects most suited to supervision by aegis are straight programs.
XWhat the non-systems-programmers out there call "tools" and
Xsometimes "applications".
XThese are programs which take a pile of input,
Xchew on it,
Xand emit a pile of output.
XThe tests can then compare actual outputs with expected outputs.
X.LP
XAs an example,
Xyou could be writing a
X.I sed (1)
Xlook-alike.
XIt is a public domain clone of the
X.UX
Xsed utility.
XYou could write tests which exercise every feature (insertion, deletion, etc.)
Xand generate the expected output with the real
X.UX
Xsed.
XYou write the code,
Xand run the tests;
Xyou can immediately see if the output matches expectations.
X.LP
XThis is a simple example.
XMore complex examples exist,
Xsuch as aegis itself.
XThe aegis program is used to supervise its own development.
XTests consist of sequences of commands and expected results
Xare tested for.
X.LP
XOther types of software have been developed using aegis:
Xcompilers and interpreters,
Xclient-server model software,
Xmagnetic tape utilities,
Xgraphics software such as a ray-tracer.
XThe range is vast, but it is not all types of software.
X.nh 3 "Projects for which Aegis is Useful"
X.LP
XFor many years there have been full-screen applications on
Xtext terminals.
XIn more recent times there is increasing use of graphical interfaces.
X.LP
XIn developing these types of programs it is still possible to use aegis,
Xbut several options need to be explored.
X.nh 4 "Limited Testing"
X.LP
XYou may choose to use aegis simply for its ability to provide
Xcontrolled access to a large source.
XYou still get the history and change mechanisms,
Xthe baseline model,
Xthe enforced review.
XYou simply don't test all changes,
Xbecause figuring out what is on the screen,
Xand testing it against expectations, is too hard.
X.LP
XIf the program has a command line interface,
Xin addition to the full-screen or GUI interface,
Xthe functionality accessible from the command line may be tested using aegis.
X.LP
XIt is possible that "limited testing" actually means "no testing",
Xif you have no functionality accessible from the command line.
X.nh 4 "Testing Mode"
X.LP
XAnother alternative is to provide hooks into your program
Xallowing you to substitute a file for user input,
Xand to be able to trigger the dump of a "screen image".
XThe simulated user input can then be fed to the program,
Xand the screen dump (in some terminal-independent form)
Xcan be compared against expectations.
X.LP
XThis is easier for full-screen applications,
Xthan for X11 applications.
XYou need to judge the cost-benefit trade-off.
XCost of development,
Xcost of storage space for X11 images,
Xcost of
X.I not
Xtesting.
X.nh 4 "Manual Tests"
X.LP
XThe aegis program provides a manual test facility.
XIt was originally intended for programs which required
Xsome physical action from a user,
Xsuch as "unplug ethernet cable now" or "mount tape XG356B now".
XIt can also be used to have a user confirm that some
Xon-screen activity has happened.
X.LP
XThe problem with manual tests is that they simply don't happen.
XIt is far more pleasant to say "run the automatic tests" and go for
Xa cup of coffee,
Xthan to wait while the computer thinks of mindless things to ask you to do.
XThis is human nature:
Xif it can be automated, it is more likely to happen.
X.nh 3 "Projects for which Aegis is Least Suitable"
X.LP
XAnother class of software is things like operating system kernels
Xand firmware;
Xthings which are "stand alone".
XThis isolated nature makes it the most difficult to test:
Xto test it you want to provide physical input and watch the physical output.
XBy its very nature,
Xit is hard to put into a shell script,
Xand thus hard to write an aegis test for.
X.nh 4 "Operating Systems"
X.LP
XIt is not impossible,
Xjust that few of us have the resources to do it.
XYou need to have a test system and a testing system:
Xthe test system has all of its input and outputs connected
Xto the outputs and inputs of the testing system.
XThat is,
Xthe testing system controls and drives the test system,
Xand watches what happens.
X.LP
XFor example,
Xmany operating system vendors test their products by
Xusing computers connected to each serial line to simulate "user input".
XThe system can be rebooted this way,
Xand using dual-ported disks
Xallows different versions of a kernel to be tried,
Xor other test conditions created.
X.LP
XFor software houses which write kernels,
Xor device drivers for kernels,
Xor some other kernel work,
Xthis is bad news:
Xthe aegis program is probably not for you.
XIt is possible,
Xbut there may be more cost-effective development strategies.
XOf course, you could always use the rest of aegis,
Xand ignore the testing part.
X.nh 4 "Firmware"
X.LP
XFirmware is a similar deal:
Xyou need some way to download the code to be tested into the test system,
Xand write-protect it to simulate ROM,
Xand have the necessary hardware to drive the inputs and watch the outputs.
X.LP
XAs you can see,
Xthis is generally not available to run-of-the-mill software houses,
Xbut then they rarely write firmware, either.
XThose that do write firmware usually have the download capabilities,
Xand some kind of remote operation facility.
END_OF_FILE
if test 7810 -ne `wc -c <'doc/c1.3.so'`; then
echo shar: \"'doc/c1.3.so'\" unpacked with wrong size!
fi
# end of 'doc/c1.3.so'
fi
if test -f 'doc/c2.4.so' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/c2.4.so'\"
else
echo shar: Extracting \"'doc/c2.4.so'\" \(7508 characters\)
sed "s/^X//" >'doc/c2.4.so' <<'END_OF_FILE'
X.\"
X.\" aegis - project change supervisor
X.\" Copyright (C) 1991, 1992, 1993 Peter Miller.
X.\" All rights reserved.
X.\"
X.\" This program is free software; you can redistribute it and/or modify
X.\" it under the terms of the GNU General Public License as published by
X.\" the Free Software Foundation; either version 2 of the License, or
X.\" (at your option) any later version.
X.\"
X.\" This program is distributed in the hope that it will be useful,
X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X.\" GNU General Public License for more details.
X.\"
X.\" You should have received a copy of the GNU General Public License
X.\" along with this program; if not, write to the Free Software
X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X.\"
X.\" MANIFEST: User Guide, The Change Development Cycle, The Administrator
X.\"
X.bp
X.nh 2 "The Administrator"
X.LP
XThe previous discussion of developers, reviewers and integrators
Xhas covered many aspects of the production of software using the aegis program.
XThe administrator has responsibility for everything they don't,
Xbut there is very little left.
X.LP
XThese responsibilities include:
X.LP
X\(bu access control:
XThe administrator adds and removes all categories of user,
Xincluding administrators.
XThis is on a per-project basis,
Xand has nothing to do with
X.UX
Xuser administration.
XThis simply nominates which users may do what.
X.LP
X\(bu change creation:
XThe administrator adds (and sometimes removes) changes to the system.
XAt later stages,
Xdevelopers may alter some attributes of the change,
Xsuch as the description,
Xto say what they fixed.
X.LP
X\(bu project creation:
XThe aegis program does not limit who may create projects,
Xbut when a project is created the user who created the project
Xis set to be the administrator of that project.
X.LP
XAll of these things will be examined
X.nh 3 "The First Change"
X.LP
XMany things need to happen before
Xdevelopment can begin on
Xthe first change;
Xthe project must be created,
Xthe staff but be given access permissions,
Xthe change must be created.
X.E(
Xalex% \f(CBaenpr example -dir /projects/example\fP
Xaegis: project "example": project directory "/projects/example"
Xaegis: project "example": created
Xalex%
X.E)
XOnce the project has been created,
Xthe project attributes are set.
XAlex will set the desired project attributes using the
X.B -Edit
Xoption of the
X.B aepa
Xcommand.
XThis will invoke an editor (\fIvi\fP(1) by default)
Xit edit the project attributes.
XAlex edits them to look like this:
X.E(
Xdescription = "Aegis Documentation Example Project";
Xdeveloper_may_review = false;
Xdeveloper_may_integrate = false;
Xreviewer_may_integrate = false;
X.E)
XThe project attributes are set as follows:
X.E(
Xalex% \f(CBaepa -edit -p example\fP
X\fI\&...edit as above...\fP
Xaegis: project "example": attributes changed
Xalex% \f(CBael p\fP
XList of Projects
X
XProject Directory Description
X------- ----------- -------------
Xexample /projects/example Aegis Documentation Example
X Project
Xalex%
X.E)
XThe various staff must be added to the project.
XDevelopers are the only staff who may actually edit files.
X.E(
Xalex% \f(CBaend pat jan sam -p example\fP
Xaegis: project "example": user "pat" is now a developer
Xaegis: project "example": user "jan" is now a developer
Xaegis: project "example": user "sam" is now a developer
Xalex%
X.E)
XReviewers may veto a change.
XThere may be overlap between the various categories,
Xas show here for Jan:
X.E(
Xalex% \f(CBaenr robyn jan -p example\fP
Xaegis: project "example": user "robyn" is now a reviewer
Xaegis: project "example": user "jan" is now a reviewer
Xalex%
X.E)
XThe next role we need to fill is an integrator.
X.E(
Xalex% \f(CBaeni isa -p example\fP
Xaegis: project "example": user "isa" is now an integrator
Xalex%
X.E)
XOnce the staff have been given access,
XAlex creates the first change.
XThe
X.B -Edit
Xoption of the
X.B annc
Xcommand is used,
Xto create the attributes of the change.
XThey are edited to look like this:
X.E(
Xbrief_description = "Create initial skeleton.";
Xdescription = "A simple calculator using native \e
Xfloating point precision. \e
XThe four basic arithmetic operators to be provided, \e
Xusing conventional infix notation. \e
XParentheses and negation also required.";
Xcause = internal_enhancement;
X.E)
XThe change is created as follows:
X.E(
Xalex% \f(CBaenc -edit -p example\fP
X\fI\&...edit as above...\fP
Xaegis: project "example": change 1: created
Xalex%
X.E)
XAt this point,
XAlex walks down the hall to Jan's office,
Xto ask Jan to develop the first change.
XJan has had some practice using aegis,
Xand can be relied on to do the rest of the project configuration speedily.
X.nh 3 "The Second Change"
X.LP
XSome time later,
XAlex patiently sits through the whining and grumbling of an
Xespecially pedantic user.
XThe following change description is duly entered:
X.E(
Xbrief_description = "file names on command line";
Xdescription = "Optional input and output files may be \e
Xspecified on the command line.";
Xcause = internal_bug;
X.E)
X.LP
XThe pedantic user wanted to be able to name
Xfiles on the command line,
Xrather than use I/O redirection.
XAlso,
Xhaving a bug in this example is useful.
XThe change is created as follows:
X.E(
Xalex% \f(CBaenc -edit -p example\fP
X\fI\&...edit as above...\fP
Xaegis: project "example": change 2: created
Xalex%
X.E)
XAt some point a developer will notice this change
Xand start work on it.
X.nh 3 "The Third Change"
X.LP
XOther features are required for the calculator,
Xand also for this example.
XThe second change adds exponentiation to the calculator,
Xand is described as follows:
X.E(
Xbrief_description = "add powers";
Xdescription = "Enhance the grammar to allow exponentiation. \e
XNo error checking required.";
Xcause = internal_enhancement;
X.E)
X.LP
XThe change is created as follows:
X.E(
Xalex% \f(CBaenc -edit -p example\fP
X\fI\&...edit as above...\fP
Xaegis: project "example": change 3: created
Xalex%
X.E)
XAt some point a developer will notice,
Xand this change will be worked on.
X.nh 3 "The Fourth Change"
X.LP
XA fourth change,
Xthis time adding variables to the calculator
Xis added.
X.E(
Xbrief_description = "add variables";
Xdescription = "Enhance the grammar to allow variables. \e
XOnly single letter variable names are required.";
Xcause = internal_enhancement;
X.E)
X.LP
XThe change is created as follows:
X.E(
Xalex% \f(CBaenc -edit -p example\fP
X\fI\&...edit as above...\fP
Xaegis: project "example": change 4: created
Xalex%
X.E)
XAt some point a developer will notice,
Xand this change will be worked on.
X.nh 3 "Administrator Command Summary"
X.LP
XOnly a few of the aegis commands available to administrators have
Xbeen used in this example.
XThe following table (very tersely) describes the aegis commands most useful to administrators.
X.sp
X.TS
Xcenter,tab(;);
Xl l.
XCommand;Description
X_
Xaeca;edit Change Attributes
Xael;List Stuff
Xaena;New Administrator
Xaenc;New Change
Xaencu;New Change Undo
Xaend;New Developer
Xaeni;New Integrator
Xaenpr;New Project
Xaenrv;New Reviewer
Xaepa;edit Project Attributes
Xaera;Remove Administrator
Xaerd;Remove Developer
Xaeri;Remove Integrator
Xaermpr;Remove Project
Xaerrv;Remove Reviewer
X.TE
X.LP
XYou will want to read the manual entries for all of these commands.
XNote that all aegis commands have a
X.I \-Help
Xoption,
Xwhich will give a result very similar to the
Xcorresponding
X.I man (1)
Xoutput.
XMost aegis commands also have a
X.I \-List
Xoption,
Xwhich usually lists interesting context sensitive information.
END_OF_FILE
if test 7508 -ne `wc -c <'doc/c2.4.so'`; then
echo shar: \"'doc/c2.4.so'\" unpacked with wrong size!
fi
# end of 'doc/c2.4.so'
fi
if test -f 'doc/c4.2.so' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'doc/c4.2.so'\"
else
echo shar: Extracting \"'doc/c4.2.so'\" \(8145 characters\)
sed "s/^X//" >'doc/c4.2.so' <<'END_OF_FILE'
X.\"
X.\" aegis - project change supervisor
X.\" Copyright (C) 1993 Peter Miller.
X.\" All rights reserved.
X.\"
X.\" This program is free software; you can redistribute it and/or modify
X.\" it under the terms of the GNU General Public License as published by
X.\" the Free Software Foundation; either version 2 of the License, or
X.\" (at your option) any later version.
X.\"
X.\" This program is distributed in the hope that it will be useful,
X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X.\" GNU General Public License for more details.
X.\"
X.\" You should have received a copy of the GNU General Public License
X.\" along with this program; if not, write to the Free Software
X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X.\"
X.\" MANIFEST: User Guide, The Dependency Maintenance Tool, Cook
X.\"
X.bp
X.nh 2 "Cook"
X.LP
XThe
X.I cook
Xprogram is the only dependency maintenance tool,
Xknown to the author,
Xwhich is sufficiently capable to supply aegis' needs.\**
X.FS
XThe version in use when writing this section was 1.3.
XEarlier versions are known to work with aegis,
Xbut the recipes are horribly cumbersome.
X.FE
X.LP
XEventually this section will provide templates for constructing
X.I Howto.cook
Xfile (Howto.cook is to cook what Makefile is to make).
X.LP
XThis section will discuss the
X.I build_command
Xand
X.I integrate_build_command
Xand
X.I link_baseline
Xand
X.I change_file_command
Xand
X.I project_file_command
Xfields of the
X.I config
Xfile.
X.LP
XIn the mean time,
Xsee
X.I aepconf 5
Xfor more information.
X.nh 3 "Invoking Cook"
X.LP
XThe
X.I build_command
Xfield of the
X.I config
Xfile is used to invoke the relevant build command.
XIn this case, it is set as follows
X.E(
Xbuild_command =
X "cook -b ${s Howto.cook} project=$p change=$c version=$v -nl";
X.E)
X.LP
XThis command tells cook
Xwhere to find the recipes.
XThe \f(CW${s Howto.cook}\fR expands to a path into the baseline
Xduring development
Xif the file is not in the change.
XLook in
X.I aesub (5)
Xfor more information about command substitutions.
X.LP
XThe recipes which follow will all remove their targets before constructing
Xthem, which qualifies them for the next entry in the
X.I config
Xfile:
X.E(
Xlink_integration_directory = true;
X.E)
X.LP
XThe files must be removed first, otherwise the baseline would
Xcease to be self-consistent.
X.nh 3 "The Recipe File"
X.LP
XThe file containing the recipes is called
X.I Howto.cook
Xand is given to cook on the command line.
X.LP
XThe following items are preamble to the rest of the file;
Xthey ask aegis for the source files of the project and change
Xso that cook can determine what needs to be compiled and linked.
X.E(
Xproject_files =
X [collect aegis -l pf -terse -p [project] -c [change]];
Xchange_files =
X [collect aegis -l cf -terse -p [project] -c [change]];
Xsource_files =
X [sort [project_files] [change_files]];
X.E)
X.LP
XThis example continues the one from chapter 3,
Xand thus has a single executable
Xto be linked from all the object files
X.E(
Xobject_files =
X [fromto %.y %.o [match_mask %.y [source_files]
X [fromto %.l %.o [match_mask %.l [source_files]
X [fromto %.c %.o [match_mask %.c [source_files]
X ;
X.E)
X.LP
XIt is necessary to determine if this is a development build,
Xand thus has the baseline for additional ingredients searches,
Xor an integration build, which does not.
XThe version supplied by aegis will tell us this information,
Xbecause it will be \fImajor.minor.\fRC\fIchange\fR for development builds and
X\fImajor.minor.\fRD\fIdelta\fR for integration builds.
X.E(
Xif [match_mask %1C%2 [version]] then
X{
X baseline = [collect aegis -cd -bl -p [project]];
X search_list = . [baseline];
X}
X.E)
X.LP
XThe
X.I search_list
Xvariable in cook is the list of directories to search for dependencies;
Xit defaults to only the current directory.
XThe
X.I resolve
Xbuiltin function of cook
Xmay be used to ask cook for the name of the file actually used to resolve dependencies,
Xso that recipe bodies may reference the appropriate file:
X.E(
Xexample: [object_files]
X{
X [cc] -o example [resolve [object_files]] -ly -ll;
X}
X.E)
X.LP
XThis recipe says that to cook the example program,
Xyou need the object files determined earlier,
Xand them link them together.
XObject files which were up to date in the baseline are used wherever possible,
Xbut files which were out of date are constructed in the current directory
Xand those will be linked.
X.nh 3 "The Recipe for C"
X.LP
XNext we need to tell cook how to manage C sources.
XOn the surface, this is a simple recipe:
X.E(
X%.o: %.c
X{
X rm %.o;
X [cc] [cc_flags] -c %.c;
X}
X.E)
X.LP
XUnfortunately it has forgotten about finding the include file dependencies.
XThe cook package includes a program called
X.I c_incl
Xwhich is used to find them.
XThe recipe now becomes
X.E(
X%.o: %.c: [collect c_incl -eia %.c]
X{
X rm %.o;
X [cc] [cc_flags] -c %.c;
X}
X.E)
X.LP
XThe file may not always be present to be removed (causing a fatal error),
Xand it is irritation to execute a redundant command,
Xso the remove is mangled to look like this:
X.E(
X%.o: %.c: [collect c_incl -eia %.c]
X{
X if [exists %.o] then
X rm %.o
X set clearstat;
X [cc] [cc_flags] -c %.c;
X}
X.E)
X.LP
XThe "set clearstat" clause tells cook that the command will
Xinvalidate parts of its
X.I stat
Xcache,
Xand to look at the command for what to invalidate.
X.LP
XAnother thing this recipe needs is to use the baseline
Xfor include files not in a change,
Xand so the recipe is altered again:
X.E(
X%.o: %.c: [collect c_incl -eia [prepost "-I" "" [search_list]] %.c]
X{
X if [exists %.o] then
X rm %.o
X set clearstat;
X [cc] [cc_flags] [prepost "-I" "" [search_list]] -c %.c;
X}
X.E)
X.LP
XSee the
X.I "Cook Reference Manual"
Xfor a description of the
X.I prepost
Xbuiltin function,
Xand other cook details.
X.LP
XUnfortunately,
Xthere is one last change that must be made to this recipe,
Xit must use the resolve function to reference the appropriate file
Xonce cook has found it on the search list:
X.E(
X%.o: %.c: [collect c_incl -eia [prepost "-I" "" [search_list]]
X [resolve %.c]]
X{
X if [exists %.o] then
X rm %.o
X set clearstat;
X [cc] [cc_flags] [prepost "-I" "" [search_list]]
X -c [resolve %.c];
X}
X.E)
X.LP
XOnly use this last recipe for C sources,
Xthe others are only shown so that the derivation of the recipe is clear;
Xwhile it is very similar to the original,
Xit looks daunting at first.
X.nh 3 "The Recipe for Yacc"
X.LP
XHaving explained the complexities of the recipes in the above section about C,
Xthe recipe for yacc will be given without delay:
X.E(
X%.c %.h: %.y
X{
X if [exists %.c] then
X rm %.c
X set clearstat;
X if [exists %.h] then
X rm %.h
X set clearstat;
X [yacc] [yacc_flags] -d [resolve %.y];
X mv y.tab.c %.c;
X mv y.tab.h %.h;
X}
X.E)
X.LP
XThis recipe could be jazzed up to cope with the listing file,
Xtoo,
Xif that was desired,
Xbut this is sufficient to work with the example.
X.LP
XCook's ability to cope with transitive dependencies will
Xpick up the generated .c file and construct the necessary .o file.
X.nh 3 "The Recipe for Lex"
X.LP
XThe recipe for lex is vary similar to the recipe for yacc.
X.E(
X%.c: %.l
X{
X if [exists %.c] then
X rm %.c
X set clearstat;
X [lex] [lex_flags] -d [resolve %.l];
X mv lex.yy.c %.c;
X}
X.E)
X.LP
XCook's ability to cope with transitive dependencies will
Xpick up the generated .c file and construct the necessary .o file.
X.nh 3 "Recipes for Documents"
X.LP
XYou can format documents,
Xsuch as user guides and manual entries with aegis and cook,
Xand the recipes are similar
Xto the ones above.
X.E(
X%.ps: %.ms: [collect c_incl -r -eia [prepost "-I" "" [search_list]]
X [resolve %.ms]]
X{
X roffpp [prepost "-I" "" [search_list]] [resolve %.ms]
X | groff -p -t -ms > [target];
X}
X.E)
X.LP
XThis recipe says to run the document through groff,
Xwith the
X.I pic (1)
Xand
X.I tbl (1)
Xfilters,
Xuse the
X.I ms (7)
Xmacro package,
Xto produce PostScript output.
XThe
X.I roffpp
Xprogram comes with cook,
Xand is like
X.I soelim (1)
Xbut it takes include search path options on the command line.
X.LP
XManual entries may be handled in a similar way
X.E(
X%.cat: %.man: [collect c_incl -r -eia [prepost "-I" ""
X [search_list]] [resolve %.man]]
X{
X roffpp [prepost "-I" "" [search_list]] [resolve %.man]
X | tbl | nroff -man > [target];
X}
X.E)
END_OF_FILE
if test 8145 -ne `wc -c <'doc/c4.2.so'`; then
echo shar: \"'doc/c4.2.so'\" unpacked with wrong size!
fi
# end of 'doc/c4.2.so'
fi
if test -f 'fmtgen/type_list.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fmtgen/type_list.c'\"
else
echo shar: Extracting \"'fmtgen/type_list.c'\" \(7919 characters\)
sed "s/^X//" >'fmtgen/type_list.c' <<'END_OF_FILE'
X/*
X * aegis - project change supervisor
X * Copyright (C) 1991, 1992, 1993 Peter Miller.
X * All rights reserved.
X *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
X * (at your option) any later version.
X *
X * This program is distributed in the hope that it will be useful,
X * but WITHOUT ANY WARRANTY; without even the implied warranty of
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
X * You should have received a copy of the GNU General Public License
X * along with this program; if not, write to the Free Software
X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X *
X * MANIFEST: list types function generation
X */
X
X#include <type.h>
X#include <indent.h>
X#include <mem.h>
X#include <id.h>
X
X
Xtypedef struct type_list_ty type_list_ty;
Xstruct type_list_ty
X{
X /* inherited */
X TYPE_T
X
X /* instance variables */
X type_ty *subtype;
X};
X
X
Xstatic void gen_include _((type_ty *, string_ty *));
X
Xstatic void
Xgen_include(type, name)
X type_ty *type;
X string_ty *name;
X{
X string_ty *s;
X type_list_ty *type2;
X
X type2 = (type_list_ty *)type;
X indent_putchar('\n');
X indent_printf("#ifndef %s_DEF\n", name->str_text);
X indent_printf("#define %s_DEF\n", name->str_text);
X indent_printf("typedef struct %s *%s;\n", name->str_text, name->str_text);
X indent_printf("struct %s\n", name->str_text);
X indent_printf("{\n"/*}*/);
X indent_printf("%s\1length;\n", "size_t", name->str_text);
X s = str_from_c("list");
X type_gen_include_declarator(type2->subtype, s, 1);
X str_free(s);
X indent_printf(/*{*/"};\n");
X indent_printf("#endif /* %s_DEF */\n", name->str_text);
X
X indent_putchar('\n');
X indent_printf("extern type_ty %s_type;\n", name->str_text);
X
X indent_putchar('\n');
X indent_printf("void %s_write _((char *, %s));\n", name->str_text, name->str_text);
X}
X
X
Xstatic void gen_include_declarator _((type_ty *, string_ty *, int));
X
Xstatic void
Xgen_include_declarator(type, name, is_a_list)
X type_ty *type;
X string_ty *name;
X int is_a_list;
X{
X char *deref;
X
X deref = (is_a_list ? "*" : "");
X indent_printf("%s\1%s%s;\n", type->name->str_text, deref, name->str_text);
X}
X
X
Xstatic void gen_code _((type_ty *, string_ty *));
X
Xstatic void
Xgen_code(type, name)
X type_ty *type;
X string_ty *name;
X{
X string_ty *s;
X type_list_ty *type2;
X
X type2 = (type_list_ty *)type;
X indent_putchar('\n');
X indent_printf("void\n");
X indent_printf("%s_write(name, this)\n", name->str_text);
X indent_more();
X indent_printf("%s\1*name;\n", "char");
X indent_printf("%s\1this;\n", name->str_text);
X indent_less();
X indent_printf("{\n"/*}*/);
X indent_printf("%s\1j;\n", "size_t");
X indent_putchar('\n');
X indent_printf("if (!this)\n");
X indent_more();
X indent_printf("return;\n");
X indent_less();
X indent_printf("trace((\"%s_write(name = \\\"%%s\\\", this = %%08lX)\\n{\\n\"/*}*/, name, this));\n", name->str_text);
X indent_printf("if (name)\n");
X indent_more();
X indent_printf("indent_printf(\"%%s =\\n\", name);\n");
X indent_less();
X indent_printf("indent_printf(\"[\\n\"/*]*/);\n");
X indent_printf("for (j = 0; j < this->length; ++j)\n");
X indent_printf("{\n"/*}*/);
X s = str_from_c("list[j]");
X type_gen_code_declarator(type2->subtype, s, 1);
X str_free(s);
X indent_printf("indent_printf(\",\\n\");\n");
X indent_printf(/*{*/"}\n");
X indent_printf("indent_printf(/*[*/\"]\");\n");
X indent_printf("if (name)\n");
X indent_more();
X indent_printf("indent_printf(\";\\n\");\n");
X indent_less();
X indent_printf("trace((/*{*/\"}\\n\"));\n");
X indent_printf(/*{*/"}\n");
X
X indent_putchar('\n');
X indent_printf("static void *%s_alloc _((void));\n", name->str_text);
X
X indent_putchar('\n');
X indent_printf("static void *\n");
X indent_printf("%s_alloc()\n", name->str_text);
X indent_printf("{\n"/*}*/);
X indent_printf("%s\1*result;\n\n", "void");
X indent_printf("trace((\"%s_alloc()\\n{\\n\"/*}*/));\n", name->str_text);
X indent_printf
X (
X "result = (void *)mem_alloc_clear(sizeof(struct %s));\n",
X name->str_text
X );
X indent_printf("trace((\"return %%08lX;\\n\", (long)result));\n");
X indent_printf("trace((/*{*/\"}\\n\"));\n");
X indent_printf("return result;\n");
X indent_printf(/*{*/"}\n");
X
X indent_putchar('\n');
X indent_printf("static void %s_free _((void *));\n", name->str_text);
X
X indent_putchar('\n');
X indent_printf("static void\n");
X indent_printf("%s_free(that)\n", name->str_text);
X indent_more();
X indent_printf("%s\1*that;\n", "void");
X indent_less();
X indent_printf("{\n"/*}*/);
X indent_printf("%s\1this = (%s)that;\n", name->str_text, name->str_text);
X indent_printf("%s\1j;\n", "size_t");
X indent_putchar('\n');
X indent_printf("if (!this)\n");
X indent_more();
X indent_printf("return;\n");
X indent_less();
X indent_printf("trace((\"%s_free(this = %%08lX)\\n{\\n\"/*}*/, this));\n", name->str_text);
X indent_printf("for (j = 0; j < this->length; ++j)\n");
X indent_more();
X s = str_from_c("list[j]");
X type_gen_free_declarator(type2->subtype, s, 1);
X str_free(s);
X indent_less();
X indent_printf("if (this->list)\n");
X indent_more();
X indent_printf("mem_free((char *)this->list);\n");
X indent_less();
X indent_printf("mem_free((char *)this);\n");
X indent_printf("trace((/*{*/\"}\\n\"));\n");
X indent_printf(/*{*/"}\n");
X
X indent_putchar('\n');
X indent_printf
X (
X "static void %s_parse _((void *, type_ty **, void **));\n",
X name->str_text
X );
X
X indent_putchar('\n');
X indent_printf("static void\n");
X indent_printf("%s_parse(that, type_pp, addr_p)\n", name->str_text);
X indent_more();
X indent_printf("%s\1*that;\n", "void");
X indent_printf("%s\1**type_pp;\n", "type_ty");
X indent_printf("%s\1**addr_p;\n", "void");
X indent_less();
X indent_printf("{\n"/*}*/);
X indent_printf("%s\1this = (%s)that;\n", name->str_text, name->str_text);
X indent_putchar('\n');
X indent_printf("trace((\"%s_parse(this = %%08lX, type_pp = %%08lX, addr_p = %%08lX)\\n{\\n\"/*}*/, this, type_pp, addr_p));\n", name->str_text);
X indent_printf("*type_pp = &%s_type;\n", type2->subtype->name->str_text);
X indent_printf("trace_pointer(*type_pp);\n");
X indent_printf("*addr_p = enlarge(&this->length, (char **)&this->list, sizeof(%s));\n", type->name->str_text);
X indent_printf("trace_pointer(*addr_p);\n");
X indent_printf("trace((/*{*/\"}\\n\"));\n");
X indent_printf(/*{*/"}\n");
X
X indent_putchar('\n');
X indent_printf("type_ty %s_type =\n", name->str_text);
X indent_printf("{\n"/*}*/);
X indent_printf("type_class_list,\n");
X indent_printf("\"%s\",\n", name->str_text);
X indent_printf("%s_alloc,\n", name->str_text);
X indent_printf("%s_free,\n", name->str_text);
X indent_printf("0, /* enum_parse */\n");
X indent_printf("%s_parse,\n", name->str_text);
X indent_printf("0, /* struct_parse */\n");
X indent_printf(/*{*/"};\n");
X}
X
X
Xstatic void gen_code_declarator _((type_ty *, string_ty *, int));
X
Xstatic void
Xgen_code_declarator(type, name, is_a_list)
X type_ty *type;
X string_ty *name;
X int is_a_list;
X{
X indent_printf("%s_write("/*)*/, type->name->str_text);
X if (is_a_list)
X indent_printf("\"\"");
X else
X indent_printf("\"%s\"", name->str_text);
X indent_printf(/*(*/", this->%s);\n", name->str_text);
X}
X
X
Xstatic void gen_free_declarator _((type_ty *, string_ty *, int));
X
Xstatic void
Xgen_free_declarator(type, name, is_a_list)
X type_ty *type;
X string_ty *name;
X int is_a_list;
X{
X indent_printf("%s_free(this->%s);\n", type->name->str_text, name->str_text);
X}
X
X
Xstatic type_method_ty method =
X{
X gen_include,
X gen_include_declarator,
X gen_code,
X gen_code_declarator,
X gen_free_declarator,
X};
X
X
Xtype_ty *
Xtype_create_list(name, subtype)
X string_ty *name;
X type_ty *subtype;
X{
X type_list_ty *type;
X
X type = (type_list_ty *)mem_alloc(sizeof(type_list_ty));
X type->class = type_class_list;
X type->method = &method;
X type->name = str_copy(name);
X type->subtype = subtype;
X id_assign(name, ID_CLASS_TYPE, (long)type);
X return (type_ty *)type;
X}
END_OF_FILE
if test 7919 -ne `wc -c <'fmtgen/type_list.c'`; then
echo shar: \"'fmtgen/type_list.c'\" unpacked with wrong size!
fi
# end of 'fmtgen/type_list.c'
fi
if test -f 'man1/aegis.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'man1/aegis.1'\"
else
echo shar: Extracting \"'man1/aegis.1'\" \(7774 characters\)
sed "s/^X//" >'man1/aegis.1' <<'END_OF_FILE'
X.\"
X.\" aegis - project change supervisor
X.\" Copyright (C) 1991, 1992, 1993 Peter Miller.
X.\" All rights reserved.
X.\"
X.\" This program is free software; you can redistribute it and/or modify
X.\" it under the terms of the GNU General Public License as published by
X.\" the Free Software Foundation; either version 2 of the License, or
X.\" (at your option) any later version.
X.\"
X.\" This program is distributed in the hope that it will be useful,
X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X.\" GNU General Public License for more details.
X.\"
X.\" You should have received a copy of the GNU General Public License
X.\" along with this program; if not, write to the Free Software
X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X.\"
X.\" MANIFEST: manual entry for aegis
X.\"
X.so z_name.so
X.TH \*(n) 1 \*(N)
X.SH NAME
X\*(n) \- project change supervisor
X.SH SYNOPSIS
X.B \*(n)
X.I function
X[
X.IR option ...
X]
X.br
X.B \*(n)
X.B -Help
X.SH DESCRIPTION
XThe
X.I \*(n)
Xprogram is used to
Xsupervise the development and integration of changes into projects.
X.SH FUNCTIONS
XThe following functions are available:
X.TP 8n
X.B -Build
X.br
XThe
X.I "\*(n) -Build"
Xcommand is used to
Xbuild a project.
XSee
X.IR aeb (1)
Xfor more information.
X.TP 8n
X.B -Change_Attributes
X.br
XThe
X.I "\*(n) -Change_Attributes"
Xcommand is used to
Xmodify the attributes of a change.
XSee
X.IR aeca (1)
Xfor more information.
X.TP 8n
X.B -Change_Directory
X.br
XThe
X.I "\*(n) -Change_Directory"
Xcommand is used to
Xchange directory.
XSee
X.IR aecd (1)
Xfor more information.
X.TP 8n
X.B -CoPy_file
X.br
XThe
X.I "\*(n) -CoPy_file"
Xcommand is used to
Xcopy a file into a change.
XSee
X.IR aecp (1)
Xfor more information.
X.TP 8n
X.B -CoPy_file_Undo
X.br
XThe
X.I "\*(n) -Copy_File_Undo"
Xcommand is used to
Xremove a copy of a file from a change.
XSee
X.IR aecpu (1)
Xfor more information.
X.TP 8n
X.B -Develop_Begin
X.br
XThe
X.I "\*(n) -Develop_Begin"
Xcommand is used to
Xbegin development of a change.
XSee
X.IR aedb (1)
Xfor more information.
X.TP 8n
X.B -Develop_Begin_Undo
X.br
XThe
X.I "\*(n) -Develop_Begin_Undo"
Xcommand is used to
Xcease development of a change.
X.See
X.IR aedbu (1)
Xfor more information.
X.TP 8n
X.B -Develop_End
X.br
XThe
X.I "\*(n) -Develop_End"
Xcommand is used to
Xcomplete development of a change.
XSee
X.IR aede (1)
Xfor more information.
X.TP 8n
X.B -Develop_End_Undo
X.br
XThe
X.I "\*(n) -Develop_End_Undo"
Xcommand is used to
Xrecall a change for further development.
XSee
X.IR aedeu (1)
Xfor more information.
X.TP 8n
X.B -DIFFerence
X.br
XThe
X.I "\*(n) -DIFFerence"
Xcommand is used to
Xfind differences between development directory and baseline.
XSee
X.IR aed (1)
Xfor more information.
X.so o_help.so
X.TP 8n
X.B -Integrate_Begin
X.br
XThe
X.I "\*(n) -Integrate_Begin"
Xcommand is used to
Xbeing integrating a change.
XSee
X.IR aeib (1)
Xfor more information.
X.TP 8n
X.B -Integrate_Begin_Undo
X.br
XThe
X.I "\*(n) -Integrate_Begin_Undo"
Xcommand is used to
Xcease integrating a change.
XSee
X.IR aeibu (1)
Xfor more information.
X.TP 8n
X.B -Integrate_Fail
X.br
XThe
X.I "\*(n) -Integrate_Fail"
Xcommand is used to
Xfail a change integration.
XSee
X.IR aeif (1)
Xfor more information.
X.TP 8n
X.B -Integrate_Pass
X.br
XThe
X.I "\*(n) -Integrate_Pass"
Xcommand is used to
Xpass a change integration.
XSee
X.IR aeip (1)
Xfor more information.
X.TP 8n
X.B -List
X.br
XThe
X.I "\*(n) -List"
Xcommand is used to
Xlist interesting things.
XSee
X.IR ael (1)
Xfor more information.
X.TP 8n
X.B -MoVe_file
X.br
XThe
X.I "\*(n) -MoVe_file"
Xcommand is used to
Xchange the name of a file
Xas part of a change.
XSee
X.IR aemv (1)
Xfor more information.
X.TP 8n
X.B -New_Administrator
X.br
XThe
X.I "\*(n) -New_Administrator"
Xcommand is used to
Xadd new administrators to a project.
XSee
X.IR aena (1)
Xfor more information.
X.TP 8n
X.B -New_Change
X.br
XThe
X.I "\*(n) -New_Change"
Xcommand is used to
Xadd a new change to a project.
XSee
X.IR aenc (1)
Xfor more information.
X.TP 8n
X.B -New_Change_Undo
X.br
XThe
X.I "\*(n) -New_Change_Undo"
Xcommand is used to
Xremove a new change from a project.
XSee
X.IR aencu (1)
Xfor more information.
X.TP 8n
X.B -New_Developer
X.br
XThe
X.I "\*(n) -New_Developer"
Xcommand is used to add
Xnew developers to a project.
XSee
X.IR aend (1)
Xfor more information.
X.TP 8n
X.B -New_File
X.br
XThe
X.I "\*(n) -New_File"
Xcommand is used to
Xadd new files to a change.
XSee
X.IR aenf (1)
Xfor more information.
X.TP 8n
X.B -New_File_Undo
X.br
XThe
X.I "\*(n) -New_File_Undo"
Xcommand is used to
Xremove new files from a change.
XSee
X.IR aenfu (1)
Xfor more information.
X.TP 8n
X.B -New_Integrator
X.br
XThe
X.I "\*(n) -New_Integrator"
Xcommand is used to
Xadd new integrators to a project.
XSee
X.IR aeni (1)
Xfor more information.
X.TP 8n
X.B -New_Project
X.br
XThe
X.I "\*(n) -New_Project"
Xcommand is used to
Xcreate a new project to be watched over by \*(n).
XSee
X.IR aenpr (1)
Xfor more information.
X.TP 8n
X.B -New_ReLeaSe
X.br
XThe
X.I "\*(n) -New_ReLeaSe"
Xcommand is used to
Xcreate a new project from an existing project.
XSee
X.IR aenrls (1)
Xfor more information.
X.TP 8n
X.B -New_ReViewer
X.br
XThe
X.I "\*(n) -New_ReViewer"
Xcommand is used to
Xadd new reviewers to a project.
XSee
X.IR aenrv (1)
Xfor more information.
X.TP 8n
X.B -New_Test
X.br
XThe
X.I "\*(n) -New_Test"
Xcommand is used to
Xadd a new test to a change
XSee
X.IR aent (1)
Xfor more information.
X.TP 8n
X.B -New_Test_Undo
X.br
XThe
X.I "\*(n) -New_Test_Undo"
Xcommand is used to
Xremove new tests from a change.
XSee
X.IR aentu (1)
Xfor more information.
X.TP 8n
X.B -Project_Attributes
X.br
XThe
X.I "\*(n) -Project_Attributes"
Xcommand is used to
Xmodify the attributes of a project.
X.TP 8n
X.B -Remove_Administrator
X.br
XThe
X.I "\*(n) -Remove_Administrator"
Xcommand is used to
Xremove administrators from a project.
XSee
X.IR aera (1)
Xfor more information.
X.TP 8n
X.B -Remove_Developer
X.br
XThe
X.I "\*(n) -Remove_Developer"
Xcommand is used to
Xremove developers from a project.
XSee
X.IR aerd (1)
Xfor more information.
X.TP 8n
X.B -ReMove_file
X.br
XThe
X.I "\*(n) -ReMove_file"
Xcommand is used to
Xadd files to be deleted to a change.
XSee
X.IR aerm (1)
Xfor more information.
X.TP 8n
X.B -ReMove_file_Undo
X.br
XThe
X.I "\*(n) -Remove_File_Undo"
Xcommand is used to
Xremove files to be deleted from a change.
XSee
X.IR aermu (1)
Xfor more information.
X.TP 8n
X.B -Remove_Integrator
X.br
XThe
X.I "\*(n) -Remove_Integrator"
Xcommand is used to
Xremove integrators from a project.
XSee
X.IR aeri (1)
Xfor more information.
X.TP 8n
X.B -ReMove_PRoject
X.br
XThe
X.I "\*(n) -ReMove_PRoject"
Xcommand is used to
Xremove a project.
XSee
X.IR aermpr (1)
Xfor more information.
X.TP 8n
X.B -Remove_ReViewer
X.br
XThe
X.I "\*(n) -Remove_ReViewer"
Xcommand is used to
Xremove reviewers from a project.
XSee
X.IR aerrv (1)
Xfor more information.
X.TP 8n
X.B -Review_Fail
X.br
XThe
X.I "\*(n) -Review_Fail"
Xcommand is used to
Xfail a change review.
XSee
X.IR aerf (1)
Xfor more information.
X.TP 8n
X.B -Review_Pass
X.br
XThe
X.I "\*(n) -Review_Pass"
Xcommand is used to
Xpass a change review.
XSee
X.IR aerp (1)
Xfor more information.
X.TP 8n
X.B -Review_Pass_Undo
X.br
XThe
X.I "\*(n) -Review_Pass_Undo"
Xcommand is used to
Xrescind a change review pass.
XSee
X.IR aerpu (1)
Xfor more information.
X.TP 8n
X.B -Test
X.br
XThe
X.I "\*(n) -Test"
Xcommand is used to
Xrun tests.
XSee
X.IR aet (1)
Xfor more information.
X.TP 8n
X.B -VERSion
X.br
XThe
X.I "\*(n) -VERSion"
Xcommand is used to
Xget copyright and version details.
XSee
X.IR aev (1)
Xfor more information.
X.PP
XAll function are case insensitive.
XFunctions may be abbreviated;
Xthe abbreviation is the upper case letters.
XFunctions must appear as the first command line argument.
X.SH OPTIONS
XThe following options are available to all functions.
XThese options may appear anywhere on the command line following
Xthe function selectors.
X.so o_lib.so
X.so o_page.so
X.so o_terse.so
X.so o_unforma.so
X.so o_verbose.so
X.so o__rules.so
X.so z_exit.so
X.so z_cr.so
END_OF_FILE
if test 7774 -ne `wc -c <'man1/aegis.1'`; then
echo shar: \"'man1/aegis.1'\" unpacked with wrong size!
fi
# end of 'man1/aegis.1'
fi
if test -f 'test/00/t0005a.sh' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'test/00/t0005a.sh'\"
else
echo shar: Extracting \"'test/00/t0005a.sh'\" \(7509 characters\)
sed "s/^X//" >'test/00/t0005a.sh' <<'END_OF_FILE'
X#! /bin/sh
X#
X# aegis - project change supervisor
X# Copyright (C) 1991, 1992, 1993 Peter Miller.
X# All rights reserved.
X#
X# This program is free software; you can redistribute it and/or modify
X# it under the terms of the GNU General Public License as published by
X# the Free Software Foundation; either version 2 of the License, or
X# (at your option) any later version.
X#
X# This program is distributed in the hope that it will be useful,
X# but WITHOUT ANY WARRANTY; without even the implied warranty of
X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X# GNU General Public License for more details.
X#
X# You should have received a copy of the GNU General Public License
X# along with this program; if not, write to the Free Software
X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X#
X# MANIFEST: Test the 'aegis -DevEnd' command.
X#
X# File which are removed should not be
X# check to see if their last-modified-time is kosher.
X#
X
Xunset AEGIS_PROJECT
Xunset AEGIS_CHANGE
Xumask 022
X
XUSER=${USER:-${LOGNAME:-`whoami`}}
X
XPAGER=cat
Xexport PAGER
Xwork=${AEGIS_TMP:-/tmp}/$$
X
Xfail()
X{
X set +x
X echo "FAILED test of 'aegis -DevEnd' command" 1>&2
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 1
X}
Xpass()
X{
X set +x
X echo PASSED 1>&2
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X#
X# some variable to make things earier to read
X#
Xworklib=$work/lib
Xworkproj=$work/foo.proj
Xworkchan=$work/foo.chan
Xtmp=$work/tmp
X
X#
X# echo commands so we can tell what failed
X#
Xset -x
X
X#
X# make the directories
X#
Xmkdir $work
X
X#
X# make a new project
X#
X./bin/aegis -newpro foo -dir $workproj -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change project attributes
X#
Xcat > $tmp << 'end'
Xdescription = "A bogus project created to test things.";
Xdeveloper_may_review = true;
Xdeveloper_may_integrate = true;
Xreviewer_may_integrate = true;
Xend
X./bin/aegis -proatt $tmp -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a new change
X# make sure it creates the files it should
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change is used to test the aegis functionality \
Xwith respect to change descriptions.";
Xcause = internal_bug;
Xend
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a second change
X# make sure it creates the files it should
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change was added to make the various listings \
Xmuch more interesting.";
Xcause = internal_bug;
Xend
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new developer
X#
X./bin/aegis -newdev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# begin development of a change
X#
X./bin/aegis -devbeg 1 -p foo -dir $workchan -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new files to the change
X#
X./bin/aegis -new_file $workchan/main.c -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -new_file $workchan/fubar -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# put something in 'main.c'
X#
Xcat > $workchan/main.c << 'end'
Xvoid
Xmain()
X{
X exit(0);
X}
Xend
X
X#
X# put something in 'config'
X#
Xcat > $workchan/config << 'end'
Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$vers\"' main.c";
Xlink_integration_directory = true;
X
Xhistory_get_command =
X "co -u'$e' -p $h,v > $o";
Xhistory_create_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_put_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_query_command =
X "rlog -r $h,v | awk '/^head:/ {print $$2}'";
X
Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
X
Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
X echo '1,$$p' ) | ed - $mr > $out";
Xend
X
X#
X# create a new test
X#
X./bin/aegis -nt -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# put something in 'test/00/t0001a.sh'
X#
Xcat > $workchan/test/00/t0001a.sh << 'end'
X#!/bin/sh
X#
X# Project: "foo"
X# Change: 1
X#
X
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo
Xq=$?
X
X# check for signals
Xif test $q -ge 128
Xthen
X fail
Xfi
X
X# should not complain
Xif test $q -ne 0
Xthen
X fail
Xfi
X
X# it probably worked
Xpass
Xend
X
X#
X# let the clock tick over, so the build will be happy
X#
Xsleep 1
X
X#
X# build the change
X#
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# difference the change
X#
X./bin/aegis -diff -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# test the change
X#
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# finish development of the change
X#
X./bin/aegis -dev_end -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new reviewer
X#
X./bin/aegis -newrev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the review
X#
X./bin/aegis -review_pass -chan 1 -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add an integrator
X#
X./bin/aegis -newint $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start integrating
X#
X./bin/aegis -intbeg 1 -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# integrate build
X#
Xsleep 1
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# integrate test
X#
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# integration pass
X#
X./bin/aegis -intpass -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start work on change 2
X#
X./bin/aegis -devbeg 2 -p foo -v -dir $workchan -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# copy a file into the change
X#
X./bin/aegis -cp $workchan/main.c -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# remove a file with the change
X#
X./bin/aegis -rm $workchan/fubar -nl -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change the file
X#
Xcat > $workchan/main.c << 'end'
X
X#include <stdio.h>
X
Xvoid
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X if (argc != 1)
X {
X fprintf(stderr, "usage: %s\n", argv[0]);
X exit(1);
X }
X printf("hello, world\n");
X exit(0);
X}
Xend
X
X#
X# need another test
X#
X./bin/aegis -nt -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/test/00/t0002a.sh << 'end'
X#!/bin/sh
X#
X# Project: "foo"
X# Change: 2
X#
X
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo ickky
Xq=$?
X
X# check for signals
Xif test $q -ge 128
Xthen
X fail
Xfi
X
X# should have complained
Xif test $q -eq 0
Xthen
X fail
Xfi
X
X# it probably worked
Xpass
Xend
X
X#
X# tick over clock to keep build happy
X#
Xsleep 1
X
X#
X# diff the change
X# copy an empty file into local area
X# to dodge diff bug.
X#
Xcp /dev/null ./fubar
X./bin/aegis -diff -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xrm ./fubar
X
X#
X# build the change
X#
Xsleep 1
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# test the change
X#
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -bl -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# end development of the change
X#
X./bin/aegis -devend -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X# should be no automatic logging
Xif test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
X
X#
X# the things tested in this test, worked
X#
Xpass
END_OF_FILE
if test 7509 -ne `wc -c <'test/00/t0005a.sh'`; then
echo shar: \"'test/00/t0005a.sh'\" unpacked with wrong size!
fi
# end of 'test/00/t0005a.sh'
fi
if test -f 'test/00/t0008a.sh' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'test/00/t0008a.sh'\"
else
echo shar: Extracting \"'test/00/t0008a.sh'\" \(7628 characters\)
sed "s/^X//" >'test/00/t0008a.sh' <<'END_OF_FILE'
X#! /bin/sh
X#
X# aegis - project change supervisor
X# Copyright (C) 1991, 1992, 1993 Peter Miller.
X# All rights reserved.
X#
X# This program is free software; you can redistribute it and/or modify
X# it under the terms of the GNU General Public License as published by
X# the Free Software Foundation; either version 2 of the License, or
X# (at your option) any later version.
X#
X# This program is distributed in the hope that it will be useful,
X# but WITHOUT ANY WARRANTY; without even the implied warranty of
X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X# GNU General Public License for more details.
X#
X# You should have received a copy of the GNU General Public License
X# along with this program; if not, write to the Free Software
X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X#
X# MANIFEST: Test command substitutions
X#
X
Xunset AEGIS_PROJECT
Xunset AEGIS_CHANGE
Xumask 022
X
XUSER=${USER:-${LOGNAME:-`whoami`}}
X
XPAGER=cat
Xexport PAGER
Xwork=${AEGIS_TMP:-/tmp}/$$
X
Xfail()
X{
X set +x
X echo FAILED test of command substitutions 1>&2
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 1
X}
Xpass()
X{
X set +x
X echo PASSED 1>&2
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X#
X# some variable to make things earier to read
X#
Xworklib=$work/lib
Xworkproj=$work/foo.proj
Xworkchan=$work/foo.chan
Xtmp=$work/tmp
X
X#
X# echo commands so we can tell what failed
X#
Xset -x
X
X#
X# make the directories
X#
Xmkdir $work
X
X#
X# make a new project
X#
X./bin/aegis -newpro foo -dir $workproj -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change project attributes
X#
Xcat > $tmp << 'end'
Xdescription = "A bogus project created to test things.";
Xdeveloper_may_review = true;
Xdeveloper_may_integrate = true;
Xreviewer_may_integrate = true;
Xend
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -proatt $tmp -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a new change
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change is used to test the aegis functionality \
Xwith respect to change descriptions.";
Xcause = internal_bug;
Xend
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a second change
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change was added to make the various listings \
Xmuch more interesting.";
Xcause = internal_bug;
Xend
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new developer
X#
X./bin/aegis -newdev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# begin development of a change
X#
X./bin/aegis -devbeg 1 -p foo -dir $workchan -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new files to the change
X#
X./bin/aegis -new_file $workchan/main.c -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/main.c << 'end'
Xvoid
Xmain()
X{
X exit(0);
X}
Xend
X
X./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/config << 'end'
Xbuild_command = "make -f ${s Makefile} PROJECT=$p CHANGE=$c VERSION=$v";
Xlink_integration_directory = true;
X
Xhistory_get_command =
X "co -u'$e' -p $h,v > $o";
Xhistory_create_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_put_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_query_command =
X "rlog -r $h,v | awk '/^head:/ {print $$2}'";
X
Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
X
Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
X echo '1,$$p' ) | ed - $mr > $out";
Xend
Xif test $? -ne 0 ; then fail; fi
X
X./bin/aegis -new_file $workchan/Makefile -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/Makefile << 'end'
Xfoo: main.c
X rm -f foo
X cc -o foo main.c
Xend
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a new test
X#
X./bin/aegis -nt -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/test/00/t0001a.sh << 'end'
X#!/bin/sh
X#
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo
Xif test $? -ne 0
Xthen
X fail
Xfi
X
X# it probably worked
Xpass
Xend
X
X#
X# let the clock tick over, so the build will be happy
X#
Xsleep 1
X
X#
X# build the change
X#
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# difference the change
X#
X./bin/aegis -diff -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# test the change
X#
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# finish development of the change
X#
X./bin/aegis -dev_end -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new reviewer
X#
X./bin/aegis -newrev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the review
X#
X./bin/aegis -review_pass -chan 1 -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add an integrator
X#
X./bin/aegis -newint $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start integrating
X#
X./bin/aegis -intbeg 1 -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# integrate build
X#
Xsleep 1
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the integration
X#
X./bin/aegis -intpass -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start work on change 2
X#
X./bin/aegis -devbeg 2 -p foo -v -dir $workchan -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# copy a file into the change
X#
X./bin/aegis -cp $workchan/main.c -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change the file
X#
Xcat > $workchan/main.c << 'end'
X
X#include <stdio.h>
X
Xvoid
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X if (argc != 1)
X {
X fprintf(stderr, "usage: %s\n", argv[0]);
X exit(1);
X }
X printf("hello, world\n");
X exit(0);
X}
Xend
X
X#
X# need another test
X#
X./bin/aegis -nt -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/test/00/t0002a.sh << 'end'
X#!/bin/sh
X#
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo ickky
Xif test $? -ne 1
Xthen
X fail
Xfi
X
X# it probably worked
Xpass
Xend
Xif test $? -ne 0 ; then fail; fi
X
X#
X# tick over clock to keep build happy
X#
Xsleep 1
X
X#
X# build the change
X# diff the change
X# test the change
X#
X./bin/aegis -b -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -diff -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -bl -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X
X#
X# end development
X# review pass
X# start integrating
X#
X./bin/aegis -devend -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -revpass -v -c 2 -p foo -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -intbeg -v -c 2 -p foo -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# build the integration
X# test the integration
X# test the integration against the baseline
X#
Xsleep 1
X./bin/aegis -b -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -t -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -t -bl -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the integration
X#
X./bin/aegis -intpass -nl -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X# should be no automatic logging
Xif test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
X
X#
X# the things tested in this test, worked
X#
Xpass
END_OF_FILE
if test 7628 -ne `wc -c <'test/00/t0008a.sh'`; then
echo shar: \"'test/00/t0008a.sh'\" unpacked with wrong size!
fi
# end of 'test/00/t0008a.sh'
fi
if test -f 'test/00/t0017a.sh' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'test/00/t0017a.sh'\"
else
echo shar: Extracting \"'test/00/t0017a.sh'\" \(7847 characters\)
sed "s/^X//" >'test/00/t0017a.sh' <<'END_OF_FILE'
X#! /bin/sh
X#
X# aegis - project change supervisor
X# Copyright (C) 1993 Peter Miller.
X# All rights reserved.
X#
X# This program is free software; you can redistribute it and/or modify
X# it under the terms of the GNU General Public License as published by
X# the Free Software Foundation; either version 2 of the License, or
X# (at your option) any later version.
X#
X# This program is distributed in the hope that it will be useful,
X# but WITHOUT ANY WARRANTY; without even the implied warranty of
X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X# GNU General Public License for more details.
X#
X# You should have received a copy of the GNU General Public License
X# along with this program; if not, write to the Free Software
X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X#
X# MANIFEST: Test 'aegis -DIFFerence -ANticipate' variant
X#
X# The bug results in a string of length 0 being passed.
X#
X
Xunset AEGIS_PROJECT
Xunset AEGIS_CHANGE
Xumask 022
X
XUSER=${USER:-${LOGNAME:-`whoami`}}
X
XPAGER=cat
Xexport PAGER
Xwork=${AEGIS_TMP:-/tmp}/$$
X
Xfail()
X{
X set +x
X echo "FAILED test of 'aegis -DIFFerence -ANticipate' variant" 1>&2
X cd $here
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 1
X}
Xpass()
X{
X set +x
X echo PASSED 1>&2
X cd $here
X find $work -type d -user $USER -exec chmod u+w {} \;
X rm -rf $work
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X#
X# some variable to make things earier to read
X#
Xworklib=$work/lib
Xworkproj=$work/foo.proj
Xworkchan=$work/foo.chan
Xworkchan3=$work/foo.chan3
Xtmp=$work/tmp
X
X#
X# echo commands so we can tell what failed
X#
Xset -x
X
X#
X# make the directories
X#
Xmkdir $work
X
X#
X# make a new project
X# and check files it should have made
X#
X./bin/aegis -newpro foo -dir $workproj -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change project attributes
X#
Xcat > $tmp << 'end'
Xdescription = "A bogus project created to test things.";
Xdeveloper_may_review = true;
Xdeveloper_may_integrate = true;
Xreviewer_may_integrate = true;
Xend
X./bin/aegis -proatt $tmp -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a new change
X# make sure it creates the files it should
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change is used to test the aegis functionality \
Xwith respect to change descriptions.";
Xcause = internal_bug;
Xend
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a second change
X# make sure it creates the files it should
X#
Xcat > $tmp << 'end'
Xbrief_description = "This change was added to make the various listings \
Xmuch more interesting.";
Xcause = internal_bug;
Xend
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# create a third change
X#
Xcat > $tmp << 'end'
Xbrief_description = "change three";
Xcause = internal_bug;
Xend
X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new developer
X#
X./bin/aegis -newdev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# begin development of a change
X# check it made the files it should
X#
X./bin/aegis -devbeg 1 -p foo -dir $workchan -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new files to the change
X#
X./bin/aegis -new_file $workchan/main.c -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/main.c << 'end'
Xvoid
Xmain()
X{
X exit(0);
X}
Xend
Xcat > $workchan/config << 'end'
Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$version\"' main.c";
Xlink_integration_directory = true;
X
Xhistory_get_command =
X "co -u'$e' -p $h,v > $o";
Xhistory_create_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_put_command =
X "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
Xhistory_query_command =
X "rlog -r $h,v | awk '/^head:/ {print $$2}'";
X
Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
X
Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
X echo '1,$$p' ) | ed - $mr > $out";
Xend
X
X#
X# create a new test
X#
X./bin/aegis -nt -l -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -nt -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/test/00/t0001a.sh << 'end'
X#!/bin/sh
X
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo
Xif test $? -ne 0; then fail; fi
X
X# it probably worked
Xpass
Xend
X
X#
X# let the clock tick over, so the build will be happy
X#
Xsleep 1
X
X#
X# build the change
X#
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# difference the change
X#
X./bin/aegis -diff -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# test the change
X#
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# finish development of the change
X#
X./bin/aegis -dev_end -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add a new reviewer
X#
X./bin/aegis -newrev $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the review
X#
X./bin/aegis -review_pass -chan 1 -proj foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# add an integrator
X#
X./bin/aegis -newint $USER -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start integrating
X#
X./bin/aegis -intbeg 1 -p foo -v -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# integrate build
X#
Xsleep 1
X./bin/aegis -build -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# pass the integration
X#
X./bin/aegis -intpass -nl -v -lib $worklib -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start work on change 2
X#
X./bin/aegis -devbeg 2 -p foo -v -dir $workchan -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# start work on change 3
X#
X./bin/aegis -devbeg 3 -p foo -v -dir $workchan3 -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# copy a file into change 2
X#
X./bin/aegis -cp $workchan/main.c -nl -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# copy a file into change 3
X#
X./bin/aegis -cp $workchan3/main.c -nl -v -lib $worklib -c 3 -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# change the file
X#
Xcat > $workchan/main.c << 'end'
X
X#include <stdio.h>
X
Xvoid
Xmain(argc, argv)
X int argc;
X char **argv;
X{
X if (argc != 1)
X {
X fprintf(stderr, "usage: %s\n", argv[0]);
X exit(1);
X }
X printf("hello, world\n");
X exit(0);
X}
Xend
X
X#
X# need another test
X#
X./bin/aegis -nt -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
Xcat > $workchan/test/00/t0002a.sh << 'end'
X#!/bin/sh
X
Xfail()
X{
X echo SHUZBUTT 1>&2
X exit 1
X}
Xpass()
X{
X exit 0
X}
Xtrap "fail" 1 2 3 15
X
X./foo ickky
Xif test $? -ne 1; then fail; fi
X
X# it probably worked
Xpass
Xend
X
X#
X# tick over clock to keep build happy
X#
Xsleep 1
X
X#
X# build the change
X# diff the change
X# test the change
X#
X./bin/aegis -b -nl -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -diff -nl -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -nl -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -test -bl -nl -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X
X#
X# end development
X# review pass
X# start integrating
X#
X./bin/aegis -devend -v -lib $worklib -c 2 -p foo
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -revpass -v -c 2 -p foo -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X./bin/aegis -intbeg -v -c 2 -p foo -lib $worklib
Xif test $? -ne 0 ; then fail; fi
X
X#
X# difference change 3 anticipating 2
X#
X./bin/aegis -diff -nl -c 3 -lib $worklib -p foo -an 2
Xif test $? -ne 0 ; then fail; fi
X
X#
X# the merged result (in change 3) should look like
X# the edited one from change 2
X#
Xdiff $workchan3/main.c,D $workchan/main.c
Xif test $? -ne 0 ; then fail; fi
X
X#
X# the things tested in this test, worked
X#
Xpass
END_OF_FILE
if test 7847 -ne `wc -c <'test/00/t0017a.sh'`; then
echo shar: \"'test/00/t0017a.sh'\" unpacked with wrong size!
fi
# end of 'test/00/t0017a.sh'
fi
echo shar: End of archive 6 \(of 19\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 19 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0