home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-09-24 | 151.0 KB | 6,464 lines |
- Newsgroups: comp.sources.unix
- From: pmiller@bmr.gov.au (Peter Miller)
- Subject: v27i042: aegis - project change supervisor (V2.1), Part07/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 42
- Archive-Name: aegis-2.1/part07
-
- #! /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 7 (of 19)."
- # Contents: aegis/aecd.c aegis/aeibu.c aegis/aencu.c aegis/aermpr.c
- # aegis/aerp.c aegis/aerpu.c aegis/commit.c aux/Makefile.sh
- # common/arglex.c doc/c5.0.so fmtgen/id.c fmtgen/lex.c
- # fmtgen/parse.y test/00/t0006a.sh test/00/t0009a.sh
- # Wrapped by vixie@gw.home.vix.com on Sat Sep 25 03:00:37 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'aegis/aecd.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aecd.c'\"
- else
- echo shar: Extracting \"'aegis/aecd.c'\" \(9595 characters\)
- sed "s/^X//" >'aegis/aecd.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 change directory or determine paths
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X
- X#include <aecd.h>
- X#include <ael.h>
- X#include <arglex2.h>
- X#include <change.h>
- X#include <error.h>
- X#include <help.h>
- X#include <option.h>
- X#include <os.h>
- X#include <project.h>
- X#include <trace.h>
- X#include <user.h>
- X
- X
- Xstatic void change_directory_usage _((void));
- X
- Xstatic void
- Xchange_directory_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf(stderr, "usage: %s -Change_Directory [ <option>... ][ <subdir> ]\n", progname);
- X fprintf(stderr, " %s -Change_Directory -List [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Change_Directory -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void change_directory_help _((void));
- X
- Xstatic void
- Xchange_directory_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -Change_Directory - change directory",
- X"",
- X"SYNOPSIS",
- X" %s -Change_Directory [ <option>... ][ <relative-path> ]",
- X" %s -Change_Directory -List [ <option>... ]",
- X" %s -Change_Directory -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -Change_Directory command is used to obtain a",
- X" path to change directory to. If the relative-path is",
- X" supplied, this will be added to the output.",
- X"",
- X" This command is usually used to calculate an argument for",
- X" cd(1), howver it can also be used to abtain an absolute",
- X" path for change and project files.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -BaseLine",
- X" This option may be used to specify that the",
- X" project baseline is the subject of the command.",
- X"",
- X" -Change <number>",
- X" This option may be used to specify a particular",
- X" change within a project. When no -Change option is",
- X" specified, the AEGIS_CHANGE environment variable is",
- X" consulted. If that does not exist, the user's",
- X" $HOME/.aegisrc file is examined for a default change",
- X" field (see aeuconf(5) for more information). If",
- X" that does not exist, when the user is only working",
- X" on one change within a project, that is the default",
- X" change number. Otherwise, it is an error.",
- X"",
- X" -Development_Directory",
- X" This option is ised to specify that the",
- X" development directory is the subject of the",
- X" command. This is only useful for a change which",
- X" is in the 'being_integrated' state, when the",
- X" default is the integration directory.",
- 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 are case insensitive. Options may be",
- X" abbreviated; the abbreviation is the upper case letters.",
- X" Options and other command line arguments may be mixed",
- X" arbitrarily on the command line.",
- X"",
- X"RECOMMENDED ALIAS",
- X" The recommended alias for this command is",
- X" csh%% alias aecd 'cd `%s -cd \\!* -v`'",
- X" sh$ aecd(){cd `%s -cd $* -v`}",
- X"",
- X"ERRORS",
- X" It is an error if the specified change is not in a state",
- X" where it has a directory to change to.",
- 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), change_directory_usage);
- X}
- X
- X
- Xstatic void change_directory_list _((void));
- X
- Xstatic void
- Xchange_directory_list()
- X{
- X string_ty *project_name;
- X
- X trace(("change_directory_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(change_directory_usage);
- X continue;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X change_directory_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_changes_in_state_mask
- X (
- X project_name,
- X (
- X (1 << cstate_state_being_developed)
- X |
- X (1 << cstate_state_being_reviewed)
- X |
- X (1 << cstate_state_awaiting_integration)
- X |
- X (1 << cstate_state_being_integrated)
- X )
- X );
- X if (project_name)
- X str_free(project_name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void change_directory_main _((void));
- X
- Xstatic void
- Xchange_directory_main()
- X{
- X char *subdir = 0;
- X int devdir = 0;
- X cstate cstate_data;
- X string_ty *d;
- X int baseline = 0;
- X string_ty *project_name;
- X project_ty *pp;
- X long change_number;
- X change_ty *cp;
- X user_ty *up;
- X
- X trace(("change_directory_main()\n{\n"/*}*/));
- X project_name = 0;
- X change_number = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(change_directory_usage);
- X continue;
- X
- X case arglex_token_string:
- X if (subdir)
- X fatal("too many subdirectories specified");
- X subdir = arglex_value.alv_string;
- X if (!*subdir || *subdir == '/')
- X fatal("subdirectory must be relative");
- X break;
- X
- X case arglex_token_development_directory:
- X if (devdir)
- X fatal("duplicate -Develompent_Directory option");
- X if (baseline)
- X {
- X bad_combo:
- X fatal
- X (
- X "only one of -BaseLine and -Development_Directory may be specified"
- X );
- X }
- X devdir = 1;
- X break;
- X
- X case arglex_token_baseline:
- X if (baseline)
- X fatal("duplicate -BaseLine option");
- X if (devdir)
- X goto bad_combo;
- X baseline = 1;
- X break;
- X
- X case arglex_token_change:
- X if (arglex() != arglex_token_number)
- X change_directory_usage();
- X /* fall through... */
- X
- X case arglex_token_number:
- X if (change_number)
- X fatal("duplicate -Change option");
- X change_number = arglex_value.alv_number;
- X if (change_number < 1)
- X fatal("change %ld out of range", change_number);
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X change_directory_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
- 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 * figure out where to go
- X */
- X if (baseline)
- X {
- X if (change_number)
- X {
- X fatal
- X (
- X "the -BaseLine and -Change options are mutually exclusive"
- X );
- X }
- X d = project_baseline_path_get(pp, 0);
- X cp = 0;
- X }
- X else
- X {
- X /*
- X * locate change data
- X */
- X if (!change_number)
- X change_number = user_default_change(up);
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X
- X cstate_data = change_cstate_get(cp);
- X switch (cstate_data->state)
- X {
- X default:
- X change_fatal(cp, "no directory");
- X
- X case cstate_state_being_integrated:
- X if (!devdir)
- X {
- X d = change_integration_directory_get(cp, 0);
- X break;
- X }
- X /* fall through... */
- X
- X case cstate_state_awaiting_integration:
- X case cstate_state_being_reviewed:
- X case cstate_state_being_developed:
- X d = change_development_directory_get(cp, 0);
- X break;
- X }
- X }
- X
- X /*
- X * Add in the extra path elements as necessary.
- X * Flatten it out if they go up the tree (etc).
- X */
- X if (subdir)
- X {
- X string_ty *tmp;
- X
- X tmp = str_format("%S/%s", d, subdir);
- X user_become(up);
- X d = os_pathname(tmp, 0);
- X user_become_undo();
- X str_free(tmp);
- X }
- X
- X /*
- X * print out the path
- X */
- X printf("%s\n", d->str_text);
- X if (!cp)
- X project_verbose(pp, "%s", d->str_text);
- X else
- X {
- X change_verbose(cp, "%s", d->str_text);
- X change_free(cp);
- X }
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xchange_directory()
- X{
- X trace(("change_directory()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X change_directory_main();
- X break;
- X
- X case arglex_token_help:
- X change_directory_help();
- X break;
- X
- X case arglex_token_list:
- X change_directory_list();
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 9595 -ne `wc -c <'aegis/aecd.c'`; then
- echo shar: \"'aegis/aecd.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aecd.c'
- fi
- if test -f 'aegis/aeibu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aeibu.c'\"
- else
- echo shar: Extracting \"'aegis/aeibu.c'\" \(10341 characters\)
- sed "s/^X//" >'aegis/aeibu.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 implementing integrate begin undo
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include <aeibu.h>
- X#include <ael.h>
- X#include <arglex2.h>
- X#include <commit.h>
- X#include <change.h>
- X#include <dir.h>
- X#include <error.h>
- X#include <file.h>
- X#include <help.h>
- X#include <lock.h>
- X#include <log.h>
- X#include <option.h>
- X#include <os.h>
- X#include <project.h>
- X#include <sub.h>
- X#include <trace.h>
- X#include <undo.h>
- X#include <user.h>
- X
- X
- Xstatic void integrate_begin_undo_usage _((void));
- X
- Xstatic void
- Xintegrate_begin_undo_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf(stderr, "usage: %s -Integrate_Begin_Undo [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Integrate_Begin_Undo -List [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Integrate_Begin_Undo -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void integrate_begin_undo_help _((void));
- X
- Xstatic void
- Xintegrate_begin_undo_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -Integrate_Begin_Undo - reverse the aeib command",
- X"",
- X"SYNOPSIS",
- X" %s -Integrate_Begin_Undo [ <option>... ]",
- X" %s -Integrate_Begin_Undo -List [ <option>... ]",
- X" %s -Integrate_Begin_Undo -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -Integrate_Begin_Undo command is used to",
- X" reverse the actions of the '%s -Integrate_Begin'",
- X" command.",
- X"",
- X" Successful execution of this command will move the change",
- X" from the 'being_integrated' state to the",
- X" 'awaiting_integration' state. The integration directory",
- X" will be deleted. The change will cease to be assigned to",
- X" the current user.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -Change <number>",
- X" This option may be used to specify a particular",
- X" change within a project. When no -Change option is",
- X" specified, the AEGIS_CHANGE environment variable is",
- X" consulted. If that does not exist, the user's",
- X" $HOME/.aegisrc file is examined for a default change",
- X" field (see aeuconf(5) for more information). If",
- X" that does not exist, when the user is only working",
- X" on one change within a project, that is the default",
- X" change number. Otherwise, it is an error.",
- X"",
- X" -Help",
- X" This option may be used to obtain more",
- X" information about how to use the %s program.",
- X"",
- X" -Keep",
- X" This option may be used to retain files and/or",
- X" directories usually deleted by the command.",
- 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 aeibu '%s -ibu \\!* -v'",
- X" sh$ aeibu(){%s -ibu $* -v}",
- X"",
- X"ERRORS",
- X" It is an error if the change is not in the",
- X" 'being_integrated' state.",
- X" It is an error if the change is not assigned to the",
- X" current user.",
- 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), integrate_begin_undo_usage);
- X}
- X
- X
- Xstatic void integrate_begin_undo_list _((void (*)(void)));
- X
- Xstatic void
- Xintegrate_begin_undo_list(usage)
- X void (*usage)_((void));
- X{
- X string_ty *project_name;
- X
- X trace(("integrate_begin_undo_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_changes_in_state_mask
- X (
- X project_name,
- X 1 << cstate_state_being_integrated
- X );
- X if (project_name)
- X str_free(project_name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void integrate_begin_undo_main _((void));
- X
- Xstatic void
- Xintegrate_begin_undo_main()
- X{
- X cstate cstate_data;
- X pstate pstate_data;
- X cstate_history history_data;
- X string_ty *dir;
- X string_ty *project_name;
- X project_ty *pp;
- X long change_number;
- X change_ty *cp;
- X user_ty *up;
- X
- X trace(("integrate_begin_main()\n{\n"/*}*/));
- X project_name = 0;
- X change_number = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(integrate_begin_undo_usage);
- X continue;
- X
- X case arglex_token_change:
- X if (arglex() != arglex_token_number)
- X integrate_begin_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_number:
- X if (change_number)
- X fatal("duplicate -Change option");
- X change_number = arglex_value.alv_number;
- X if (change_number < 1)
- X fatal("change %ld out of range", change_number);
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X integrate_begin_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_string:
- 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
- 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 * locate change data
- X */
- X if (!change_number)
- X change_number = user_default_change(up);
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X
- X /*
- X * lock the change for writing
- X */
- X project_pstate_lock_prepare(pp);
- X change_cstate_lock_prepare(cp);
- X user_ustate_lock_prepare(up);
- X lock_take();
- X cstate_data = change_cstate_get(cp);
- X pstate_data = project_pstate_get(pp);
- X
- X /*
- X * it is an error if the change is not in the 'being_integrated' state.
- X */
- X if (cstate_data->state != cstate_state_being_integrated)
- X change_fatal(cp, "not in 'being_integrated' state");
- X if (!str_equal(change_integrator_name(cp), user_name(up)))
- X {
- X change_fatal
- X (
- X cp,
- X "user \"%S\" is not the integrator",
- X user_name(up)
- X );
- X }
- X
- X /*
- X * Change the state.
- X * Add to the change's history.
- X */
- X cstate_data->state = cstate_state_awaiting_integration;
- X history_data = change_history_new(cp, up);
- X history_data->what = cstate_history_what_integrate_begin_undo;
- X
- X /*
- X * remove it from the user's change list
- X */
- X user_own_remove(up, project_name_get(pp), change_number);
- X
- X /*
- X * Note that the project has no current integration
- X */
- X pstate_data->currently_integrating_change = 0;
- X dir = str_copy(change_integration_directory_get(cp, 1));
- X change_integration_directory_clear(cp);
- X cstate_data->build_time = 0;
- X cstate_data->delta_number = 0;
- X
- X /*
- X * Complain if they are in the integration directory,
- X * because the rmdir at the end can't then run to completion.
- X */
- X os_become_orig();
- X if (os_below_dir(dir, os_curdir()))
- X change_fatal(cp, "please leave the integration directory");
- X os_become_undo();
- X
- X /*
- X * write out the data and release the locks
- X */
- X change_cstate_write(cp);
- X user_ustate_write(up);
- X project_pstate_write(pp);
- X user_become(up);
- X commit_rmdir_tree_errok(dir);
- X user_become_undo();
- X str_free(dir);
- X commit();
- X lock_release();
- X
- X /*
- X * verbose success message
- X */
- X change_verbose(cp, "integrate begin undo");
- X change_free(cp);
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xintegrate_begin_undo()
- X{
- X trace(("integrate_begin_undo()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X integrate_begin_undo_main();
- X break;
- X
- X case arglex_token_help:
- X integrate_begin_undo_help();
- X break;
- X
- X case arglex_token_list:
- X integrate_begin_undo_list(integrate_begin_undo_usage);
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 10341 -ne `wc -c <'aegis/aeibu.c'`; then
- echo shar: \"'aegis/aeibu.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aeibu.c'
- fi
- if test -f 'aegis/aencu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aencu.c'\"
- else
- echo shar: Extracting \"'aegis/aencu.c'\" \(9535 characters\)
- sed "s/^X//" >'aegis/aencu.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 change undo
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <time.h>
- X
- X#include <aeca.h>
- X#include <ael.h>
- X#include <aencu.h>
- X#include <arglex2.h>
- X#include <cattr.h>
- X#include <change.h>
- X#include <col.h>
- X#include <commit.h>
- X#include <common.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
- X
- Xstatic void new_change_undo_usage _((void));
- X
- Xstatic void
- Xnew_change_undo_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf(stderr, "usage: %s -New_Change_Undo [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -New_Change_Undo -List [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -New_Change_Undo -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void new_change_undo_help _((void));
- X
- Xstatic void
- Xnew_change_undo_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -New_Change_Undo - remove a new change from a project",
- X"",
- X"SYNOPSIS",
- X" %s -New_Change_Undo [ <option>... ]",
- X" %s -New_Change_Undo -List [ <option>... ]",
- X" %s -New_Change_Undo -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -New_Change_Undo command is used to remove a",
- X" new change from a project.",
- X"",
- X" It wan't called '%s -Remove_Change' in order to",
- X" emphasize that fact the the change must be in the",
- X" 'awaiting_development' state. In practice it is",
- X" possible, with a combination of commands, to remove any",
- X" change which has not reached the 'completed' state.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -Change <number>",
- X" This option may be used to specify a particular",
- X" change within a project. When no -Change option is",
- X" specified, the AEGIS_CHANGE environment variable is",
- X" consulted. If that does not exist, the user's",
- X" $HOME/.aegisrc file is examined for a default change",
- X" field (see aeuconf(5) for more information). If",
- X" that does not exist, when the user is only working",
- X" on one change within a project, that is the default",
- X" change number. Otherwise, it is an error.",
- 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 aencu '%s -ncu \\!* -v'",
- X" sh$ aencu(){%s -ncu $* -v}",
- X"",
- X"ERRORS",
- X" It is an error if the change is not in the",
- X" 'awaiting_development' state.",
- 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_change_undo_usage);
- X}
- X
- X
- Xstatic void new_change_undo_list _((void));
- X
- Xstatic void
- Xnew_change_undo_list()
- X{
- X string_ty *project_name;
- X
- X trace(("new_change_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_change_undo_usage);
- X continue;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X new_change_undo_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_changes_in_state_mask
- X (
- X project_name,
- X 1 << cstate_state_awaiting_development
- X );
- X if (project_name)
- X str_free(project_name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void new_change_undo_main _((void));
- X
- Xstatic void
- Xnew_change_undo_main()
- X{
- X string_ty *project_name;
- X long change_number;
- X project_ty *pp;
- X user_ty *up;
- X change_ty *cp;
- X cstate cstate_data;
- X pstate pstate_data;
- X
- X trace(("new_change_undo_main()\n{\n"/*}*/));
- X project_name = 0;
- X change_number = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(new_change_undo_usage);
- X continue;
- X
- X case arglex_token_change:
- X if (arglex() != arglex_token_number)
- X new_change_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_number:
- X if (change_number)
- X fatal("duplicate -Change option");
- X change_number = arglex_value.alv_number;
- X if (change_number < 1)
- X fatal("change %ld out of range", change_number);
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X new_change_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_string:
- 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
- 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 * locate change data
- X *
- X * The change number must be given on the command line,
- X * even if there is only one appropriate change.
- X * The is the "least surprizes" principle at work,
- X * even though we could sometimes work this out for ourself.
- X */
- X if (!change_number)
- X change_number = user_default_change(up);
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X
- X /*
- X * Take an advisory write lock on the project state
- X * and the change state.
- X */
- X project_pstate_lock_prepare(pp);
- X change_cstate_lock_prepare(cp);
- X lock_take();
- X cstate_data = change_cstate_get(cp);
- X pstate_data = project_pstate_get(pp);
- X
- X /*
- X * Extract the appropriate row of the change table.
- X * It is an error if the change is not in the
- X * awaiting_development state.
- X */
- X if (cstate_data->state != cstate_state_awaiting_development)
- X change_fatal(cp, "not in 'awaiting_development' state");
- 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 * tell the project to forget this change
- X */
- X project_change_delete(pp, change_number);
- X
- X /*
- X * delete the change state file
- X */
- X project_become(pp);
- X commit_unlink_errok(cp->filename);
- X project_become_undo();
- X
- X /*
- X * Update change table row (and change history table).
- X * Update user table row.
- X * Release advisory write locks.
- X */
- X project_pstate_write(pp);
- X commit();
- X lock_release();
- X
- X /*
- X * verbose success message
- X */
- X change_verbose(cp, "removed");
- X change_free(cp);
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xnew_change_undo()
- X{
- X trace(("new_change_undo()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X new_change_undo_main();
- X break;
- X
- X case arglex_token_help:
- X new_change_undo_help();
- X break;
- X
- X case arglex_token_list:
- X new_change_undo_list();
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 9535 -ne `wc -c <'aegis/aencu.c'`; then
- echo shar: \"'aegis/aencu.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aencu.c'
- fi
- if test -f 'aegis/aermpr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aermpr.c'\"
- else
- echo shar: Extracting \"'aegis/aermpr.c'\" \(8594 characters\)
- sed "s/^X//" >'aegis/aermpr.c' <<'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: functions to implement remove project
- X */
- X
- X#include <stdio.h>
- X
- X#include <ael.h>
- X#include <aermpr.h>
- X#include <arglex2.h>
- X#include <change.h>
- X#include <commit.h>
- X#include <error.h>
- X#include <gonzo.h>
- X#include <help.h>
- X#include <lock.h>
- X#include <option.h>
- X#include <project.h>
- X#include <str.h>
- X#include <trace.h>
- X#include <user.h>
- X
- X
- Xstatic void remove_project_usage _((void));
- X
- Xstatic void
- Xremove_project_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf
- X (
- X stderr,
- X "usage: %s -ReMove_PRoject [ <option>... ]\n",
- X progname
- X );
- X fprintf
- X (
- X stderr,
- X " %s -ReMove_PRoject -List [ <option>... ]\n",
- X progname
- X );
- X fprintf(stderr, " %s -ReMove_PRoject -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void remove_project_help _((void));
- X
- Xstatic void
- Xremove_project_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -ReMove_PRoject - remove project",
- X"",
- X"SYNOPSIS",
- X" %s -ReMove_Project <project-name> [ <option>... ]",
- X" %s -ReMove_Project -List [ <option>... ]",
- X" %s -ReMove_Project -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -ReMove_PRoject command is used to remove a",
- X" project, either entirely, or just from %s' supervision.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -Keep",
- X" This option may be used to retain files and/or",
- X" directories usually deleted by the command.",
- X"",
- X" -LIBrary <abspath>",
- X" This option may be used to specify a directory to be",
- X" searched for global state files and user state",
- X" files. (See aegstate(5) and aeustate(5) for more",
- X" information.) Several library options may be present",
- X" on the command line, and are search in the order",
- X" given. Appended to this explicit search path are",
- X" the directories specified by the AEGIS enviroment",
- X" variable (colon separated), and finally,",
- X" /usr/local/lib/%s is always searched. All paths",
- X" specified, either on the command line or in the",
- X" AEGIS environment variable, must be absolute.",
- 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" -Help",
- X" This option may be used to obtain more information",
- X" about how to use the %s program.",
- 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 aermpr '%s -rmpr \\!* -v'",
- X" sh$ aermpr(){%s -rmpr $* -v}",
- X"",
- X"ERRORS",
- X" It is an error if the project has any changes between the",
- X" being developed and being integrated states, inclusive.",
- X" It is an error if the current user is not an administrator.",
- 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_project_usage);
- X}
- X
- X
- Xstatic void remove_project_list _((void));
- X
- Xstatic void
- Xremove_project_list()
- X{
- X arglex();
- X while (arglex_token != arglex_token_eoln)
- X generic_argument(remove_project_usage);
- X list_projects(0, 0);
- X}
- X
- X
- Xstatic void remove_project_main _((void));
- X
- Xstatic void
- Xremove_project_main()
- X{
- X long nerr;
- X int j;
- X pstate pstate_data;
- X string_ty *project_name;
- X project_ty *pp;
- X change_ty *cp;
- X cstate cstate_data;
- X user_ty *up;
- X int keep;
- X
- X trace(("remove_project_main()\n{\n"/*}*/));
- X keep = 0;
- X project_name = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(remove_project_usage);
- X continue;
- X
- X case arglex_token_keep:
- X if (keep)
- X {
- X error
- X (
- X "duplicate \"%s\" option",
- X arglex_value.alv_string
- X );
- X remove_project_usage();
- X }
- X keep = 1;
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X remove_project_usage();
- X /* fall through... */
- X
- X case arglex_token_string:
- 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
- X /*
- X * locate project data
- X */
- X if (!project_name)
- X fatal("project must be named explicitly");
- 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
- X */
- X project_pstate_lock_prepare(pp);
- X gonzo_gstate_lock_prepare_new();
- X lock_take();
- X pstate_data = project_pstate_get(pp);
- X
- X /*
- X * it is an error if any of the changes are active
- X */
- X nerr = 0;
- X for (j = 0; j < pstate_data->change->length; ++j)
- X {
- X long change_number;
- X
- X change_number = pstate_data->change->list[j];
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X cstate_data = change_cstate_get(cp);
- X if
- X (
- X cstate_data->state >= cstate_state_being_developed
- X &&
- X cstate_data->state <= cstate_state_being_integrated
- X )
- X {
- X change_error(cp, "still active");
- X ++nerr;
- X }
- X change_free(cp);
- X }
- X
- X /*
- X * it is an error if the current user is not an administrator
- X */
- X if (!project_administrator_query(pp, user_name(up)))
- X {
- X project_error
- X (
- X pp,
- X "user \"%S\" is not an administrator",
- X user_name(up)
- X );
- X nerr++;
- X }
- X if (nerr)
- X quit(1);
- X
- X /*
- X * remove the project directory
- X */
- X if (!keep)
- X {
- X project_verbose(pp, "remove project directory");
- X project_become(pp);
- X commit_rmdir_tree_errok(project_home_path_get(pp));
- X project_become_undo();
- X }
- X
- X /*
- X * tell gonzo to forget about this project
- X */
- X gonzo_project_delete(pp);
- X gonzo_gstate_write();
- X
- X /*
- X * release the locks
- X */
- X commit();
- X lock_release();
- X
- X /*
- X * verbose success message
- X */
- X project_verbose(pp, "removed");
- X
- X /*
- X * clean up and go home
- X */
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xremove_project()
- X{
- X trace(("remove_project()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X remove_project_main();
- X break;
- X
- X case arglex_token_help:
- X remove_project_help();
- X break;
- X
- X case arglex_token_list:
- X remove_project_list();
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 8594 -ne `wc -c <'aegis/aermpr.c'`; then
- echo shar: \"'aegis/aermpr.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aermpr.c'
- fi
- if test -f 'aegis/aerp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aerp.c'\"
- else
- echo shar: Extracting \"'aegis/aerp.c'\" \(9365 characters\)
- sed "s/^X//" >'aegis/aerp.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 review pass
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include <ael.h>
- X#include <aerp.h>
- X#include <arglex2.h>
- X#include <change.h>
- X#include <commit.h>
- X#include <dir.h>
- X#include <error.h>
- X#include <file.h>
- X#include <help.h>
- X#include <lock.h>
- X#include <mem.h>
- X#include <option.h>
- X#include <os.h>
- X#include <project.h>
- X#include <sub.h>
- X#include <trace.h>
- X#include <undo.h>
- X#include <user.h>
- X
- X
- Xstatic void review_pass_usage _((void));
- X
- Xstatic void
- Xreview_pass_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf(stderr, "usage: %s -Review_PASS <change_number> [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Review_PASS -List [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Review_PASS -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void review_pass_help _((void));
- X
- Xstatic void
- Xreview_pass_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -Review_PASS - pass a change review",
- X"",
- X"SYNOPSIS",
- X" %s -Review_PASS [ <option>... ]",
- X" %s -Review_PASS -List [ <option>... ]",
- X" %s -Review_PASS -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -Review_PASS command is used to notify",
- X" %s that a change has passed review.",
- X"",
- X" The change will be advenced from the 'being_reviewed'",
- X" state to the 'awaitiong_integration' state.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -Change <number>",
- X" This option may be used to specify a particular",
- X" change within a project. When no -Change option is",
- X" specified, the AEGIS_CHANGE environment variable is",
- X" consulted. If that does not exist, the user's",
- X" $HOME/.aegisrc file is examined for a default change",
- X" field (see aeuconf(5) for more information). If",
- X" that does not exist, when the user is only working",
- X" on one change within a project, that is the default",
- X" change number. Otherwise, it is an error.",
- 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 aerp '%s -rp \\!* -v'",
- X" sh$ aerp(){%s -rp $* -v}",
- X"",
- X"ERRORS",
- X" It is an error if the change is not in the",
- X" 'being_reviewed' state.",
- X" It is an error if the current user is not a reviewer of",
- X" the project.",
- X" Its is an error if the current user developed the change",
- X" and the project is configured to disallow developers to",
- X" review their own changes (default).",
- 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), review_pass_usage);
- X}
- X
- X
- Xstatic void review_pass_list _((void (*usage)(void)));
- X
- Xstatic void
- Xreview_pass_list(usage)
- X void (*usage)_((void));
- X{
- X string_ty *project_name;
- X
- X trace(("review_pass_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 /* fall through... */
- X
- X case arglex_token_string:
- 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_changes_in_state_mask
- X (
- X project_name,
- X 1 << cstate_state_being_reviewed
- X );
- X if (project_name)
- X str_free(project_name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void review_pass_main _((void));
- X
- Xstatic void
- Xreview_pass_main()
- X{
- X cstate cstate_data;
- X pstate pstate_data;
- X cstate_history history_data;
- X string_ty *project_name;
- X project_ty *pp;
- X long change_number;
- X change_ty *cp;
- X user_ty *up;
- X
- X trace(("review_pass_main()\n{\n"/*}*/));
- X project_name = 0;
- X change_number = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(review_pass_usage);
- X continue;
- X
- X case arglex_token_change:
- X if (arglex() != arglex_token_number)
- X review_pass_usage();
- X /* fall through... */
- X
- X case arglex_token_number:
- X if (change_number)
- X fatal("duplicate -Change option");
- X change_number = arglex_value.alv_number;
- X if (change_number < 1)
- X fatal("change %ld out of range", change_number);
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X review_pass_usage();
- X /* fall through... */
- X
- X case arglex_token_string:
- 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
- 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 * locate change data
- X */
- X if (!change_number)
- X change_number = user_default_change(up);
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X
- X /*
- X * lock the change for writing
- X */
- X change_cstate_lock_prepare(cp);
- X lock_take();
- X cstate_data = change_cstate_get(cp);
- X pstate_data = project_pstate_get(pp);
- X
- X /*
- X * it is an error if the change is not in the 'being_reviewed' state.
- X */
- X if (cstate_data->state != cstate_state_being_reviewed)
- X change_fatal(cp, "not in 'being_reviewed' state");
- X if (!project_reviewer_query(pp, user_name(up)))
- X {
- X project_fatal
- X (
- X pp,
- X "user \"%S\" is not a reviewer",
- X user_name(up)
- X );
- X }
- X if
- X (
- X !pstate_data->developer_may_review
- X &&
- X str_equal(change_developer_name(cp), user_name(up))
- X )
- X change_fatal(cp, "developer may not review");
- X
- X /*
- X * change the state
- X * remember who reviewed it
- X * add to the change's history
- X */
- X cstate_data->state = cstate_state_awaiting_integration;
- X history_data = change_history_new(cp, up);
- X history_data->what = cstate_history_what_review_pass;
- X
- X /*
- X * write out the data and release the locks
- X */
- X change_cstate_write(cp);
- X commit();
- X lock_release();
- X
- X /*
- X * run the notify command
- X */
- X change_run_review_pass_notify_command(cp);
- X
- X /*
- X * verbose success message
- X */
- X change_verbose(cp, "passed review");
- X change_free(cp);
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xreview_pass()
- X{
- X trace(("review_pass()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X review_pass_main();
- X break;
- X
- X case arglex_token_help:
- X review_pass_help();
- X break;
- X
- X case arglex_token_list:
- X review_pass_list(review_pass_usage);
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 9365 -ne `wc -c <'aegis/aerp.c'`; then
- echo shar: \"'aegis/aerp.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aerp.c'
- fi
- if test -f 'aegis/aerpu.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/aerpu.c'\"
- else
- echo shar: Extracting \"'aegis/aerpu.c'\" \(9352 characters\)
- sed "s/^X//" >'aegis/aerpu.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 review pass undo
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include <ael.h>
- X#include <aerpu.h>
- X#include <arglex2.h>
- X#include <change.h>
- X#include <commit.h>
- X#include <dir.h>
- X#include <error.h>
- X#include <file.h>
- X#include <help.h>
- X#include <lock.h>
- X#include <mem.h>
- X#include <option.h>
- X#include <os.h>
- X#include <project.h>
- X#include <sub.h>
- X#include <trace.h>
- X#include <undo.h>
- X#include <user.h>
- X
- X
- Xstatic void review_pass_undo_usage _((void));
- X
- Xstatic void
- Xreview_pass_undo_usage()
- X{
- X char *progname;
- X
- X progname = option_progname_get();
- X fprintf(stderr, "usage: %s -Review_Pass_Undo <change_number> [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Review_Pass_Undo -List [ <option>... ]\n", progname);
- X fprintf(stderr, " %s -Review_Pass_Undo -Help\n", progname);
- X quit(1);
- X}
- X
- X
- Xstatic void review_pass_undo_help _((void));
- X
- Xstatic void
- Xreview_pass_undo_help()
- X{
- X static char *text[] =
- X {
- X"NAME",
- X" %s -Review_Pass_Undo - rescind a change review pass",
- X"",
- X"SYNOPSIS",
- X" %s -Review_Pass_Undo [ <option>... ]",
- X" %s -Review_Pass_Undo -List [ <option>... ]",
- X" %s -Review_Pass_Undo -Help",
- X"",
- X"DESCRIPTION",
- X" The %s -Review_Pass_Undo command is used to notify %s",
- X" that a change review pass has been rescinded.",
- X"",
- X" The change will be moved from the 'awaiting_integration'",
- X" state to the 'being_reviewed' state.",
- X"",
- X"OPTIONS",
- X" The following options are understood:",
- X"",
- X" -Change <number>",
- X" This option may be used to specify a particular",
- X" change within a project. When no -Change option is",
- X" specified, the AEGIS_CHANGE environment variable is",
- X" consulted. If that does not exist, the user's",
- X" $HOME/.aegisrc file is examined for a default change",
- X" field (see aeuconf(5) for more information). If",
- X" that does not exist, when the user is only working",
- X" on one change within a project, that is the default",
- X" change number. Otherwise, it is an error.",
- 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 aerpu '%s -rp \\!* -v'",
- X" sh$ aerpu(){%s -rp $* -v}",
- X"",
- X"ERRORS",
- X" It is an error if the change is not in the",
- X" 'awaiting_integration' state.",
- X" It is an error if the current user is not the reviewer of",
- X" the change.",
- 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"NAME",
- X"",
- X"COPYRIGHT",
- X" %C",
- X"",
- X"AUTHOR",
- X" %A",
- X };
- X
- X help(text, SIZEOF(text), review_pass_undo_usage);
- X}
- X
- X
- Xstatic void review_pass_undo_list _((void (*usage)(void)));
- X
- Xstatic void
- Xreview_pass_undo_list(usage)
- X void (*usage)_((void));
- X{
- X string_ty *project_name;
- X
- X trace(("review_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 /* fall through... */
- X
- X case arglex_token_string:
- 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_changes_in_state_mask
- X (
- X project_name,
- X 1 << cstate_state_awaiting_integration
- X );
- X if (project_name)
- X str_free(project_name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void review_pass_undo_main _((void));
- X
- Xstatic void
- Xreview_pass_undo_main()
- X{
- X cstate cstate_data;
- X pstate pstate_data;
- X cstate_history history_data;
- X string_ty *project_name;
- X project_ty *pp;
- X long change_number;
- X change_ty *cp;
- X user_ty *up;
- X
- X trace(("review_pass_undo_main()\n{\n"/*}*/));
- X project_name = 0;
- X change_number = 0;
- X while (arglex_token != arglex_token_eoln)
- X {
- X switch (arglex_token)
- X {
- X default:
- X generic_argument(review_pass_undo_usage);
- X continue;
- X
- X case arglex_token_change:
- X if (arglex() != arglex_token_number)
- X review_pass_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_number:
- X if (change_number)
- X fatal("duplicate -Change option");
- X change_number = arglex_value.alv_number;
- X if (change_number < 1)
- X fatal("change %ld out of range", change_number);
- X break;
- X
- X case arglex_token_project:
- X if (arglex() != arglex_token_string)
- X review_pass_undo_usage();
- X /* fall through... */
- X
- X case arglex_token_string:
- 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
- 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 * locate change data
- X */
- X if (!change_number)
- X change_number = user_default_change(up);
- X cp = change_alloc(pp, change_number);
- X change_bind_existing(cp);
- X
- X /*
- X * lock the change for writing
- X */
- X change_cstate_lock_prepare(cp);
- X lock_take();
- X cstate_data = change_cstate_get(cp);
- X pstate_data = project_pstate_get(pp);
- X
- X /*
- X * it is an error if the change is not in the 'being_reviewed' state.
- X * it is an error if the current user is not the original reviewer
- X */
- X if (cstate_data->state != cstate_state_awaiting_integration)
- X change_fatal(cp, "not in 'awaiting_integration' state");
- X if (!str_equal(change_reviewer_name(cp), user_name(up)))
- X {
- X change_fatal
- X (
- X cp,
- X "user \"%S\" is not the reviewer",
- X user_name(up)
- X );
- X }
- X
- X /*
- X * change the state
- X * add to the change's history
- X */
- X cstate_data->state = cstate_state_being_reviewed;
- X history_data = change_history_new(cp, up);
- X history_data->what = cstate_history_what_review_pass_undo;
- X
- X /*
- X * write out the data and release the locks
- X */
- X change_cstate_write(cp);
- X commit();
- X lock_release();
- X
- X /*
- X * run the notify command
- X */
- X change_run_review_pass_undo_notify_command(cp);
- X
- X /*
- X * verbose success message
- X */
- X change_verbose(cp, "review pass rescinded");
- X change_free(cp);
- X project_free(pp);
- X user_free(up);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xvoid
- Xreview_pass_undo()
- X{
- X trace(("review_pass_undo()\n{\n"/*}*/));
- X switch (arglex())
- X {
- X default:
- X review_pass_undo_main();
- X break;
- X
- X case arglex_token_help:
- X review_pass_undo_help();
- X break;
- X
- X case arglex_token_list:
- X review_pass_undo_list(review_pass_undo_usage);
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 9352 -ne `wc -c <'aegis/aerpu.c'`; then
- echo shar: \"'aegis/aerpu.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/aerpu.c'
- fi
- if test -f 'aegis/commit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aegis/commit.c'\"
- else
- echo shar: Extracting \"'aegis/commit.c'\" \(9183 characters\)
- sed "s/^X//" >'aegis/commit.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 store and enact file manipulations for commit
- X */
- X
- X#include <commit.h>
- X#include <dir.h>
- X#include <mem.h>
- X#include <os.h>
- X#include <trace.h>
- X#include <undo.h>
- X
- X/*
- X * This file contains "commit" functions.
- X *
- X * The idea is that aegis can be interrupted, or fail from errors,
- X * and behave as if "nothing" had happened.
- X * That is, no user discernable difference to their environment,
- X * and certainly no changes to aegis' data base.
- X *
- X * To do this, many database functions write updates to temporary files
- X * "near" where they are to go, eventually. A commit and an abort function
- X * are both issued, one to put the new file where it really goes, and one
- X * to remove it. Exactly one option will be exercised.
- X *
- X * Commit actions will be performed with the user-id set the same as was
- X * set at the time the commit call was issued.
- X */
- X
- Xenum what_ty
- X{
- X what_rename,
- X what_unlink_errok,
- X what_rmdir_errok,
- X what_rmdir_tree_errok
- X};
- Xtypedef enum what_ty what_ty;
- X
- Xtypedef struct action_ty action_ty;
- Xstruct action_ty
- X{
- X what_ty what;
- X string_ty *path1;
- X string_ty *path2;
- X action_ty *next;
- X int uid;
- X int gid;
- X int umask;
- X};
- X
- Xstatic action_ty *head1;
- Xstatic action_ty *tail1;
- Xstatic action_ty *head2;
- X
- X
- X/*
- X * NAME
- X * link1
- X *
- X * SYNOPSIS
- X * void link1(what_ty action, string_ty *path1, string_ty *path2);
- X *
- X * DESCRIPTION
- X * The link1 function is used to
- X * add an new item to the head of chain1.
- X *
- X * ARGUMENTS
- X * action - what to do
- X * path1 - mandatory argument
- X * path2 - optional argument (NULL if not used)
- X */
- X
- Xstatic void link1 _((what_ty, string_ty *, string_ty *));
- X
- Xstatic void
- Xlink1(what, path1, path2)
- X what_ty what;
- X string_ty *path1;
- X string_ty *path2;
- X{
- X action_ty *new;
- X
- X trace(("commit::link1(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
- X new = (action_ty *)mem_alloc(sizeof(action_ty));
- X new->what = what;
- X os_become_query(&new->uid, &new->gid, &new->umask);
- X new->path1 = str_copy(path1);
- X if (path2)
- X new->path2 = str_copy(path2);
- X else
- X new->path2 = 0;
- X new->next = 0;
- X if (head1)
- X {
- X tail1->next = new;
- X tail1 = new;
- X }
- X else
- X head1 = tail1 = new;
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * link2
- X *
- X * SYNOPSIS
- X * void link2(what_ty action, string_ty *path1, string_ty *path2);
- X *
- X * DESCRIPTION
- X * The link2 function is used to
- X * add an new item to the head of chain2
- X *
- X * ARGUMENTS
- X * action - what to do
- X * path1 - mandatory argument
- X * path2 - optional argument (NULL if not used)
- X */
- X
- Xstatic void link2 _((what_ty, string_ty *, string_ty *));
- X
- Xstatic void
- Xlink2(what, path1, path2)
- X what_ty what;
- X string_ty *path1;
- X string_ty *path2;
- X{
- X action_ty *new;
- X
- X trace(("commit::link2(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
- X new = (action_ty *)mem_alloc(sizeof(action_ty));
- X new->what = what;
- X os_become_query(&new->uid, &new->gid, &new->umask);
- X new->path1 = str_copy(path1);
- X if (path2)
- X new->path2 = str_copy(path2);
- X else
- X new->path2 = 0;
- X new->next = head2;
- X head2 = new;
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * commit_rename
- X *
- X * SYNOPSIS
- X * void commit_rename(void);
- X *
- X * DESCRIPTION
- X * The commit_rename function is used to
- X * submit a commit request to rename a file.
- X *
- X * ARGUMENTS
- X * from - path of file now
- X * to - path of file after commit
- X */
- X
- Xvoid
- Xcommit_rename(from, to)
- X string_ty *from;
- X string_ty *to;
- X{
- X trace(("commit_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
- X trace_string(from->str_text);
- X trace_string(to->str_text);
- X link1(what_rename, from, to);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * commit_unlink_errok
- X *
- X * SYNOPSIS
- X * void commit_unlink_errok(void);
- X *
- X * DESCRIPTION
- X * The commit_unlink_errok function is used to
- X * unlink a file on commit.
- X * It will not be an error if the file does not exist.
- X *
- X * ARGUMENTS
- X * path - path of file to be unlinked
- X */
- X
- Xvoid
- Xcommit_unlink_errok(path)
- X string_ty *path;
- X{
- X trace(("commit_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
- X trace_string(path->str_text);
- X link2(what_unlink_errok, path, (string_ty *)0);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * commit_rmdir_errok
- X *
- X * SYNOPSIS
- X * void commit_rmdir_errok(string_ty *path);
- X *
- X * DESCRIPTION
- X * The commit_rmdir_errok function is used to
- X * delete an empty directory on commit.
- X * It will not be an error if the directory does not exist.
- X * It will not be an error if the directory is not empty.
- X *
- X * ARGUMENTS
- X * path - path of directory to be deleted
- X */
- X
- Xvoid
- Xcommit_rmdir_errok(path)
- X string_ty *path;
- X{
- X trace(("commit_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
- X trace_string(path->str_text);
- X link2(what_rmdir_errok, path, (string_ty *)0);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * commit_rmdir_tree_errok
- X *
- X * SYNOPSIS
- X * void commit_rmdir_tree_errok(string_ty *path);
- X *
- X * DESCRIPTION
- X * The commit_rmdir_tree_errok function is used to
- X * delete a directory tree on commit.
- X * It will not be an error if the directory does not exist.
- X * It will not be an error if the directory, or any subtree, is not empty.
- X *
- X * ARGUMENTS
- X * path - path of directory to be deleted
- X */
- X
- Xvoid
- Xcommit_rmdir_tree_errok(path)
- X string_ty *path;
- X{
- X trace(("commit_rmdir_tree_errok(path = %08lX)\n{\n"/*}*/, path));
- X trace_string(path->str_text);
- X link2(what_rmdir_tree_errok, path, (string_ty *)0);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * rmdir_tree_callback
- X *
- X * SYNOPSIS
- X * void rmdir_tree_callback(void * arg, dir_walk_message_ty message,
- X * string_ty *path, struct stat *st);
- X *
- X * DESCRIPTION
- X * The rmdir_tree_callback function is used to
- X * perform an action while walking a directory tree's structure.
- X *
- X * This function is the one that actually deletes things out of the
- X * directory tree as it is walked.
- X * Note that the directory should be deleted last,
- X * after all contents have been nuked.
- X *
- X * Some sleight-of-hand is involved here,
- X * as this function pushes extra stuff onto the lists of
- X * things to be deleted, rather than really doing it itself.
- X *
- X * ARGUMENTS
- X * arg - argument given to dir_walk for us
- X * message - what sort of file system entity we are looking at
- X * path - the absolute path of the file system entity
- X * st - pointer to stat structure describing file system entity
- X */
- X
- Xstatic void rmdir_tree_callback _((void *, dir_walk_message_ty,
- X string_ty *path, struct stat *));
- X
- Xstatic void
- Xrmdir_tree_callback(arg, message, path, stat)
- X void *arg;
- X dir_walk_message_ty message;
- X string_ty *path;
- X struct stat *stat;
- X{
- X trace(("rmdir_tree_callback(message = %d, path = %08lX, \
- Xstat = %08lX)\n{\n"/*}*/, message, path, stat));
- X trace_string(path->str_text);
- X switch (message)
- X {
- X case dir_walk_dir_before:
- X commit_rmdir_errok(path);
- X os_chmod_errok(path, 0750);
- X break;
- X
- X case dir_walk_dir_after:
- X break;
- X
- X case dir_walk_file:
- X case dir_walk_special:
- X case dir_walk_symlink:
- X commit_unlink_errok(path);
- X break;
- X }
- X trace((/*{*/"}\n"));
- X}
- X
- X
- X/*
- X * NAME
- X * commit
- X *
- X * SYNOPSIS
- X * void commit(void);
- X *
- X * DESCRIPTION
- X * The commit function is used to
- X * perform all the actions queued using the commit_* functions.
- X *
- X * After it has completed successfully, further calls to commit()
- X * will be NOPs, until new commit_* functions are used.
- X *
- X * When the commit has succeeded, the undo list is cancelled,
- X * since there is now no reason to undo anything.
- X */
- X
- Xvoid
- Xcommit()
- X{
- X trace(("commit()\n{\n"/*}*/));
- X while (head1 || head2)
- X {
- X action_ty *action;
- X
- X /*
- X * Take the first item off the list.
- X * Note that actions may append more items to the list.
- X */
- X if (head1)
- X {
- X action = head1;
- X head1 = action->next;
- X if (!head1)
- X tail1 = 0;
- X }
- X else
- X {
- X action = head2;
- X head2 = action->next;
- X }
- X
- X /*
- X * Do the action.
- X */
- X os_become(action->uid, action->gid, action->umask);
- X switch (action->what)
- X {
- X case what_rename:
- X os_rename(action->path1, action->path2);
- X undo_rename(action->path2, action->path1);
- X break;
- X
- X case what_unlink_errok:
- X os_unlink_errok(action->path1);
- X break;
- X
- X case what_rmdir_errok:
- X os_rmdir_errok(action->path1);
- X break;
- X
- X case what_rmdir_tree_errok:
- X dir_walk(action->path1, rmdir_tree_callback, 0);
- X break;
- X }
- X os_become_undo();
- X
- X /*
- X * Free the list element.
- X */
- X str_free(action->path1);
- X if (action->path2)
- X str_free(action->path2);
- X mem_free((char *)action);
- X }
- X
- X /*
- X * it's all committed, nothing left to undo.
- X */
- X undo_cancel();
- X trace((/*{*/"}\n"));
- X}
- END_OF_FILE
- if test 9183 -ne `wc -c <'aegis/commit.c'`; then
- echo shar: \"'aegis/commit.c'\" unpacked with wrong size!
- fi
- # end of 'aegis/commit.c'
- fi
- if test -f 'aux/Makefile.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'aux/Makefile.sh'\"
- else
- echo shar: Extracting \"'aux/Makefile.sh'\" \(8640 characters\)
- sed "s/^X//" >'aux/Makefile.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: shell script to generate the Mafile file
- X#
- Xfmtgen_files=
- Xaegis_files=
- Xtest_files=
- Xclean_files="core bin/fmtgen"
- Xecho "#"
- Xecho "# You may need to change this for your system."
- Xecho "# The \`\`h'' directory supplements your system, not replacing it."
- Xecho "# The first variation is for gcc when it isn't the native complier,"
- Xecho "# the second variation is for systems with missing ANSI C include files,"
- Xecho "# the third variation is for conforming ANSI C implementations."
- Xecho "#"
- Xecho "# H = -I/usr/local/lib/gcc-include -I/usr/include -Ih"
- Xecho "# H = -I/usr/include -Ih"
- Xecho "H ="
- Xecho "# H = # SunOS"
- Xecho "# H = # ConvexOS"
- Xecho "# H = # dgux"
- Xecho "# H = # dcosx (pyramid)"
- Xecho "# H = # ULTRIX"
- Xecho "# H = # hpux"
- Xecho "# H = # SCO"
- Xecho "# H = # IRIX"
- Xecho
- Xecho "#"
- Xecho "# the name of the compiler to use"
- Xecho "#"
- Xecho "CC = cc"
- Xecho "# CC = gcc"
- Xecho "# CC = cc # SunOS"
- Xecho "# CC = cc # ConvexOS"
- Xecho "# CC = cc # dgux"
- Xecho "# CC = /usr/ucb/cc # dcosx (pyramid)"
- Xecho "# CC = cc # ULTRIX"
- Xecho "# CC = cc # hpux"
- Xecho "# CC = rcc # SCO"
- Xecho "# CC = cc # IRIX"
- Xecho
- Xecho "#"
- Xecho "# The compiler flags to use, except for include path."
- Xecho "#"
- Xecho "CFLAGS = -O"
- Xecho "# CFLAGS = -g"
- Xecho "# CFLAGS = -O # SunOS"
- Xecho "# CFLAGS = -O # ConvexOS"
- Xecho "# CFLAGS = -O # dgux"
- Xecho "# CFLAGS = -O -Wall -ansi # gcc"
- Xecho "# CFLAGS = -O -Xt -U__STDC__ # dcosx (pyramid /usr/ucb/cc is brain-dead)"
- Xecho "# CFLAGS = -O # ULTRIX"
- Xecho "# CFLAGS = -O # hpux"
- Xecho "# CFLAGS = -O # SCO"
- Xecho "# CFLAGS = -O # IRIX"
- Xecho
- Xecho "#"
- Xecho "# which yacc to use"
- Xecho "#"
- Xecho "YACC = yacc"
- Xecho "# YACC = byacc # Berkeley"
- Xecho "# YACC = bison -y # GNU"
- Xecho ""
- Xecho "#"
- Xecho "# where to put the library directory"
- Xecho "# (not used in testing mode)"
- Xecho "#"
- Xecho "LIB = /usr/local/lib/aegis"
- Xecho ""
- Xecho "#"
- Xecho "# where to put the executables"
- Xecho "#"
- Xecho "BIN = /usr/local/bin"
- Xecho ""
- Xecho "#"
- Xecho "# where to put the manual entries"
- Xecho "#"
- Xecho "MAN = /usr/local/man"
- Xecho ""
- Xecho "#"
- Xecho "# extra libraries required for your system"
- Xecho "#"
- Xecho "LIBRARIES ="
- Xecho "# LIBRARIES = -lbsd"
- Xecho "# LIBRARIES = # SunOS"
- Xecho "# LIBRARIES = # ConvexOS"
- Xecho "# LIBRARIES = # dgux"
- Xecho "# LIBRARIES = -lucb # dcosx (pyramid)"
- Xecho "# LIBRARIES = # ULTRIX"
- Xecho "# LIBRARIES = # hpux"
- Xecho "# LIBRARIES = -lsocket # SCO"
- Xecho "# LIBRARIES = # IRIX"
- Xecho ""
- Xecho "#"
- Xecho "# shell to use to run the tests"
- Xecho "# make sure there are no spaces after the definition,"
- Xecho "# many flavours of make(1) can't cope with them."
- Xecho "#"
- Xecho "SHELL = /bin/sh"
- Xecho "# SHELL = /bin/sh # SunOS"
- Xecho "# SHELL = /bin/sh # ConvexOS"
- Xecho "# SHELL = /bin/sh # dgux"
- Xecho "# SHELL = /bin/sh # dcosx (pyramid)"
- Xecho "# SHELL = /bin/sh5 # ULTRIX"
- Xecho "# SHELL = /bin/ksh # apollo"
- Xecho "# SHELL = /bin/sh # hpux"
- Xecho "# SHELL = /bin/sh # SCO"
- Xecho "# SHELL = /bin/sh # IRIX"
- Xecho ""
- Xecho "# You should not need to alter anything below this point."
- Xecho "#------------------------------------------------------------"
- Xecho ""
- Xecho "all: bin/aegis"
- Xecho
- Xrm -f common/conf.h
- Xcp /dev/null common/conf.h
- Xfor file in $*
- Xdo
- X case $file in
- X
- X fmtgen/*.y)
- X root=`basename $file .y`
- X dep=`c_incl -Ifmtgen -Icommon -ns -nc $file`
- X echo
- X echo "fmtgen/${root}.gen.c fmtgen/${root}.gen.h: $file"
- X echo " $(YACC) -d $file"
- X echo " sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > fmtgen/${root}.gen.c"
- X echo " rm y.tab.c"
- X echo " sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > fmtgen/${root}.gen.h"
- X echo " rm y.tab.h"
- X clean_files="$clean_files fmtgen/${root}.gen.c fmtgen/${root}.gen.h"
- X echo
- X echo "fmtgen/${root}.gen.o: fmtgen/${root}.gen.c" $dep
- X echo " $(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/${root}.gen.c"
- X echo " mv ${root}.gen.o fmtgen/${root}.gen.o"
- X fmtgen_files="$fmtgen_files fmtgen/${root}.gen.o"
- X clean_files="$clean_files fmtgen/${root}.gen.o"
- X ;;
- X
- X fmtgen/*.c)
- X root=`basename $file .c`
- X dep=`c_incl -Ifmtgen -Icommon -ns -nc $file`
- X echo
- X echo "fmtgen/${root}.o: $file" $dep
- X echo " $(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/${root}.c"
- X echo " mv ${root}.o fmtgen/${root}.o"
- X fmtgen_files="$fmtgen_files fmtgen/${root}.o"
- X clean_files="$clean_files fmtgen/${root}.o"
- X ;;
- X
- X aegis/*.def)
- X root=`basename $file .def`
- X dep=`c_incl -Iaegis -ns -nc $file`
- X echo
- X echo "aegis/${root}.c aegis/${root}.h: $file bin/fmtgen" $dep
- X echo " bin/fmtgen -Iaegis $file aegis/${root}.c aegis/${root}.h"
- X clean_files="$clean_files aegis/${root}.c aegis/${root}.h"
- X echo
- X dep=`c_incl -Iaegis -Icommon -ns -nc aegis/${root}.c`
- X echo "aegis/${root}.o: aegis/${root}.c" $dep
- X echo " $(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/${root}.c"
- X echo " mv ${root}.o aegis/${root}.o"
- X aegis_files="$aegis_files aegis/${root}.o"
- X clean_files="$clean_files aegis/${root}.o"
- X ;;
- X
- X aegis/*.y)
- X root=`basename $file .y`
- X dep=`c_incl -Iaegis -Icommon -ns -nc $file`
- X echo
- X echo "aegis/${root}.gen.c aegis/${root}.gen.h: $file"
- X echo " $(YACC) -d $file"
- X echo " sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > aegis/${root}.gen.c"
- X echo " rm y.tab.c"
- X echo " sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > aegis/${root}.gen.h"
- X echo " rm y.tab.h"
- X clean_files="$clean_files aegis/${root}.gen.c aegis/${root}.gen.h"
- X echo
- X echo "aegis/${root}.gen.o: aegis/${root}.gen.c" $dep
- X echo " $(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/${root}.gen.c"
- X echo " mv ${root}.gen.o aegis/${root}.gen.o"
- X aegis_files="$aegis_files aegis/${root}.gen.o"
- X clean_files="$clean_files aegis/${root}.gen.o"
- X ;;
- X
- X aegis/*.c)
- X root=`basename $file .c`
- X dep=`c_incl -Iaegis -Icommon -ns -nc $file`
- X echo
- X echo "aegis/${root}.o: $file" $dep
- X oflg=
- X if [ $root = gonzo ]
- X then
- X oflg="-D'LIB=\"$(LIB)\"'"
- X fi
- X echo " $(CC) $(CFLAGS) $oflg -Iaegis -Icommon $(H) -c $file"
- X echo " mv ${root}.o aegis/${root}.o"
- X aegis_files="$aegis_files aegis/${root}.o"
- X clean_files="$clean_files aegis/${root}.o"
- X ;;
- X
- X common/*.c)
- X root=`basename $file .c`
- X dep=`c_incl -Icommon -ns -nc $file`
- X echo
- X echo "common/${root}.o: $file" $dep
- X echo " $(CC) $(CFLAGS) -Icommon $(H) -c $file"
- X echo " mv ${root}.o common/${root}.o"
- X aegis_files="$aegis_files common/${root}.o"
- X fmtgen_files="$fmtgen_files common/${root}.o"
- X clean_files="$clean_files common/${root}.o"
- X ;;
- X
- X test/*/*)
- X root=`basename $file .sh`
- X echo ""
- X echo "${root}: all $file"
- X echo " $(SHELL) $file"
- X test_files="$test_files $root"
- X ;;
- X
- X *)
- X ;;
- X esac
- Xdone
- X
- X#
- X# clean up the area
- X#
- Xecho ''
- Xecho 'clean:'
- Xecho ' rm -f' $clean_files
- Xecho ''
- Xecho 'realclean: clean'
- Xecho ' rm -f bin/aegis'
- Xecho ''
- Xecho 'clobber: realclean'
- Xecho ' rm -f common/conf.h'
- X
- X#
- X# default the conf.h file
- X# if they have forgotten to set it
- X#
- Xecho ''
- Xecho 'common/conf.h:'
- Xecho ' echo "#include <../conf/`uname -s`-`uname -r`>" > common/conf.h'
- X
- Xecho
- Xecho "FmtgenFiles = $fmtgen_files"
- Xecho
- Xecho "bin/fmtgen: $(FmtgenFiles)"
- Xecho " if test ! -d bin; then mkdir bin; fi; exit 0"
- Xecho " $(CC) -o bin/fmtgen $(FmtgenFiles) $(LIBRARIES)"
- X
- Xecho
- Xecho "AegisFiles = $aegis_files"
- Xecho
- Xecho "bin/aegis: $(AegisFiles)"
- Xecho " if test ! -d bin; then mkdir bin; fi; exit 0"
- Xecho " $(CC) -o bin/aegis $(AegisFiles) $(LIBRARIES)"
- X
- Xecho
- Xecho "sure:" $test_files
- Xecho " @echo Passed All Tests"
- X
- Xecho
- Xecho "install: all"
- Xecho " cp bin/aegis $(BIN)"
- Xecho " chown root $(BIN)/aegis"
- Xecho " chmod a+x,u+s $(BIN)/aegis"
- Xecho " -mkdir $(LIB)"
- Xecho " chmod 0755 $(LIB)"
- Xecho " cp lib/* $(LIB)"
- Xecho " chmod a+r $(LIB)/*"
- Xecho " chmod a+x $(LIB)/*.sh"
- Xecho " chown bin $(LIB)"
- Xecho " chgrp bin $(LIB)"
- Xecho " $(SHELL) man1/install.sh $(MAN)/man1"
- Xecho " $(SHELL) man5/install.sh $(MAN)/man5"
- X
- Xrm common/conf.h
- Xexit 0
- END_OF_FILE
- if test 8640 -ne `wc -c <'aux/Makefile.sh'`; then
- echo shar: \"'aux/Makefile.sh'\" unpacked with wrong size!
- fi
- # end of 'aux/Makefile.sh'
- fi
- if test -f 'common/arglex.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'common/arglex.c'\"
- else
- echo shar: Extracting \"'common/arglex.c'\" \(10257 characters\)
- sed "s/^X//" >'common/arglex.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: lexical analysis of command line arguments
- X */
- X
- X#include <stddef.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X#include <arglex.h>
- X#include <error.h>
- X#include <option.h>
- X#include <str.h>
- X#include <trace.h>
- X
- Xstatic arglex_table_ty table[] =
- X{
- X { "-", arglex_token_stdio, },
- X { "-Help", arglex_token_help, },
- X { "-VERSion", arglex_token_version, },
- X { "-TRace", arglex_token_trace, },
- X};
- X
- Xstatic int argc;
- Xstatic char **argv;
- X arglex_value_ty arglex_value;
- X arglex_token_ty arglex_token;
- Xstatic arglex_table_ty *utable;
- Xstatic char *partial;
- X
- X
- X/*
- X * NAME
- X * arglex_init
- X *
- X * SYNOPSIS
- X * void arglex_init(int ac, char **av, arglex_table-t *tp);
- X *
- X * DESCRIPTION
- X * The arglex_init function is used to initialize the
- X * command line processing.
- X *
- X * ARGUMENTS
- X * ac - aergument count, from main
- X * av - argument values, from main
- X * tp - pointer to table of options
- X *
- X * CAVEAT
- X * Must be called before the arglex() function.
- X */
- X
- Xvoid
- Xarglex_init(ac, av, tp)
- X int ac;
- X char **av;
- X arglex_table_ty *tp;
- X{
- X option_progname_set(av[0]);
- X argc = ac - 1;
- X argv = av + 1;
- X utable = tp;
- X}
- X
- X
- X/*
- X * NAME
- X * arglex_compare
- X *
- X * SYNOPSIS
- X * int arglex_compare(char *formal, char *actual);
- X *
- X * DESCRIPTION
- X * The arglex_compare function is used to compare
- X * a command line string with a formal spec of the option,
- X * to see if they compare equal.
- X *
- X * The actual is case-insensitive. Uppercase in the formal
- X * means a mandatory character, while lower case means optional.
- X * Any number of consecutive optional characters may be supplied
- X * by actual, but none may be skipped, unless all are skipped to
- X * the next non-lower-case letter.
- X *
- X * The underscore (_) is like a lower-case minus,
- X * it matches "", "-" and "_".
- X *
- X * The "*" in a pattern matches everything to the end of the line,
- X * anything after the "*" is ignored. The rest of the line is pointed
- X * to by the "partial" variable as a side-effect (else it will be 0).
- X * This rather ugly feature is to support "-I./dir" type options.
- X *
- X * A backslash in a pattern nominates an exact match required,
- X * case must matche excatly here.
- X * This rather ugly feature is to support "-I./dir" type options.
- X *
- X * For example: "-project" and "-P' both match "-Project",
- X * as does "-proJ", but "-prj" does not.
- X *
- X * For example: "-devDir" and "-d_d' both match "-Development_Directory",
- X * but "-dvlpmnt_drctry" does not.
- X *
- X * For example: to match include path specifications, use a pattern
- X * such as "-\\I*", and the partial global variable will have the
- X * path in it on return.
- X *
- X * ARGUMENTS
- X * formal - the "pattern" for the option
- X * actual - what the user supplied
- X *
- X * RETURNS
- X * int; zero if no match,
- X * non-zero if they do match.
- X */
- X
- Xint
- Xarglex_compare(formal, actual)
- X char *formal;
- X char *actual;
- X{
- X char fc;
- X char ac;
- X int result;
- X
- X trace(("arglex_compare(formal = \"%s\", actual = \"%s\")\n{\n",
- X formal, actual));
- X for (;;)
- X {
- X trace_string(formal);
- X trace_string(actual);
- X ac = *actual++;
- X if (isupper(ac))
- X ac = tolower(ac);
- X fc = *formal++;
- X switch (fc)
- X {
- X case 0:
- X result = !ac;
- X goto done;
- X
- X case '_':
- X if (ac == '-')
- X break;
- X /* fall through... */
- X
- X case 'a': case 'b': case 'c': case 'd': case 'e':
- X case 'f': case 'g': case 'h': case 'i': case 'j':
- X case 'k': case 'l': case 'm': case 'n': case 'o':
- X case 'p': case 'q': case 'r': case 's': case 't':
- X case 'u': case 'v': case 'w': case 'x': case 'y':
- X case 'z':
- X /*
- X * optional characters
- X */
- X if (ac == fc && arglex_compare(formal, actual))
- X {
- X result = 1;
- X goto done;
- X }
- X
- X /*
- X * skip forward to next
- X * mandatory character, or after '_'
- X */
- X while (islower(*formal))
- X ++formal;
- X if (*formal == '_')
- X {
- X ++formal;
- X if (ac == '_' || ac == '-')
- X ++actual;
- X }
- X --actual;
- X break;
- X
- X case '*':
- X /*
- X * This is a hack, it should really
- X * check for a match match the stuff after
- X * the '*', too, a la glob.
- X */
- X if (!ac)
- X {
- X result = 0;
- X goto done;
- X }
- X partial = actual - 1;
- X result = 1;
- X goto done;
- X
- X case '\\':
- X if (actual[-1] != *formal++)
- X {
- X result = 0;
- X goto done;
- X }
- X break;
- X
- X case 'A': case 'B': case 'C': case 'D': case 'E':
- X case 'F': case 'G': case 'H': case 'I': case 'J':
- X case 'K': case 'L': case 'M': case 'N': case 'O':
- X case 'P': case 'Q': case 'R': case 'S': case 'T':
- X case 'U': case 'V': case 'W': case 'X': case 'Y':
- X case 'Z':
- X fc = tolower(fc);
- X /* fall through... */
- X
- X default:
- X /*
- X * mandatory characters
- X */
- X if (fc != ac)
- X {
- X result = 0;
- X goto done;
- X }
- X break;
- X }
- X }
- X done:
- X trace(("return %d;\n}\n", result));
- X return result;
- X}
- X
- X
- X/*
- X * NAME
- X * is_a_number
- X *
- X * SYNOPSIS
- X * int is_a_number(char *s);
- X *
- X * DESCRIPTION
- X * The is_a_number function is used to determine if the
- X * argument is a number.
- X *
- X * The value is placed in arglex_value.alv_number as
- X * a side effect.
- X *
- X * Negative and positive signs are accepted.
- X * The C conventions for decimal, octal and hexadecimal are understood.
- X *
- X * There may be no white space anywhere in the string,
- X * and the string must end after the last digit.
- X * Trailing garbage will be interpreted to mean it is not a string.
- X *
- X * ARGUMENTS
- X * s - string to be tested and evaluated
- X *
- X * RETURNS
- X * int; zero if not a number,
- X * non-zero if is a number.
- X */
- X
- Xstatic int is_a_number _((char *));
- X
- Xstatic int
- Xis_a_number(s)
- X char *s;
- X{
- X long n;
- X int sign;
- X
- X n = 0;
- X switch (*s)
- X {
- X case '-':
- X ++s;
- X sign = -1;
- X break;
- X
- X case '+':
- X ++s;
- X sign = 1;
- X break;
- X
- X default:
- X sign = 1;
- X break;
- X }
- X switch (*s)
- X {
- X case '0':
- X if ((s[1] == 'x' || s[1] == 'X') && s[2])
- X {
- X s += 2;
- X for (;;)
- X {
- X switch (*s)
- 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 = n * 16 + *s++ - '0';
- X continue;
- X
- X case 'A': case 'B': case 'C':
- X case 'D': case 'E': case 'F':
- X n = n * 16 + *s++ - 'A' + 10;
- X continue;
- X
- X case 'a': case 'b': case 'c':
- X case 'd': case 'e': case 'f':
- X n = n * 16 + *s++ - 'a' + 10;
- X continue;
- X }
- X break;
- X }
- X }
- X else
- X {
- X for (;;)
- X {
- X switch (*s)
- X {
- X case '0': case '1': case '2': case '3':
- X case '4': case '5': case '6': case '7':
- X n = n * 8 + *s++ - '0';
- X continue;
- X }
- X break;
- X }
- X }
- X break;
- X
- X case '1': case '2': case '3': case '4':
- X case '5': case '6': case '7': case '8': case '9':
- X for (;;)
- X {
- X switch (*s)
- 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 = n * 10 + *s++ - '0';
- X continue;
- X }
- X break;
- X }
- X break;
- X
- X default:
- X return 0;
- X }
- X if (*s)
- X return 0;
- X arglex_value.alv_number = n * sign;
- X return 1;
- X}
- X
- X
- X/*
- X * NAME
- X * arglex
- X *
- X * SYNOPSIS
- X * arglex_token_ty arglex(void);
- X *
- X * DESCRIPTION
- X * The arglex function is used to perfom lexical analysis
- X * on the command line arguments.
- X *
- X * Unrecognised options are returned as arglex_token_option
- X * for anything starting with a '-', or
- X * arglex_token_string otherwise.
- X *
- X * RETURNS
- X * The next token in the token stream.
- X * When the end is reached, arglex_token_eoln is returned forever.
- X *
- X * CAVEAT
- X * Must call arglex_init befor this function is called.
- X */
- X
- Xarglex_token_ty
- Xarglex()
- X{
- X arglex_table_ty *tp;
- X int j;
- X arglex_table_ty *hit[20];
- X int nhit;
- X static char *pushback;
- X char *arg;
- X
- X trace(("arglex()\n{\n"));
- X if (pushback)
- X {
- X /*
- X * the second half of a "-foo=bar" style argument.
- X */
- X arg = pushback;
- X pushback = 0;
- X }
- X else
- X {
- X if (argc <= 0)
- X {
- X arglex_token = arglex_token_eoln;
- X arg = "";
- X goto done;
- X }
- X arg = argv[0];
- X argc--;
- X argv++;
- X
- X /*
- X * See if it looks like a GNU "-foo=bar" option.
- X * Split it at the '=' to make it something the
- X * rest of the code understands.
- X */
- X if (arg[0] == '-' && arg[1] != '=')
- X {
- X char *eqp;
- X
- X eqp = strchr(arg, '=');
- X if (eqp)
- X {
- X pushback = eqp + 1;
- X *eqp = 0;
- X }
- X }
- X
- X /*
- X * Turn the GNU-style leading "--"
- X * into "-" if necessary.
- X */
- X if
- X (
- X arg[0] == '-'
- X &&
- X arg[1] == '-'
- X &&
- X arg[2]
- X &&
- X !is_a_number(arg + 1)
- X )
- X ++arg;
- X }
- X
- X /*
- X * see if it is a number
- X */
- X if (is_a_number(arg))
- X {
- X arglex_token = arglex_token_number;
- X goto done;
- X }
- X
- X /*
- X * scan the tables to see what it matches
- X */
- X nhit = 0;
- X partial = 0;
- X for (tp = table; tp < ENDOF(table); tp++)
- X {
- X if (arglex_compare(tp->t_name, arg))
- X hit[nhit++] = tp;
- X }
- X if (utable)
- X {
- X for (tp = utable; tp->t_name; tp++)
- X {
- X if (arglex_compare(tp->t_name, arg))
- X hit[nhit++] = tp;
- X }
- X }
- X
- X /*
- X * deal with unknown or ambiguous options
- X */
- X switch (nhit)
- X {
- X case 0:
- X /*
- X * not found in the tables
- X */
- X if (*arg == '-')
- X arglex_token = arglex_token_option;
- X else
- X arglex_token = arglex_token_string;
- X break;
- X
- X case 1:
- X arglex_token = hit[0]->t_token;
- X if (partial)
- X arg = partial;
- X else
- X arg = hit[0]->t_name;
- X break;
- X
- X default:
- X {
- X string_ty *s1;
- X string_ty *s2;
- X
- X s1 = str_from_c(hit[0]->t_name);
- X for (j = 1; j < nhit; ++j)
- X {
- X s2 = str_format("%S, %s", s1, hit[j]->t_name);
- X str_free(s1);
- X s2 = s2;
- X }
- X fatal
- X (
- X "option \"%s\" abmiguous (%s)",
- X arg,
- X s1->str_text
- X );
- X }
- X }
- X
- X /*
- X * here for all exits
- X */
- X done:
- X arglex_value.alv_string = arg;
- X trace(("return %d; /* %s */\n", arglex_token, arglex_value.alv_string));
- X trace((/*{*/"}\n"));
- X return arglex_token;
- X}
- END_OF_FILE
- if test 10257 -ne `wc -c <'common/arglex.c'`; then
- echo shar: \"'common/arglex.c'\" unpacked with wrong size!
- fi
- # end of 'common/arglex.c'
- fi
- if test -f 'doc/c5.0.so' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/c5.0.so'\"
- else
- echo shar: Extracting \"'doc/c5.0.so'\" \(10142 characters\)
- sed "s/^X//" >'doc/c5.0.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 Project Attributes
- X.\"
- X.bp
- X.1C
- X.nh 1 "The Project Attributes"
- X.LP
- XThe project attributes are manipulated using the
- X.I aepa (1)
- Xcommand.
- XThis command reads a project attributes file to set the project attributes.
- XThis file can be thought of as having several sections,
- Xeach of which will be covered by this chapter.
- XYou should see the
- X.I aepattr (5)
- Xmanual entry for more details.
- X.nh 2 "Description and Access"
- X.LP
- XThe
- X.I description
- Xfield is a string which contains
- Xa description of the project.
- XLarge amounts of prose are not required;
- Xa single line is sufficient.
- X.LP
- XThe
- X.I default_development_directory
- Xfield is a string which contains
- Xthe pathname of where to place new development directories.
- XThe pathname must be absolute.
- XThis field is only
- Xconsulted if the
- X.I uconf (5)
- Xfield of the same name is not set.
- XDefaults to
- X.I $HOME .
- X.LP
- XThe
- X.I umask
- Xfield is an integer which is set to the
- Xfile permission mode mask.
- XSee
- X.I umask (2)
- Xfor more information.
- XThis value will always be OR'ed with 022,
- Xbecause aegis is paranoid.
- X.nh 2 "Notification Commands"
- X.LP
- XThe
- X.I develop_end_notify_command
- Xfield is a string which contains a command to be used to
- Xnotify that a change requires reviewing.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I develop_end_undo_notify_command
- Xfield is a string containing a command used to
- Xnotify that a change has been withdrawn from review
- Xfor further development.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I review_pass_notify_command
- Xfield is a string containing the command to
- Xnotify that the review has passed.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I review_pass_undo_notify_command
- Xfield is a string containing the command to
- Xnotify that a review pass has has been rescinded.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, and defaults to the
- X.I develop_end_notify_command
- Xfield if not specified.
- XIf neither is specified, no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I review_fail_notify_command
- Xfield is a string containing the command to
- Xnotify that the review has failed.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I integrate_pass_notify_command
- Xfield is a string containing the command to
- Xnotify that the integration has passed.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.LP
- XThe
- X.I integrate_fail_notify_command
- Xfield is a string containing the command to
- Xnotify that the integration has failed.
- XAll of the substitutions described in
- X.I aesub (5)
- Xare available.
- XThis field is optional, if it is not specified no notification will be issued.
- XThis command could also be used to notify other management systems,
- Xsuch as progress and defect tracking,
- Xin addition to notifying users.
- X.nh 3 "Notification by email"
- X.LP
- XThe aegis command is distributed with a set of shell scripts to
- Xperform these notifications by email.
- XThey are installed into the
- X.I /usr/local/lib/aegis
- Xdirectory.
- XThe entries in the project attribute file look like this:
- X.E(
- Xdevelop_end_notify_command =
- X "sh /usr/local/lib/aegis/de.sh $project $change \e
- X $developer";
- Xdevelop_end_undo_notify_command =
- X "sh /usr/local/lib/aegis/deu.sh $project $change \e
- X $developer";
- Xreview_pass_notify_command =
- X "sh /usr/local/lib/aegis/rp.sh $project $change \e
- X $developer $reviewer";
- Xreview_pass_undo_notify_command =
- X "sh /usr/local/lib/aegis/rpu.sh $project $change \e
- X $developer $reviewer";
- Xreview_fail_notify_command =
- X "sh /usr/local/lib/aegis/rf.sh $project $change \e
- X $developer $reviewer";
- Xintegrate_pass_notify_command =
- X "sh /usr/local/lib/aegis/ip.sh $project $change \e
- X $developer $reviewer $integrator";
- Xintegrate_fail_notify_command =
- X "sh /usr/local/lib/aegis/if.sh $project $change \e
- X $developer $reviewer $integrator";
- X.E)
- X.nh 3 "Notification by USENET"
- X.LP
- XThe aegis command is distributed with a set of shell scripts to
- Xperform these notifications by USENET.
- XThey are installed into the
- X.I /usr/local/lib/aegis
- Xdirectory.
- XThe entries in the project attribute file look like this:
- X.E(
- Xdevelop_end_notify_command =
- X "sh /usr/local/lib/aegis/de.inews.sh $p $c alt.$p";
- Xdevelop_end_undo_notify_command =
- X "sh /usr/local/lib/aegis/deu.inews.sh $p $c alt.$p";
- Xreview_pass_notify_command =
- X "sh /usr/local/lib/aegis/rp.inews.sh $p $c alt.$p";
- Xreview_pass_undo_notify_command =
- X "sh /usr/local/lib/aegis/rpu.inews.sh $p $c alt.$p";
- Xreview_fail_notify_command =
- X "sh /usr/local/lib/aegis/rf.inews.sh $p $c alt.$p";
- Xintegrate_pass_notify_command =
- X "sh /usr/local/lib/aegis/ip.inews.sh $p $c alt.$p";
- Xintegrate_fail_notify_command =
- X "sh /usr/local/lib/aegis/if.inews.sh $p $c alt.$p";
- X.E)
- X.LP
- XThe last argument to each command is the newsgroup to post the article in,
- Xyou may want to use some other group.
- XNote that "$p" is an abbreviation for "$project"
- Xand "$c" is an abbreviation for "$change".
- X.nh 2 "Exemption Controls"
- X.LP
- XThe
- X.I developer_may_review
- Xfield is a boolean.
- XIf this field is true,
- Xthen a developer may review her own change.
- XThis is probably only a good idea for projects of less than 3 people.
- XThe idea is for as many people as possible to critically examine a change.
- X.LP
- XThe
- X.I developer_may_integrate
- Xfield is a boolean.
- XIf this field is true,
- Xthen a developer may integrate her own change.
- XThis is probably only a good idea for projects of less than 3 people.
- XThe idea is for as many people as possible to critically examine a change.
- X.LP
- XThe
- X.I reviewer_may_integrate
- Xfield is a boolean.
- XIf this field is true,
- Xthen a reviewer may integrate a change she reviewed.
- XThis is probably only a good idea for projects of less than 3 people.
- XThe idea is for as many people as possible to critically examine a change.
- X.LP
- XThe
- X.I developers_may_create_changes
- Xfield is a boolean.
- XThis field is true if developers may created changes,
- Xin addition to administrators.
- XThis tends to be a very useful thing,
- Xsince developers find most of the bugs.
- X.LP
- XThe
- X.I default_test_exemption
- Xfield is a boolean.
- XThis field contains what to do when a change is created with
- Xno test exemption specified.
- XThe default is "false", i.e. no testing exemption,
- Xtests must be provided.
- X.LP
- XThis kind of blanket exemption should only be set when
- Xa project has absolutely no functionality available from the command line;
- Xexamples include X11 programs.
- XThe program could possibly be improved by providing access to
- Xthe functionality from the command line,
- Xthus allowing tests to be written.
- X.nh 3 "One Person Projects"
- X.LP
- XThe entries in the project attributes file for a
- Xone person project look like this:
- X.E(
- Xdeveloper_may_review = true;
- Xdeveloper_may_integrate = true;
- Xreviewer_may_integrate = true;
- Xdevelopers_may_create_changes = true;
- X.E)
- X.LP
- XAll of the staff roles
- X(administrator, developer, reviewer and integrator)
- Xare all set to be the same user.
- X.nh 3 "Two Person Projects"
- X.LP
- XA two person project has the opportunity for each to review the other's work.
- X.LP
- XThe entries in the project attributes file for a
- Xone person project look like this:
- X.E(
- Xdeveloper_may_review = false.
- Xdeveloper_may_integrate = true;
- Xreviewer_may_integrate = true;
- Xdevelopers_may_create_changes = true;
- X.E)
- X.LP
- XAll of the staff roles
- X(developer, reviewer and integrator)
- Xare all set to allow both users.
- X.nh 3 "Larger Projects"
- X.LP
- XOnce you have 3 or more staff on a project,
- Xyou can assign all of the roles to separate people.
- XThe idea is for the greatest number of eyes to see each change
- Xand detect flaws before they reach the baseline.
- X.LP
- XThe entries in the project attributes file for a
- Xone person project look like this:
- X.E(
- Xdeveloper_may_review = false.
- Xdeveloper_may_integrate = false;
- Xreviewer_may_integrate = false;
- Xdevelopers_may_create_changes = true;
- X.E)
- X.LP
- XFor smaller teams,
- Xeveryone may be a developer.
- XAs the teams get larger,
- Xthe more experienced staff are often the reviewers,
- Xrather than everyone.
- END_OF_FILE
- if test 10142 -ne `wc -c <'doc/c5.0.so'`; then
- echo shar: \"'doc/c5.0.so'\" unpacked with wrong size!
- fi
- # end of 'doc/c5.0.so'
- fi
- if test -f 'fmtgen/id.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fmtgen/id.c'\"
- else
- echo shar: Extracting \"'fmtgen/id.c'\" \(9297 characters\)
- sed "s/^X//" >'fmtgen/id.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: symbol table manipulation
- X */
- X
- X#include <stddef.h>
- X#include <stdlib.h>
- X#include <string.h>
- X
- X#include <main.h>
- X#include <id.h>
- X#include <word.h>
- X#include <mem.h>
- X#include <error.h>
- X
- X
- X#define HEADER \
- X string_ty *id_name; \
- X str_hash_ty id_hash; \
- X id *id_next; \
- X id_class_ty id_class;
- X
- Xtypedef struct id id;
- Xstruct id
- X{
- X HEADER
- X};
- X
- Xtypedef struct id_int id_int;
- Xstruct id_int
- X{
- X HEADER
- X int id_value;
- X};
- X
- Xtypedef struct id_void id_void;
- Xstruct id_void
- X{
- X HEADER
- X void *id_value;
- X};
- X
- Xstatic id **hash_table;
- Xstatic str_hash_ty hash_modulus;
- Xstatic str_hash_ty hash_cutover;
- Xstatic str_hash_ty hash_cutover_mask;
- Xstatic str_hash_ty hash_cutover_split_mask;
- Xstatic str_hash_ty hash_split;
- Xstatic str_hash_ty hash_load;
- X
- X
- X/*
- X * NAME
- X * id_initialize - start up symbol table
- X *
- X * SYNOPSIS
- X * void id_initialize(void);
- X *
- X * DESCRIPTION
- X * The id_initialize function is used to create the hash table.
- X *
- X * CAVEAT
- X * Assumes the str_initialize function has been called already.
- X */
- X
- Xvoid
- Xid_initialize()
- X{
- X str_hash_ty j;
- X
- X hash_modulus = 1<<8; /* MUST be a power of 2 */
- X hash_cutover = hash_modulus;
- X hash_split = hash_modulus - hash_cutover;
- X hash_cutover_mask = hash_cutover - 1;
- X hash_cutover_split_mask = (hash_cutover * 2) - 1;
- X hash_load = 0;
- X hash_table = (id **)mem_alloc(hash_modulus * sizeof(id *));
- X for (j = 0; j < hash_modulus; ++j)
- X hash_table[j] = 0;
- X}
- X
- X
- X/*
- X * NAME
- X * split - reduce symbol table load
- X *
- X * SYNOPSIS
- X * void split(void);
- X *
- X * DESCRIPTION
- X * The split function is used to split symbols in the bucket indicated by
- X * the split point. The symbols are split between that bucket and the one
- X * after the current end of the table.
- X *
- X * CAVEAT
- X * It is only sensable to do this when the symbol table load exceeds some
- X * reasonable threshold. A threshold of 80% is suggested.
- X */
- X
- Xstatic void split _((void));
- X
- Xstatic void
- Xsplit()
- X{
- X id *p;
- X id **ipp;
- X id *p2;
- X str_hash_ty index;
- X
- X /*
- X * get the list to be split across buckets
- X */
- X p = hash_table[hash_split];
- X hash_table[hash_split] = 0;
- X
- X /*
- X * increase the modulus by one
- X */
- X hash_modulus++;
- X mem_change_size((char **)&hash_table, hash_modulus * sizeof(id *));
- X hash_table[hash_modulus - 1] = 0;
- X hash_split = hash_modulus - hash_cutover;
- X if (hash_split >= hash_cutover)
- X {
- X hash_cutover = hash_modulus;
- X hash_split = 0;
- X hash_cutover_mask = hash_cutover - 1;
- X hash_cutover_split_mask = (hash_cutover * 2) - 1;
- X }
- X
- X /*
- X * now redistribute the list elements
- X *
- X * It is important to preserve the order of the links because
- X * they can be push-down stacks, and to simply add them to the
- X * head of the list will reverse the order of the stack!
- X */
- X while (p)
- X {
- X p2 = p;
- X p = p2->id_next;
- X p2->id_next = 0;
- X
- X index = p2->id_hash & hash_cutover_mask;
- X if (index < hash_split)
- X index = p2->id_hash & hash_cutover_split_mask;
- X for (ipp = &hash_table[index]; *ipp; ipp = &(*ipp)->id_next)
- X ;
- X *ipp = p2;
- X }
- X}
- X
- X
- X/*
- X * NAME
- X * copy - copy a symbol value
- X *
- X * SYNOPSIS
- X * void copy(id *p, long *valuep);
- X *
- X * DESCRIPTION
- X * The copy function is used to copy the passed value of a symbol into the
- X * storage of that symbol.
- X */
- X
- Xstatic void copy _((id *, long *));
- X
- Xstatic void
- Xcopy(p, valuep)
- X id *p;
- X long *valuep;
- X{
- X switch (p->id_class)
- X {
- X case ID_CLASS_KEYWORD:
- X {
- X id_int *ip;
- X
- X ip = (id_int *)p;
- X *valuep = ip->id_value;
- X }
- X break;
- X
- X case ID_CLASS_ENUMEL:
- X case ID_CLASS_FIELD:
- X case ID_CLASS_TYPE:
- X {
- X id_void *ip;
- X
- X ip = (id_void *)p;
- X *(void **)valuep = ip->id_value;
- X }
- X break;
- X }
- X}
- X
- X
- X/*
- X * NAME
- X * id_search - search for a variable
- X *
- X * SYNOPSIS
- X * int id_search(string_ty *name, id_class_ty class, long *value);
- X *
- X * DESCRIPTION
- X * Id_search is used to reference a variable.
- X *
- X * RETURNS
- X * If the variable has been defined, the function returns a non-zero value
- X * and the value is returned through the 'value' pointer.
- X * If the variable has not been defined, it returns zero,
- X * and 'value' is unaltered.
- X *
- X * CAVEAT
- X * The value returned from this function, when returned, is allocated
- X * in dynamic memory (it is a copy of the value remembered by this module).
- X * It is the responsibility of the caller to free it when finished with,
- X * by a wl_free() call.
- X */
- X
- X/*VARARGS2*/
- Xint
- Xid_search(name, class, valuep)
- X string_ty *name;
- X id_class_ty class;
- X long *valuep;
- X{
- X str_hash_ty myhash;
- X str_hash_ty index;
- X id *p;
- X
- X myhash = name->str_hash + (int)class;
- X index = myhash & hash_cutover_mask;
- X if (index < hash_split)
- X index = myhash & hash_cutover_split_mask;
- X for (p = hash_table[index]; p; p = p->id_next)
- X {
- X if (p->id_class == class && str_equal(name, p->id_name))
- X {
- X copy(p, valuep);
- X return 1;
- X }
- X }
- X return 0;
- X}
- X
- X
- X/*
- X * NAME
- X * assign - set value of symbol
- X *
- X * SYNOPSIS
- X * void assign(id *p, long value);
- X *
- X * DESCRIPTION
- X * The assign function is used to change the value of a symbol.
- X *
- X * CAVEAT
- X * The value is not released first, so use stomp if necessary.
- X */
- X
- Xstatic void assign _((id *, long));
- X
- Xstatic void
- Xassign(p, value)
- X id *p;
- X long value;
- X{
- X switch (p->id_class)
- X {
- X case ID_CLASS_KEYWORD:
- X {
- X id_int *ip;
- X
- X ip = (id_int *)p;
- X ip->id_value = value;
- X }
- X break;
- X
- X case ID_CLASS_TYPE:
- X case ID_CLASS_FIELD:
- X case ID_CLASS_ENUMEL:
- X {
- X id_void *ip;
- X
- X ip = (id_void *)p;
- X ip->id_value = (void *)value;
- X }
- X break;
- X }
- X}
- X
- X
- X/*
- X * NAME
- X * size_by_class - determine symbol size
- X *
- X * SYNOPSIS
- X * size_t size_by_class(id_class_ty class);
- X *
- X * DESCRIPTION
- X * The size_by_class function is used to determine the correct size to
- X * allocate for symbol storage.
- X *
- X * RETURNS
- X * size_t: the correct size to malloc.
- X *
- X * CAVEAT
- X * Never malloc(sizeof(id)) as this will be too small.
- X */
- X
- Xstatic size_t size_by_class _((id_class_ty));
- X
- Xstatic size_t
- Xsize_by_class(class)
- X id_class_ty class;
- X{
- X switch ((int)class)
- X {
- X default:
- X assert(0);
- X
- X case ID_CLASS_KEYWORD:
- X return sizeof(id_int);
- X
- X case ID_CLASS_TYPE:
- X case ID_CLASS_FIELD:
- X case ID_CLASS_ENUMEL:
- X return sizeof(id_void);
- X }
- X}
- X
- X
- X/*
- X * NAME
- X * id_assign - assign a variable
- X *
- X * SYNOPSIS
- X * void id_assign(string_ty *name, id_class_ty class, long value);
- X *
- X * DESCRIPTION
- X * Id_assign is used to assign a value to a given variable.
- X *
- X * CAVEAT
- X * The name and value are copied by id_assign, so the user may
- X * modify or free them at a later date without affecting the
- X * variable.
- X */
- X
- X/*VARARGS2*/
- Xvoid
- Xid_assign(name, class, value)
- X string_ty *name;
- X id_class_ty class;
- X long value;
- X{
- X str_hash_ty myhash;
- X str_hash_ty index;
- X id *p;
- X
- X myhash = name->str_hash + (int)class;
- X index = myhash & hash_cutover_mask;
- X if (index < hash_split)
- X index = myhash & hash_cutover_split_mask;
- X
- X for (p = hash_table[index]; p; p = p->id_next)
- X {
- X if (p->id_class == class && str_equal(name, p->id_name))
- X {
- X assign(p, value);
- X return;
- X }
- X }
- X
- X p = (id *)mem_alloc_clear(size_by_class(class));
- X p->id_name = str_copy(name);
- X p->id_next = hash_table[index];
- X p->id_class = class;
- X p->id_hash = myhash;
- X hash_table[index] = p;
- X assign(p, value);
- X
- X hash_load++;
- X while (hash_load * 10 >= hash_modulus * 8)
- X split();
- X}
- X
- X
- X/*
- X * NAME
- X * id_dump - dump id table
- X *
- X * SYNOPSIS
- X * void id_dump(char *title, int mask);
- X *
- X * DESCRIPTION
- X * The id_dump function is used to dump the contents of the id table.
- X * The title will be used to indicate why the table was dumped. The mask
- X * may be used to selectively dump the table, 0 means everything, bits
- X * correspond directly with ID_CLASS defines.
- X *
- X * CAVEAT
- X * This function is only available when symbol DEBUG is defined.
- X */
- X
- X#ifdef DEBUG
- X
- Xvoid
- Xid_dump(s, mask)
- X char *s;
- X int mask;
- X{
- X int j;
- X id *p;
- X
- X if (!mask)
- X mask = ~0;
- X error("id table %s = {"/*}*/, s);
- X for (j = 0; j < hash_modulus; ++j)
- X {
- X for (p = hash_table[j]; p; p = p->id_next)
- X {
- X if (mask & (1<< (int)p->id_class))
- X switch ((int)p->id_class)
- X {
- X default:
- X error
- X (
- X "name = \"%s\", class = %d",
- X p->id_name->str_text,
- X p->id_class
- X );
- X break;
- X
- X case ID_CLASS_KEYWORD:
- X {
- X id_int *ip;
- X
- X ip = (id_int*)p;
- X error
- X (
- X "name = \"%s\", class = %d, value = %d",
- X p->id_name->str_text,
- X p->id_class,
- X ip->id_value
- X );
- X }
- X break;
- X
- X case ID_CLASS_TYPE:
- X case ID_CLASS_FIELD:
- X {
- X id_void *ip;
- X
- X ip = (id_void *)p;
- X error
- X (
- X "name = \"%s\", class = %d, value = %08X",
- X p->id_name->str_text,
- X p->id_class,
- X ip->id_value
- X );
- X }
- X break;
- X }
- X }
- X }
- X error(/*{*/"}");
- X}
- X
- X#endif
- END_OF_FILE
- if test 9297 -ne `wc -c <'fmtgen/id.c'`; then
- echo shar: \"'fmtgen/id.c'\" unpacked with wrong size!
- fi
- # end of 'fmtgen/id.c'
- fi
- if test -f 'fmtgen/lex.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fmtgen/lex.c'\"
- else
- echo shar: Extracting \"'fmtgen/lex.c'\" \(9885 characters\)
- sed "s/^X//" >'fmtgen/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: lexical analyzer
- X */
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <errno.h>
- X
- X#include <error.h>
- X#include <id.h>
- X#include <lex.h>
- X#include <mem.h>
- X#include <s-v-arg.h>
- X#include <str.h>
- X#include <type.h>
- X#include <parse.gen.h> /* must be last */
- X
- X
- X#define strel(a, op, b) (strcmp(a, b) op 0)
- X
- Xtypedef struct file_ty file_ty;
- Xstruct file_ty
- X{
- X FILE *fp;
- X int line_number;
- X char *file_name;
- X file_ty *next;
- X};
- X
- Xstatic file_ty *file;
- Xstatic int error_count;
- Xextern parse_STYPE parse_lval;
- Xstatic wlist ifiles;
- Xstatic wlist include_path;
- X
- X
- X/*
- X * NAME
- X * lex_initialize - look for keywords
- X *
- X * SYNOPSIS
- X * int lex_initialize(void);
- X *
- X * DESCRIPTION
- X * The lex_initialize function adds all the keywords to the symbol table.
- X *
- X * CAVEAT
- X * The keywords are intentionally case sensitive.
- X * Assumes that str_initialize has already been called.
- X */
- X
- Xstatic void lex_initialize _((void));
- X
- Xstatic void
- Xlex_initialize()
- X{
- X typedef struct keyword_ty keyword_ty;
- X struct keyword_ty
- X {
- X char *k_name;
- X int k_token;
- X };
- X
- X static keyword_ty keyword[] =
- X {
- X { "type", TYPE, },
- X { "string", STRING, },
- X { "integer", INTEGER, },
- X { "include", INCLUDE, },
- X };
- X keyword_ty *kp;
- X static int done;
- X
- X if (done)
- X return;
- X done = 1;
- X for (kp = keyword; kp < ENDOF(keyword); ++kp)
- X {
- X string_ty *s;
- X
- X s = str_from_c(kp->k_name);
- X id_assign(s, ID_CLASS_KEYWORD, kp->k_token);
- X str_free(s);
- X }
- X}
- X
- X
- Xvoid
- Xlex_open(s)
- X char *s;
- X{
- X file_ty *f;
- X
- X f = (file_ty *)mem_alloc_clear(sizeof(file_ty));
- X if (!file)
- X {
- X lex_initialize();
- X f->file_name = mem_copy_string(s);
- X f->fp = fopen(s, "r");
- X if (!f->fp)
- X nfatal("%s", s);
- X }
- X else
- X {
- X int j;
- X
- X f->fp = 0;
- X for (j = 0; j < include_path.wl_nwords; ++j)
- X {
- X char buffer[2000];
- X
- X sprintf(buffer, "%s/%s", include_path.wl_word[j]->str_text, s);
- X f->fp = fopen(buffer, "r");
- X if (f->fp)
- X {
- X f->file_name = mem_copy_string(buffer);
- X break;
- X }
- X if (errno != ENOENT)
- X nfatal("%s", buffer);
- X }
- X if (!f->fp)
- X {
- X f->fp = fopen(s, "r");
- X if (!f->fp)
- X nfatal("%s", s);
- X f->file_name = mem_copy_string(s);
- X }
- X f->next = file;
- X wl_append_unique(&ifiles, str_from_c(s));
- X }
- X f->line_number = 1;
- X file = f;
- X}
- X
- X
- Xvoid
- Xlex_close()
- X{
- X if (error_count)
- X exit(1);
- X fclose(file->fp);
- X free(file->file_name);
- X free(file);
- X}
- X
- X
- Xstatic int lex_getc _((void));
- X
- Xstatic int
- Xlex_getc()
- X{
- X int c;
- X
- X for (;;)
- X {
- X file_ty *old;
- X
- X c = fgetc(file->fp);
- X if (c != EOF)
- X break;
- X if (ferror(file->fp))
- X nfatal("%s", file->file_name);
- X if (!file->next)
- X break;
- X old = file;
- X file = old->next;
- X fclose(old->fp);
- X free(old->file_name);
- X free(old);
- X }
- X if (c == '\n')
- X file->line_number++;
- 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 file->line_number--;
- X /* fall through... */
- X
- X default:
- X ungetc(c, file->fp);
- X break;
- X }
- X}
- X
- X
- Xint
- Xparse_lex()
- X{
- X int line_number_start;
- X char buffer[1<<12];
- X char *cp;
- X
- X for (;;)
- X {
- X int c;
- 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 case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X parse_lval.lv_integer = 0;
- X for (;;)
- X {
- X parse_lval.lv_integer = 10 * parse_lval.lv_integer + c - '0';
- X c = lex_getc();
- X if (c < '0' || c > '9')
- X {
- X lex_getc_undo(c);
- X break;
- X }
- X }
- X return INTEGER_CONSTANT;
- X
- X case 'A': case 'B': case 'C': case 'D': case 'E':
- X case 'F': case 'G': case 'H': case 'I': case 'J':
- X case 'K': case 'L': case 'M': case 'N': case 'O':
- X case 'P': case 'Q': case 'R': case 'S': case 'T':
- X case 'U': case 'V': case 'W': case 'X': case 'Y':
- X case 'Z': case '_': case 'a': case 'b': case 'c':
- X case 'd': case 'e': case 'f': case 'g': case 'h':
- X case 'i': case 'j': case 'k': case 'l': case 'm':
- X case 'n': case 'o': case 'p': case 'q': case 'r':
- X case 's': case 't': case 'u': case 'v': case 'w':
- X case 'x': case 'y': case 'z':
- X {
- X char *cp;
- X char buffer[1000];
- X string_ty *s;
- X long tok;
- X
- 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 '_': case 'a':
- X case 'b': case 'c': case 'd': case 'e':
- X case 'f': case 'g': case 'h': case 'i':
- X case 'j': case 'k': case 'l': case 'm':
- X case 'n': case 'o': case 'p': case 'q':
- X case 'r': case 's': case 't': case 'u':
- X case 'v': case 'w': case 'x': case 'y':
- X case 'z':
- X continue;
- X }
- X lex_getc_undo(c);
- X *cp = 0;
- X break;
- X }
- X s = str_from_c(buffer);
- X if (id_search(s, ID_CLASS_KEYWORD, &tok))
- X {
- X str_free(s);
- X return tok;
- X }
- X parse_lval.lv_string = s;
- X return NAME;
- X }
- X
- X case '/':
- 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 parse_error("end-of-file inside comment");
- X exit(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 case '<':
- X line_number_start = file->line_number;
- X cp = buffer;
- X for (;;)
- X {
- X c = lex_getc();
- X if (c == EOF)
- X goto str_eof;
- X if (c == '\n')
- X goto str_eoln;
- X if (c == '>')
- X break;
- X *cp++ = c;
- X }
- X *cp = 0;
- X parse_lval.lv_string = str_from_c(buffer);
- X return STRING_CONSTANT;
- X
- X case '"':
- X line_number_start = file->line_number;
- X cp = buffer;
- X for (;;)
- X {
- X c = lex_getc();
- X if (c == EOF)
- X {
- X str_eof:
- X file->line_number = line_number_start;
- X parse_error("end-of-file within string");
- X break;
- X }
- X if (c == '\n')
- X {
- X str_eoln:
- X file->line_number = line_number_start;
- X parse_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 parse_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':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X 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 parse_lval.lv_string = str_from_c(buffer);
- X return STRING_CONSTANT;
- X
- X default:
- X return c;
- X }
- X }
- X}
- X
- X
- Xvoid
- Xparse_error(s sva_last)
- X char *s;
- X sva_last_decl
- X{
- X va_list ap;
- X char buffer[1000];
- X
- X sva_init(ap, s);
- X vsprintf(buffer, s, ap);
- X va_end(ap);
- X error("%s: %d: %s", file->file_name, file->line_number, buffer);
- X if (++error_count >= 20)
- X error("%s: too many errors, bye!", file->file_name);
- X}
- X
- X
- Xint
- Xlex_in_include_file()
- X{
- X return !!file->next;
- X}
- X
- X
- Xvoid
- Xlex_include_path(s)
- X char *s;
- X{
- X wl_append_unique(&include_path, str_from_c(s));
- X}
- END_OF_FILE
- if test 9885 -ne `wc -c <'fmtgen/lex.c'`; then
- echo shar: \"'fmtgen/lex.c'\" unpacked with wrong size!
- fi
- # end of 'fmtgen/lex.c'
- fi
- if test -f 'fmtgen/parse.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fmtgen/parse.y'\"
- else
- echo shar: Extracting \"'fmtgen/parse.y'\" \(9538 characters\)
- sed "s/^X//" >'fmtgen/parse.y' <<'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: grammar and functions to parse aegis file contents definitions
- X */
- X
- X%{
- X
- X#include <ctype.h>
- X#include <string.h>
- X#include <stdlib.h>
- X
- X#include <error.h>
- X#include <id.h>
- X#include <indent.h>
- X#include <lex.h>
- X#include <mem.h>
- X#include <parse.h>
- X#include <str.h>
- X#include <trace.h>
- X#include <type.h>
- X
- X#ifdef DEBUG
- X#define YYDEBUG 1
- Xextern int yydebug;
- X#define printf trace_where, trace_printf
- X#endif
- X
- X%}
- X
- X%token TYPE
- X%token NAME
- X%token STRING
- X%token STRING_CONSTANT
- X%token INTEGER
- X%token INTEGER_CONSTANT
- X%token INCLUDE
- X
- X%union
- X{
- X string_ty *lv_string;
- X long lv_integer;
- X parse_list_ty *lv_parse_list;
- X type_ty *lv_type;
- X}
- X
- X%type <lv_string> NAME
- X%type <lv_integer> INTEGER_CONSTANT
- X%type <lv_parse_list> field_list enum_list
- X%type <lv_type> type structure list enumeration
- X%type <lv_string> type_name field field_name enum_name STRING_CONSTANT
- X
- X%{
- X
- Xtypedef struct name_ty name_ty;
- Xstruct name_ty
- X{
- X string_ty *name;
- X name_ty *prev;
- X};
- X
- Xstatic parse_list_ty *type_root;
- Xstatic name_ty *name_root;
- X
- X
- Xstatic void pl_append _((parse_list_ty **, string_ty *));
- X
- Xstatic void
- Xpl_append(listp, s)
- X parse_list_ty **listp;
- X string_ty *s;
- X{
- X parse_list_ty *plp;
- X
- X trace(("pl_append(listp = %08lX, s = \"%s\")\n{\n"/*}*/, listp, s->str_text));
- X while (*listp)
- X listp = &(*listp)->next;
- X plp = (parse_list_ty *)mem_alloc(sizeof(parse_list_ty));
- X plp->name = str_copy(s);
- X plp->next = 0;
- X *listp = plp;
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void push_name _((string_ty *));
- X
- Xstatic void
- Xpush_name(s)
- X string_ty *s;
- X{
- X name_ty *np;
- X
- X trace(("push_name(s = \"%s\")\n{\n"/*}*/, s->str_text));
- X assert(name_root);
- X np = (name_ty *)mem_alloc(sizeof(name_ty));
- X np->name = str_format("%S_%S", name_root->name, s);
- X np->prev = name_root;
- X name_root = np;
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void push_name_abs _((string_ty *));
- X
- Xstatic void
- Xpush_name_abs(s)
- X string_ty *s;
- X{
- X name_ty *np;
- X
- X trace(("push_name_abs(s = \"%s\")\n{\n"/*}*/, s->str_text));
- X np = (name_ty *)mem_alloc(sizeof(name_ty));
- X np->name = str_copy(s);
- X np->prev = name_root;
- X name_root = np;
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic void pop_name _((void));
- X
- Xstatic void
- Xpop_name()
- X{
- X name_ty *np;
- X
- X trace(("pop_name()\n{\n"/*}*/));
- X np = name_root;
- X name_root = np->prev;
- X str_free(np->name);
- X free(np);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic string_ty *get_name _((void));
- X
- Xstatic string_ty *
- Xget_name()
- X{
- X return str_copy(name_root->name);
- X}
- X
- X
- Xstatic void define_type _((string_ty *, type_ty *));
- X
- Xstatic void
- Xdefine_type(name, type)
- X string_ty *name;
- X type_ty *type;
- X{
- X trace(("define_type(name = \"%s\")\n{\n"/*}*/, name->str_text));
- X type->included_flag = lex_in_include_file();
- X pl_append(&type_root, name);
- X trace((/*{*/"}\n"));
- X}
- X
- X
- Xstatic char *basename _((char *));
- X
- Xstatic char *
- Xbasename(s)
- X char *s;
- X{
- X static char buffer[256];
- X char *cp;
- X
- X cp = strrchr(s, '/');
- X if (cp)
- X ++cp;
- X else
- X cp = s;
- X strcpy(buffer, cp);
- X cp = strrchr(buffer, '.');
- X if (cp)
- X *cp = 0;
- X for (cp = buffer; *cp; ++cp)
- X {
- X if (!isalnum(*cp))
- X *cp = '_';
- X }
- X return buffer;
- X}
- X
- X
- Xvoid
- Xparse(definition_file, code_file, include_file)
- X char *definition_file;
- X char *code_file;
- X char *include_file;
- X{
- X string_ty *s;
- X char *cp1;
- X parse_list_ty *tnp;
- X
- X trace(("parse(def = \"%s\", c = \"%s\", h = \"%s\")\n{\n"/*}*/,
- X definition_file, code_file, include_file));
- X#ifdef DEBUG
- X yydebug = trace_pretest_;
- X#endif
- X
- X s = str_from_c(basename(definition_file));
- X push_name_abs(s);
- X
- X lex_open(definition_file);
- X trace(("yyparse()\n{\n"/*}*/));
- X yyparse();
- X trace((/*{*/"}\n"));
- X lex_close();
- X
- X pop_name();
- X
- X indent_open(include_file);
- X cp1 = basename(include_file);
- X indent_putchar('\n');
- X indent_printf("#ifndef %s_H\n", cp1);
- X indent_printf("#define %s_H\n", cp1);
- X indent_putchar('\n');
- X indent_printf("#include <main.h>\n");
- X indent_printf("#include <type.h>\n");
- X indent_printf("#include <str.h>\n");
- X indent_printf("#include <parse.h>\n");
- X for (tnp = type_root; tnp; tnp = tnp->next)
- X {
- X type_ty *tp;
- X
- X if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
- X fatal("type \"%s\" lost!", tnp->name->str_text);
- X type_gen_include(tp, tnp->name);
- X }
- X indent_putchar('\n');
- X indent_printf
- X (
- X "void %s_write_file _((char *filename, %s value));\n",
- X s->str_text,
- X s->str_text
- X );
- X indent_printf
- X (
- X "%s %s_read_file _((char *filename));\n",
- X s->str_text,
- X s->str_text
- X );
- X indent_putchar('\n');
- X indent_printf("#endif /* %s_H */\n", cp1);
- X indent_close();
- X
- X cp1 = strrchr(include_file, '/');
- X if (cp1)
- X cp1++;
- X else
- X cp1 = include_file;
- X
- X indent_open(code_file);
- X indent_putchar('\n');
- X indent_printf("#include <stddef.h>\n");
- X indent_printf("#include <stdio.h>\n");
- X indent_putchar('\n');
- X indent_printf("#include <%s>\n", cp1);
- X indent_printf("#include <error.h>\n");
- X indent_printf("#include <indent.h>\n");
- X indent_printf("#include <io.h>\n");
- X indent_printf("#include <mem.h>\n");
- X indent_printf("#include <os.h>\n");
- X indent_printf("#include <trace.h>\n");
- X indent_printf("#include <type.h>\n");
- X cp1 = basename(code_file);
- X for (tnp = type_root; tnp; tnp = tnp->next)
- X {
- X type_ty *tp;
- X
- X if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
- X fatal("type \"%s\" lost!", tnp->name->str_text);
- X if (tp->included_flag)
- X continue;
- X type_gen_code(tp, tnp->name);
- X }
- X indent_putchar('\n');
- X indent_printf("%s\n", cp1);
- X indent_printf("%s_read_file(filename)\n", s->str_text);
- X indent_more();
- X indent_printf("%s\1*filename;\n", "char");
- X indent_less();
- X indent_printf("{\n"/*}*/);
- X indent_printf("%s\1result;\n\n", cp1);
- X indent_printf("trace((\"%s_read_file(filename = \\\"%%s\\\")\\n{\\n\"/*}*/, filename));\n", cp1);
- X indent_printf("os_become_must_be_active();\n");
- X indent_printf
- X (
- X "result = (%s)parse(filename, &%s_type);\n",
- X s->str_text,
- X s->str_text
- X );
- X indent_printf("trace((\"return %%08lX;\\n\", result));\n");
- X indent_printf("trace((/*{*/\"}\\n\"));\n");
- X indent_printf("return result;\n");
- X indent_printf(/*{*/"}\n");
- X indent_putchar('\n');
- X indent_printf("void\n");
- X indent_printf("%s_write_file(filename, value)\n", s->str_text);
- X indent_more();
- X indent_printf("%s\1*filename;\n", "char");
- X indent_printf("%s\1value;\n", s->str_text);
- X indent_less();
- X indent_printf("{\n"/*}*/);
- X indent_printf("trace((\"%s_write_file(filename = \\\"%%s\\\", value = %%08lX)\\n{\\n\"/*}*/, filename, value));\n", cp1);
- X indent_printf("if (filename)\n");
- X indent_more();
- X indent_printf("os_become_must_be_active();\n");
- X indent_less();
- X indent_printf("indent_open(filename);\n");
- X indent_printf("%s_write(value);\n", s->str_text);
- X indent_printf("indent_close();\n");
- X indent_printf("trace((/*{*/\"}\\n\"));\n");
- X indent_printf(/*{*/"}\n");
- X indent_close();
- X
- X str_free(s);
- X trace((/*{*/"}\n"));
- X}
- X
- X%}
- X
- X%%
- X
- Xdescription
- X : typedef_list field_list
- X {
- X string_ty *s;
- X type_ty *type;
- X
- X s = get_name();
- X type = type_create_struct(s, $2, 1);
- X define_type(s, type);
- X }
- X ;
- X
- Xtypedef_list
- X : /* empty */
- X | typedef_list typedef
- X ;
- X
- Xtypedef
- X : TYPE type_name '=' type ';'
- X {
- X str_free($2);
- X pop_name();
- X }
- X | '#' INCLUDE STRING_CONSTANT
- X {
- X lex_open($3->str_text);
- X str_free($3);
- X }
- X ;
- X
- Xtype_name
- X : NAME
- X {
- X $$ = $1;
- X push_name_abs($1);
- X }
- X ;
- X
- Xfield
- X : field_name '=' type ';'
- X {
- X id_assign($1, ID_CLASS_FIELD, (long)$3);
- X $$ = $1;
- X pop_name();
- X }
- X ;
- X
- Xfield_name
- X : NAME
- X {
- X push_name($1);
- X $$ = $1;
- X }
- X ;
- X
- Xtype
- X : STRING
- X {
- X $$ = type_create_string();
- X }
- X | INTEGER
- X {
- X $$ = type_create_integer();
- X }
- X | NAME
- X {
- X type_ty *tp;
- X
- X if (id_search($1, ID_CLASS_TYPE, (long *)&tp))
- X {
- X /* $$ = type_create_ref(get_name(), $1); */
- X $$ = tp;
- X }
- X else
- X {
- X yyerror("type \"%s\" undefined", $1->str_text);
- X $$ = type_create_integer();
- X }
- X str_free($1);
- X }
- X | structure
- X { $$ = $1; }
- X | list
- X { $$ = $1; }
- X | enumeration
- X { $$ = $1; }
- X ;
- X
- Xstructure
- X : '{' field_list '}'
- X {
- X string_ty *s;
- X
- X s = get_name();
- X $$ = type_create_struct(s, $2, 0);
- X define_type(s, $$);
- X }
- X ;
- X
- Xfield_list
- X : /* empty */
- X {
- X $$ = 0;
- X }
- X | field_list field
- X {
- X $$ = $1;
- X pl_append(&$$, $2);
- X }
- X ;
- X
- Xlist
- X : '[' type ']'
- X {
- X string_ty *s;
- X static string_ty *list;
- X
- X if (!list)
- X list = str_from_c("list");
- X push_name(list);
- X s = get_name();
- X $$ = type_create_list(s, $2);
- X define_type(s, $$);
- X pop_name();
- X }
- X ;
- X
- Xenumeration
- X : '(' enum_list optional_comma ')'
- X {
- X string_ty *s;
- X
- X s = get_name();
- X $$ = type_create_enum(s, $2);
- X define_type(s, $$);
- X }
- X ;
- X
- Xoptional_comma
- X : /* empty */
- X | ','
- X ;
- X
- Xenum_list
- X : enum_name
- X {
- X $$ = 0;
- X pl_append(&$$, $1);
- X }
- X | enum_list ',' enum_name
- X {
- X $$ = $1;
- X pl_append(&$$, $3);
- X }
- X ;
- X
- Xenum_name
- X : NAME
- X {
- X string_ty *s;
- X
- X push_name($1);
- X s = get_name();
- X pop_name();
- X id_assign(s, ID_CLASS_ENUMEL, (long)$1);
- X $$ = s;
- X }
- X ;
- END_OF_FILE
- if test 9538 -ne `wc -c <'fmtgen/parse.y'`; then
- echo shar: \"'fmtgen/parse.y'\" unpacked with wrong size!
- fi
- # end of 'fmtgen/parse.y'
- fi
- if test -f 'test/00/t0006a.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'test/00/t0006a.sh'\"
- else
- echo shar: Extracting \"'test/00/t0006a.sh'\" \(8528 characters\)
- sed "s/^X//" >'test/00/t0006a.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 'aegis -DIFFerence' when the edit number is out-of-date.
- 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' when the edit number is out-of-date" 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
- 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#
- 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./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#
- 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# 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# 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 -c 2 -p foo
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -t -nl -v -lib $worklib -c 2 -p foo
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -t -bl -nl -v -lib $worklib -c 2 -p foo
- Xif test $? -ne 0 ; then fail; fi
- X
- X#
- X# pass the integration
- X# make sure it create the files, etc
- X#
- X./bin/aegis -intpass -nl -lib $worklib -c 2 -p foo
- Xif test $? -ne 0 ; then fail; fi
- X
- X#
- X# difference change 3
- X#
- X./bin/aegis -diff -nl -c 3 -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 8528 -ne `wc -c <'test/00/t0006a.sh'`; then
- echo shar: \"'test/00/t0006a.sh'\" unpacked with wrong size!
- fi
- # end of 'test/00/t0006a.sh'
- fi
- if test -f 'test/00/t0009a.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'test/00/t0009a.sh'\"
- else
- echo shar: Extracting \"'test/00/t0009a.sh'\" \(8705 characters\)
- sed "s/^X//" >'test/00/t0009a.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 -New_ReLeaSe functionality.
- 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 -New_ReLeaSe functionality 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
- Xworkproj2=$work/foo.proj2
- 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# 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#
- 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# 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/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
- Xif test $? -ne 0 ; then fail; fi
- Xcat > $workchan/config << 'end'
- Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' 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
- 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#
- 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
- Xif test $? -ne 0 ; then fail; fi
- 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# create the new release
- X#
- X./bin/aegis -nrls -l -v -lib $worklib
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -nrls -v foo -dir $workproj2 -lib $worklib -nl
- Xif test $? -ne 0 ; then fail; fi
- Xls -lRA $workproj2
- Xcat $workproj2/info/change/0/001
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/state
- Xif test $? -ne 0 ; then fail; fi
- Xls -lgRA $worklib
- X./bin/aegis -nrls -l -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 = "Second change of second project";
- Xcause = internal_enhancement;
- Xend
- X./bin/aegis -new_change $tmp -project foo.1.1 -v -lib $worklib
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/change/0/002
- Xif test $? -ne 0 ; then fail; fi
- X
- X#
- X# start work on change 2 of foo.1.1
- X#
- X./bin/aegis -devbeg 2 -p foo.1.1 -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 -v -nl -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/change/0/002
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/state
- Xif test $? -ne 0 ; then fail; fi
- Xcat $worklib/user/$USER
- Xif test $? -ne 0 ; then fail; fi
- Xls -lRA $work
- 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.1.1
- Xif test $? -ne 0 ; then fail; fi
- Xcat > $workchan/test/00/t0002a.sh << 'end'
- X#!/bin/sh
- X#
- X# Project: "foo.1.1"
- 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
- 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 -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -diff -nl -v -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -test -nl -v -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -test -bl -nl -v -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workchan/main.c,D
- 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.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -revpass -v -c 2 -p foo.1.1 -lib $worklib
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -intbeg -v -c 2 -p foo.1.1 -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.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -t -nl -v -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- X./bin/aegis -t -bl -nl -v -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- X
- X#
- X# pass the integration
- X# make sure it create the files, etc
- X#
- X./bin/aegis -intpass -nl -lib $worklib -p foo.1.1
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/change/0/002
- Xif test $? -ne 0 ; then fail; fi
- Xcat $workproj2/info/state
- Xif test $? -ne 0 ; then fail; fi
- Xcat $worklib/user/$USER
- Xif test $? -ne 0 ; then fail; fi
- Xls -lR $work
- X./bin/aegis -l projhist -v -p foo.1.1 -lib $worklib
- 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 8705 -ne `wc -c <'test/00/t0009a.sh'`; then
- echo shar: \"'test/00/t0009a.sh'\" unpacked with wrong size!
- fi
- # end of 'test/00/t0009a.sh'
- fi
- echo shar: End of archive 7 \(of 19\).
- cp /dev/null ark7isdone
- 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
-