home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / aegis-2.1 / part07 < prev    next >
Text File  |  1993-09-24  |  155KB  |  6,464 lines

  1. Newsgroups: comp.sources.unix
  2. From: pmiller@bmr.gov.au (Peter Miller)
  3. Subject: v27i042: aegis - project change supervisor (V2.1), Part07/19
  4. References: <1.748951883.12788@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: pmiller@bmr.gov.au (Peter Miller)
  9. Posting-Number: Volume 27, Issue 42
  10. Archive-Name: aegis-2.1/part07
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 7 (of 19)."
  19. # Contents:  aegis/aecd.c aegis/aeibu.c aegis/aencu.c aegis/aermpr.c
  20. #   aegis/aerp.c aegis/aerpu.c aegis/commit.c aux/Makefile.sh
  21. #   common/arglex.c doc/c5.0.so fmtgen/id.c fmtgen/lex.c
  22. #   fmtgen/parse.y test/00/t0006a.sh test/00/t0009a.sh
  23. # Wrapped by vixie@gw.home.vix.com on Sat Sep 25 03:00:37 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'aegis/aecd.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'aegis/aecd.c'\"
  27. else
  28. echo shar: Extracting \"'aegis/aecd.c'\" \(9595 characters\)
  29. sed "s/^X//" >'aegis/aecd.c' <<'END_OF_FILE'
  30. X/*
  31. X *    aegis - project change supervisor
  32. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  33. X *    All rights reserved.
  34. X *
  35. X *    This program is free software; you can redistribute it and/or modify
  36. X *    it under the terms of the GNU General Public License as published by
  37. X *    the Free Software Foundation; either version 2 of the License, or
  38. X *    (at your option) any later version.
  39. X *
  40. X *    This program is distributed in the hope that it will be useful,
  41. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  42. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  43. X *    GNU General Public License for more details.
  44. X *
  45. X *    You should have received a copy of the GNU General Public License
  46. X *    along with this program; if not, write to the Free Software
  47. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  48. X *
  49. X * MANIFEST: functions to change directory or determine paths
  50. X */
  51. X
  52. X#include <stdio.h>
  53. X#include <stdlib.h>
  54. X
  55. X#include <aecd.h>
  56. X#include <ael.h>
  57. X#include <arglex2.h>
  58. X#include <change.h>
  59. X#include <error.h>
  60. X#include <help.h>
  61. X#include <option.h>
  62. X#include <os.h>
  63. X#include <project.h>
  64. X#include <trace.h>
  65. X#include <user.h>
  66. X
  67. X
  68. Xstatic void change_directory_usage _((void));
  69. X
  70. Xstatic void
  71. Xchange_directory_usage()
  72. X{
  73. X    char        *progname;
  74. X
  75. X    progname = option_progname_get();
  76. X    fprintf(stderr, "usage: %s -Change_Directory [ <option>... ][ <subdir> ]\n", progname);
  77. X    fprintf(stderr, "       %s -Change_Directory -List [ <option>... ]\n", progname);
  78. X    fprintf(stderr, "       %s -Change_Directory -Help\n", progname);
  79. X    quit(1);
  80. X}
  81. X
  82. X
  83. Xstatic void change_directory_help _((void));
  84. X
  85. Xstatic void
  86. Xchange_directory_help()
  87. X{
  88. X    static char *text[] =
  89. X    {
  90. X"NAME",
  91. X"    %s -Change_Directory - change directory",
  92. X"",
  93. X"SYNOPSIS",
  94. X"    %s -Change_Directory [ <option>... ][ <relative-path> ]",
  95. X"    %s -Change_Directory -List [ <option>... ]",
  96. X"    %s -Change_Directory -Help",
  97. X"",
  98. X"DESCRIPTION",
  99. X"    The %s -Change_Directory command is used to obtain a",
  100. X"    path to change directory to.  If the relative-path is",
  101. X"    supplied, this will be added to the output.",
  102. X"",
  103. X"    This command is usually used to calculate an argument for",
  104. X"    cd(1), howver it can also be used to abtain an absolute",
  105. X"    path for change and project files.",
  106. X"",
  107. X"OPTIONS",
  108. X"    The following options are understood:",
  109. X"",
  110. X"    -BaseLine",
  111. X"        This option may be used to specify that the",
  112. X"        project baseline is the subject of the command.",
  113. X"",
  114. X"    -Change <number>",
  115. X"        This option may be used to specify a particular",
  116. X"        change within a project.  When no -Change option is",
  117. X"        specified, the AEGIS_CHANGE environment variable is",
  118. X"        consulted.  If that does not exist, the user's",
  119. X"        $HOME/.aegisrc file is examined for a default change",
  120. X"        field (see aeuconf(5) for more information).  If",
  121. X"        that does not exist, when the user is only working",
  122. X"        on one change within a project, that is the default",
  123. X"        change number.  Otherwise, it is an error.",
  124. X"",
  125. X"    -Development_Directory",
  126. X"        This option is ised to specify that the",
  127. X"        development directory is the subject of the",
  128. X"        command.  This is only useful for a change which",
  129. X"        is in the 'being_integrated' state, when the",
  130. X"        default is the integration directory.",
  131. X"",
  132. X"    -Help",
  133. X"        This option may be used to obtain more",
  134. X"        information about how to use the %s program.",
  135. X"",
  136. X"    -List",
  137. X"        This option may be used to obtain a list of",
  138. X"        suitable subjects for this command.  The list may",
  139. X"        be more general than expected.",
  140. X"",
  141. X"    -Project <name>",
  142. X"        This option may be used to select the project of",
  143. X"        interest.  When no -Project option is specified, the",
  144. X"        AEGIS_PROJECT environment variable is consulted.  If",
  145. X"        that does not exist, the user's $HOME/.aegisrc file",
  146. X"        is examined for a default project field (see",
  147. X"        aeuconf(5) for more information).  If that does not",
  148. X"        exist, when the user is only working on changes",
  149. X"        within a single project, the project name defaults",
  150. X"        to that project.  Otherwise, it is an error.",
  151. X"",
  152. X"    -TERse",
  153. X"        This option may be used to cause listings to",
  154. X"        produce the bare minimum of information.  It is",
  155. X"        usually useful for shell scripts.",
  156. X"",
  157. X"    -Verbose",
  158. X"        This option may be used to cause %s to produce",
  159. X"        more output.  By default %s only produces",
  160. X"        output on errors.  When used with the -List",
  161. X"        option this option causes column headings to be",
  162. X"        added.",
  163. X"",
  164. X"    All options are case insensitive.  Options may be",
  165. X"    abbreviated; the abbreviation is the upper case letters.",
  166. X"    Options and other command line arguments may be mixed",
  167. X"    arbitrarily on the command line.",
  168. X"",
  169. X"RECOMMENDED ALIAS",
  170. X"    The recommended alias for this command is",
  171. X"    csh%%    alias aecd 'cd `%s -cd \\!* -v`'",
  172. X"    sh$    aecd(){cd `%s -cd $* -v`}",
  173. X"",
  174. X"ERRORS",
  175. X"    It is an error if the specified change is not in a state",
  176. X"    where it has a directory to change to.",
  177. X"",
  178. X"EXIT STATUS",
  179. X"    The %s command will exit with a status of 1 on any",
  180. X"    error.    The %s command will only exit with a status of",
  181. X"    0 if there are no errors.",
  182. X"",
  183. X"COPYRIGHT",
  184. X"    %C",
  185. X"",
  186. X"AUTHOR",
  187. X"    %A",
  188. X    };
  189. X
  190. X    help(text, SIZEOF(text), change_directory_usage);
  191. X}
  192. X
  193. X
  194. Xstatic void change_directory_list _((void));
  195. X
  196. Xstatic void
  197. Xchange_directory_list()
  198. X{
  199. X    string_ty    *project_name;
  200. X
  201. X    trace(("change_directory_list()\n{\n"/*}*/));
  202. X    arglex();
  203. X    project_name = 0;
  204. X    while (arglex_token != arglex_token_eoln)
  205. X    {
  206. X        switch (arglex_token)
  207. X        {
  208. X        default:
  209. X            generic_argument(change_directory_usage);
  210. X            continue;
  211. X
  212. X        case arglex_token_project:
  213. X            if (arglex() != arglex_token_string)
  214. X                change_directory_usage();
  215. X            if (project_name)
  216. X                fatal("duplicate -Project option");
  217. X            project_name = str_from_c(arglex_value.alv_string);
  218. X            break;
  219. X        }
  220. X        arglex();
  221. X    }
  222. X    list_changes_in_state_mask
  223. X    (
  224. X        project_name,
  225. X        (
  226. X            (1 << cstate_state_being_developed)
  227. X        |
  228. X            (1 << cstate_state_being_reviewed)
  229. X        |
  230. X            (1 << cstate_state_awaiting_integration)
  231. X        |
  232. X            (1 << cstate_state_being_integrated)
  233. X        )
  234. X    );
  235. X    if (project_name)
  236. X        str_free(project_name);
  237. X    trace((/*{*/"}\n"));
  238. X}
  239. X
  240. X
  241. Xstatic void change_directory_main _((void));
  242. X
  243. Xstatic void
  244. Xchange_directory_main()
  245. X{
  246. X    char        *subdir = 0;
  247. X    int        devdir = 0;
  248. X    cstate        cstate_data;
  249. X    string_ty    *d;
  250. X    int        baseline = 0;
  251. X    string_ty    *project_name;
  252. X    project_ty    *pp;
  253. X    long        change_number;
  254. X    change_ty    *cp;
  255. X    user_ty        *up;
  256. X
  257. X    trace(("change_directory_main()\n{\n"/*}*/));
  258. X    project_name = 0;
  259. X    change_number = 0;
  260. X    while (arglex_token != arglex_token_eoln)
  261. X    {
  262. X        switch (arglex_token)
  263. X        {
  264. X        default:
  265. X            generic_argument(change_directory_usage);
  266. X            continue;
  267. X
  268. X        case arglex_token_string:
  269. X            if (subdir)
  270. X                fatal("too many subdirectories specified");
  271. X            subdir = arglex_value.alv_string;
  272. X            if (!*subdir || *subdir == '/')
  273. X                fatal("subdirectory must be relative");
  274. X            break;
  275. X
  276. X        case arglex_token_development_directory:
  277. X            if (devdir)
  278. X                   fatal("duplicate -Develompent_Directory option");
  279. X            if (baseline)
  280. X            {
  281. X                bad_combo:
  282. X                fatal
  283. X                (
  284. X         "only one of -BaseLine and -Development_Directory may be specified"
  285. X                );
  286. X            }
  287. X            devdir = 1;
  288. X            break;
  289. X
  290. X        case arglex_token_baseline:
  291. X            if (baseline)
  292. X                fatal("duplicate -BaseLine option");
  293. X            if (devdir)
  294. X                goto bad_combo;
  295. X            baseline = 1;
  296. X            break;
  297. X
  298. X        case arglex_token_change:
  299. X            if (arglex() != arglex_token_number)
  300. X                change_directory_usage();
  301. X            /* fall through... */
  302. X
  303. X        case arglex_token_number:
  304. X            if (change_number)
  305. X                fatal("duplicate -Change option");
  306. X            change_number = arglex_value.alv_number;
  307. X            if (change_number < 1)
  308. X                fatal("change %ld out of range", change_number);
  309. X            break;
  310. X
  311. X        case arglex_token_project:
  312. X            if (arglex() != arglex_token_string)
  313. X                change_directory_usage();
  314. X            if (project_name)
  315. X                fatal("duplicate -Project option");
  316. X            project_name = str_from_c(arglex_value.alv_string);
  317. X            break;
  318. X        }
  319. X        arglex();
  320. X    }
  321. X
  322. X    /*
  323. X     * locate project data
  324. X     */
  325. X    if (!project_name)
  326. X        project_name = user_default_project();
  327. X    pp = project_alloc(project_name);
  328. X    str_free(project_name);
  329. X    project_bind_existing(pp);
  330. X
  331. X    /*
  332. X     * locate user data
  333. X     */
  334. X    up = user_executing(pp);
  335. X
  336. X    /*
  337. X     * figure out where to go
  338. X     */
  339. X    if (baseline)
  340. X    {
  341. X        if (change_number)
  342. X        {
  343. X            fatal
  344. X            (
  345. X              "the -BaseLine and -Change options are mutually exclusive"
  346. X            );
  347. X        }
  348. X        d = project_baseline_path_get(pp, 0);
  349. X        cp = 0;
  350. X    }
  351. X    else
  352. X    {
  353. X        /*
  354. X         * locate change data
  355. X         */
  356. X        if (!change_number)
  357. X            change_number = user_default_change(up);
  358. X        cp = change_alloc(pp, change_number);
  359. X        change_bind_existing(cp);
  360. X
  361. X        cstate_data = change_cstate_get(cp);
  362. X        switch (cstate_data->state)
  363. X        {
  364. X        default:
  365. X            change_fatal(cp, "no directory");
  366. X
  367. X        case cstate_state_being_integrated:
  368. X            if (!devdir)
  369. X            {
  370. X                d = change_integration_directory_get(cp, 0);
  371. X                break;
  372. X            }
  373. X            /* fall through... */
  374. X
  375. X        case cstate_state_awaiting_integration:
  376. X        case cstate_state_being_reviewed:
  377. X        case cstate_state_being_developed:
  378. X            d = change_development_directory_get(cp, 0);
  379. X            break;
  380. X        }
  381. X    }
  382. X
  383. X    /*
  384. X     * Add in the extra path elements as necessary.
  385. X     * Flatten it out if they go up the tree (etc).
  386. X     */
  387. X    if (subdir)
  388. X    {
  389. X        string_ty *tmp;
  390. X
  391. X        tmp = str_format("%S/%s", d, subdir);
  392. X        user_become(up);
  393. X        d = os_pathname(tmp, 0);
  394. X        user_become_undo();
  395. X        str_free(tmp);
  396. X    }
  397. X
  398. X    /*
  399. X     * print out the path
  400. X     */
  401. X    printf("%s\n", d->str_text);
  402. X    if (!cp)
  403. X        project_verbose(pp, "%s", d->str_text);
  404. X    else
  405. X    {
  406. X        change_verbose(cp, "%s", d->str_text);
  407. X        change_free(cp);
  408. X    }
  409. X    project_free(pp);
  410. X    user_free(up);
  411. X    trace((/*{*/"}\n"));
  412. X}
  413. X
  414. X
  415. Xvoid
  416. Xchange_directory()
  417. X{
  418. X    trace(("change_directory()\n{\n"/*}*/));
  419. X    switch (arglex())
  420. X    {
  421. X    default:
  422. X        change_directory_main();
  423. X        break;
  424. X
  425. X    case arglex_token_help:
  426. X        change_directory_help();
  427. X        break;
  428. X
  429. X    case arglex_token_list:
  430. X        change_directory_list();
  431. X        break;
  432. X    }
  433. X    trace((/*{*/"}\n"));
  434. X}
  435. END_OF_FILE
  436. if test 9595 -ne `wc -c <'aegis/aecd.c'`; then
  437.     echo shar: \"'aegis/aecd.c'\" unpacked with wrong size!
  438. fi
  439. # end of 'aegis/aecd.c'
  440. fi
  441. if test -f 'aegis/aeibu.c' -a "${1}" != "-c" ; then 
  442.   echo shar: Will not clobber existing file \"'aegis/aeibu.c'\"
  443. else
  444. echo shar: Extracting \"'aegis/aeibu.c'\" \(10341 characters\)
  445. sed "s/^X//" >'aegis/aeibu.c' <<'END_OF_FILE'
  446. X/*
  447. X *    aegis - project change supervisor
  448. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  449. X *    All rights reserved.
  450. X *
  451. X *    This program is free software; you can redistribute it and/or modify
  452. X *    it under the terms of the GNU General Public License as published by
  453. X *    the Free Software Foundation; either version 2 of the License, or
  454. X *    (at your option) any later version.
  455. X *
  456. X *    This program is distributed in the hope that it will be useful,
  457. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  458. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  459. X *    GNU General Public License for more details.
  460. X *
  461. X *    You should have received a copy of the GNU General Public License
  462. X *    along with this program; if not, write to the Free Software
  463. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  464. X *
  465. X * MANIFEST: functions for implementing integrate begin undo
  466. X */
  467. X
  468. X#include <stdio.h>
  469. X#include <stdlib.h>
  470. X#include <string.h>
  471. X#include <sys/types.h>
  472. X#include <sys/stat.h>
  473. X
  474. X#include <aeibu.h>
  475. X#include <ael.h>
  476. X#include <arglex2.h>
  477. X#include <commit.h>
  478. X#include <change.h>
  479. X#include <dir.h>
  480. X#include <error.h>
  481. X#include <file.h>
  482. X#include <help.h>
  483. X#include <lock.h>
  484. X#include <log.h>
  485. X#include <option.h>
  486. X#include <os.h>
  487. X#include <project.h>
  488. X#include <sub.h>
  489. X#include <trace.h>
  490. X#include <undo.h>
  491. X#include <user.h>
  492. X
  493. X
  494. Xstatic void integrate_begin_undo_usage _((void));
  495. X
  496. Xstatic void
  497. Xintegrate_begin_undo_usage()
  498. X{
  499. X    char        *progname;
  500. X
  501. X    progname = option_progname_get();
  502. X    fprintf(stderr, "usage: %s -Integrate_Begin_Undo [ <option>... ]\n", progname);
  503. X    fprintf(stderr, "       %s -Integrate_Begin_Undo -List [ <option>... ]\n", progname);
  504. X    fprintf(stderr, "       %s -Integrate_Begin_Undo -Help\n", progname);
  505. X    quit(1);
  506. X}
  507. X
  508. X
  509. Xstatic void integrate_begin_undo_help _((void));
  510. X
  511. Xstatic void
  512. Xintegrate_begin_undo_help()
  513. X{
  514. X    static char *text[] =
  515. X    {
  516. X"NAME",
  517. X"    %s -Integrate_Begin_Undo - reverse the aeib command",
  518. X"",
  519. X"SYNOPSIS",
  520. X"    %s -Integrate_Begin_Undo [ <option>... ]",
  521. X"    %s -Integrate_Begin_Undo -List [ <option>... ]",
  522. X"    %s -Integrate_Begin_Undo -Help",
  523. X"",
  524. X"DESCRIPTION",
  525. X"    The %s -Integrate_Begin_Undo command is used to",
  526. X"    reverse the actions of the '%s -Integrate_Begin'",
  527. X"    command.",
  528. X"",
  529. X"    Successful execution of this command will move the change",
  530. X"    from the 'being_integrated' state to the",
  531. X"    'awaiting_integration' state.  The integration directory",
  532. X"    will be deleted.  The change will cease to be assigned to",
  533. X"    the current user.",
  534. X"",
  535. X"OPTIONS",
  536. X"    The following options are understood:",
  537. X"",
  538. X"    -Change <number>",
  539. X"        This option may be used to specify a particular",
  540. X"        change within a project.  When no -Change option is",
  541. X"        specified, the AEGIS_CHANGE environment variable is",
  542. X"        consulted.  If that does not exist, the user's",
  543. X"        $HOME/.aegisrc file is examined for a default change",
  544. X"        field (see aeuconf(5) for more information).  If",
  545. X"        that does not exist, when the user is only working",
  546. X"        on one change within a project, that is the default",
  547. X"        change number.  Otherwise, it is an error.",
  548. X"",
  549. X"    -Help",
  550. X"        This option may be used to obtain more",
  551. X"        information about how to use the %s program.",
  552. X"",
  553. X"    -Keep",
  554. X"        This option may be used to retain files and/or",
  555. X"        directories usually deleted by the command.",
  556. X"",
  557. X"    -List",
  558. X"        This option may be used to obtain a list of",
  559. X"        suitable subjects for this command.  The list may",
  560. X"        be more general than expected.",
  561. X"",
  562. X"    -Project <name>",
  563. X"        This option may be used to select the project of",
  564. X"        interest.  When no -Project option is specified, the",
  565. X"        AEGIS_PROJECT environment variable is consulted.  If",
  566. X"        that does not exist, the user's $HOME/.aegisrc file",
  567. X"        is examined for a default project field (see",
  568. X"        aeuconf(5) for more information).  If that does not",
  569. X"        exist, when the user is only working on changes",
  570. X"        within a single project, the project name defaults",
  571. X"        to that project.  Otherwise, it is an error.",
  572. X"",
  573. X"    -TERse",
  574. X"        This option may be used to cause listings to",
  575. X"        produce the bare minimum of information.  It is",
  576. X"        usually useful for shell scripts.",
  577. X"",
  578. X"    -Verbose",
  579. X"        This option may be used to cause %s to produce",
  580. X"        more output.  By default %s only produces",
  581. X"        output on errors.  When used with the -List",
  582. X"        option this option causes column headings to be",
  583. X"        added.",
  584. X"",
  585. X"    All options may be abbreviated; the abbreviation is",
  586. X"    documented as the upper case letters, all lower case",
  587. X"    letters and underscores (_) are optional.  You must use",
  588. X"    consecutive sequences of optional letters.",
  589. X"",
  590. X"    All options are case insensitive, you may type them in",
  591. X"    upper case or lower case or a combination of both, case",
  592. X"    is not important.",
  593. X"",
  594. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  595. X"    are all interpreted to mean the -Project option.  The",
  596. X"    argument \"-prj\" will not be understood, because",
  597. X"    consecutive optional characters were not supplied.",
  598. X"",
  599. X"    Options and other command line arguments may be mixed",
  600. X"    arbitrarily on the command line, after the function",
  601. X"    selectors.",
  602. X"",
  603. X"    The GNU long option names are understood.  Since all",
  604. X"    option names for aegis are long, this means ignoring the",
  605. X"    extra leading '-'.  The \"--option=value\" convention is",
  606. X"    also understood.",
  607. X"",
  608. X"RECOMMENDED ALIAS",
  609. X"    The recommended alias for this command is",
  610. X"    csh%%    alias aeibu '%s -ibu \\!* -v'",
  611. X"    sh$    aeibu(){%s -ibu $* -v}",
  612. X"",
  613. X"ERRORS",
  614. X"    It is an error if the change is not in the",
  615. X"    'being_integrated' state.",
  616. X"    It is an error if the change is not assigned to the",
  617. X"    current user.",
  618. X"",
  619. X"EXIT STATUS",
  620. X"    The %s command will exit with a status of 1 on any",
  621. X"    error.    The %s command will only exit with a status of",
  622. X"    0 if there are no errors.",
  623. X"",
  624. X"COPYRIGHT",
  625. X"    %C",
  626. X"",
  627. X"AUTHOR",
  628. X"    %A",
  629. X    };
  630. X
  631. X    help(text, SIZEOF(text), integrate_begin_undo_usage);
  632. X}
  633. X
  634. X
  635. Xstatic void integrate_begin_undo_list _((void (*)(void)));
  636. X
  637. Xstatic void
  638. Xintegrate_begin_undo_list(usage)
  639. X    void        (*usage)_((void));
  640. X{
  641. X    string_ty    *project_name;
  642. X
  643. X    trace(("integrate_begin_undo_list()\n{\n"/*}*/));
  644. X    arglex();
  645. X    project_name = 0;
  646. X    while (arglex_token != arglex_token_eoln)
  647. X    {
  648. X        switch (arglex_token)
  649. X        {
  650. X        default:
  651. X            generic_argument(usage);
  652. X            continue;
  653. X
  654. X        case arglex_token_project:
  655. X            if (arglex() != arglex_token_string)
  656. X                usage();
  657. X            if (project_name)
  658. X                fatal("duplicate -Project option");
  659. X            project_name = str_from_c(arglex_value.alv_string);
  660. X            break;
  661. X        }
  662. X        arglex();
  663. X    }
  664. X    list_changes_in_state_mask
  665. X    (
  666. X        project_name,
  667. X        1 << cstate_state_being_integrated
  668. X    );
  669. X    if (project_name)
  670. X        str_free(project_name);
  671. X    trace((/*{*/"}\n"));
  672. X}
  673. X
  674. X
  675. Xstatic void integrate_begin_undo_main _((void));
  676. X
  677. Xstatic void
  678. Xintegrate_begin_undo_main()
  679. X{
  680. X    cstate        cstate_data;
  681. X    pstate        pstate_data;
  682. X    cstate_history    history_data;
  683. X    string_ty    *dir;
  684. X    string_ty    *project_name;
  685. X    project_ty    *pp;
  686. X    long        change_number;
  687. X    change_ty    *cp;
  688. X    user_ty        *up;
  689. X
  690. X    trace(("integrate_begin_main()\n{\n"/*}*/));
  691. X    project_name = 0;
  692. X    change_number = 0;
  693. X    while (arglex_token != arglex_token_eoln)
  694. X    {
  695. X        switch (arglex_token)
  696. X        {
  697. X        default:
  698. X            generic_argument(integrate_begin_undo_usage);
  699. X            continue;
  700. X
  701. X        case arglex_token_change:
  702. X            if (arglex() != arglex_token_number)
  703. X                integrate_begin_undo_usage();
  704. X            /* fall through... */
  705. X
  706. X        case arglex_token_number:
  707. X            if (change_number)
  708. X                fatal("duplicate -Change option");
  709. X            change_number = arglex_value.alv_number;
  710. X            if (change_number < 1)
  711. X                fatal("change %ld out of range", change_number);
  712. X            break;
  713. X
  714. X        case arglex_token_project:
  715. X            if (arglex() != arglex_token_string)
  716. X                integrate_begin_undo_usage();
  717. X            /* fall through... */
  718. X
  719. X        case arglex_token_string:
  720. X            if (project_name)
  721. X                fatal("duplicate -Project option");
  722. X            project_name = str_from_c(arglex_value.alv_string);
  723. X            break;
  724. X        }
  725. X        arglex();
  726. X    }
  727. X
  728. X    /*
  729. X     * locate project data
  730. X     */
  731. X    if (!project_name)
  732. X        project_name = user_default_project();
  733. X    pp = project_alloc(project_name);
  734. X    str_free(project_name);
  735. X    project_bind_existing(pp);
  736. X
  737. X    /*
  738. X     * locate user data
  739. X     */
  740. X    up = user_executing(pp);
  741. X
  742. X    /*
  743. X     * locate change data
  744. X     */
  745. X    if (!change_number)
  746. X        change_number = user_default_change(up);
  747. X    cp = change_alloc(pp, change_number);
  748. X    change_bind_existing(cp);
  749. X
  750. X    /*
  751. X     * lock the change for writing
  752. X     */
  753. X    project_pstate_lock_prepare(pp);
  754. X    change_cstate_lock_prepare(cp);
  755. X    user_ustate_lock_prepare(up);
  756. X    lock_take();
  757. X    cstate_data = change_cstate_get(cp);
  758. X    pstate_data = project_pstate_get(pp);
  759. X
  760. X    /*
  761. X     * it is an error if the change is not in the 'being_integrated' state.
  762. X     */
  763. X    if (cstate_data->state != cstate_state_being_integrated)
  764. X        change_fatal(cp, "not in 'being_integrated' state");
  765. X    if (!str_equal(change_integrator_name(cp), user_name(up)))
  766. X    {
  767. X        change_fatal
  768. X        (
  769. X            cp,
  770. X            "user \"%S\" is not the integrator",
  771. X            user_name(up)
  772. X        );
  773. X    }
  774. X
  775. X    /*
  776. X     * Change the state.
  777. X     * Add to the change's history.
  778. X     */
  779. X    cstate_data->state = cstate_state_awaiting_integration;
  780. X    history_data = change_history_new(cp, up);
  781. X    history_data->what = cstate_history_what_integrate_begin_undo;
  782. X
  783. X    /*
  784. X     * remove it from the user's change list
  785. X     */
  786. X    user_own_remove(up, project_name_get(pp), change_number);
  787. X
  788. X    /*
  789. X     * Note that the project has no current integration
  790. X     */
  791. X    pstate_data->currently_integrating_change = 0;
  792. X    dir = str_copy(change_integration_directory_get(cp, 1));
  793. X    change_integration_directory_clear(cp);
  794. X    cstate_data->build_time = 0;
  795. X    cstate_data->delta_number = 0;
  796. X
  797. X    /*
  798. X     * Complain if they are in the integration directory,
  799. X     * because the rmdir at the end can't then run to completion.
  800. X     */
  801. X    os_become_orig();
  802. X    if (os_below_dir(dir, os_curdir()))
  803. X        change_fatal(cp, "please leave the integration directory");
  804. X    os_become_undo();
  805. X
  806. X    /*
  807. X     * write out the data and release the locks
  808. X     */
  809. X    change_cstate_write(cp);
  810. X    user_ustate_write(up);
  811. X    project_pstate_write(pp);
  812. X    user_become(up);
  813. X    commit_rmdir_tree_errok(dir);
  814. X    user_become_undo();
  815. X    str_free(dir);
  816. X    commit();
  817. X    lock_release();
  818. X
  819. X    /*
  820. X     * verbose success message
  821. X     */
  822. X    change_verbose(cp, "integrate begin undo");
  823. X    change_free(cp);
  824. X    project_free(pp);
  825. X    user_free(up);
  826. X    trace((/*{*/"}\n"));
  827. X}
  828. X
  829. X
  830. Xvoid
  831. Xintegrate_begin_undo()
  832. X{
  833. X    trace(("integrate_begin_undo()\n{\n"/*}*/));
  834. X    switch (arglex())
  835. X    {
  836. X    default:
  837. X        integrate_begin_undo_main();
  838. X        break;
  839. X
  840. X    case arglex_token_help:
  841. X        integrate_begin_undo_help();
  842. X        break;
  843. X
  844. X    case arglex_token_list:
  845. X        integrate_begin_undo_list(integrate_begin_undo_usage);
  846. X        break;
  847. X    }
  848. X    trace((/*{*/"}\n"));
  849. X}
  850. END_OF_FILE
  851. if test 10341 -ne `wc -c <'aegis/aeibu.c'`; then
  852.     echo shar: \"'aegis/aeibu.c'\" unpacked with wrong size!
  853. fi
  854. # end of 'aegis/aeibu.c'
  855. fi
  856. if test -f 'aegis/aencu.c' -a "${1}" != "-c" ; then 
  857.   echo shar: Will not clobber existing file \"'aegis/aencu.c'\"
  858. else
  859. echo shar: Extracting \"'aegis/aencu.c'\" \(9535 characters\)
  860. sed "s/^X//" >'aegis/aencu.c' <<'END_OF_FILE'
  861. X/*
  862. X *    aegis - project change supervisor
  863. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  864. X *    All rights reserved.
  865. X *
  866. X *    This program is free software; you can redistribute it and/or modify
  867. X *    it under the terms of the GNU General Public License as published by
  868. X *    the Free Software Foundation; either version 2 of the License, or
  869. X *    (at your option) any later version.
  870. X *
  871. X *    This program is distributed in the hope that it will be useful,
  872. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  873. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  874. X *    GNU General Public License for more details.
  875. X *
  876. X *    You should have received a copy of the GNU General Public License
  877. X *    along with this program; if not, write to the Free Software
  878. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  879. X *
  880. X * MANIFEST: functions to implement new change undo
  881. X */
  882. X
  883. X#include <stdio.h>
  884. X#include <stdlib.h>
  885. X#include <time.h>
  886. X
  887. X#include <aeca.h>
  888. X#include <ael.h>
  889. X#include <aencu.h>
  890. X#include <arglex2.h>
  891. X#include <cattr.h>
  892. X#include <change.h>
  893. X#include <col.h>
  894. X#include <commit.h>
  895. X#include <common.h>
  896. X#include <error.h>
  897. X#include <help.h>
  898. X#include <lock.h>
  899. X#include <option.h>
  900. X#include <os.h>
  901. X#include <project.h>
  902. X#include <trace.h>
  903. X#include <user.h>
  904. X
  905. X
  906. Xstatic void new_change_undo_usage _((void));
  907. X
  908. Xstatic void
  909. Xnew_change_undo_usage()
  910. X{
  911. X    char    *progname;
  912. X
  913. X    progname = option_progname_get();
  914. X    fprintf(stderr, "usage: %s -New_Change_Undo [ <option>... ]\n", progname);
  915. X    fprintf(stderr, "       %s -New_Change_Undo -List [ <option>... ]\n", progname);
  916. X    fprintf(stderr, "       %s -New_Change_Undo -Help\n", progname);
  917. X    quit(1);
  918. X}
  919. X
  920. X
  921. Xstatic void new_change_undo_help _((void));
  922. X
  923. Xstatic void
  924. Xnew_change_undo_help()
  925. X{
  926. X    static char *text[] =
  927. X    {
  928. X"NAME",
  929. X"    %s -New_Change_Undo - remove a new change from a project",
  930. X"",
  931. X"SYNOPSIS",
  932. X"    %s -New_Change_Undo [ <option>... ]",
  933. X"    %s -New_Change_Undo -List [ <option>... ]",
  934. X"    %s -New_Change_Undo -Help",
  935. X"",
  936. X"DESCRIPTION",
  937. X"    The %s -New_Change_Undo command is used to remove a",
  938. X"    new change from a project.",
  939. X"",
  940. X"    It wan't called '%s -Remove_Change' in order to",
  941. X"    emphasize that fact the the change must be in the",
  942. X"    'awaiting_development' state.  In practice it is",
  943. X"    possible, with a combination of commands, to remove any",
  944. X"    change which has not reached the 'completed' state.",
  945. X"",
  946. X"OPTIONS",
  947. X"    The following options are understood:",
  948. X"",
  949. X"    -Change <number>",
  950. X"        This option may be used to specify a particular",
  951. X"        change within a project.  When no -Change option is",
  952. X"        specified, the AEGIS_CHANGE environment variable is",
  953. X"        consulted.  If that does not exist, the user's",
  954. X"        $HOME/.aegisrc file is examined for a default change",
  955. X"        field (see aeuconf(5) for more information).  If",
  956. X"        that does not exist, when the user is only working",
  957. X"        on one change within a project, that is the default",
  958. X"        change number.  Otherwise, it is an error.",
  959. X"",
  960. X"    -Help",
  961. X"        This option may be used to obtain more",
  962. X"        information about how to use the %s program.",
  963. X"",
  964. X"    -List",
  965. X"        This option may be used to obtain a list of",
  966. X"        suitable subjects for this command.  The list may",
  967. X"        be more general than expected.",
  968. X"",
  969. X"    -Project <name>",
  970. X"        This option may be used to select the project of",
  971. X"        interest.  When no -Project option is specified, the",
  972. X"        AEGIS_PROJECT environment variable is consulted.  If",
  973. X"        that does not exist, the user's $HOME/.aegisrc file",
  974. X"        is examined for a default project field (see",
  975. X"        aeuconf(5) for more information).  If that does not",
  976. X"        exist, when the user is only working on changes",
  977. X"        within a single project, the project name defaults",
  978. X"        to that project.  Otherwise, it is an error.",
  979. X"",
  980. X"    -TERse",
  981. X"        This option may be used to cause listings to",
  982. X"        produce the bare minimum of information.  It is",
  983. X"        usually useful for shell scripts.",
  984. X"",
  985. X"    -Verbose",
  986. X"        This option may be used to cause %s to produce",
  987. X"        more output.  By default %s only produces",
  988. X"        output on errors.  When used with the -List",
  989. X"        option this option causes column headings to be",
  990. X"        added.",
  991. X"",
  992. X"    All options may be abbreviated; the abbreviation is",
  993. X"    documented as the upper case letters, all lower case",
  994. X"    letters and underscores (_) are optional.  You must use",
  995. X"    consecutive sequences of optional letters.",
  996. X"",
  997. X"    All options are case insensitive, you may type them in",
  998. X"    upper case or lower case or a combination of both, case",
  999. X"    is not important.",
  1000. X"",
  1001. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  1002. X"    are all interpreted to mean the -Project option.  The",
  1003. X"    argument \"-prj\" will not be understood, because",
  1004. X"    consecutive optional characters were not supplied.",
  1005. X"",
  1006. X"    Options and other command line arguments may be mixed",
  1007. X"    arbitrarily on the command line, after the function",
  1008. X"    selectors.",
  1009. X"",
  1010. X"    The GNU long option names are understood.  Since all",
  1011. X"    option names for aegis are long, this means ignoring the",
  1012. X"    extra leading '-'.  The \"--option=value\" convention is",
  1013. X"    also understood.",
  1014. X"",
  1015. X"RECOMMENDED ALIAS",
  1016. X"    The recommended alias for this command is",
  1017. X"    csh%%    alias aencu '%s -ncu \\!* -v'",
  1018. X"    sh$    aencu(){%s -ncu $* -v}",
  1019. X"",
  1020. X"ERRORS",
  1021. X"    It is an error if the change is not in the",
  1022. X"    'awaiting_development' state.",
  1023. X"    It is an error if the current user is not an",
  1024. X"    administrator of the project.",
  1025. X"",
  1026. X"EXIT STATUS",
  1027. X"    The %s command will exit with a status of 1 on any",
  1028. X"    error.    The %s command will only exit with a status of",
  1029. X"    0 if there are no errors.",
  1030. X"",
  1031. X"COPYRIGHT",
  1032. X"    %C",
  1033. X"",
  1034. X"AUTHOR",
  1035. X"    %A",
  1036. X    };
  1037. X
  1038. X    help(text, SIZEOF(text), new_change_undo_usage);
  1039. X}
  1040. X
  1041. X
  1042. Xstatic void new_change_undo_list _((void));
  1043. X
  1044. Xstatic void
  1045. Xnew_change_undo_list()
  1046. X{
  1047. X    string_ty    *project_name;
  1048. X
  1049. X    trace(("new_change_list()\n{\n"/*}*/));
  1050. X    arglex();
  1051. X    project_name = 0;
  1052. X    while (arglex_token != arglex_token_eoln)
  1053. X    {
  1054. X        switch (arglex_token)
  1055. X        {
  1056. X        default:
  1057. X            generic_argument(new_change_undo_usage);
  1058. X            continue;
  1059. X
  1060. X        case arglex_token_project:
  1061. X            if (arglex() != arglex_token_string)
  1062. X                new_change_undo_usage();
  1063. X            if (project_name)
  1064. X                fatal("duplicate -Project option");
  1065. X            project_name = str_from_c(arglex_value.alv_string);
  1066. X            break;
  1067. X        }
  1068. X        arglex();
  1069. X    }
  1070. X    list_changes_in_state_mask
  1071. X    (
  1072. X        project_name,
  1073. X        1 << cstate_state_awaiting_development
  1074. X    );
  1075. X    if (project_name)
  1076. X        str_free(project_name);
  1077. X    trace((/*{*/"}\n"));
  1078. X}
  1079. X
  1080. X
  1081. Xstatic void new_change_undo_main _((void));
  1082. X
  1083. Xstatic void
  1084. Xnew_change_undo_main()
  1085. X{
  1086. X    string_ty    *project_name;
  1087. X    long        change_number;
  1088. X    project_ty    *pp;
  1089. X    user_ty        *up;
  1090. X    change_ty    *cp;
  1091. X    cstate        cstate_data;
  1092. X    pstate        pstate_data;
  1093. X
  1094. X    trace(("new_change_undo_main()\n{\n"/*}*/));
  1095. X    project_name = 0;
  1096. X    change_number = 0;
  1097. X    while (arglex_token != arglex_token_eoln)
  1098. X    {
  1099. X        switch (arglex_token)
  1100. X        {
  1101. X        default:
  1102. X            generic_argument(new_change_undo_usage);
  1103. X            continue;
  1104. X
  1105. X        case arglex_token_change:
  1106. X            if (arglex() != arglex_token_number)
  1107. X                new_change_undo_usage();
  1108. X            /* fall through... */
  1109. X
  1110. X        case arglex_token_number:
  1111. X            if (change_number)
  1112. X                fatal("duplicate -Change option");
  1113. X            change_number = arglex_value.alv_number;
  1114. X            if (change_number < 1)
  1115. X                fatal("change %ld out of range", change_number);
  1116. X            break;
  1117. X
  1118. X        case arglex_token_project:
  1119. X            if (arglex() != arglex_token_string)
  1120. X                new_change_undo_usage();
  1121. X            /* fall through... */
  1122. X        
  1123. X        case arglex_token_string:
  1124. X            if (project_name)
  1125. X                fatal("duplicate -Project option");
  1126. X            project_name = str_from_c(arglex_value.alv_string);
  1127. X            break;
  1128. X        }
  1129. X        arglex();
  1130. X    }
  1131. X
  1132. X    /*
  1133. X     * locate project data
  1134. X     */
  1135. X    if (!project_name)
  1136. X        project_name = user_default_project();
  1137. X    pp = project_alloc(project_name);
  1138. X    str_free(project_name);
  1139. X    project_bind_existing(pp);
  1140. X
  1141. X    /*
  1142. X     * locate user data
  1143. X     */
  1144. X    up = user_executing(pp);
  1145. X
  1146. X    /*
  1147. X     * locate change data
  1148. X     *
  1149. X     * The change number must be given on the command line,
  1150. X     * even if there is only one appropriate change.
  1151. X     * The is the "least surprizes" principle at work,
  1152. X     * even though we could sometimes work this out for ourself.
  1153. X     */
  1154. X    if (!change_number)
  1155. X        change_number = user_default_change(up);
  1156. X    cp = change_alloc(pp, change_number);
  1157. X    change_bind_existing(cp);
  1158. X
  1159. X    /*
  1160. X     * Take an advisory write lock on the project state
  1161. X     * and the change state.
  1162. X     */
  1163. X    project_pstate_lock_prepare(pp);
  1164. X    change_cstate_lock_prepare(cp);
  1165. X    lock_take();
  1166. X    cstate_data = change_cstate_get(cp);
  1167. X    pstate_data = project_pstate_get(pp);
  1168. X
  1169. X    /*
  1170. X     * Extract the appropriate row of the change table.
  1171. X     * It is an error if the change is not in the
  1172. X     * awaiting_development state.
  1173. X     */
  1174. X    if (cstate_data->state != cstate_state_awaiting_development)
  1175. X        change_fatal(cp, "not in 'awaiting_development' state");
  1176. X    if (!project_administrator_query(pp, user_name(up)))
  1177. X    {
  1178. X        project_fatal
  1179. X        (
  1180. X            pp,
  1181. X            "user \"%S\" is not an administrator",
  1182. X            user_name(up)
  1183. X        );
  1184. X    }
  1185. X
  1186. X    /*
  1187. X     * tell the project to forget this change
  1188. X     */
  1189. X    project_change_delete(pp, change_number);
  1190. X
  1191. X    /*
  1192. X     * delete the change state file
  1193. X     */
  1194. X    project_become(pp);
  1195. X    commit_unlink_errok(cp->filename);
  1196. X    project_become_undo();
  1197. X
  1198. X    /*
  1199. X     * Update change table row (and change history table).
  1200. X     * Update user table row.
  1201. X     * Release advisory write locks.
  1202. X     */
  1203. X    project_pstate_write(pp);
  1204. X    commit();
  1205. X    lock_release();
  1206. X
  1207. X    /*
  1208. X     * verbose success message
  1209. X     */
  1210. X    change_verbose(cp, "removed");
  1211. X    change_free(cp);
  1212. X    project_free(pp);
  1213. X    user_free(up);
  1214. X    trace((/*{*/"}\n"));
  1215. X}
  1216. X
  1217. X
  1218. Xvoid
  1219. Xnew_change_undo()
  1220. X{
  1221. X    trace(("new_change_undo()\n{\n"/*}*/));
  1222. X    switch (arglex())
  1223. X    {
  1224. X    default:
  1225. X        new_change_undo_main();
  1226. X        break;
  1227. X
  1228. X    case arglex_token_help:
  1229. X        new_change_undo_help();
  1230. X        break;
  1231. X
  1232. X    case arglex_token_list:
  1233. X        new_change_undo_list();
  1234. X        break;
  1235. X    }
  1236. X    trace((/*{*/"}\n"));
  1237. X}
  1238. END_OF_FILE
  1239. if test 9535 -ne `wc -c <'aegis/aencu.c'`; then
  1240.     echo shar: \"'aegis/aencu.c'\" unpacked with wrong size!
  1241. fi
  1242. # end of 'aegis/aencu.c'
  1243. fi
  1244. if test -f 'aegis/aermpr.c' -a "${1}" != "-c" ; then 
  1245.   echo shar: Will not clobber existing file \"'aegis/aermpr.c'\"
  1246. else
  1247. echo shar: Extracting \"'aegis/aermpr.c'\" \(8594 characters\)
  1248. sed "s/^X//" >'aegis/aermpr.c' <<'END_OF_FILE'
  1249. X/*
  1250. X *    aegis - project change supervisor
  1251. X *    Copyright (C) 1993 Peter Miller.
  1252. X *    All rights reserved.
  1253. X *
  1254. X *    This program is free software; you can redistribute it and/or modify
  1255. X *    it under the terms of the GNU General Public License as published by
  1256. X *    the Free Software Foundation; either version 2 of the License, or
  1257. X *    (at your option) any later version.
  1258. X *
  1259. X *    This program is distributed in the hope that it will be useful,
  1260. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1261. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1262. X *    GNU General Public License for more details.
  1263. X *
  1264. X *    You should have received a copy of the GNU General Public License
  1265. X *    along with this program; if not, write to the Free Software
  1266. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1267. X *
  1268. X * MANIFEST: functions to implement remove project
  1269. X */
  1270. X
  1271. X#include <stdio.h>
  1272. X
  1273. X#include <ael.h>
  1274. X#include <aermpr.h>
  1275. X#include <arglex2.h>
  1276. X#include <change.h>
  1277. X#include <commit.h>
  1278. X#include <error.h>
  1279. X#include <gonzo.h>
  1280. X#include <help.h>
  1281. X#include <lock.h>
  1282. X#include <option.h>
  1283. X#include <project.h>
  1284. X#include <str.h>
  1285. X#include <trace.h>
  1286. X#include <user.h>
  1287. X
  1288. X
  1289. Xstatic void remove_project_usage _((void));
  1290. X
  1291. Xstatic void
  1292. Xremove_project_usage()
  1293. X{
  1294. X    char    *progname;
  1295. X
  1296. X    progname = option_progname_get();
  1297. X    fprintf
  1298. X    (
  1299. X        stderr,
  1300. X        "usage: %s -ReMove_PRoject [ <option>... ]\n",
  1301. X        progname
  1302. X    );
  1303. X    fprintf
  1304. X    (
  1305. X        stderr,
  1306. X        "       %s -ReMove_PRoject -List [ <option>... ]\n",
  1307. X        progname
  1308. X    );
  1309. X    fprintf(stderr, "       %s -ReMove_PRoject -Help\n", progname);
  1310. X    quit(1);
  1311. X}
  1312. X
  1313. X
  1314. Xstatic void remove_project_help _((void));
  1315. X
  1316. Xstatic void
  1317. Xremove_project_help()
  1318. X{
  1319. X    static char *text[] =
  1320. X    {
  1321. X"NAME",
  1322. X"    %s -ReMove_PRoject - remove project",
  1323. X"",
  1324. X"SYNOPSIS",
  1325. X"    %s -ReMove_Project <project-name> [ <option>...  ]",
  1326. X"    %s -ReMove_Project -List [ <option>...  ]",
  1327. X"    %s -ReMove_Project -Help",
  1328. X"",
  1329. X"DESCRIPTION",
  1330. X"    The %s -ReMove_PRoject command is used to remove a",
  1331. X"    project, either entirely, or just from %s' supervision.",
  1332. X"",
  1333. X"OPTIONS",
  1334. X"    The following options are understood:",
  1335. X"",
  1336. X"    -Keep",
  1337. X"        This option may be used to retain files and/or",
  1338. X"        directories usually deleted by the command.",
  1339. X"",
  1340. X"    -LIBrary <abspath>",
  1341. X"        This option may be used to specify a directory to be",
  1342. X"        searched for global state files and user state",
  1343. X"        files.  (See aegstate(5) and aeustate(5) for more",
  1344. X"        information.) Several library options may be present",
  1345. X"        on the command line, and are search in the order",
  1346. X"        given.  Appended to this explicit search path are",
  1347. X"        the directories specified by the AEGIS enviroment",
  1348. X"        variable (colon separated), and finally,",
  1349. X"        /usr/local/lib/%s is always searched.  All paths",
  1350. X"        specified, either on the command line or in the",
  1351. X"        AEGIS environment variable, must be absolute.",
  1352. X"",
  1353. X"    -List",
  1354. X"        This option may be used to obtain a list of suitable",
  1355. X"        subjects for this command.  The list may be more",
  1356. X"        general than expected.",
  1357. X"",
  1358. X"    -Help",
  1359. X"        This option may be used to obtain more information",
  1360. X"        about how to use the %s program.",
  1361. X"",
  1362. X"    -Project <name>",
  1363. X"        This option may be used to select the project of",
  1364. X"        interest.  When no -Project option is specified, the",
  1365. X"        AEGIS_PROJECT environment variable is consulted.  If",
  1366. X"        that does not exist, the user's $HOME/.aegisrc file",
  1367. X"        is examined for a default project field (see",
  1368. X"        aeuconf(5) for more information).  If that does not",
  1369. X"        exist, when the user is only working on changes",
  1370. X"        within a single project, the project name defaults",
  1371. X"        to that project.  Otherwise, it is an error.",
  1372. X"",
  1373. X"    -TERse",
  1374. X"        This option may be used to cause listings to produce",
  1375. X"        the bare minimum of information.  It is usually",
  1376. X"        useful for shell scripts.",
  1377. X"",
  1378. X"    -Verbose",
  1379. X"        This option may be used to cause %s to produce",
  1380. X"        more output.  By default %s only produces output",
  1381. X"        on errors.  When used with the -List option this",
  1382. X"        option causes column headings to be added.",
  1383. X"",
  1384. X"    All options may be abbreviated; the abbreviation is",
  1385. X"    documented as the upper case letters, all lower case",
  1386. X"    letters and underscores (_) are optional.  You must use",
  1387. X"    consecutive sequences of optional letters.",
  1388. X"",
  1389. X"    All options are case insensitive, you may type them in",
  1390. X"    upper case or lower case or a combination of both, case",
  1391. X"    is not important.",
  1392. X"",
  1393. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  1394. X"    are all interpreted to mean the -Project option.  The",
  1395. X"    argument \"-prj\" will not be understood, because",
  1396. X"    consecutive optional characters were not supplied.",
  1397. X"",
  1398. X"    Options and other command line arguments may be mixed",
  1399. X"    arbitrarily on the command line, after the function",
  1400. X"    selectors.",
  1401. X"",
  1402. X"    The GNU long option names are understood.  Since all",
  1403. X"    option names for aegis are long, this means ignoring the",
  1404. X"    extra leading '-'.  The \"--option=value\" convention is",
  1405. X"    also understood.",
  1406. X"",
  1407. X"RECOMMENDED ALIAS",
  1408. X"    The recommended alias for this command is",
  1409. X"    csh%%    alias aermpr '%s -rmpr \\!* -v'",
  1410. X"    sh$    aermpr(){%s -rmpr $* -v}",
  1411. X"",
  1412. X"ERRORS",
  1413. X"    It is an error if the project has any changes between the",
  1414. X"    being developed and being integrated states, inclusive.",
  1415. X"    It is an error if the current user is not an administrator.",
  1416. X"",
  1417. X"EXIT STATUS",
  1418. X"    The %s command will exit with a status of 1 on any error.",
  1419. X"    The %s command will only exit with a status of 0 if there",
  1420. X"    are no errors.",
  1421. X"",
  1422. X"COPYRIGHT",
  1423. X"    %C",
  1424. X"",
  1425. X"AUTHOR",
  1426. X"    %A",
  1427. X    };
  1428. X
  1429. X    help(text, SIZEOF(text), remove_project_usage);
  1430. X}
  1431. X
  1432. X
  1433. Xstatic void remove_project_list _((void));
  1434. X
  1435. Xstatic void
  1436. Xremove_project_list()
  1437. X{
  1438. X    arglex();
  1439. X    while (arglex_token != arglex_token_eoln)
  1440. X        generic_argument(remove_project_usage);
  1441. X    list_projects(0, 0);
  1442. X}
  1443. X
  1444. X
  1445. Xstatic void remove_project_main _((void));
  1446. X
  1447. Xstatic void
  1448. Xremove_project_main()
  1449. X{
  1450. X    long        nerr;
  1451. X    int        j;
  1452. X    pstate        pstate_data;
  1453. X    string_ty    *project_name;
  1454. X    project_ty    *pp;
  1455. X    change_ty    *cp;
  1456. X    cstate        cstate_data;
  1457. X    user_ty        *up;
  1458. X    int        keep;
  1459. X
  1460. X    trace(("remove_project_main()\n{\n"/*}*/));
  1461. X    keep = 0;
  1462. X    project_name = 0;
  1463. X    while (arglex_token != arglex_token_eoln)
  1464. X    {
  1465. X        switch (arglex_token)
  1466. X        {
  1467. X        default:
  1468. X            generic_argument(remove_project_usage);
  1469. X            continue;
  1470. X
  1471. X        case arglex_token_keep:
  1472. X            if (keep)
  1473. X            {
  1474. X                error
  1475. X                (
  1476. X                    "duplicate \"%s\" option",
  1477. X                    arglex_value.alv_string
  1478. X                );
  1479. X                remove_project_usage();
  1480. X            }
  1481. X            keep = 1;
  1482. X            break;
  1483. X
  1484. X        case arglex_token_project:
  1485. X            if (arglex() != arglex_token_string)
  1486. X                remove_project_usage();
  1487. X            /* fall through... */
  1488. X
  1489. X        case arglex_token_string:
  1490. X            if (project_name)
  1491. X                fatal("duplicate -Project option");
  1492. X            project_name = str_from_c(arglex_value.alv_string);
  1493. X            break;
  1494. X        }
  1495. X        arglex();
  1496. X    }
  1497. X
  1498. X    /*
  1499. X     * locate project data
  1500. X     */
  1501. X    if (!project_name)
  1502. X        fatal("project must be named explicitly");
  1503. X    pp = project_alloc(project_name);
  1504. X    str_free(project_name);
  1505. X    project_bind_existing(pp);
  1506. X
  1507. X    /*
  1508. X     * locate user data
  1509. X     */
  1510. X    up = user_executing(pp);
  1511. X
  1512. X    /*
  1513. X     * lock the project
  1514. X     */
  1515. X    project_pstate_lock_prepare(pp);
  1516. X    gonzo_gstate_lock_prepare_new();
  1517. X    lock_take();
  1518. X    pstate_data = project_pstate_get(pp);
  1519. X
  1520. X    /*
  1521. X     * it is an error if any of the changes are active
  1522. X     */
  1523. X    nerr = 0;
  1524. X    for (j = 0; j < pstate_data->change->length; ++j)
  1525. X    {
  1526. X        long    change_number;
  1527. X
  1528. X        change_number = pstate_data->change->list[j];
  1529. X        cp = change_alloc(pp, change_number);
  1530. X        change_bind_existing(cp);
  1531. X        cstate_data = change_cstate_get(cp);
  1532. X        if
  1533. X        (
  1534. X            cstate_data->state >= cstate_state_being_developed
  1535. X        && 
  1536. X            cstate_data->state <= cstate_state_being_integrated
  1537. X        )
  1538. X        {
  1539. X            change_error(cp, "still active");
  1540. X            ++nerr;
  1541. X        }
  1542. X        change_free(cp);
  1543. X    }
  1544. X
  1545. X    /*
  1546. X     * it is an error if the current user is not an administrator
  1547. X     */
  1548. X    if (!project_administrator_query(pp, user_name(up)))
  1549. X    {
  1550. X        project_error
  1551. X        (
  1552. X            pp,
  1553. X            "user \"%S\" is not an administrator",
  1554. X            user_name(up)
  1555. X        );
  1556. X        nerr++;
  1557. X    }
  1558. X    if (nerr)
  1559. X        quit(1);
  1560. X
  1561. X    /*
  1562. X     * remove the project directory
  1563. X     */
  1564. X    if (!keep)
  1565. X    {
  1566. X        project_verbose(pp, "remove project directory");
  1567. X        project_become(pp);
  1568. X        commit_rmdir_tree_errok(project_home_path_get(pp));
  1569. X        project_become_undo();
  1570. X    }
  1571. X
  1572. X    /*
  1573. X     * tell gonzo to forget about this project
  1574. X     */
  1575. X    gonzo_project_delete(pp);
  1576. X    gonzo_gstate_write();
  1577. X
  1578. X    /*
  1579. X     * release the locks
  1580. X     */
  1581. X    commit();
  1582. X    lock_release();
  1583. X
  1584. X    /*
  1585. X     * verbose success message
  1586. X     */
  1587. X    project_verbose(pp, "removed");
  1588. X
  1589. X    /*
  1590. X     * clean up and go home
  1591. X     */
  1592. X    project_free(pp);
  1593. X    user_free(up);
  1594. X    trace((/*{*/"}\n"));
  1595. X}
  1596. X
  1597. X
  1598. Xvoid
  1599. Xremove_project()
  1600. X{
  1601. X    trace(("remove_project()\n{\n"/*}*/));
  1602. X    switch (arglex())
  1603. X    {
  1604. X    default:
  1605. X        remove_project_main();
  1606. X        break;
  1607. X
  1608. X    case arglex_token_help:
  1609. X        remove_project_help();
  1610. X        break;
  1611. X
  1612. X    case arglex_token_list:
  1613. X        remove_project_list();
  1614. X        break;
  1615. X    }
  1616. X    trace((/*{*/"}\n"));
  1617. X}
  1618. END_OF_FILE
  1619. if test 8594 -ne `wc -c <'aegis/aermpr.c'`; then
  1620.     echo shar: \"'aegis/aermpr.c'\" unpacked with wrong size!
  1621. fi
  1622. # end of 'aegis/aermpr.c'
  1623. fi
  1624. if test -f 'aegis/aerp.c' -a "${1}" != "-c" ; then 
  1625.   echo shar: Will not clobber existing file \"'aegis/aerp.c'\"
  1626. else
  1627. echo shar: Extracting \"'aegis/aerp.c'\" \(9365 characters\)
  1628. sed "s/^X//" >'aegis/aerp.c' <<'END_OF_FILE'
  1629. X/*
  1630. X *    aegis - project change supervisor
  1631. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  1632. X *    All rights reserved.
  1633. X *
  1634. X *    This program is free software; you can redistribute it and/or modify
  1635. X *    it under the terms of the GNU General Public License as published by
  1636. X *    the Free Software Foundation; either version 2 of the License, or
  1637. X *    (at your option) any later version.
  1638. X *
  1639. X *    This program is distributed in the hope that it will be useful,
  1640. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1641. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1642. X *    GNU General Public License for more details.
  1643. X *
  1644. X *    You should have received a copy of the GNU General Public License
  1645. X *    along with this program; if not, write to the Free Software
  1646. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1647. X *
  1648. X * MANIFEST: functions to implement review pass
  1649. X */
  1650. X
  1651. X#include <stdio.h>
  1652. X#include <stdlib.h>
  1653. X#include <sys/types.h>
  1654. X#include <sys/stat.h>
  1655. X
  1656. X#include <ael.h>
  1657. X#include <aerp.h>
  1658. X#include <arglex2.h>
  1659. X#include <change.h>
  1660. X#include <commit.h>
  1661. X#include <dir.h>
  1662. X#include <error.h>
  1663. X#include <file.h>
  1664. X#include <help.h>
  1665. X#include <lock.h>
  1666. X#include <mem.h>
  1667. X#include <option.h>
  1668. X#include <os.h>
  1669. X#include <project.h>
  1670. X#include <sub.h>
  1671. X#include <trace.h>
  1672. X#include <undo.h>
  1673. X#include <user.h>
  1674. X
  1675. X
  1676. Xstatic void review_pass_usage _((void));
  1677. X
  1678. Xstatic void
  1679. Xreview_pass_usage()
  1680. X{
  1681. X    char        *progname;
  1682. X
  1683. X    progname = option_progname_get();
  1684. X    fprintf(stderr, "usage: %s -Review_PASS <change_number> [ <option>... ]\n", progname);
  1685. X    fprintf(stderr, "       %s -Review_PASS -List [ <option>... ]\n", progname);
  1686. X    fprintf(stderr, "       %s -Review_PASS -Help\n", progname);
  1687. X    quit(1);
  1688. X}
  1689. X
  1690. X
  1691. Xstatic void review_pass_help _((void));
  1692. X
  1693. Xstatic void
  1694. Xreview_pass_help()
  1695. X{
  1696. X    static char *text[] =
  1697. X    {
  1698. X"NAME",
  1699. X"    %s -Review_PASS - pass a change review",
  1700. X"",
  1701. X"SYNOPSIS",
  1702. X"    %s -Review_PASS [ <option>... ]",
  1703. X"    %s -Review_PASS -List [ <option>... ]",
  1704. X"    %s -Review_PASS -Help",
  1705. X"",
  1706. X"DESCRIPTION",
  1707. X"    The %s -Review_PASS command is used to notify",
  1708. X"    %s that a change has passed review.",
  1709. X"",
  1710. X"    The change will be advenced from the 'being_reviewed'",
  1711. X"    state to the 'awaitiong_integration' state.",
  1712. X"",
  1713. X"OPTIONS",
  1714. X"    The following options are understood:",
  1715. X"",
  1716. X"    -Change <number>",
  1717. X"        This option may be used to specify a particular",
  1718. X"        change within a project.  When no -Change option is",
  1719. X"        specified, the AEGIS_CHANGE environment variable is",
  1720. X"        consulted.  If that does not exist, the user's",
  1721. X"        $HOME/.aegisrc file is examined for a default change",
  1722. X"        field (see aeuconf(5) for more information).  If",
  1723. X"        that does not exist, when the user is only working",
  1724. X"        on one change within a project, that is the default",
  1725. X"        change number.  Otherwise, it is an error.",
  1726. X"",
  1727. X"    -Help",
  1728. X"        This option may be used to obtain more",
  1729. X"        information about how to use the %s program.",
  1730. X"",
  1731. X"    -List",
  1732. X"        This option may be used to obtain a list of",
  1733. X"        suitable subjects for this command.  The list may",
  1734. X"        be more general than expected.",
  1735. X"",
  1736. X"    -Project <name>",
  1737. X"        This option may be used to select the project of",
  1738. X"        interest.  When no -Project option is specified, the",
  1739. X"        AEGIS_PROJECT environment variable is consulted.  If",
  1740. X"        that does not exist, the user's $HOME/.aegisrc file",
  1741. X"        is examined for a default project field (see",
  1742. X"        aeuconf(5) for more information).  If that does not",
  1743. X"        exist, when the user is only working on changes",
  1744. X"        within a single project, the project name defaults",
  1745. X"        to that project.  Otherwise, it is an error.",
  1746. X"",
  1747. X"    -TERse",
  1748. X"        This option may be used to cause listings to",
  1749. X"        produce the bare minimum of information.  It is",
  1750. X"        usually useful for shell scripts.",
  1751. X"",
  1752. X"    -Verbose",
  1753. X"        This option may be used to cause %s to produce",
  1754. X"        more output.  By default %s only produces",
  1755. X"        output on errors.  When used with the -List",
  1756. X"        option this option causes column headings to be",
  1757. X"        added.",
  1758. X"",
  1759. X"    All options may be abbreviated; the abbreviation is",
  1760. X"    documented as the upper case letters, all lower case",
  1761. X"    letters and underscores (_) are optional.  You must use",
  1762. X"    consecutive sequences of optional letters.",
  1763. X"",
  1764. X"    All options are case insensitive, you may type them in",
  1765. X"    upper case or lower case or a combination of both, case",
  1766. X"    is not important.",
  1767. X"",
  1768. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  1769. X"    are all interpreted to mean the -Project option.  The",
  1770. X"    argument \"-prj\" will not be understood, because",
  1771. X"    consecutive optional characters were not supplied.",
  1772. X"",
  1773. X"    Options and other command line arguments may be mixed",
  1774. X"    arbitrarily on the command line, after the function",
  1775. X"    selectors.",
  1776. X"",
  1777. X"    The GNU long option names are understood.  Since all",
  1778. X"    option names for aegis are long, this means ignoring the",
  1779. X"    extra leading '-'.  The \"--option=value\" convention is",
  1780. X"    also understood.",
  1781. X"",
  1782. X"RECOMMENDED ALIAS",
  1783. X"    The recommended alias for this command is",
  1784. X"    csh%%    alias aerp '%s -rp \\!* -v'",
  1785. X"    sh$    aerp(){%s -rp $* -v}",
  1786. X"",
  1787. X"ERRORS",
  1788. X"    It is an error if the change is not in the",
  1789. X"    'being_reviewed' state.",
  1790. X"    It is an error if the current user is not a reviewer of",
  1791. X"    the project.",
  1792. X"    Its is an error if the current user developed the change",
  1793. X"    and the project is configured to disallow developers to",
  1794. X"    review their own changes (default).",
  1795. X"",
  1796. X"EXIT STATUS",
  1797. X"    The %s command will exit with a status of 1 on any",
  1798. X"    error.    The %s command will only exit with a status of",
  1799. X"    0 if there are no errors.",
  1800. X"",
  1801. X"COPYRIGHT",
  1802. X"    %C",
  1803. X"",
  1804. X"AUTHOR",
  1805. X"    %A",
  1806. X    };
  1807. X
  1808. X    help(text, SIZEOF(text), review_pass_usage);
  1809. X}
  1810. X
  1811. X
  1812. Xstatic void review_pass_list _((void (*usage)(void)));
  1813. X
  1814. Xstatic void
  1815. Xreview_pass_list(usage)
  1816. X    void        (*usage)_((void));
  1817. X{
  1818. X    string_ty    *project_name;
  1819. X
  1820. X    trace(("review_pass_list()\n{\n"/*}*/));
  1821. X    project_name = 0;
  1822. X    arglex();
  1823. X    while (arglex_token != arglex_token_eoln)
  1824. X    {
  1825. X        switch (arglex_token)
  1826. X        {
  1827. X        default:
  1828. X            generic_argument(usage);
  1829. X            continue;
  1830. X
  1831. X        case arglex_token_project:
  1832. X            if (arglex() != arglex_token_string)
  1833. X                usage();
  1834. X            /* fall through... */
  1835. X
  1836. X        case arglex_token_string:
  1837. X            if (project_name)
  1838. X                fatal("duplicate -Project option");
  1839. X            project_name = str_from_c(arglex_value.alv_string);
  1840. X            break;
  1841. X        }
  1842. X        arglex();
  1843. X    }
  1844. X    list_changes_in_state_mask
  1845. X    (
  1846. X        project_name,
  1847. X        1 << cstate_state_being_reviewed
  1848. X    );
  1849. X    if (project_name)
  1850. X        str_free(project_name);
  1851. X    trace((/*{*/"}\n"));
  1852. X}
  1853. X
  1854. X
  1855. Xstatic void review_pass_main _((void));
  1856. X
  1857. Xstatic void
  1858. Xreview_pass_main()
  1859. X{
  1860. X    cstate        cstate_data;
  1861. X    pstate        pstate_data;
  1862. X    cstate_history    history_data;
  1863. X    string_ty    *project_name;
  1864. X    project_ty    *pp;
  1865. X    long        change_number;
  1866. X    change_ty    *cp;
  1867. X    user_ty        *up;
  1868. X
  1869. X    trace(("review_pass_main()\n{\n"/*}*/));
  1870. X    project_name = 0;
  1871. X    change_number = 0;
  1872. X    while (arglex_token != arglex_token_eoln)
  1873. X    {
  1874. X        switch (arglex_token)
  1875. X        {
  1876. X        default:
  1877. X            generic_argument(review_pass_usage);
  1878. X            continue;
  1879. X
  1880. X        case arglex_token_change:
  1881. X            if (arglex() != arglex_token_number)
  1882. X                review_pass_usage();
  1883. X            /* fall through... */
  1884. X
  1885. X        case arglex_token_number:
  1886. X            if (change_number)
  1887. X                fatal("duplicate -Change option");
  1888. X            change_number = arglex_value.alv_number;
  1889. X            if (change_number < 1)
  1890. X                fatal("change %ld out of range", change_number);
  1891. X            break;
  1892. X
  1893. X        case arglex_token_project:
  1894. X            if (arglex() != arglex_token_string)
  1895. X                review_pass_usage();
  1896. X            /* fall through... */
  1897. X
  1898. X        case arglex_token_string:
  1899. X            if (project_name)
  1900. X                fatal("duplicate -Project option");
  1901. X            project_name = str_from_c(arglex_value.alv_string);
  1902. X            break;
  1903. X        }
  1904. X        arglex();
  1905. X    }
  1906. X
  1907. X    /*
  1908. X     * locate project data
  1909. X     */
  1910. X    if (!project_name)
  1911. X        project_name = user_default_project();
  1912. X    pp = project_alloc(project_name);
  1913. X    str_free(project_name);
  1914. X    project_bind_existing(pp);
  1915. X
  1916. X    /*
  1917. X     * locate user data
  1918. X     */
  1919. X    up = user_executing(pp);
  1920. X
  1921. X    /*
  1922. X     * locate change data
  1923. X     */
  1924. X    if (!change_number)
  1925. X        change_number = user_default_change(up);
  1926. X    cp = change_alloc(pp, change_number);
  1927. X    change_bind_existing(cp);
  1928. X
  1929. X    /*
  1930. X     * lock the change for writing
  1931. X     */
  1932. X    change_cstate_lock_prepare(cp);
  1933. X    lock_take();
  1934. X    cstate_data = change_cstate_get(cp);
  1935. X    pstate_data = project_pstate_get(pp);
  1936. X
  1937. X    /*
  1938. X     * it is an error if the change is not in the 'being_reviewed' state.
  1939. X     */
  1940. X    if (cstate_data->state != cstate_state_being_reviewed)
  1941. X        change_fatal(cp, "not in 'being_reviewed' state");
  1942. X    if (!project_reviewer_query(pp, user_name(up)))
  1943. X    {
  1944. X        project_fatal
  1945. X        (
  1946. X            pp,
  1947. X            "user \"%S\" is not a reviewer",
  1948. X            user_name(up)
  1949. X        );
  1950. X    }
  1951. X    if
  1952. X    (
  1953. X        !pstate_data->developer_may_review
  1954. X    &&
  1955. X        str_equal(change_developer_name(cp), user_name(up))
  1956. X    )
  1957. X        change_fatal(cp, "developer may not review");
  1958. X
  1959. X    /*
  1960. X     * change the state
  1961. X     * remember who reviewed it
  1962. X     * add to the change's history
  1963. X     */
  1964. X    cstate_data->state = cstate_state_awaiting_integration;
  1965. X    history_data = change_history_new(cp, up);
  1966. X    history_data->what = cstate_history_what_review_pass;
  1967. X
  1968. X    /*
  1969. X     * write out the data and release the locks
  1970. X     */
  1971. X    change_cstate_write(cp);
  1972. X    commit();
  1973. X    lock_release();
  1974. X
  1975. X    /*
  1976. X     * run the notify command
  1977. X     */
  1978. X    change_run_review_pass_notify_command(cp);
  1979. X
  1980. X    /*
  1981. X     * verbose success message
  1982. X     */
  1983. X    change_verbose(cp, "passed review");
  1984. X    change_free(cp);
  1985. X    project_free(pp);
  1986. X    user_free(up);
  1987. X    trace((/*{*/"}\n"));
  1988. X}
  1989. X
  1990. X
  1991. Xvoid
  1992. Xreview_pass()
  1993. X{
  1994. X    trace(("review_pass()\n{\n"/*}*/));
  1995. X    switch (arglex())
  1996. X    {
  1997. X    default:
  1998. X        review_pass_main();
  1999. X        break;
  2000. X
  2001. X    case arglex_token_help:
  2002. X        review_pass_help();
  2003. X        break;
  2004. X
  2005. X    case arglex_token_list:
  2006. X        review_pass_list(review_pass_usage);
  2007. X        break;
  2008. X    }
  2009. X    trace((/*{*/"}\n"));
  2010. X}
  2011. END_OF_FILE
  2012. if test 9365 -ne `wc -c <'aegis/aerp.c'`; then
  2013.     echo shar: \"'aegis/aerp.c'\" unpacked with wrong size!
  2014. fi
  2015. # end of 'aegis/aerp.c'
  2016. fi
  2017. if test -f 'aegis/aerpu.c' -a "${1}" != "-c" ; then 
  2018.   echo shar: Will not clobber existing file \"'aegis/aerpu.c'\"
  2019. else
  2020. echo shar: Extracting \"'aegis/aerpu.c'\" \(9352 characters\)
  2021. sed "s/^X//" >'aegis/aerpu.c' <<'END_OF_FILE'
  2022. X/*
  2023. X *    aegis - project change supervisor
  2024. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  2025. X *    All rights reserved.
  2026. X *
  2027. X *    This program is free software; you can redistribute it and/or modify
  2028. X *    it under the terms of the GNU General Public License as published by
  2029. X *    the Free Software Foundation; either version 2 of the License, or
  2030. X *    (at your option) any later version.
  2031. X *
  2032. X *    This program is distributed in the hope that it will be useful,
  2033. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2034. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2035. X *    GNU General Public License for more details.
  2036. X *
  2037. X *    You should have received a copy of the GNU General Public License
  2038. X *    along with this program; if not, write to the Free Software
  2039. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2040. X *
  2041. X * MANIFEST: functions to implement review pass undo
  2042. X */
  2043. X
  2044. X#include <stdio.h>
  2045. X#include <stdlib.h>
  2046. X#include <sys/types.h>
  2047. X#include <sys/stat.h>
  2048. X
  2049. X#include <ael.h>
  2050. X#include <aerpu.h>
  2051. X#include <arglex2.h>
  2052. X#include <change.h>
  2053. X#include <commit.h>
  2054. X#include <dir.h>
  2055. X#include <error.h>
  2056. X#include <file.h>
  2057. X#include <help.h>
  2058. X#include <lock.h>
  2059. X#include <mem.h>
  2060. X#include <option.h>
  2061. X#include <os.h>
  2062. X#include <project.h>
  2063. X#include <sub.h>
  2064. X#include <trace.h>
  2065. X#include <undo.h>
  2066. X#include <user.h>
  2067. X
  2068. X
  2069. Xstatic void review_pass_undo_usage _((void));
  2070. X
  2071. Xstatic void
  2072. Xreview_pass_undo_usage()
  2073. X{
  2074. X    char        *progname;
  2075. X
  2076. X    progname = option_progname_get();
  2077. X    fprintf(stderr, "usage: %s -Review_Pass_Undo <change_number> [ <option>... ]\n", progname);
  2078. X    fprintf(stderr, "       %s -Review_Pass_Undo -List [ <option>... ]\n", progname);
  2079. X    fprintf(stderr, "       %s -Review_Pass_Undo -Help\n", progname);
  2080. X    quit(1);
  2081. X}
  2082. X
  2083. X
  2084. Xstatic void review_pass_undo_help _((void));
  2085. X
  2086. Xstatic void
  2087. Xreview_pass_undo_help()
  2088. X{
  2089. X    static char *text[] =
  2090. X    {
  2091. X"NAME",
  2092. X"    %s -Review_Pass_Undo - rescind a change review pass",
  2093. X"",
  2094. X"SYNOPSIS",
  2095. X"    %s -Review_Pass_Undo [ <option>... ]",
  2096. X"    %s -Review_Pass_Undo -List [ <option>... ]",
  2097. X"    %s -Review_Pass_Undo -Help",
  2098. X"",
  2099. X"DESCRIPTION",
  2100. X"    The %s -Review_Pass_Undo command is used to notify %s",
  2101. X"    that a change review pass has been rescinded.",
  2102. X"",
  2103. X"    The change will be moved from the 'awaiting_integration'",
  2104. X"    state to the 'being_reviewed' state.",
  2105. X"",
  2106. X"OPTIONS",
  2107. X"    The following options are understood:",
  2108. X"",
  2109. X"    -Change <number>",
  2110. X"        This option may be used to specify a particular",
  2111. X"        change within a project.  When no -Change option is",
  2112. X"        specified, the AEGIS_CHANGE environment variable is",
  2113. X"        consulted.  If that does not exist, the user's",
  2114. X"        $HOME/.aegisrc file is examined for a default change",
  2115. X"        field (see aeuconf(5) for more information).  If",
  2116. X"        that does not exist, when the user is only working",
  2117. X"        on one change within a project, that is the default",
  2118. X"        change number.  Otherwise, it is an error.",
  2119. X"",
  2120. X"    -Help",
  2121. X"         This option may be used to obtain more information",
  2122. X"         about how to use the %s program.",
  2123. X"",
  2124. X"    -List",
  2125. X"         This option may be used to obtain a list of suitable",
  2126. X"         subjects for this command.  The list may be more",
  2127. X"         general than expected.",
  2128. X"",
  2129. X"    -Project <name>",
  2130. X"        This option may be used to select the project of",
  2131. X"        interest.  When no -Project option is specified, the",
  2132. X"        AEGIS_PROJECT environment variable is consulted.  If",
  2133. X"        that does not exist, the user's $HOME/.aegisrc file",
  2134. X"        is examined for a default project field (see",
  2135. X"        aeuconf(5) for more information).  If that does not",
  2136. X"        exist, when the user is only working on changes",
  2137. X"        within a single project, the project name defaults",
  2138. X"        to that project.  Otherwise, it is an error.",
  2139. X"",
  2140. X"    -TERse",
  2141. X"         This option may be used to cause listings to produce",
  2142. X"         the bare minimum of information.  It is usually",
  2143. X"         useful for shell scripts.",
  2144. X"",
  2145. X"    -Verbose",
  2146. X"         This option may be used to cause %s to produce",
  2147. X"         more output.  By default %s only produces output",
  2148. X"         on errors.  When used with the -List option this",
  2149. X"         option causes column headings to be added.",
  2150. X"",
  2151. X"    All options may be abbreviated; the abbreviation is",
  2152. X"    documented as the upper case letters, all lower case",
  2153. X"    letters and underscores (_) are optional.  You must use",
  2154. X"    consecutive sequences of optional letters.",
  2155. X"",
  2156. X"    All options are case insensitive, you may type them in",
  2157. X"    upper case or lower case or a combination of both, case",
  2158. X"    is not important.",
  2159. X"",
  2160. X"    For example: the arguments \"-project, \"-PROJ\" and \"-p\"",
  2161. X"    are all interpreted to mean the -Project option.  The",
  2162. X"    argument \"-prj\" will not be understood, because",
  2163. X"    consecutive optional characters were not supplied.",
  2164. X"",
  2165. X"    Options and other command line arguments may be mixed",
  2166. X"    arbitrarily on the command line, after the function",
  2167. X"    selectors.",
  2168. X"",
  2169. X"    The GNU long option names are understood.  Since all",
  2170. X"    option names for aegis are long, this means ignoring the",
  2171. X"    extra leading '-'.  The \"--option=value\" convention is",
  2172. X"    also understood.",
  2173. X"",
  2174. X"RECOMMENDED ALIAS",
  2175. X"    The recommended alias for this command is",
  2176. X"    csh%%    alias aerpu '%s -rp \\!* -v'",
  2177. X"    sh$    aerpu(){%s -rp $* -v}",
  2178. X"",
  2179. X"ERRORS",
  2180. X"    It is an error if the change is not in the",
  2181. X"    'awaiting_integration' state.",
  2182. X"    It is an error if the current user is not the reviewer of",
  2183. X"    the change.",
  2184. X"",
  2185. X"EXIT STATUS",
  2186. X"    The %s command will exit with a status of 1 on any error.",
  2187. X"    The %s command will only exit with a status of 0 if there",
  2188. X"    are no errors.",
  2189. X"",
  2190. X"COPYRIGHT",
  2191. X"    %C",
  2192. X"",
  2193. X"AUTHOR",
  2194. X"    %A",
  2195. X"NAME",
  2196. X"",
  2197. X"COPYRIGHT",
  2198. X"    %C",
  2199. X"",
  2200. X"AUTHOR",
  2201. X"    %A",
  2202. X    };
  2203. X
  2204. X    help(text, SIZEOF(text), review_pass_undo_usage);
  2205. X}
  2206. X
  2207. X
  2208. Xstatic void review_pass_undo_list _((void (*usage)(void)));
  2209. X
  2210. Xstatic void
  2211. Xreview_pass_undo_list(usage)
  2212. X    void        (*usage)_((void));
  2213. X{
  2214. X    string_ty    *project_name;
  2215. X
  2216. X    trace(("review_list()\n{\n"/*}*/));
  2217. X    project_name = 0;
  2218. X    arglex();
  2219. X    while (arglex_token != arglex_token_eoln)
  2220. X    {
  2221. X        switch (arglex_token)
  2222. X        {
  2223. X        default:
  2224. X            generic_argument(usage);
  2225. X            continue;
  2226. X
  2227. X        case arglex_token_project:
  2228. X            if (arglex() != arglex_token_string)
  2229. X                usage();
  2230. X            /* fall through... */
  2231. X
  2232. X        case arglex_token_string:
  2233. X            if (project_name)
  2234. X                fatal("duplicate -Project option");
  2235. X            project_name = str_from_c(arglex_value.alv_string);
  2236. X            break;
  2237. X        }
  2238. X        arglex();
  2239. X    }
  2240. X    list_changes_in_state_mask
  2241. X    (
  2242. X        project_name,
  2243. X        1 << cstate_state_awaiting_integration
  2244. X    );
  2245. X    if (project_name)
  2246. X        str_free(project_name);
  2247. X    trace((/*{*/"}\n"));
  2248. X}
  2249. X
  2250. X
  2251. Xstatic void review_pass_undo_main _((void));
  2252. X
  2253. Xstatic void
  2254. Xreview_pass_undo_main()
  2255. X{
  2256. X    cstate        cstate_data;
  2257. X    pstate        pstate_data;
  2258. X    cstate_history    history_data;
  2259. X    string_ty    *project_name;
  2260. X    project_ty    *pp;
  2261. X    long        change_number;
  2262. X    change_ty    *cp;
  2263. X    user_ty        *up;
  2264. X
  2265. X    trace(("review_pass_undo_main()\n{\n"/*}*/));
  2266. X    project_name = 0;
  2267. X    change_number = 0;
  2268. X    while (arglex_token != arglex_token_eoln)
  2269. X    {
  2270. X        switch (arglex_token)
  2271. X        {
  2272. X        default:
  2273. X            generic_argument(review_pass_undo_usage);
  2274. X            continue;
  2275. X
  2276. X        case arglex_token_change:
  2277. X            if (arglex() != arglex_token_number)
  2278. X                review_pass_undo_usage();
  2279. X            /* fall through... */
  2280. X
  2281. X        case arglex_token_number:
  2282. X            if (change_number)
  2283. X                fatal("duplicate -Change option");
  2284. X            change_number = arglex_value.alv_number;
  2285. X            if (change_number < 1)
  2286. X                fatal("change %ld out of range", change_number);
  2287. X            break;
  2288. X
  2289. X        case arglex_token_project:
  2290. X            if (arglex() != arglex_token_string)
  2291. X                review_pass_undo_usage();
  2292. X            /* fall through... */
  2293. X
  2294. X        case arglex_token_string:
  2295. X            if (project_name)
  2296. X                fatal("duplicate -Project option");
  2297. X            project_name = str_from_c(arglex_value.alv_string);
  2298. X            break;
  2299. X        }
  2300. X        arglex();
  2301. X    }
  2302. X
  2303. X    /*
  2304. X     * locate project data
  2305. X     */
  2306. X    if (!project_name)
  2307. X        project_name = user_default_project();
  2308. X    pp = project_alloc(project_name);
  2309. X    str_free(project_name);
  2310. X    project_bind_existing(pp);
  2311. X
  2312. X    /*
  2313. X     * locate user data
  2314. X     */
  2315. X    up = user_executing(pp);
  2316. X
  2317. X    /*
  2318. X     * locate change data
  2319. X     */
  2320. X    if (!change_number)
  2321. X        change_number = user_default_change(up);
  2322. X    cp = change_alloc(pp, change_number);
  2323. X    change_bind_existing(cp);
  2324. X
  2325. X    /*
  2326. X     * lock the change for writing
  2327. X     */
  2328. X    change_cstate_lock_prepare(cp);
  2329. X    lock_take();
  2330. X    cstate_data = change_cstate_get(cp);
  2331. X    pstate_data = project_pstate_get(pp);
  2332. X
  2333. X    /*
  2334. X     * it is an error if the change is not in the 'being_reviewed' state.
  2335. X     * it is an error if the current user is not the original reviewer
  2336. X     */
  2337. X    if (cstate_data->state != cstate_state_awaiting_integration)
  2338. X        change_fatal(cp, "not in 'awaiting_integration' state");
  2339. X    if (!str_equal(change_reviewer_name(cp), user_name(up)))
  2340. X    {
  2341. X        change_fatal
  2342. X        (
  2343. X            cp,
  2344. X            "user \"%S\" is not the reviewer",
  2345. X            user_name(up)
  2346. X        );
  2347. X    }
  2348. X
  2349. X    /*
  2350. X     * change the state
  2351. X     * add to the change's history
  2352. X     */
  2353. X    cstate_data->state = cstate_state_being_reviewed;
  2354. X    history_data = change_history_new(cp, up);
  2355. X    history_data->what = cstate_history_what_review_pass_undo;
  2356. X
  2357. X    /*
  2358. X     * write out the data and release the locks
  2359. X     */
  2360. X    change_cstate_write(cp);
  2361. X    commit();
  2362. X    lock_release();
  2363. X
  2364. X    /*
  2365. X     * run the notify command
  2366. X     */
  2367. X    change_run_review_pass_undo_notify_command(cp);
  2368. X
  2369. X    /*
  2370. X     * verbose success message
  2371. X     */
  2372. X    change_verbose(cp, "review pass rescinded");
  2373. X    change_free(cp);
  2374. X    project_free(pp);
  2375. X    user_free(up);
  2376. X    trace((/*{*/"}\n"));
  2377. X}
  2378. X
  2379. X
  2380. Xvoid
  2381. Xreview_pass_undo()
  2382. X{
  2383. X    trace(("review_pass_undo()\n{\n"/*}*/));
  2384. X    switch (arglex())
  2385. X    {
  2386. X    default:
  2387. X        review_pass_undo_main();
  2388. X        break;
  2389. X
  2390. X    case arglex_token_help:
  2391. X        review_pass_undo_help();
  2392. X        break;
  2393. X
  2394. X    case arglex_token_list:
  2395. X        review_pass_undo_list(review_pass_undo_usage);
  2396. X        break;
  2397. X    }
  2398. X    trace((/*{*/"}\n"));
  2399. X}
  2400. END_OF_FILE
  2401. if test 9352 -ne `wc -c <'aegis/aerpu.c'`; then
  2402.     echo shar: \"'aegis/aerpu.c'\" unpacked with wrong size!
  2403. fi
  2404. # end of 'aegis/aerpu.c'
  2405. fi
  2406. if test -f 'aegis/commit.c' -a "${1}" != "-c" ; then 
  2407.   echo shar: Will not clobber existing file \"'aegis/commit.c'\"
  2408. else
  2409. echo shar: Extracting \"'aegis/commit.c'\" \(9183 characters\)
  2410. sed "s/^X//" >'aegis/commit.c' <<'END_OF_FILE'
  2411. X/*
  2412. X *    aegis - project change supervisor
  2413. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  2414. X *    All rights reserved.
  2415. X *
  2416. X *    This program is free software; you can redistribute it and/or modify
  2417. X *    it under the terms of the GNU General Public License as published by
  2418. X *    the Free Software Foundation; either version 2 of the License, or
  2419. X *    (at your option) any later version.
  2420. X *
  2421. X *    This program is distributed in the hope that it will be useful,
  2422. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2423. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2424. X *    GNU General Public License for more details.
  2425. X *
  2426. X *    You should have received a copy of the GNU General Public License
  2427. X *    along with this program; if not, write to the Free Software
  2428. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2429. X *
  2430. X * MANIFEST: functions to store and enact file manipulations for commit
  2431. X */
  2432. X
  2433. X#include <commit.h>
  2434. X#include <dir.h>
  2435. X#include <mem.h>
  2436. X#include <os.h>
  2437. X#include <trace.h>
  2438. X#include <undo.h>
  2439. X
  2440. X/*
  2441. X * This file contains "commit" functions.
  2442. X *
  2443. X * The idea is that aegis can be interrupted, or fail from errors,
  2444. X * and behave as if "nothing" had happened.
  2445. X * That is, no user discernable difference to their environment,
  2446. X * and certainly no changes to aegis' data base.
  2447. X *
  2448. X * To do this, many database functions write updates to temporary files
  2449. X * "near" where they are to go, eventually.  A commit and an abort function
  2450. X * are both issued, one to put the new file where it really goes, and one
  2451. X * to remove it.  Exactly one option will be exercised.
  2452. X *
  2453. X * Commit actions will be performed with the user-id set the same as was
  2454. X * set at the time the commit call was issued.
  2455. X */
  2456. X
  2457. Xenum what_ty
  2458. X{
  2459. X    what_rename,
  2460. X    what_unlink_errok,
  2461. X    what_rmdir_errok,
  2462. X    what_rmdir_tree_errok
  2463. X};
  2464. Xtypedef enum what_ty what_ty;
  2465. X
  2466. Xtypedef struct action_ty action_ty;
  2467. Xstruct action_ty
  2468. X{
  2469. X    what_ty        what;
  2470. X    string_ty    *path1;
  2471. X    string_ty    *path2;
  2472. X    action_ty    *next;
  2473. X    int        uid;
  2474. X    int        gid;
  2475. X    int        umask;
  2476. X};
  2477. X
  2478. Xstatic    action_ty    *head1;
  2479. Xstatic    action_ty    *tail1;
  2480. Xstatic    action_ty    *head2;
  2481. X
  2482. X
  2483. X/*
  2484. X * NAME
  2485. X *    link1
  2486. X *
  2487. X * SYNOPSIS
  2488. X *    void link1(what_ty action, string_ty *path1, string_ty *path2);
  2489. X *
  2490. X * DESCRIPTION
  2491. X *    The link1 function is used to
  2492. X *    add an new item to the head of chain1.
  2493. X *
  2494. X * ARGUMENTS
  2495. X *    action    - what to do
  2496. X *    path1    - mandatory argument
  2497. X *    path2    - optional argument (NULL if not used)
  2498. X */
  2499. X
  2500. Xstatic void link1 _((what_ty, string_ty *, string_ty *));
  2501. X
  2502. Xstatic void
  2503. Xlink1(what, path1, path2)
  2504. X    what_ty        what;
  2505. X    string_ty    *path1;
  2506. X    string_ty    *path2;
  2507. X{
  2508. X    action_ty    *new;
  2509. X
  2510. X    trace(("commit::link1(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
  2511. X    new = (action_ty *)mem_alloc(sizeof(action_ty));
  2512. X    new->what = what;
  2513. X    os_become_query(&new->uid, &new->gid, &new->umask);
  2514. X    new->path1 = str_copy(path1);
  2515. X    if (path2)
  2516. X        new->path2 = str_copy(path2);
  2517. X    else
  2518. X        new->path2 = 0;
  2519. X    new->next = 0;
  2520. X    if (head1)
  2521. X    {
  2522. X        tail1->next = new;
  2523. X        tail1 = new;
  2524. X    }
  2525. X    else
  2526. X        head1 = tail1 = new;
  2527. X    trace((/*{*/"}\n"));
  2528. X}
  2529. X
  2530. X
  2531. X/*
  2532. X * NAME
  2533. X *    link2
  2534. X *
  2535. X * SYNOPSIS
  2536. X *    void link2(what_ty action, string_ty *path1, string_ty *path2);
  2537. X *
  2538. X * DESCRIPTION
  2539. X *    The link2 function is used to
  2540. X *    add an new item to the head of chain2
  2541. X *
  2542. X * ARGUMENTS
  2543. X *    action    - what to do
  2544. X *    path1    - mandatory argument
  2545. X *    path2    - optional argument (NULL if not used)
  2546. X */
  2547. X
  2548. Xstatic void link2 _((what_ty, string_ty *, string_ty *));
  2549. X
  2550. Xstatic void
  2551. Xlink2(what, path1, path2)
  2552. X    what_ty        what;
  2553. X    string_ty    *path1;
  2554. X    string_ty    *path2;
  2555. X{
  2556. X    action_ty    *new;
  2557. X
  2558. X    trace(("commit::link2(what = %d, path1 = %08lX, path2 = %08lX)\n{\n"/*}*/, what, path1, path2));
  2559. X    new = (action_ty *)mem_alloc(sizeof(action_ty));
  2560. X    new->what = what;
  2561. X    os_become_query(&new->uid, &new->gid, &new->umask);
  2562. X    new->path1 = str_copy(path1);
  2563. X    if (path2)
  2564. X        new->path2 = str_copy(path2);
  2565. X    else
  2566. X        new->path2 = 0;
  2567. X    new->next = head2;
  2568. X    head2 = new;
  2569. X    trace((/*{*/"}\n"));
  2570. X}
  2571. X
  2572. X
  2573. X/*
  2574. X * NAME
  2575. X *    commit_rename
  2576. X *
  2577. X * SYNOPSIS
  2578. X *    void commit_rename(void);
  2579. X *
  2580. X * DESCRIPTION
  2581. X *    The commit_rename function is used to
  2582. X *    submit a commit request to rename a file.
  2583. X *
  2584. X * ARGUMENTS
  2585. X *    from    - path of file now
  2586. X *    to    - path of file after commit
  2587. X */
  2588. X
  2589. Xvoid
  2590. Xcommit_rename(from, to)
  2591. X    string_ty    *from;
  2592. X    string_ty    *to;
  2593. X{
  2594. X    trace(("commit_rename(from = %08lX, to = %08lX)\n{\n"/*}*/, from, to));
  2595. X    trace_string(from->str_text);
  2596. X    trace_string(to->str_text);
  2597. X    link1(what_rename, from, to);
  2598. X    trace((/*{*/"}\n"));
  2599. X}
  2600. X
  2601. X
  2602. X/*
  2603. X * NAME
  2604. X *    commit_unlink_errok
  2605. X *
  2606. X * SYNOPSIS
  2607. X *    void commit_unlink_errok(void);
  2608. X *
  2609. X * DESCRIPTION
  2610. X *    The commit_unlink_errok function is used to
  2611. X *    unlink a file on commit.
  2612. X *    It will not be an error if the file does not exist.
  2613. X *
  2614. X * ARGUMENTS
  2615. X *    path    - path of file to be unlinked
  2616. X */
  2617. X
  2618. Xvoid
  2619. Xcommit_unlink_errok(path)
  2620. X    string_ty    *path;
  2621. X{
  2622. X    trace(("commit_unlink_errok(path = %08lX)\n{\n"/*}*/, path));
  2623. X    trace_string(path->str_text);
  2624. X    link2(what_unlink_errok, path, (string_ty *)0);
  2625. X    trace((/*{*/"}\n"));
  2626. X}
  2627. X
  2628. X
  2629. X/*
  2630. X * NAME
  2631. X *    commit_rmdir_errok
  2632. X *
  2633. X * SYNOPSIS
  2634. X *    void commit_rmdir_errok(string_ty *path);
  2635. X *
  2636. X * DESCRIPTION
  2637. X *    The commit_rmdir_errok function is used to
  2638. X *    delete an empty directory on commit.
  2639. X *    It will not be an error if the directory does not exist.
  2640. X *    It will not be an error if the directory is not empty.
  2641. X *
  2642. X * ARGUMENTS
  2643. X *    path    - path of directory to be deleted
  2644. X */
  2645. X
  2646. Xvoid
  2647. Xcommit_rmdir_errok(path)
  2648. X    string_ty    *path;
  2649. X{
  2650. X    trace(("commit_rmdir_errok(path = %08lX)\n{\n"/*}*/, path));
  2651. X    trace_string(path->str_text);
  2652. X    link2(what_rmdir_errok, path, (string_ty *)0);
  2653. X    trace((/*{*/"}\n"));
  2654. X}
  2655. X
  2656. X
  2657. X/*
  2658. X * NAME
  2659. X *    commit_rmdir_tree_errok
  2660. X *
  2661. X * SYNOPSIS
  2662. X *    void commit_rmdir_tree_errok(string_ty *path);
  2663. X *
  2664. X * DESCRIPTION
  2665. X *    The commit_rmdir_tree_errok function is used to
  2666. X *    delete a directory tree on commit.
  2667. X *    It will not be an error if the directory does not exist.
  2668. X *    It will not be an error if the directory, or any subtree, is not empty.
  2669. X *
  2670. X * ARGUMENTS
  2671. X *    path    - path of directory to be deleted
  2672. X */
  2673. X
  2674. Xvoid
  2675. Xcommit_rmdir_tree_errok(path)
  2676. X    string_ty    *path;
  2677. X{
  2678. X    trace(("commit_rmdir_tree_errok(path = %08lX)\n{\n"/*}*/, path));
  2679. X    trace_string(path->str_text);
  2680. X    link2(what_rmdir_tree_errok, path, (string_ty *)0);
  2681. X    trace((/*{*/"}\n"));
  2682. X}
  2683. X
  2684. X
  2685. X/*
  2686. X * NAME
  2687. X *    rmdir_tree_callback
  2688. X *
  2689. X * SYNOPSIS
  2690. X *    void rmdir_tree_callback(void * arg, dir_walk_message_ty message,
  2691. X *        string_ty *path, struct stat *st);
  2692. X *
  2693. X * DESCRIPTION
  2694. X *    The rmdir_tree_callback function is used to
  2695. X *    perform an action while walking a directory tree's structure.
  2696. X *
  2697. X *    This function is the one that actually deletes things out of the
  2698. X *    directory tree as it is walked.
  2699. X *    Note that the directory should be deleted last,
  2700. X *    after all contents have been nuked.
  2701. X *
  2702. X *    Some sleight-of-hand is involved here,
  2703. X *    as this function pushes extra stuff onto the lists of
  2704. X *    things to be deleted, rather than really doing it itself.
  2705. X *
  2706. X * ARGUMENTS
  2707. X *    arg    - argument given to dir_walk for us
  2708. X *    message    - what sort of file system entity we are looking at
  2709. X *    path    - the absolute path of the file system entity
  2710. X *    st    - pointer to stat structure describing file system entity
  2711. X */
  2712. X
  2713. Xstatic void rmdir_tree_callback _((void *, dir_walk_message_ty,
  2714. X    string_ty *path, struct stat *));
  2715. X
  2716. Xstatic void
  2717. Xrmdir_tree_callback(arg, message, path, stat)
  2718. X    void        *arg;
  2719. X    dir_walk_message_ty message;
  2720. X    string_ty    *path;
  2721. X    struct stat    *stat;
  2722. X{
  2723. X    trace(("rmdir_tree_callback(message = %d, path = %08lX, \
  2724. Xstat = %08lX)\n{\n"/*}*/, message, path, stat));
  2725. X    trace_string(path->str_text);
  2726. X    switch (message)
  2727. X    {
  2728. X    case dir_walk_dir_before:
  2729. X        commit_rmdir_errok(path);
  2730. X        os_chmod_errok(path, 0750);
  2731. X        break;
  2732. X
  2733. X    case dir_walk_dir_after:
  2734. X        break;
  2735. X
  2736. X    case dir_walk_file:
  2737. X    case dir_walk_special:
  2738. X    case dir_walk_symlink:
  2739. X        commit_unlink_errok(path);
  2740. X        break;
  2741. X    }
  2742. X    trace((/*{*/"}\n"));
  2743. X}
  2744. X
  2745. X
  2746. X/*
  2747. X * NAME
  2748. X *    commit
  2749. X *
  2750. X * SYNOPSIS
  2751. X *    void commit(void);
  2752. X *
  2753. X * DESCRIPTION
  2754. X *    The commit function is used to
  2755. X *    perform all the actions queued using the commit_* functions.
  2756. X *
  2757. X *    After it has completed successfully, further calls to commit()
  2758. X *    will be NOPs, until new commit_* functions are used.
  2759. X *
  2760. X *    When the commit has succeeded, the undo list is cancelled,
  2761. X *    since there is now no reason to undo anything.
  2762. X */
  2763. X
  2764. Xvoid
  2765. Xcommit()
  2766. X{
  2767. X    trace(("commit()\n{\n"/*}*/));
  2768. X    while (head1 || head2)
  2769. X    {
  2770. X        action_ty    *action;
  2771. X
  2772. X        /*
  2773. X         * Take the first item off the list.
  2774. X         * Note that actions may append more items to the list.
  2775. X         */
  2776. X        if (head1)
  2777. X        {
  2778. X            action = head1;
  2779. X            head1 = action->next;
  2780. X            if (!head1)
  2781. X                tail1 = 0;
  2782. X        }
  2783. X        else
  2784. X        {
  2785. X            action = head2;
  2786. X            head2 = action->next;
  2787. X        }
  2788. X
  2789. X        /*
  2790. X         * Do the action.
  2791. X         */
  2792. X        os_become(action->uid, action->gid, action->umask);
  2793. X        switch (action->what)
  2794. X        {
  2795. X        case what_rename:
  2796. X            os_rename(action->path1, action->path2);
  2797. X            undo_rename(action->path2, action->path1);
  2798. X            break;
  2799. X    
  2800. X        case what_unlink_errok:
  2801. X            os_unlink_errok(action->path1);
  2802. X            break;
  2803. X    
  2804. X        case what_rmdir_errok:
  2805. X            os_rmdir_errok(action->path1);
  2806. X            break;
  2807. X    
  2808. X        case what_rmdir_tree_errok:
  2809. X            dir_walk(action->path1, rmdir_tree_callback, 0);
  2810. X            break;
  2811. X        }
  2812. X        os_become_undo();
  2813. X
  2814. X        /*
  2815. X         * Free the list element.
  2816. X         */
  2817. X        str_free(action->path1);
  2818. X        if (action->path2)
  2819. X            str_free(action->path2);
  2820. X        mem_free((char *)action);
  2821. X    }
  2822. X
  2823. X    /*
  2824. X     * it's all committed, nothing left to undo.
  2825. X     */
  2826. X    undo_cancel();
  2827. X    trace((/*{*/"}\n"));
  2828. X}
  2829. END_OF_FILE
  2830. if test 9183 -ne `wc -c <'aegis/commit.c'`; then
  2831.     echo shar: \"'aegis/commit.c'\" unpacked with wrong size!
  2832. fi
  2833. # end of 'aegis/commit.c'
  2834. fi
  2835. if test -f 'aux/Makefile.sh' -a "${1}" != "-c" ; then 
  2836.   echo shar: Will not clobber existing file \"'aux/Makefile.sh'\"
  2837. else
  2838. echo shar: Extracting \"'aux/Makefile.sh'\" \(8640 characters\)
  2839. sed "s/^X//" >'aux/Makefile.sh' <<'END_OF_FILE'
  2840. X#! /bin/sh
  2841. X#
  2842. X#    aegis - project change supervisor
  2843. X#    Copyright (C) 1991, 1992, 1993 Peter Miller.
  2844. X#    All rights reserved.
  2845. X#
  2846. X#    This program is free software; you can redistribute it and/or modify
  2847. X#    it under the terms of the GNU General Public License as published by
  2848. X#    the Free Software Foundation; either version 2 of the License, or
  2849. X#    (at your option) any later version.
  2850. X#
  2851. X#    This program is distributed in the hope that it will be useful,
  2852. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2853. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2854. X#    GNU General Public License for more details.
  2855. X#
  2856. X#    You should have received a copy of the GNU General Public License
  2857. X#    along with this program; if not, write to the Free Software
  2858. X#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2859. X#
  2860. X# MANIFEST: shell script to generate the Mafile file
  2861. X#
  2862. Xfmtgen_files=
  2863. Xaegis_files=
  2864. Xtest_files=
  2865. Xclean_files="core bin/fmtgen"
  2866. Xecho  "#"
  2867. Xecho  "# You may need to change this for your system."
  2868. Xecho  "# The \`\`h'' directory supplements your system, not replacing it."
  2869. Xecho  "# The first variation is for gcc when it isn't the native complier,"
  2870. Xecho  "# the second variation is for systems with missing ANSI C include files,"
  2871. Xecho  "# the third variation is for conforming ANSI C implementations."
  2872. Xecho  "#"
  2873. Xecho  "# H = -I/usr/local/lib/gcc-include -I/usr/include -Ih"
  2874. Xecho  "# H = -I/usr/include -Ih"
  2875. Xecho  "H ="
  2876. Xecho  "# H =                # SunOS"
  2877. Xecho  "# H =                # ConvexOS"
  2878. Xecho  "# H =                # dgux"
  2879. Xecho  "# H =                # dcosx (pyramid)"
  2880. Xecho  "# H =                # ULTRIX"
  2881. Xecho  "# H =                # hpux"
  2882. Xecho  "# H =                # SCO"
  2883. Xecho  "# H =                # IRIX"
  2884. Xecho
  2885. Xecho  "#"
  2886. Xecho  "# the name of the compiler to use"
  2887. Xecho  "#"
  2888. Xecho  "CC = cc"
  2889. Xecho  "# CC = gcc"
  2890. Xecho  "# CC = cc            # SunOS"
  2891. Xecho  "# CC = cc            # ConvexOS"
  2892. Xecho  "# CC = cc            # dgux"
  2893. Xecho  "# CC = /usr/ucb/cc        # dcosx (pyramid)"
  2894. Xecho  "# CC = cc            # ULTRIX"
  2895. Xecho  "# CC = cc            # hpux"
  2896. Xecho  "# CC = rcc            # SCO"
  2897. Xecho  "# CC = cc            # IRIX"
  2898. Xecho
  2899. Xecho  "#"
  2900. Xecho  "# The compiler flags to use, except for include path."
  2901. Xecho  "#"
  2902. Xecho  "CFLAGS = -O"
  2903. Xecho  "# CFLAGS = -g"
  2904. Xecho  "# CFLAGS = -O            # SunOS"
  2905. Xecho  "# CFLAGS = -O            # ConvexOS"
  2906. Xecho  "# CFLAGS = -O            # dgux"
  2907. Xecho  "# CFLAGS = -O -Wall -ansi    # gcc"
  2908. Xecho  "# CFLAGS = -O -Xt -U__STDC__    # dcosx (pyramid /usr/ucb/cc is brain-dead)"
  2909. Xecho  "# CFLAGS = -O            # ULTRIX"
  2910. Xecho  "# CFLAGS = -O            # hpux"
  2911. Xecho  "# CFLAGS = -O            # SCO"
  2912. Xecho  "# CFLAGS = -O            # IRIX"
  2913. Xecho
  2914. Xecho  "#"
  2915. Xecho  "# which yacc to use"
  2916. Xecho  "#"
  2917. Xecho  "YACC = yacc"
  2918. Xecho  "# YACC = byacc            # Berkeley"
  2919. Xecho  "# YACC = bison -y        # GNU"
  2920. Xecho  ""
  2921. Xecho  "#"
  2922. Xecho  "# where to put the library directory"
  2923. Xecho  "#    (not used in testing mode)"
  2924. Xecho  "#"
  2925. Xecho  "LIB = /usr/local/lib/aegis"
  2926. Xecho  ""
  2927. Xecho  "#"
  2928. Xecho  "# where to put the executables"
  2929. Xecho  "#"
  2930. Xecho  "BIN = /usr/local/bin"
  2931. Xecho  ""
  2932. Xecho  "#"
  2933. Xecho  "# where to put the manual entries"
  2934. Xecho  "#"
  2935. Xecho  "MAN = /usr/local/man"
  2936. Xecho  ""
  2937. Xecho  "#"
  2938. Xecho  "# extra libraries required for your system"
  2939. Xecho  "#"
  2940. Xecho  "LIBRARIES ="
  2941. Xecho  "# LIBRARIES = -lbsd"
  2942. Xecho  "# LIBRARIES =            # SunOS"
  2943. Xecho  "# LIBRARIES =            # ConvexOS"
  2944. Xecho  "# LIBRARIES =            # dgux"
  2945. Xecho  "# LIBRARIES = -lucb        # dcosx (pyramid)"
  2946. Xecho  "# LIBRARIES =            # ULTRIX"
  2947. Xecho  "# LIBRARIES =            # hpux"
  2948. Xecho  "# LIBRARIES = -lsocket        # SCO"
  2949. Xecho  "# LIBRARIES =            # IRIX"
  2950. Xecho  ""
  2951. Xecho  "#"
  2952. Xecho  "# shell to use to run the tests"
  2953. Xecho  "#    make sure there are no spaces after the definition,"
  2954. Xecho  "#    many flavours of make(1) can't cope with them."
  2955. Xecho  "#"
  2956. Xecho  "SHELL = /bin/sh"
  2957. Xecho  "# SHELL = /bin/sh        # SunOS"
  2958. Xecho  "# SHELL = /bin/sh        # ConvexOS"
  2959. Xecho  "# SHELL = /bin/sh        # dgux"
  2960. Xecho  "# SHELL = /bin/sh        # dcosx (pyramid)"
  2961. Xecho  "# SHELL = /bin/sh5        # ULTRIX"
  2962. Xecho  "# SHELL = /bin/ksh        # apollo"
  2963. Xecho  "# SHELL = /bin/sh        # hpux"
  2964. Xecho  "# SHELL = /bin/sh        # SCO"
  2965. Xecho  "# SHELL = /bin/sh        # IRIX"
  2966. Xecho  ""
  2967. Xecho  "# You should not need to alter anything below this point."
  2968. Xecho  "#------------------------------------------------------------"
  2969. Xecho  ""
  2970. Xecho  "all: bin/aegis"
  2971. Xecho
  2972. Xrm -f common/conf.h
  2973. Xcp /dev/null common/conf.h
  2974. Xfor file in $*
  2975. Xdo
  2976. X    case $file in
  2977. X
  2978. X    fmtgen/*.y)
  2979. X        root=`basename $file .y`
  2980. X        dep=`c_incl -Ifmtgen -Icommon -ns -nc $file`
  2981. X        echo
  2982. X        echo "fmtgen/${root}.gen.c fmtgen/${root}.gen.h: $file"
  2983. X        echo "    $(YACC) -d $file"
  2984. X        echo "    sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > fmtgen/${root}.gen.c"
  2985. X        echo "    rm y.tab.c"
  2986. X        echo "    sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > fmtgen/${root}.gen.h"
  2987. X        echo "    rm y.tab.h"
  2988. X        clean_files="$clean_files fmtgen/${root}.gen.c fmtgen/${root}.gen.h"
  2989. X        echo
  2990. X        echo "fmtgen/${root}.gen.o: fmtgen/${root}.gen.c" $dep
  2991. X        echo "    $(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/${root}.gen.c"
  2992. X        echo "    mv ${root}.gen.o fmtgen/${root}.gen.o"
  2993. X        fmtgen_files="$fmtgen_files fmtgen/${root}.gen.o"
  2994. X        clean_files="$clean_files fmtgen/${root}.gen.o"
  2995. X        ;;
  2996. X
  2997. X    fmtgen/*.c)
  2998. X        root=`basename $file .c`
  2999. X        dep=`c_incl -Ifmtgen -Icommon -ns -nc $file`
  3000. X        echo
  3001. X        echo "fmtgen/${root}.o: $file" $dep
  3002. X        echo "    $(CC) $(CFLAGS) -Ifmtgen -Icommon $(H) -c fmtgen/${root}.c"
  3003. X        echo "    mv ${root}.o fmtgen/${root}.o"
  3004. X        fmtgen_files="$fmtgen_files fmtgen/${root}.o"
  3005. X        clean_files="$clean_files fmtgen/${root}.o"
  3006. X        ;;
  3007. X
  3008. X    aegis/*.def)
  3009. X        root=`basename $file .def`
  3010. X        dep=`c_incl -Iaegis -ns -nc $file`
  3011. X        echo
  3012. X        echo "aegis/${root}.c aegis/${root}.h: $file bin/fmtgen" $dep
  3013. X        echo "    bin/fmtgen -Iaegis $file aegis/${root}.c aegis/${root}.h"
  3014. X        clean_files="$clean_files aegis/${root}.c aegis/${root}.h"
  3015. X        echo
  3016. X        dep=`c_incl -Iaegis -Icommon -ns -nc aegis/${root}.c`
  3017. X        echo "aegis/${root}.o: aegis/${root}.c" $dep
  3018. X        echo "    $(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/${root}.c"
  3019. X        echo "    mv ${root}.o aegis/${root}.o"
  3020. X        aegis_files="$aegis_files aegis/${root}.o"
  3021. X        clean_files="$clean_files aegis/${root}.o"
  3022. X        ;;
  3023. X
  3024. X    aegis/*.y)
  3025. X        root=`basename $file .y`
  3026. X        dep=`c_incl -Iaegis -Icommon -ns -nc $file`
  3027. X        echo
  3028. X        echo "aegis/${root}.gen.c aegis/${root}.gen.h: $file"
  3029. X        echo "    $(YACC) -d $file"
  3030. X        echo "    sed \"s/[yY][yY]/${root}_/g\" < y.tab.c > aegis/${root}.gen.c"
  3031. X        echo "    rm y.tab.c"
  3032. X        echo "    sed \"s/[yY][yY]/${root}_/g\" < y.tab.h > aegis/${root}.gen.h"
  3033. X        echo "    rm y.tab.h"
  3034. X        clean_files="$clean_files aegis/${root}.gen.c aegis/${root}.gen.h"
  3035. X        echo
  3036. X        echo "aegis/${root}.gen.o: aegis/${root}.gen.c" $dep
  3037. X        echo "    $(CC) $(CFLAGS) -Iaegis -Icommon $(H) -c aegis/${root}.gen.c"
  3038. X        echo "    mv ${root}.gen.o aegis/${root}.gen.o"
  3039. X        aegis_files="$aegis_files aegis/${root}.gen.o"
  3040. X        clean_files="$clean_files aegis/${root}.gen.o"
  3041. X        ;;
  3042. X
  3043. X    aegis/*.c)
  3044. X        root=`basename $file .c`
  3045. X        dep=`c_incl -Iaegis -Icommon -ns -nc $file`
  3046. X        echo
  3047. X        echo "aegis/${root}.o: $file" $dep
  3048. X        oflg=
  3049. X        if [ $root = gonzo ]
  3050. X        then
  3051. X            oflg="-D'LIB=\"$(LIB)\"'"
  3052. X        fi
  3053. X        echo "    $(CC) $(CFLAGS) $oflg -Iaegis -Icommon $(H) -c $file"
  3054. X        echo "    mv ${root}.o aegis/${root}.o"
  3055. X        aegis_files="$aegis_files aegis/${root}.o"
  3056. X        clean_files="$clean_files aegis/${root}.o"
  3057. X        ;;
  3058. X
  3059. X    common/*.c)
  3060. X        root=`basename $file .c`
  3061. X        dep=`c_incl -Icommon -ns -nc $file`
  3062. X        echo
  3063. X        echo "common/${root}.o: $file" $dep
  3064. X        echo "    $(CC) $(CFLAGS) -Icommon $(H) -c $file"
  3065. X        echo "    mv ${root}.o common/${root}.o"
  3066. X        aegis_files="$aegis_files common/${root}.o"
  3067. X        fmtgen_files="$fmtgen_files common/${root}.o"
  3068. X        clean_files="$clean_files common/${root}.o"
  3069. X        ;;
  3070. X
  3071. X    test/*/*)
  3072. X        root=`basename $file .sh`
  3073. X        echo ""
  3074. X        echo "${root}: all $file"
  3075. X        echo "    $(SHELL) $file"
  3076. X        test_files="$test_files $root"
  3077. X        ;;
  3078. X
  3079. X    *)
  3080. X        ;;
  3081. X    esac
  3082. Xdone
  3083. X
  3084. X#
  3085. X# clean up the area
  3086. X#
  3087. Xecho ''
  3088. Xecho 'clean:'
  3089. Xecho '    rm -f' $clean_files
  3090. Xecho ''
  3091. Xecho 'realclean: clean'
  3092. Xecho '    rm -f bin/aegis'
  3093. Xecho ''
  3094. Xecho 'clobber: realclean'
  3095. Xecho '    rm -f common/conf.h'
  3096. X
  3097. X#
  3098. X# default the conf.h file
  3099. X# if they have forgotten to set it
  3100. X#
  3101. Xecho ''
  3102. Xecho 'common/conf.h:'
  3103. Xecho '    echo "#include <../conf/`uname -s`-`uname -r`>" > common/conf.h'
  3104. X
  3105. Xecho
  3106. Xecho "FmtgenFiles = $fmtgen_files"
  3107. Xecho
  3108. Xecho "bin/fmtgen: $(FmtgenFiles)"
  3109. Xecho "    if test ! -d bin; then mkdir bin; fi; exit 0"
  3110. Xecho "    $(CC) -o bin/fmtgen $(FmtgenFiles) $(LIBRARIES)"
  3111. X
  3112. Xecho
  3113. Xecho "AegisFiles = $aegis_files"
  3114. Xecho
  3115. Xecho "bin/aegis: $(AegisFiles)"
  3116. Xecho "    if test ! -d bin; then mkdir bin; fi; exit 0"
  3117. Xecho "    $(CC) -o bin/aegis $(AegisFiles) $(LIBRARIES)"
  3118. X
  3119. Xecho
  3120. Xecho "sure:" $test_files
  3121. Xecho "    @echo Passed All Tests"
  3122. X
  3123. Xecho
  3124. Xecho "install: all"
  3125. Xecho "    cp bin/aegis $(BIN)"
  3126. Xecho "    chown root $(BIN)/aegis"
  3127. Xecho "    chmod a+x,u+s $(BIN)/aegis"
  3128. Xecho "    -mkdir $(LIB)"
  3129. Xecho "    chmod 0755 $(LIB)"
  3130. Xecho "    cp lib/* $(LIB)"
  3131. Xecho "    chmod a+r $(LIB)/*"
  3132. Xecho "    chmod a+x $(LIB)/*.sh"
  3133. Xecho "    chown bin $(LIB)"
  3134. Xecho "    chgrp bin $(LIB)"
  3135. Xecho "    $(SHELL) man1/install.sh $(MAN)/man1"
  3136. Xecho "    $(SHELL) man5/install.sh $(MAN)/man5"
  3137. X
  3138. Xrm common/conf.h
  3139. Xexit 0
  3140. END_OF_FILE
  3141. if test 8640 -ne `wc -c <'aux/Makefile.sh'`; then
  3142.     echo shar: \"'aux/Makefile.sh'\" unpacked with wrong size!
  3143. fi
  3144. # end of 'aux/Makefile.sh'
  3145. fi
  3146. if test -f 'common/arglex.c' -a "${1}" != "-c" ; then 
  3147.   echo shar: Will not clobber existing file \"'common/arglex.c'\"
  3148. else
  3149. echo shar: Extracting \"'common/arglex.c'\" \(10257 characters\)
  3150. sed "s/^X//" >'common/arglex.c' <<'END_OF_FILE'
  3151. X/*
  3152. X *    aegis - project change supervisor
  3153. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  3154. X *    All rights reserved.
  3155. X *
  3156. X *    This program is free software; you can redistribute it and/or modify
  3157. X *    it under the terms of the GNU General Public License as published by
  3158. X *    the Free Software Foundation; either version 2 of the License, or
  3159. X *    (at your option) any later version.
  3160. X *
  3161. X *    This program is distributed in the hope that it will be useful,
  3162. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  3163. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3164. X *    GNU General Public License for more details.
  3165. X *
  3166. X *    You should have received a copy of the GNU General Public License
  3167. X *    along with this program; if not, write to the Free Software
  3168. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3169. X *
  3170. X * MANIFEST: lexical analysis of command line arguments
  3171. X */
  3172. X
  3173. X#include <stddef.h>
  3174. X#include <string.h>
  3175. X#include <ctype.h>
  3176. X
  3177. X#include <arglex.h>
  3178. X#include <error.h>
  3179. X#include <option.h>
  3180. X#include <str.h>
  3181. X#include <trace.h>
  3182. X
  3183. Xstatic arglex_table_ty table[] =
  3184. X{
  3185. X    { "-",            arglex_token_stdio,        },
  3186. X    { "-Help",        arglex_token_help,        },
  3187. X    { "-VERSion",        arglex_token_version,        },
  3188. X    { "-TRace",        arglex_token_trace,        },
  3189. X};
  3190. X
  3191. Xstatic    int        argc;
  3192. Xstatic    char        **argv;
  3193. X    arglex_value_ty    arglex_value;
  3194. X    arglex_token_ty    arglex_token;
  3195. Xstatic    arglex_table_ty    *utable;
  3196. Xstatic    char        *partial;
  3197. X
  3198. X
  3199. X/*
  3200. X * NAME
  3201. X *    arglex_init
  3202. X *
  3203. X * SYNOPSIS
  3204. X *    void arglex_init(int ac, char **av, arglex_table-t *tp);
  3205. X *
  3206. X * DESCRIPTION
  3207. X *    The arglex_init function is used to initialize the
  3208. X *    command line processing.
  3209. X *
  3210. X * ARGUMENTS
  3211. X *    ac    - aergument count, from main
  3212. X *    av    - argument values, from main
  3213. X *    tp    - pointer to table of options
  3214. X *
  3215. X * CAVEAT
  3216. X *    Must be called before the arglex() function.
  3217. X */
  3218. X
  3219. Xvoid
  3220. Xarglex_init(ac, av, tp)
  3221. X    int        ac;
  3222. X    char        **av;
  3223. X    arglex_table_ty    *tp;
  3224. X{
  3225. X    option_progname_set(av[0]);
  3226. X    argc = ac - 1;
  3227. X    argv = av + 1;
  3228. X    utable = tp;
  3229. X}
  3230. X
  3231. X
  3232. X/*
  3233. X * NAME
  3234. X *    arglex_compare
  3235. X *
  3236. X * SYNOPSIS
  3237. X *    int arglex_compare(char *formal, char *actual);
  3238. X *
  3239. X * DESCRIPTION
  3240. X *    The arglex_compare function is used to compare
  3241. X *    a command line string with a formal spec of the option,
  3242. X *    to see if they compare equal.
  3243. X *
  3244. X *    The actual is case-insensitive.  Uppercase in the formal
  3245. X *    means a mandatory character, while lower case means optional.
  3246. X *    Any number of consecutive optional characters may be supplied
  3247. X *    by actual, but none may be skipped, unless all are skipped to
  3248. X *    the next non-lower-case letter.
  3249. X *
  3250. X *    The underscore (_) is like a lower-case minus,
  3251. X *    it matches "", "-" and "_".
  3252. X *
  3253. X *    The "*" in a pattern matches everything to the end of the line,
  3254. X *    anything after the "*" is ignored.  The rest of the line is pointed
  3255. X *    to by the "partial" variable as a side-effect (else it will be 0).
  3256. X *    This rather ugly feature is to support "-I./dir" type options.
  3257. X *
  3258. X *    A backslash in a pattern nominates an exact match required,
  3259. X *    case must matche excatly here.
  3260. X *    This rather ugly feature is to support "-I./dir" type options.
  3261. X *
  3262. X *    For example: "-project" and "-P' both match "-Project",
  3263. X *    as does "-proJ", but "-prj" does not.
  3264. X *
  3265. X *    For example: "-devDir" and "-d_d' both match "-Development_Directory",
  3266. X *    but "-dvlpmnt_drctry" does not.
  3267. X *
  3268. X *    For example: to match include path specifications, use a pattern
  3269. X *    such as "-\\I*", and the partial global variable will have the
  3270. X *    path in it on return.
  3271. X *
  3272. X * ARGUMENTS
  3273. X *    formal    - the "pattern" for the option
  3274. X *    actual    - what the user supplied
  3275. X *
  3276. X * RETURNS
  3277. X *    int;    zero if no match,
  3278. X *        non-zero if they do match.
  3279. X */
  3280. X
  3281. Xint
  3282. Xarglex_compare(formal, actual)
  3283. X    char    *formal;
  3284. X    char    *actual;
  3285. X{
  3286. X    char    fc;
  3287. X    char    ac;
  3288. X    int    result;
  3289. X
  3290. X    trace(("arglex_compare(formal = \"%s\", actual = \"%s\")\n{\n",
  3291. X        formal, actual));
  3292. X    for (;;)
  3293. X    {
  3294. X        trace_string(formal);
  3295. X        trace_string(actual);
  3296. X        ac = *actual++;
  3297. X        if (isupper(ac))
  3298. X            ac = tolower(ac);
  3299. X        fc = *formal++;
  3300. X        switch (fc)
  3301. X        {
  3302. X        case 0:
  3303. X            result = !ac;
  3304. X            goto done;
  3305. X            
  3306. X        case '_':
  3307. X            if (ac == '-')
  3308. X                break;
  3309. X            /* fall through... */
  3310. X
  3311. X        case 'a': case 'b': case 'c': case 'd': case 'e':
  3312. X        case 'f': case 'g': case 'h': case 'i': case 'j':
  3313. X        case 'k': case 'l': case 'm': case 'n': case 'o':
  3314. X        case 'p': case 'q': case 'r': case 's': case 't':
  3315. X        case 'u': case 'v': case 'w': case 'x': case 'y':
  3316. X        case 'z': 
  3317. X            /*
  3318. X             * optional characters
  3319. X             */
  3320. X            if (ac == fc && arglex_compare(formal, actual))
  3321. X            {
  3322. X                result = 1;
  3323. X                goto done;
  3324. X            }
  3325. X
  3326. X            /*
  3327. X             * skip forward to next
  3328. X             * mandatory character, or after '_'
  3329. X             */
  3330. X            while (islower(*formal))
  3331. X                ++formal;
  3332. X            if (*formal == '_')
  3333. X            {
  3334. X                ++formal;
  3335. X                if (ac == '_' || ac == '-')
  3336. X                    ++actual;
  3337. X            }
  3338. X            --actual;
  3339. X            break;
  3340. X
  3341. X        case '*':
  3342. X            /*
  3343. X             * This is a hack, it should really 
  3344. X             * check for a match match the stuff after
  3345. X             * the '*', too, a la glob.
  3346. X             */
  3347. X            if (!ac)
  3348. X            {
  3349. X                result = 0;
  3350. X                goto done;
  3351. X            }
  3352. X            partial = actual - 1;
  3353. X            result = 1;
  3354. X            goto done;
  3355. X
  3356. X        case '\\':
  3357. X            if (actual[-1] != *formal++)
  3358. X            {
  3359. X                result = 0;
  3360. X                goto done;
  3361. X            }
  3362. X            break;
  3363. X
  3364. X        case 'A': case 'B': case 'C': case 'D': case 'E':
  3365. X        case 'F': case 'G': case 'H': case 'I': case 'J':
  3366. X        case 'K': case 'L': case 'M': case 'N': case 'O':
  3367. X        case 'P': case 'Q': case 'R': case 'S': case 'T':
  3368. X        case 'U': case 'V': case 'W': case 'X': case 'Y':
  3369. X        case 'Z': 
  3370. X            fc = tolower(fc);
  3371. X            /* fall through... */
  3372. X
  3373. X        default:
  3374. X            /*
  3375. X             * mandatory characters
  3376. X             */
  3377. X            if (fc != ac)
  3378. X            {
  3379. X                result = 0;
  3380. X                goto done;
  3381. X            }
  3382. X            break;
  3383. X        }
  3384. X    }
  3385. X    done:
  3386. X    trace(("return %d;\n}\n", result));
  3387. X    return result;
  3388. X}
  3389. X
  3390. X
  3391. X/*
  3392. X * NAME
  3393. X *    is_a_number
  3394. X *
  3395. X * SYNOPSIS
  3396. X *    int is_a_number(char *s);
  3397. X *
  3398. X * DESCRIPTION
  3399. X *    The is_a_number function is used to determine if the
  3400. X *    argument is a number.
  3401. X *
  3402. X *    The value is placed in arglex_value.alv_number as
  3403. X *    a side effect.
  3404. X *
  3405. X *    Negative and positive signs are accepted.
  3406. X *    The C conventions for decimal, octal and hexadecimal are understood.
  3407. X *
  3408. X *    There may be no white space anywhere in the string,
  3409. X *    and the string must end after the last digit.
  3410. X *    Trailing garbage will be interpreted to mean it is not a string.
  3411. X *
  3412. X * ARGUMENTS
  3413. X *    s    - string to be tested and evaluated
  3414. X *
  3415. X * RETURNS
  3416. X *    int;    zero if not a number,
  3417. X *        non-zero if is a number.
  3418. X */
  3419. X
  3420. Xstatic int is_a_number _((char *));
  3421. X
  3422. Xstatic int
  3423. Xis_a_number(s)
  3424. X    char    *s;
  3425. X{
  3426. X    long    n;
  3427. X    int    sign;
  3428. X
  3429. X    n = 0;
  3430. X    switch (*s)
  3431. X    {
  3432. X    case '-':
  3433. X        ++s;
  3434. X        sign = -1;
  3435. X        break;
  3436. X
  3437. X    case '+':
  3438. X        ++s;
  3439. X        sign = 1;
  3440. X        break;
  3441. X
  3442. X    default:
  3443. X        sign = 1;
  3444. X        break;
  3445. X    }
  3446. X    switch (*s)
  3447. X    {
  3448. X    case '0':
  3449. X        if ((s[1] == 'x' || s[1] == 'X') && s[2])
  3450. X        {
  3451. X            s += 2;
  3452. X            for (;;)
  3453. X            {
  3454. X                switch (*s)
  3455. X                {
  3456. X                case '0': case '1': case '2': case '3':
  3457. X                case '4': case '5': case '6': case '7':
  3458. X                case '8': case '9':
  3459. X                    n = n * 16 + *s++ - '0';
  3460. X                    continue;
  3461. X
  3462. X                case 'A': case 'B': case 'C':
  3463. X                case 'D': case 'E': case 'F':
  3464. X                    n = n * 16 + *s++ - 'A' + 10;
  3465. X                    continue;
  3466. X
  3467. X                case 'a': case 'b': case 'c':
  3468. X                case 'd': case 'e': case 'f':
  3469. X                    n = n * 16 + *s++ - 'a' + 10;
  3470. X                    continue;
  3471. X                }
  3472. X                break;
  3473. X            }
  3474. X        }
  3475. X        else
  3476. X        {
  3477. X            for (;;)
  3478. X            {
  3479. X                switch (*s)
  3480. X                {
  3481. X                case '0': case '1': case '2': case '3':
  3482. X                case '4': case '5': case '6': case '7':
  3483. X                    n = n * 8 + *s++ - '0';
  3484. X                    continue;
  3485. X                }
  3486. X                break;
  3487. X            }
  3488. X        }
  3489. X        break;
  3490. X
  3491. X    case '1': case '2': case '3': case '4':
  3492. X    case '5': case '6': case '7': case '8': case '9':
  3493. X        for (;;)
  3494. X        {
  3495. X            switch (*s)
  3496. X            {
  3497. X            case '0': case '1': case '2': case '3':
  3498. X            case '4': case '5': case '6': case '7':
  3499. X            case '8': case '9':
  3500. X                n = n * 10 + *s++ - '0';
  3501. X                continue;
  3502. X            }
  3503. X            break;
  3504. X        }
  3505. X        break;
  3506. X
  3507. X    default:
  3508. X        return 0;
  3509. X    }
  3510. X    if (*s)
  3511. X        return 0;
  3512. X    arglex_value.alv_number = n * sign;
  3513. X    return 1;
  3514. X}
  3515. X
  3516. X
  3517. X/*
  3518. X * NAME
  3519. X *    arglex
  3520. X *
  3521. X * SYNOPSIS
  3522. X *    arglex_token_ty arglex(void);
  3523. X *
  3524. X * DESCRIPTION
  3525. X *    The arglex function is used to perfom lexical analysis
  3526. X *    on the command line arguments.
  3527. X *
  3528. X *    Unrecognised options are returned as arglex_token_option
  3529. X *    for anything starting with a '-', or
  3530. X *    arglex_token_string otherwise.
  3531. X *
  3532. X * RETURNS
  3533. X *    The next token in the token stream.
  3534. X *    When the end is reached, arglex_token_eoln is returned forever.
  3535. X *
  3536. X * CAVEAT
  3537. X *    Must call arglex_init befor this function is called.
  3538. X */
  3539. X
  3540. Xarglex_token_ty
  3541. Xarglex()
  3542. X{
  3543. X    arglex_table_ty    *tp;
  3544. X    int        j;
  3545. X    arglex_table_ty    *hit[20];
  3546. X    int        nhit;
  3547. X    static char    *pushback;
  3548. X    char        *arg;
  3549. X
  3550. X    trace(("arglex()\n{\n"));
  3551. X    if (pushback)
  3552. X    {
  3553. X        /*
  3554. X         * the second half of a "-foo=bar" style argument.
  3555. X         */
  3556. X        arg = pushback;
  3557. X        pushback = 0;
  3558. X    }
  3559. X    else
  3560. X    {
  3561. X        if (argc <= 0)
  3562. X        {
  3563. X            arglex_token = arglex_token_eoln;
  3564. X            arg = "";
  3565. X            goto done;
  3566. X        }
  3567. X        arg = argv[0];
  3568. X        argc--;
  3569. X        argv++;
  3570. X
  3571. X        /*
  3572. X         * See if it looks like a GNU "-foo=bar" option.
  3573. X         * Split it at the '=' to make it something the
  3574. X         * rest of the code understands.
  3575. X         */
  3576. X        if (arg[0] == '-' && arg[1] != '=')
  3577. X        {
  3578. X            char    *eqp;
  3579. X
  3580. X            eqp = strchr(arg, '=');
  3581. X            if (eqp)
  3582. X            {
  3583. X                pushback = eqp + 1;
  3584. X                *eqp = 0;
  3585. X            }
  3586. X        }
  3587. X
  3588. X        /*
  3589. X         * Turn the GNU-style leading "--"
  3590. X         * into "-" if necessary.
  3591. X         */
  3592. X        if
  3593. X        (
  3594. X            arg[0] == '-'
  3595. X        &&
  3596. X            arg[1] == '-'
  3597. X        &&
  3598. X            arg[2]
  3599. X        &&
  3600. X            !is_a_number(arg + 1)
  3601. X        )
  3602. X            ++arg;
  3603. X    }
  3604. X
  3605. X    /*
  3606. X     * see if it is a number
  3607. X     */
  3608. X    if (is_a_number(arg))
  3609. X    {
  3610. X        arglex_token = arglex_token_number;
  3611. X        goto done;
  3612. X    }
  3613. X
  3614. X    /*
  3615. X     * scan the tables to see what it matches
  3616. X     */
  3617. X    nhit = 0;
  3618. X    partial = 0;
  3619. X    for (tp = table; tp < ENDOF(table); tp++)
  3620. X    {
  3621. X        if (arglex_compare(tp->t_name, arg))
  3622. X            hit[nhit++] = tp;
  3623. X    }
  3624. X    if (utable)
  3625. X    {
  3626. X        for (tp = utable; tp->t_name; tp++)
  3627. X        {
  3628. X            if (arglex_compare(tp->t_name, arg))
  3629. X                hit[nhit++] = tp;
  3630. X        }
  3631. X    }
  3632. X
  3633. X    /*
  3634. X     * deal with unknown or ambiguous options
  3635. X     */
  3636. X    switch (nhit)
  3637. X    {
  3638. X    case 0:
  3639. X        /*
  3640. X         * not found in the tables
  3641. X         */
  3642. X        if (*arg == '-')
  3643. X            arglex_token = arglex_token_option;
  3644. X        else
  3645. X            arglex_token = arglex_token_string;
  3646. X        break;
  3647. X
  3648. X    case 1:
  3649. X        arglex_token = hit[0]->t_token;
  3650. X        if (partial)
  3651. X            arg = partial;
  3652. X        else
  3653. X            arg = hit[0]->t_name;
  3654. X        break;
  3655. X
  3656. X    default:
  3657. X        {
  3658. X            string_ty    *s1;
  3659. X            string_ty    *s2;
  3660. X
  3661. X            s1 = str_from_c(hit[0]->t_name);
  3662. X            for (j = 1; j < nhit; ++j)
  3663. X            {
  3664. X                s2 = str_format("%S, %s", s1, hit[j]->t_name);
  3665. X                str_free(s1);
  3666. X                s2 = s2;
  3667. X            }
  3668. X            fatal
  3669. X            (
  3670. X                "option \"%s\" abmiguous (%s)",
  3671. X                arg,
  3672. X                s1->str_text
  3673. X            );
  3674. X        }
  3675. X    }
  3676. X
  3677. X    /*
  3678. X     * here for all exits
  3679. X     */
  3680. X    done:
  3681. X    arglex_value.alv_string = arg;
  3682. X    trace(("return %d; /* %s */\n", arglex_token, arglex_value.alv_string));
  3683. X    trace((/*{*/"}\n"));
  3684. X    return arglex_token;
  3685. X}
  3686. END_OF_FILE
  3687. if test 10257 -ne `wc -c <'common/arglex.c'`; then
  3688.     echo shar: \"'common/arglex.c'\" unpacked with wrong size!
  3689. fi
  3690. # end of 'common/arglex.c'
  3691. fi
  3692. if test -f 'doc/c5.0.so' -a "${1}" != "-c" ; then 
  3693.   echo shar: Will not clobber existing file \"'doc/c5.0.so'\"
  3694. else
  3695. echo shar: Extracting \"'doc/c5.0.so'\" \(10142 characters\)
  3696. sed "s/^X//" >'doc/c5.0.so' <<'END_OF_FILE'
  3697. X.\"
  3698. X.\"    aegis - project change supervisor
  3699. X.\"    Copyright (C) 1991, 1992, 1993 Peter Miller.
  3700. X.\"    All rights reserved.
  3701. X.\"
  3702. X.\"    This program is free software; you can redistribute it and/or modify
  3703. X.\"    it under the terms of the GNU General Public License as published by
  3704. X.\"    the Free Software Foundation; either version 2 of the License, or
  3705. X.\"    (at your option) any later version.
  3706. X.\"
  3707. X.\"    This program is distributed in the hope that it will be useful,
  3708. X.\"    but WITHOUT ANY WARRANTY; without even the implied warranty of
  3709. X.\"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3710. X.\"    GNU General Public License for more details.
  3711. X.\"
  3712. X.\"    You should have received a copy of the GNU General Public License
  3713. X.\"    along with this program; if not, write to the Free Software
  3714. X.\"    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3715. X.\"
  3716. X.\" MANIFEST: User Guide, The Project Attributes
  3717. X.\"
  3718. X.bp
  3719. X.1C
  3720. X.nh 1 "The Project Attributes"
  3721. X.LP
  3722. XThe project attributes are manipulated using the
  3723. X.I aepa (1)
  3724. Xcommand.
  3725. XThis command reads a project attributes file to set the project attributes.
  3726. XThis file can be thought of as having several sections,
  3727. Xeach of which will be covered by this chapter.
  3728. XYou should see the
  3729. X.I aepattr (5)
  3730. Xmanual entry for more details.
  3731. X.nh 2 "Description and Access"
  3732. X.LP
  3733. XThe
  3734. X.I description
  3735. Xfield is a string which contains
  3736. Xa description of the project.
  3737. XLarge amounts of prose are not required;
  3738. Xa single line is sufficient.
  3739. X.LP
  3740. XThe
  3741. X.I default_development_directory
  3742. Xfield is a string which contains
  3743. Xthe pathname of where to place new development directories.
  3744. XThe pathname must be absolute.
  3745. XThis field is only
  3746. Xconsulted if the
  3747. X.I uconf (5)
  3748. Xfield of the same name is not set.
  3749. XDefaults to
  3750. X.I $HOME .
  3751. X.LP
  3752. XThe
  3753. X.I umask
  3754. Xfield is an integer which is set to the
  3755. Xfile permission mode mask.
  3756. XSee
  3757. X.I umask (2)
  3758. Xfor more information.
  3759. XThis value will always be OR'ed with 022,
  3760. Xbecause aegis is paranoid.
  3761. X.nh 2 "Notification Commands"
  3762. X.LP
  3763. XThe
  3764. X.I develop_end_notify_command
  3765. Xfield is a string which contains a command to be used to
  3766. Xnotify that a change requires reviewing.
  3767. XAll of the substitutions described in
  3768. X.I aesub (5)
  3769. Xare available.
  3770. XThis field is optional, if it is not specified no notification will be issued.
  3771. XThis command could also be used to notify other management systems,
  3772. Xsuch as progress and defect tracking,
  3773. Xin addition to notifying users.
  3774. X.LP
  3775. XThe
  3776. X.I develop_end_undo_notify_command
  3777. Xfield is a string containing a command used to
  3778. Xnotify that a change has been withdrawn from review
  3779. Xfor further development.
  3780. XAll of the substitutions described in
  3781. X.I aesub (5)
  3782. Xare available.
  3783. XThis field is optional, if it is not specified no notification will be issued.
  3784. XThis command could also be used to notify other management systems,
  3785. Xsuch as progress and defect tracking,
  3786. Xin addition to notifying users.
  3787. X.LP
  3788. XThe
  3789. X.I review_pass_notify_command
  3790. Xfield is a string containing the command to
  3791. Xnotify that the review has passed.
  3792. XAll of the substitutions described in
  3793. X.I aesub (5)
  3794. Xare available.
  3795. XThis field is optional, if it is not specified no notification will be issued.
  3796. XThis command could also be used to notify other management systems,
  3797. Xsuch as progress and defect tracking,
  3798. Xin addition to notifying users.
  3799. X.LP
  3800. XThe
  3801. X.I review_pass_undo_notify_command
  3802. Xfield is a string containing the command to
  3803. Xnotify that a review pass has has been rescinded.
  3804. XAll of the substitutions described in
  3805. X.I aesub (5)
  3806. Xare available.
  3807. XThis field is optional, and defaults to the
  3808. X.I develop_end_notify_command
  3809. Xfield if not specified.
  3810. XIf neither is specified, no notification will be issued.
  3811. XThis command could also be used to notify other management systems,
  3812. Xsuch as progress and defect tracking,
  3813. Xin addition to notifying users.
  3814. X.LP
  3815. XThe
  3816. X.I review_fail_notify_command
  3817. Xfield is a string containing the command to
  3818. Xnotify that the review has failed.
  3819. XAll of the substitutions described in
  3820. X.I aesub (5)
  3821. Xare available.
  3822. XThis field is optional, if it is not specified no notification will be issued.
  3823. XThis command could also be used to notify other management systems,
  3824. Xsuch as progress and defect tracking,
  3825. Xin addition to notifying users.
  3826. X.LP
  3827. XThe
  3828. X.I integrate_pass_notify_command
  3829. Xfield is a string containing the command to
  3830. Xnotify that the integration has passed.
  3831. XAll of the substitutions described in
  3832. X.I aesub (5)
  3833. Xare available.
  3834. XThis field is optional, if it is not specified no notification will be issued.
  3835. XThis command could also be used to notify other management systems,
  3836. Xsuch as progress and defect tracking,
  3837. Xin addition to notifying users.
  3838. X.LP
  3839. XThe
  3840. X.I integrate_fail_notify_command
  3841. Xfield is a string containing the command to
  3842. Xnotify that the integration has failed.
  3843. XAll of the substitutions described in
  3844. X.I aesub (5)
  3845. Xare available.
  3846. XThis field is optional, if it is not specified no notification will be issued.
  3847. XThis command could also be used to notify other management systems,
  3848. Xsuch as progress and defect tracking,
  3849. Xin addition to notifying users.
  3850. X.nh 3 "Notification by email"
  3851. X.LP
  3852. XThe aegis command is distributed with a set of shell scripts to
  3853. Xperform these notifications by email.
  3854. XThey are installed into the
  3855. X.I /usr/local/lib/aegis
  3856. Xdirectory.
  3857. XThe entries in the project attribute file look like this:
  3858. X.E(
  3859. Xdevelop_end_notify_command =
  3860. X        "sh /usr/local/lib/aegis/de.sh $project $change \e
  3861. X        $developer";
  3862. Xdevelop_end_undo_notify_command =
  3863. X        "sh /usr/local/lib/aegis/deu.sh $project $change \e
  3864. X        $developer";
  3865. Xreview_pass_notify_command =
  3866. X        "sh /usr/local/lib/aegis/rp.sh $project $change \e
  3867. X        $developer $reviewer";
  3868. Xreview_pass_undo_notify_command =
  3869. X        "sh /usr/local/lib/aegis/rpu.sh $project $change \e
  3870. X        $developer $reviewer";
  3871. Xreview_fail_notify_command =
  3872. X        "sh /usr/local/lib/aegis/rf.sh $project $change \e
  3873. X        $developer $reviewer";
  3874. Xintegrate_pass_notify_command =
  3875. X        "sh /usr/local/lib/aegis/ip.sh $project $change \e
  3876. X        $developer $reviewer $integrator";
  3877. Xintegrate_fail_notify_command =
  3878. X        "sh /usr/local/lib/aegis/if.sh $project $change \e
  3879. X        $developer $reviewer $integrator";
  3880. X.E)
  3881. X.nh 3 "Notification by USENET"
  3882. X.LP
  3883. XThe aegis command is distributed with a set of shell scripts to
  3884. Xperform these notifications by USENET.
  3885. XThey are installed into the
  3886. X.I /usr/local/lib/aegis
  3887. Xdirectory.
  3888. XThe entries in the project attribute file look like this:
  3889. X.E(
  3890. Xdevelop_end_notify_command =
  3891. X        "sh /usr/local/lib/aegis/de.inews.sh $p $c alt.$p";
  3892. Xdevelop_end_undo_notify_command =
  3893. X        "sh /usr/local/lib/aegis/deu.inews.sh $p $c alt.$p";
  3894. Xreview_pass_notify_command =
  3895. X        "sh /usr/local/lib/aegis/rp.inews.sh $p $c alt.$p";
  3896. Xreview_pass_undo_notify_command =
  3897. X        "sh /usr/local/lib/aegis/rpu.inews.sh $p $c alt.$p";
  3898. Xreview_fail_notify_command =
  3899. X        "sh /usr/local/lib/aegis/rf.inews.sh $p $c alt.$p";
  3900. Xintegrate_pass_notify_command =
  3901. X        "sh /usr/local/lib/aegis/ip.inews.sh $p $c alt.$p";
  3902. Xintegrate_fail_notify_command =
  3903. X        "sh /usr/local/lib/aegis/if.inews.sh $p $c alt.$p";
  3904. X.E)
  3905. X.LP
  3906. XThe last argument to each command is the newsgroup to post the article in,
  3907. Xyou may want to use some other group.
  3908. XNote that "$p" is an abbreviation for "$project" 
  3909. Xand "$c" is an abbreviation for "$change".
  3910. X.nh 2 "Exemption Controls"
  3911. X.LP
  3912. XThe
  3913. X.I developer_may_review
  3914. Xfield is a boolean.
  3915. XIf this field is true,
  3916. Xthen a developer may review her own change.
  3917. XThis is probably only a good idea for projects of less than 3 people.
  3918. XThe idea is for as many people as possible to critically examine a change.
  3919. X.LP
  3920. XThe
  3921. X.I developer_may_integrate
  3922. Xfield is a boolean.
  3923. XIf this field is true,
  3924. Xthen a developer may integrate her own change.
  3925. XThis is probably only a good idea for projects of less than 3 people.
  3926. XThe idea is for as many people as possible to critically examine a change.
  3927. X.LP
  3928. XThe
  3929. X.I reviewer_may_integrate
  3930. Xfield is a boolean.
  3931. XIf this field is true,
  3932. Xthen a reviewer may integrate a change she reviewed.
  3933. XThis is probably only a good idea for projects of less than 3 people.
  3934. XThe idea is for as many people as possible to critically examine a change.
  3935. X.LP
  3936. XThe
  3937. X.I developers_may_create_changes
  3938. Xfield is a boolean.
  3939. XThis field is true if developers may created changes,
  3940. Xin addition to administrators.
  3941. XThis tends to be a very useful thing,
  3942. Xsince developers find most of the bugs.
  3943. X.LP
  3944. XThe
  3945. X.I default_test_exemption
  3946. Xfield is a boolean.
  3947. XThis field contains what to do when a change is created with
  3948. Xno test exemption specified.
  3949. XThe default is "false", i.e. no testing exemption,
  3950. Xtests must be provided.
  3951. X.LP
  3952. XThis kind of blanket exemption should only be set when
  3953. Xa project has absolutely no functionality available from the command line;
  3954. Xexamples include X11 programs.
  3955. XThe program could possibly be improved by providing access to
  3956. Xthe functionality from the command line,
  3957. Xthus allowing tests to be written.
  3958. X.nh 3 "One Person Projects"
  3959. X.LP
  3960. XThe entries in the project attributes file for a
  3961. Xone person project look like this:
  3962. X.E(
  3963. Xdeveloper_may_review = true;
  3964. Xdeveloper_may_integrate = true;
  3965. Xreviewer_may_integrate = true;
  3966. Xdevelopers_may_create_changes = true;
  3967. X.E)
  3968. X.LP
  3969. XAll of the staff roles
  3970. X(administrator, developer, reviewer and integrator)
  3971. Xare all set to be the same user.
  3972. X.nh 3 "Two Person Projects"
  3973. X.LP
  3974. XA two person project has the opportunity for each to review the other's work.
  3975. X.LP
  3976. XThe entries in the project attributes file for a
  3977. Xone person project look like this:
  3978. X.E(
  3979. Xdeveloper_may_review = false.
  3980. Xdeveloper_may_integrate = true;
  3981. Xreviewer_may_integrate = true;
  3982. Xdevelopers_may_create_changes = true;
  3983. X.E)
  3984. X.LP
  3985. XAll of the staff roles
  3986. X(developer, reviewer and integrator)
  3987. Xare all set to allow both users.
  3988. X.nh 3 "Larger Projects"
  3989. X.LP
  3990. XOnce you have 3 or more staff on a project,
  3991. Xyou can assign all of the roles to separate people.
  3992. XThe idea is for the greatest number of eyes to see each change
  3993. Xand detect flaws before they reach the baseline.
  3994. X.LP
  3995. XThe entries in the project attributes file for a
  3996. Xone person project look like this:
  3997. X.E(
  3998. Xdeveloper_may_review = false.
  3999. Xdeveloper_may_integrate = false;
  4000. Xreviewer_may_integrate = false;
  4001. Xdevelopers_may_create_changes = true;
  4002. X.E)
  4003. X.LP
  4004. XFor smaller teams,
  4005. Xeveryone may be a developer.
  4006. XAs the teams get larger,
  4007. Xthe more experienced staff are often the reviewers,
  4008. Xrather than everyone.
  4009. END_OF_FILE
  4010. if test 10142 -ne `wc -c <'doc/c5.0.so'`; then
  4011.     echo shar: \"'doc/c5.0.so'\" unpacked with wrong size!
  4012. fi
  4013. # end of 'doc/c5.0.so'
  4014. fi
  4015. if test -f 'fmtgen/id.c' -a "${1}" != "-c" ; then 
  4016.   echo shar: Will not clobber existing file \"'fmtgen/id.c'\"
  4017. else
  4018. echo shar: Extracting \"'fmtgen/id.c'\" \(9297 characters\)
  4019. sed "s/^X//" >'fmtgen/id.c' <<'END_OF_FILE'
  4020. X/*
  4021. X *    aegis - project change supervisor
  4022. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  4023. X *    All rights reserved.
  4024. X *
  4025. X *    This program is free software; you can redistribute it and/or modify
  4026. X *    it under the terms of the GNU General Public License as published by
  4027. X *    the Free Software Foundation; either version 2 of the License, or
  4028. X *    (at your option) any later version.
  4029. X *
  4030. X *    This program is distributed in the hope that it will be useful,
  4031. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  4032. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4033. X *    GNU General Public License for more details.
  4034. X *
  4035. X *    You should have received a copy of the GNU General Public License
  4036. X *    along with this program; if not, write to the Free Software
  4037. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4038. X *
  4039. X * MANIFEST: symbol table manipulation
  4040. X */
  4041. X
  4042. X#include <stddef.h>
  4043. X#include <stdlib.h>
  4044. X#include <string.h>
  4045. X
  4046. X#include <main.h>
  4047. X#include <id.h>
  4048. X#include <word.h>
  4049. X#include <mem.h>
  4050. X#include <error.h>
  4051. X
  4052. X
  4053. X#define HEADER \
  4054. X    string_ty    *id_name; \
  4055. X    str_hash_ty    id_hash; \
  4056. X    id        *id_next; \
  4057. X    id_class_ty    id_class;
  4058. X
  4059. Xtypedef struct id id;
  4060. Xstruct id
  4061. X{
  4062. X    HEADER
  4063. X};
  4064. X
  4065. Xtypedef struct id_int id_int;
  4066. Xstruct id_int
  4067. X{
  4068. X    HEADER
  4069. X    int        id_value;
  4070. X};
  4071. X
  4072. Xtypedef struct id_void id_void;
  4073. Xstruct id_void
  4074. X{
  4075. X    HEADER
  4076. X    void        *id_value;
  4077. X};
  4078. X
  4079. Xstatic    id        **hash_table;
  4080. Xstatic    str_hash_ty    hash_modulus;
  4081. Xstatic    str_hash_ty    hash_cutover;
  4082. Xstatic    str_hash_ty    hash_cutover_mask;
  4083. Xstatic    str_hash_ty    hash_cutover_split_mask;
  4084. Xstatic    str_hash_ty    hash_split;
  4085. Xstatic    str_hash_ty    hash_load;
  4086. X
  4087. X
  4088. X/*
  4089. X * NAME
  4090. X *    id_initialize - start up symbol table
  4091. X *
  4092. X * SYNOPSIS
  4093. X *    void id_initialize(void);
  4094. X *
  4095. X * DESCRIPTION
  4096. X *    The id_initialize function is used to create the hash table.
  4097. X *
  4098. X * CAVEAT
  4099. X *    Assumes the str_initialize function has been called already.
  4100. X */
  4101. X
  4102. Xvoid
  4103. Xid_initialize()
  4104. X{
  4105. X    str_hash_ty    j;
  4106. X
  4107. X    hash_modulus = 1<<8; /* MUST be a power of 2 */
  4108. X    hash_cutover = hash_modulus;
  4109. X    hash_split = hash_modulus - hash_cutover;
  4110. X    hash_cutover_mask = hash_cutover - 1;
  4111. X    hash_cutover_split_mask = (hash_cutover * 2) - 1;
  4112. X    hash_load = 0;
  4113. X    hash_table = (id **)mem_alloc(hash_modulus * sizeof(id *));
  4114. X    for (j = 0; j < hash_modulus; ++j)
  4115. X        hash_table[j] = 0;
  4116. X}
  4117. X
  4118. X
  4119. X/*
  4120. X * NAME
  4121. X *    split - reduce symbol table load
  4122. X *
  4123. X * SYNOPSIS
  4124. X *    void split(void);
  4125. X *
  4126. X * DESCRIPTION
  4127. X *    The split function is used to split symbols in the bucket indicated by
  4128. X *    the split point.  The symbols are split between that bucket and the one
  4129. X *    after the current end of the table.
  4130. X *
  4131. X * CAVEAT
  4132. X *    It is only sensable to do this when the symbol table load exceeds some
  4133. X *    reasonable threshold.  A threshold of 80% is suggested.
  4134. X */
  4135. X
  4136. Xstatic void split _((void));
  4137. X
  4138. Xstatic void
  4139. Xsplit()
  4140. X{
  4141. X    id        *p;
  4142. X    id        **ipp;
  4143. X    id        *p2;
  4144. X    str_hash_ty    index;
  4145. X
  4146. X    /*
  4147. X     * get the list to be split across buckets 
  4148. X     */
  4149. X    p = hash_table[hash_split];
  4150. X    hash_table[hash_split] = 0;
  4151. X
  4152. X    /*
  4153. X     * increase the modulus by one
  4154. X     */
  4155. X    hash_modulus++;
  4156. X    mem_change_size((char **)&hash_table, hash_modulus * sizeof(id *));
  4157. X    hash_table[hash_modulus - 1] = 0;
  4158. X    hash_split = hash_modulus - hash_cutover;
  4159. X    if (hash_split >= hash_cutover)
  4160. X    {
  4161. X        hash_cutover = hash_modulus;
  4162. X        hash_split = 0;
  4163. X        hash_cutover_mask = hash_cutover - 1;
  4164. X        hash_cutover_split_mask = (hash_cutover * 2) - 1;
  4165. X    }
  4166. X
  4167. X    /*
  4168. X     * now redistribute the list elements
  4169. X     *
  4170. X     * It is important to preserve the order of the links because
  4171. X     * they can be push-down stacks, and to simply add them to the
  4172. X     * head of the list will reverse the order of the stack!
  4173. X     */
  4174. X    while (p)
  4175. X    {
  4176. X        p2 = p;
  4177. X        p = p2->id_next;
  4178. X        p2->id_next = 0;
  4179. X
  4180. X        index = p2->id_hash & hash_cutover_mask;
  4181. X        if (index < hash_split)
  4182. X            index = p2->id_hash & hash_cutover_split_mask;
  4183. X        for (ipp = &hash_table[index]; *ipp; ipp = &(*ipp)->id_next)
  4184. X            ;
  4185. X        *ipp = p2;
  4186. X    }
  4187. X}
  4188. X
  4189. X
  4190. X/*
  4191. X * NAME
  4192. X *    copy - copy a symbol value
  4193. X *
  4194. X * SYNOPSIS
  4195. X *    void copy(id *p, long *valuep);
  4196. X *
  4197. X * DESCRIPTION
  4198. X *    The copy function is used to copy the passed value of a symbol into the
  4199. X *    storage of that symbol.
  4200. X */
  4201. X
  4202. Xstatic void copy _((id *, long *));
  4203. X
  4204. Xstatic void
  4205. Xcopy(p, valuep)
  4206. X    id    *p;
  4207. X    long    *valuep;
  4208. X{
  4209. X    switch (p->id_class)
  4210. X    {
  4211. X    case ID_CLASS_KEYWORD:
  4212. X        {
  4213. X            id_int    *ip;
  4214. X
  4215. X            ip = (id_int *)p;
  4216. X            *valuep = ip->id_value;
  4217. X        }
  4218. X        break;
  4219. X
  4220. X    case ID_CLASS_ENUMEL:
  4221. X    case ID_CLASS_FIELD:
  4222. X    case ID_CLASS_TYPE:
  4223. X        {
  4224. X            id_void    *ip;
  4225. X
  4226. X            ip = (id_void *)p;
  4227. X            *(void **)valuep = ip->id_value;
  4228. X        }
  4229. X        break;
  4230. X    }
  4231. X}
  4232. X
  4233. X
  4234. X/*
  4235. X * NAME
  4236. X *    id_search - search for a variable
  4237. X *
  4238. X * SYNOPSIS
  4239. X *    int id_search(string_ty *name, id_class_ty class, long *value);
  4240. X *
  4241. X * DESCRIPTION
  4242. X *    Id_search is used to reference a variable.
  4243. X *
  4244. X * RETURNS
  4245. X *    If the variable has been defined, the function returns a non-zero value
  4246. X *    and the value is returned through the 'value' pointer.
  4247. X *    If the variable has not been defined, it returns zero,
  4248. X *    and 'value' is unaltered.
  4249. X *
  4250. X * CAVEAT
  4251. X *    The value returned from this function, when returned, is allocated
  4252. X *    in dynamic memory (it is a copy of the value remembered by this module).
  4253. X *    It is the responsibility of the caller to free it when finished with,
  4254. X *    by a wl_free() call.
  4255. X */
  4256. X
  4257. X/*VARARGS2*/
  4258. Xint
  4259. Xid_search(name, class, valuep)
  4260. X    string_ty    *name;
  4261. X    id_class_ty    class;
  4262. X    long        *valuep;
  4263. X{
  4264. X    str_hash_ty    myhash;
  4265. X    str_hash_ty    index;
  4266. X    id        *p;
  4267. X
  4268. X    myhash = name->str_hash + (int)class;
  4269. X    index = myhash & hash_cutover_mask;
  4270. X    if (index < hash_split)
  4271. X        index = myhash & hash_cutover_split_mask;
  4272. X    for (p = hash_table[index]; p; p = p->id_next)
  4273. X    {
  4274. X        if (p->id_class == class && str_equal(name, p->id_name))
  4275. X        {
  4276. X            copy(p, valuep);
  4277. X            return 1;
  4278. X        }
  4279. X    }
  4280. X    return 0;
  4281. X}
  4282. X
  4283. X
  4284. X/*
  4285. X * NAME
  4286. X *    assign - set value of symbol
  4287. X *
  4288. X * SYNOPSIS
  4289. X *    void assign(id *p, long value);
  4290. X *
  4291. X * DESCRIPTION
  4292. X *    The assign function is used to change the value of a symbol.
  4293. X *
  4294. X * CAVEAT
  4295. X *    The value is not released first, so use stomp if necessary.
  4296. X */
  4297. X
  4298. Xstatic void assign _((id *, long));
  4299. X
  4300. Xstatic void
  4301. Xassign(p, value)
  4302. X    id    *p;
  4303. X    long    value;
  4304. X{
  4305. X    switch (p->id_class)
  4306. X    {
  4307. X    case ID_CLASS_KEYWORD:
  4308. X        {
  4309. X            id_int    *ip;
  4310. X
  4311. X            ip = (id_int *)p;
  4312. X            ip->id_value = value;
  4313. X        }
  4314. X        break;
  4315. X
  4316. X    case ID_CLASS_TYPE:
  4317. X    case ID_CLASS_FIELD:
  4318. X    case ID_CLASS_ENUMEL:
  4319. X        {
  4320. X            id_void    *ip;
  4321. X
  4322. X            ip = (id_void *)p;
  4323. X            ip->id_value = (void *)value;
  4324. X        }
  4325. X        break;
  4326. X    }
  4327. X}
  4328. X
  4329. X
  4330. X/*
  4331. X * NAME
  4332. X *    size_by_class - determine symbol size
  4333. X *
  4334. X * SYNOPSIS
  4335. X *    size_t size_by_class(id_class_ty class);
  4336. X *
  4337. X * DESCRIPTION
  4338. X *    The size_by_class function is used to determine the correct size to
  4339. X *    allocate for symbol storage.
  4340. X *
  4341. X * RETURNS
  4342. X *    size_t: the correct size to malloc.
  4343. X *
  4344. X * CAVEAT
  4345. X *    Never malloc(sizeof(id)) as this will be too small.
  4346. X */
  4347. X
  4348. Xstatic size_t size_by_class _((id_class_ty));
  4349. X
  4350. Xstatic size_t
  4351. Xsize_by_class(class)
  4352. X    id_class_ty class;
  4353. X{
  4354. X    switch ((int)class)
  4355. X    {
  4356. X    default:
  4357. X        assert(0);
  4358. X
  4359. X    case ID_CLASS_KEYWORD:
  4360. X        return sizeof(id_int);
  4361. X
  4362. X    case ID_CLASS_TYPE:
  4363. X    case ID_CLASS_FIELD:
  4364. X    case ID_CLASS_ENUMEL:
  4365. X        return sizeof(id_void);
  4366. X    }
  4367. X}
  4368. X
  4369. X
  4370. X/*
  4371. X * NAME
  4372. X *    id_assign - assign a variable
  4373. X *
  4374. X * SYNOPSIS
  4375. X *    void id_assign(string_ty *name, id_class_ty class, long value);
  4376. X *
  4377. X * DESCRIPTION
  4378. X *    Id_assign is used to assign a value to a given variable.
  4379. X *
  4380. X * CAVEAT
  4381. X *    The name and value are copied by id_assign, so the user may
  4382. X *    modify or free them at a later date without affecting the
  4383. X *    variable.
  4384. X */
  4385. X
  4386. X/*VARARGS2*/
  4387. Xvoid
  4388. Xid_assign(name, class, value)
  4389. X    string_ty    *name;
  4390. X    id_class_ty    class;
  4391. X    long        value;
  4392. X{
  4393. X    str_hash_ty    myhash;
  4394. X    str_hash_ty    index;
  4395. X    id        *p;
  4396. X
  4397. X    myhash = name->str_hash + (int)class;
  4398. X    index = myhash & hash_cutover_mask;
  4399. X    if (index < hash_split)
  4400. X        index = myhash & hash_cutover_split_mask;
  4401. X
  4402. X    for (p = hash_table[index]; p; p = p->id_next)
  4403. X    {
  4404. X        if (p->id_class == class && str_equal(name, p->id_name))
  4405. X        {
  4406. X            assign(p, value);
  4407. X            return;
  4408. X        }
  4409. X    }
  4410. X
  4411. X    p = (id *)mem_alloc_clear(size_by_class(class));
  4412. X    p->id_name = str_copy(name);
  4413. X    p->id_next = hash_table[index];
  4414. X    p->id_class = class;
  4415. X    p->id_hash = myhash;
  4416. X    hash_table[index] = p;
  4417. X    assign(p, value);
  4418. X
  4419. X    hash_load++;
  4420. X    while (hash_load * 10 >= hash_modulus * 8)
  4421. X        split();
  4422. X}
  4423. X
  4424. X
  4425. X/*
  4426. X * NAME
  4427. X *    id_dump - dump id table
  4428. X *
  4429. X * SYNOPSIS
  4430. X *    void id_dump(char *title, int mask);
  4431. X *
  4432. X * DESCRIPTION
  4433. X *    The id_dump function is used to dump the contents of the id table.
  4434. X *    The title will be used to indicate why the table was dumped.  The mask
  4435. X *    may be used to selectively dump the table, 0 means everything, bits
  4436. X *    correspond directly with ID_CLASS defines.
  4437. X *
  4438. X * CAVEAT
  4439. X *    This function is only available when symbol DEBUG is defined.
  4440. X */
  4441. X
  4442. X#ifdef DEBUG
  4443. X
  4444. Xvoid
  4445. Xid_dump(s, mask)
  4446. X    char    *s;
  4447. X    int    mask;
  4448. X{
  4449. X    int    j;
  4450. X    id    *p;
  4451. X
  4452. X    if (!mask)
  4453. X        mask = ~0;
  4454. X    error("id table %s = {"/*}*/, s);
  4455. X    for (j = 0; j < hash_modulus; ++j)
  4456. X    {
  4457. X        for (p = hash_table[j]; p; p = p->id_next)
  4458. X        {
  4459. X            if (mask & (1<< (int)p->id_class))
  4460. X            switch ((int)p->id_class)
  4461. X            {
  4462. X            default:
  4463. X                error
  4464. X                (
  4465. X                    "name = \"%s\", class = %d",
  4466. X                    p->id_name->str_text,
  4467. X                    p->id_class
  4468. X                );
  4469. X                break;
  4470. X
  4471. X            case ID_CLASS_KEYWORD:
  4472. X                {
  4473. X                    id_int    *ip;
  4474. X        
  4475. X                    ip = (id_int*)p;
  4476. X                    error
  4477. X                    (
  4478. X                    "name = \"%s\", class = %d, value = %d",
  4479. X                        p->id_name->str_text,
  4480. X                        p->id_class,
  4481. X                        ip->id_value
  4482. X                    );
  4483. X                }
  4484. X                break;
  4485. X
  4486. X            case ID_CLASS_TYPE:
  4487. X            case ID_CLASS_FIELD:
  4488. X                {
  4489. X                    id_void    *ip;
  4490. X        
  4491. X                    ip = (id_void *)p;
  4492. X                    error
  4493. X                    (
  4494. X                      "name = \"%s\", class = %d, value = %08X",
  4495. X                        p->id_name->str_text,
  4496. X                        p->id_class,
  4497. X                        ip->id_value
  4498. X                    );
  4499. X                }
  4500. X                break;
  4501. X            }
  4502. X        }
  4503. X    }
  4504. X    error(/*{*/"}");
  4505. X}
  4506. X
  4507. X#endif
  4508. END_OF_FILE
  4509. if test 9297 -ne `wc -c <'fmtgen/id.c'`; then
  4510.     echo shar: \"'fmtgen/id.c'\" unpacked with wrong size!
  4511. fi
  4512. # end of 'fmtgen/id.c'
  4513. fi
  4514. if test -f 'fmtgen/lex.c' -a "${1}" != "-c" ; then 
  4515.   echo shar: Will not clobber existing file \"'fmtgen/lex.c'\"
  4516. else
  4517. echo shar: Extracting \"'fmtgen/lex.c'\" \(9885 characters\)
  4518. sed "s/^X//" >'fmtgen/lex.c' <<'END_OF_FILE'
  4519. X/*
  4520. X *    aegis - project change supervisor
  4521. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  4522. X *    All rights reserved.
  4523. X *
  4524. X *    This program is free software; you can redistribute it and/or modify
  4525. X *    it under the terms of the GNU General Public License as published by
  4526. X *    the Free Software Foundation; either version 2 of the License, or
  4527. X *    (at your option) any later version.
  4528. X *
  4529. X *    This program is distributed in the hope that it will be useful,
  4530. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  4531. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4532. X *    GNU General Public License for more details.
  4533. X *
  4534. X *    You should have received a copy of the GNU General Public License
  4535. X *    along with this program; if not, write to the Free Software
  4536. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4537. X *
  4538. X * MANIFEST: lexical analyzer
  4539. X */
  4540. X
  4541. X#include <stdio.h>
  4542. X#include <stdlib.h>
  4543. X#include <string.h>
  4544. X#include <errno.h>
  4545. X
  4546. X#include <error.h>
  4547. X#include <id.h>
  4548. X#include <lex.h>
  4549. X#include <mem.h>
  4550. X#include <s-v-arg.h>
  4551. X#include <str.h>
  4552. X#include <type.h>
  4553. X#include <parse.gen.h> /* must be last */
  4554. X
  4555. X
  4556. X#define strel(a, op, b) (strcmp(a, b) op 0)
  4557. X
  4558. Xtypedef struct file_ty file_ty;
  4559. Xstruct file_ty
  4560. X{
  4561. X    FILE    *fp;
  4562. X    int    line_number;
  4563. X    char    *file_name;
  4564. X    file_ty    *next;
  4565. X};
  4566. X
  4567. Xstatic    file_ty        *file;
  4568. Xstatic    int        error_count;
  4569. Xextern    parse_STYPE    parse_lval;
  4570. Xstatic    wlist        ifiles;
  4571. Xstatic    wlist        include_path;
  4572. X
  4573. X
  4574. X/*
  4575. X *  NAME
  4576. X *    lex_initialize - look for keywords
  4577. X *
  4578. X *  SYNOPSIS
  4579. X *    int lex_initialize(void);
  4580. X *
  4581. X *  DESCRIPTION
  4582. X *    The lex_initialize function adds all the keywords to the symbol table.
  4583. X *
  4584. X *  CAVEAT
  4585. X *    The keywords are intentionally case sensitive.
  4586. X *      Assumes that str_initialize has already been called.
  4587. X */
  4588. X
  4589. Xstatic void lex_initialize _((void));
  4590. X
  4591. Xstatic void
  4592. Xlex_initialize()
  4593. X{
  4594. X    typedef struct keyword_ty keyword_ty;
  4595. X    struct keyword_ty
  4596. X    {
  4597. X        char    *k_name;
  4598. X        int    k_token;
  4599. X    };
  4600. X
  4601. X    static keyword_ty keyword[] =
  4602. X    {
  4603. X        { "type", TYPE, },
  4604. X        { "string", STRING, },
  4605. X        { "integer", INTEGER, },
  4606. X        { "include", INCLUDE, },
  4607. X    };
  4608. X    keyword_ty *kp;
  4609. X    static int done;
  4610. X
  4611. X    if (done)
  4612. X        return;
  4613. X    done = 1;
  4614. X    for (kp = keyword; kp < ENDOF(keyword); ++kp)
  4615. X    {
  4616. X        string_ty *s;
  4617. X
  4618. X        s = str_from_c(kp->k_name);
  4619. X        id_assign(s, ID_CLASS_KEYWORD, kp->k_token);
  4620. X        str_free(s);
  4621. X    }
  4622. X}
  4623. X
  4624. X
  4625. Xvoid
  4626. Xlex_open(s)
  4627. X    char    *s;
  4628. X{
  4629. X    file_ty    *f;
  4630. X
  4631. X    f = (file_ty *)mem_alloc_clear(sizeof(file_ty));
  4632. X    if (!file)
  4633. X    {
  4634. X        lex_initialize();
  4635. X        f->file_name = mem_copy_string(s);
  4636. X        f->fp = fopen(s, "r");
  4637. X        if (!f->fp)
  4638. X            nfatal("%s", s);
  4639. X    }
  4640. X    else
  4641. X    {
  4642. X        int    j;
  4643. X
  4644. X        f->fp = 0;
  4645. X        for (j = 0; j < include_path.wl_nwords; ++j)
  4646. X        {
  4647. X            char    buffer[2000];
  4648. X
  4649. X            sprintf(buffer, "%s/%s", include_path.wl_word[j]->str_text, s);
  4650. X            f->fp = fopen(buffer, "r");
  4651. X            if (f->fp)
  4652. X            {
  4653. X                f->file_name = mem_copy_string(buffer);
  4654. X                break;
  4655. X            }
  4656. X            if (errno != ENOENT)
  4657. X                nfatal("%s", buffer);
  4658. X        }
  4659. X        if (!f->fp)
  4660. X        {
  4661. X            f->fp = fopen(s, "r");
  4662. X            if (!f->fp)
  4663. X                nfatal("%s", s);
  4664. X            f->file_name = mem_copy_string(s);
  4665. X        }
  4666. X        f->next = file;
  4667. X        wl_append_unique(&ifiles, str_from_c(s));
  4668. X    }
  4669. X    f->line_number = 1;
  4670. X    file = f;
  4671. X}
  4672. X
  4673. X
  4674. Xvoid
  4675. Xlex_close()
  4676. X{
  4677. X    if (error_count)
  4678. X        exit(1);
  4679. X    fclose(file->fp);
  4680. X    free(file->file_name);
  4681. X    free(file);
  4682. X}
  4683. X
  4684. X
  4685. Xstatic int lex_getc _((void));
  4686. X
  4687. Xstatic int
  4688. Xlex_getc()
  4689. X{
  4690. X    int    c;
  4691. X
  4692. X    for (;;)
  4693. X    {
  4694. X        file_ty    *old;
  4695. X
  4696. X        c = fgetc(file->fp);
  4697. X        if (c != EOF)
  4698. X            break;
  4699. X        if (ferror(file->fp))
  4700. X            nfatal("%s", file->file_name);
  4701. X        if (!file->next)
  4702. X            break;
  4703. X        old = file;
  4704. X        file = old->next;
  4705. X        fclose(old->fp);
  4706. X        free(old->file_name);
  4707. X        free(old);
  4708. X    }
  4709. X    if (c == '\n')
  4710. X        file->line_number++;
  4711. X    return c;
  4712. X}
  4713. X
  4714. X
  4715. Xstatic void lex_getc_undo _((int));
  4716. X
  4717. Xstatic void
  4718. Xlex_getc_undo(c)
  4719. X    int    c;
  4720. X{
  4721. X    switch (c)
  4722. X    {
  4723. X    case EOF:
  4724. X        break;
  4725. X
  4726. X    case '\n':
  4727. X        file->line_number--;
  4728. X        /* fall through... */
  4729. X
  4730. X    default:
  4731. X        ungetc(c, file->fp);
  4732. X        break;
  4733. X    }
  4734. X}
  4735. X
  4736. X
  4737. Xint
  4738. Xparse_lex()
  4739. X{
  4740. X    int    line_number_start;
  4741. X    char    buffer[1<<12];
  4742. X    char    *cp;
  4743. X
  4744. X    for (;;)
  4745. X    {
  4746. X        int     c;
  4747. X
  4748. X        c = lex_getc();
  4749. X        switch (c)
  4750. X        {
  4751. X        case ' ':
  4752. X        case '\t':
  4753. X        case '\f':
  4754. X        case '\n':
  4755. X            break;
  4756. X
  4757. X        case '0':
  4758. X        case '1':
  4759. X        case '2':
  4760. X        case '3':
  4761. X        case '4':
  4762. X        case '5':
  4763. X        case '6':
  4764. X        case '7':
  4765. X        case '8':
  4766. X        case '9': 
  4767. X            parse_lval.lv_integer = 0;
  4768. X            for (;;)
  4769. X            {
  4770. X                parse_lval.lv_integer = 10 * parse_lval.lv_integer + c - '0';
  4771. X                c = lex_getc();
  4772. X                if (c < '0' || c > '9')
  4773. X                {
  4774. X                    lex_getc_undo(c);
  4775. X                    break;
  4776. X                }
  4777. X            }
  4778. X            return INTEGER_CONSTANT;
  4779. X
  4780. X        case 'A': case 'B': case 'C': case 'D': case 'E':
  4781. X        case 'F': case 'G': case 'H': case 'I': case 'J':
  4782. X        case 'K': case 'L': case 'M': case 'N': case 'O':
  4783. X        case 'P': case 'Q': case 'R': case 'S': case 'T':
  4784. X        case 'U': case 'V': case 'W': case 'X': case 'Y':
  4785. X        case 'Z': case '_': case 'a': case 'b': case 'c':
  4786. X        case 'd': case 'e': case 'f': case 'g': case 'h':
  4787. X        case 'i': case 'j': case 'k': case 'l': case 'm':
  4788. X        case 'n': case 'o': case 'p': case 'q': case 'r':
  4789. X        case 's': case 't': case 'u': case 'v': case 'w':
  4790. X        case 'x': case 'y': case 'z': 
  4791. X            {
  4792. X                char        *cp;
  4793. X                char        buffer[1000];
  4794. X                string_ty    *s;
  4795. X                long        tok;
  4796. X    
  4797. X                cp = buffer;
  4798. X                for (;;)
  4799. X                {
  4800. X                    *cp++ = c;
  4801. X                    c = lex_getc();
  4802. X                    switch (c)
  4803. X                    {
  4804. X                    case '0': case '1': case '2': case '3':
  4805. X                    case '4': case '5': case '6': case '7':
  4806. X                    case '8': case '9': 
  4807. X                    case 'A': case 'B': case 'C': case 'D':
  4808. X                    case 'E': case 'F': case 'G': case 'H':
  4809. X                    case 'I': case 'J': case 'K': case 'L':
  4810. X                    case 'M': case 'N': case 'O': case 'P':
  4811. X                    case 'Q': case 'R': case 'S': case 'T':
  4812. X                    case 'U': case 'V': case 'W': case 'X':
  4813. X                    case 'Y': case 'Z': case '_': case 'a':
  4814. X                    case 'b': case 'c': case 'd': case 'e':
  4815. X                    case 'f': case 'g': case 'h': case 'i':
  4816. X                    case 'j': case 'k': case 'l': case 'm':
  4817. X                    case 'n': case 'o': case 'p': case 'q':
  4818. X                    case 'r': case 's': case 't': case 'u':
  4819. X                    case 'v': case 'w': case 'x': case 'y':
  4820. X                    case 'z': 
  4821. X                        continue;
  4822. X                    }
  4823. X                    lex_getc_undo(c);
  4824. X                    *cp = 0;
  4825. X                    break;
  4826. X                }
  4827. X                s = str_from_c(buffer);
  4828. X                    if (id_search(s, ID_CLASS_KEYWORD, &tok))
  4829. X                {
  4830. X                    str_free(s);
  4831. X                    return tok;
  4832. X                }
  4833. X                parse_lval.lv_string = s;
  4834. X                return NAME;
  4835. X            }
  4836. X
  4837. X        case '/':
  4838. X            c = lex_getc();
  4839. X            if (c != '*')
  4840. X            {
  4841. X                lex_getc_undo(c);
  4842. X                return '/';
  4843. X            }
  4844. X            for (;;)
  4845. X            {
  4846. X                for (;;)
  4847. X                {
  4848. X                    c = lex_getc();
  4849. X                    if (c == EOF)
  4850. X                    {
  4851. X    bad_comment:
  4852. X                        parse_error("end-of-file inside comment");
  4853. X                        exit(1);
  4854. X                    }
  4855. X                    if (c == '*')
  4856. X                        break;
  4857. X                }
  4858. X                for (;;)
  4859. X                {
  4860. X                    c = lex_getc();
  4861. X                    if (c == EOF)
  4862. X                        goto bad_comment;
  4863. X                    if (c != '*')
  4864. X                        break;
  4865. X                }
  4866. X                if (c == '/')
  4867. X                    break;
  4868. X            }
  4869. X            break;
  4870. X
  4871. X        case '<':
  4872. X                line_number_start = file->line_number;
  4873. X                cp = buffer;
  4874. X                for (;;)
  4875. X                {
  4876. X                    c = lex_getc();
  4877. X                    if (c == EOF)
  4878. X                goto str_eof;
  4879. X                    if (c == '\n')
  4880. X                goto str_eoln;
  4881. X                    if (c == '>')
  4882. X                        break;
  4883. X                    *cp++ = c;
  4884. X                }
  4885. X                *cp = 0;
  4886. X                parse_lval.lv_string = str_from_c(buffer);
  4887. X                return STRING_CONSTANT;
  4888. X
  4889. X            case '"':
  4890. X                line_number_start = file->line_number;
  4891. X                cp = buffer;
  4892. X                for (;;)
  4893. X                {
  4894. X                    c = lex_getc();
  4895. X                    if (c == EOF)
  4896. X                    {
  4897. X                        str_eof:
  4898. X                        file->line_number = line_number_start;
  4899. X                        parse_error("end-of-file within string");
  4900. X                        break;
  4901. X                    }
  4902. X                    if (c == '\n')
  4903. X                    {
  4904. X                str_eoln:
  4905. X                        file->line_number = line_number_start;
  4906. X                        parse_error("end-of-line within string");
  4907. X                        break;
  4908. X                    }
  4909. X                    if (c == '"')
  4910. X                        break;
  4911. X                    if (c == '\\')
  4912. X                    {
  4913. X                        c = lex_getc();
  4914. X                        switch (c)
  4915. X                        {
  4916. X                default:
  4917. X                parse_error("unknown '\\%c' escape", c);
  4918. X                break;
  4919. X    
  4920. X                        case '\n':
  4921. X                            break;
  4922. X    
  4923. X                        case EOF:
  4924. X                            goto str_eof;
  4925. X    
  4926. X                        case 'b':
  4927. X                *cp++ = '\b';
  4928. X                break;
  4929. X    
  4930. X                        case 'n':
  4931. X                *cp++ = '\n';
  4932. X                break;
  4933. X    
  4934. X                        case 'r':
  4935. X                *cp++ = '\r';
  4936. X                break;
  4937. X    
  4938. X                        case 't':
  4939. X                *cp++ = '\t';
  4940. X                break;
  4941. X    
  4942. X                        case 'f':
  4943. X                *cp++ = '\f';
  4944. X                break;
  4945. X    
  4946. X                case '"':
  4947. X                case '\\':
  4948. X                *cp++ = c;
  4949. X                break;
  4950. X    
  4951. X                        case '0':
  4952. X                case '1':
  4953. X                case '2':
  4954. X                case '3':
  4955. X                        case '4':
  4956. X                case '5':
  4957. X                case '6':
  4958. X                case '7':
  4959. X                            {
  4960. X                                int             n;
  4961. X                                int             v;
  4962. X    
  4963. X                    v = 0;
  4964. X                                for (n = 0; n < 3; ++n)
  4965. X                                {
  4966. X                    v = v * 8 + c - '0';
  4967. X                    c = lex_getc();
  4968. X                    switch (c)
  4969. X                    {
  4970. X                    case '0':
  4971. X                    case '1':
  4972. X                    case '2':
  4973. X                    case '3':
  4974. X                    case '4':
  4975. X                    case '5':
  4976. X                    case '6':
  4977. X                    case '7':
  4978. X                        continue;
  4979. X    
  4980. X                    default:
  4981. X                        lex_getc_undo(c);
  4982. X                        break;
  4983. X                    }
  4984. X                    break;
  4985. X                                }
  4986. X                    *cp++ = v;
  4987. X                            }
  4988. X                            break;
  4989. X                        }
  4990. X                    }
  4991. X                    else
  4992. X                        *cp++ = c;
  4993. X                }
  4994. X                *cp = 0;
  4995. X                parse_lval.lv_string = str_from_c(buffer);
  4996. X                return STRING_CONSTANT;
  4997. X
  4998. X        default:
  4999. X            return c;
  5000. X        }
  5001. X    }
  5002. X}
  5003. X
  5004. X
  5005. Xvoid
  5006. Xparse_error(s sva_last)
  5007. X    char        *s;
  5008. X    sva_last_decl
  5009. X{
  5010. X    va_list        ap;
  5011. X    char        buffer[1000];
  5012. X
  5013. X    sva_init(ap, s);
  5014. X    vsprintf(buffer, s, ap);
  5015. X    va_end(ap);
  5016. X    error("%s: %d: %s", file->file_name, file->line_number, buffer);
  5017. X    if (++error_count >= 20)
  5018. X        error("%s: too many errors, bye!", file->file_name);
  5019. X}
  5020. X
  5021. X
  5022. Xint
  5023. Xlex_in_include_file()
  5024. X{
  5025. X    return !!file->next;
  5026. X}
  5027. X
  5028. X
  5029. Xvoid
  5030. Xlex_include_path(s)
  5031. X    char    *s;
  5032. X{
  5033. X    wl_append_unique(&include_path, str_from_c(s));
  5034. X}
  5035. END_OF_FILE
  5036. if test 9885 -ne `wc -c <'fmtgen/lex.c'`; then
  5037.     echo shar: \"'fmtgen/lex.c'\" unpacked with wrong size!
  5038. fi
  5039. # end of 'fmtgen/lex.c'
  5040. fi
  5041. if test -f 'fmtgen/parse.y' -a "${1}" != "-c" ; then 
  5042.   echo shar: Will not clobber existing file \"'fmtgen/parse.y'\"
  5043. else
  5044. echo shar: Extracting \"'fmtgen/parse.y'\" \(9538 characters\)
  5045. sed "s/^X//" >'fmtgen/parse.y' <<'END_OF_FILE'
  5046. X/*
  5047. X *    aegis - project change supervisor
  5048. X *    Copyright (C) 1991, 1992, 1993 Peter Miller.
  5049. X *    All rights reserved.
  5050. X *
  5051. X *    This program is free software; you can redistribute it and/or modify
  5052. X *    it under the terms of the GNU General Public License as published by
  5053. X *    the Free Software Foundation; either version 2 of the License, or
  5054. X *    (at your option) any later version.
  5055. X *
  5056. X *    This program is distributed in the hope that it will be useful,
  5057. X *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  5058. X *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5059. X *    GNU General Public License for more details.
  5060. X *
  5061. X *    You should have received a copy of the GNU General Public License
  5062. X *    along with this program; if not, write to the Free Software
  5063. X *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5064. X *
  5065. X * MANIFEST: grammar and functions to parse aegis file contents definitions
  5066. X */
  5067. X
  5068. X%{
  5069. X
  5070. X#include <ctype.h>
  5071. X#include <string.h>
  5072. X#include <stdlib.h>
  5073. X
  5074. X#include <error.h>
  5075. X#include <id.h>
  5076. X#include <indent.h>
  5077. X#include <lex.h>
  5078. X#include <mem.h>
  5079. X#include <parse.h>
  5080. X#include <str.h>
  5081. X#include <trace.h>
  5082. X#include <type.h>
  5083. X
  5084. X#ifdef DEBUG
  5085. X#define YYDEBUG 1
  5086. Xextern int yydebug;
  5087. X#define printf trace_where, trace_printf
  5088. X#endif
  5089. X
  5090. X%}
  5091. X
  5092. X%token    TYPE
  5093. X%token    NAME
  5094. X%token    STRING
  5095. X%token    STRING_CONSTANT
  5096. X%token    INTEGER
  5097. X%token    INTEGER_CONSTANT
  5098. X%token    INCLUDE
  5099. X
  5100. X%union
  5101. X{
  5102. X    string_ty    *lv_string;
  5103. X    long        lv_integer;
  5104. X    parse_list_ty    *lv_parse_list;
  5105. X    type_ty        *lv_type;
  5106. X}
  5107. X
  5108. X%type <lv_string> NAME
  5109. X%type <lv_integer> INTEGER_CONSTANT
  5110. X%type <lv_parse_list> field_list enum_list
  5111. X%type <lv_type> type structure list enumeration
  5112. X%type <lv_string> type_name field field_name enum_name STRING_CONSTANT
  5113. X
  5114. X%{
  5115. X
  5116. Xtypedef struct name_ty name_ty;
  5117. Xstruct name_ty
  5118. X{
  5119. X    string_ty    *name;
  5120. X    name_ty        *prev;
  5121. X};
  5122. X
  5123. Xstatic    parse_list_ty    *type_root;
  5124. Xstatic    name_ty        *name_root;
  5125. X
  5126. X
  5127. Xstatic void pl_append _((parse_list_ty **, string_ty *));
  5128. X
  5129. Xstatic void
  5130. Xpl_append(listp, s)
  5131. X    parse_list_ty    **listp;
  5132. X    string_ty    *s;
  5133. X{
  5134. X    parse_list_ty    *plp;
  5135. X
  5136. X    trace(("pl_append(listp = %08lX, s = \"%s\")\n{\n"/*}*/, listp, s->str_text));
  5137. X    while (*listp)
  5138. X        listp = &(*listp)->next;
  5139. X    plp = (parse_list_ty *)mem_alloc(sizeof(parse_list_ty));
  5140. X    plp->name = str_copy(s);
  5141. X    plp->next = 0;
  5142. X    *listp = plp;
  5143. X    trace((/*{*/"}\n"));
  5144. X}
  5145. X
  5146. X
  5147. Xstatic void push_name _((string_ty *));
  5148. X
  5149. Xstatic void
  5150. Xpush_name(s)
  5151. X    string_ty *s;
  5152. X{
  5153. X    name_ty    *np;
  5154. X
  5155. X    trace(("push_name(s = \"%s\")\n{\n"/*}*/, s->str_text));
  5156. X    assert(name_root);
  5157. X    np = (name_ty *)mem_alloc(sizeof(name_ty));
  5158. X    np->name = str_format("%S_%S", name_root->name, s);
  5159. X    np->prev = name_root;
  5160. X    name_root = np;
  5161. X    trace((/*{*/"}\n"));
  5162. X}
  5163. X
  5164. X
  5165. Xstatic void push_name_abs _((string_ty *));
  5166. X
  5167. Xstatic void
  5168. Xpush_name_abs(s)
  5169. X    string_ty *s;
  5170. X{
  5171. X    name_ty    *np;
  5172. X
  5173. X    trace(("push_name_abs(s = \"%s\")\n{\n"/*}*/, s->str_text));
  5174. X    np = (name_ty *)mem_alloc(sizeof(name_ty));
  5175. X    np->name = str_copy(s);
  5176. X    np->prev = name_root;
  5177. X    name_root = np;
  5178. X    trace((/*{*/"}\n"));
  5179. X}
  5180. X
  5181. X
  5182. Xstatic void pop_name _((void));
  5183. X
  5184. Xstatic void
  5185. Xpop_name()
  5186. X{
  5187. X    name_ty    *np;
  5188. X
  5189. X    trace(("pop_name()\n{\n"/*}*/));
  5190. X    np = name_root;
  5191. X    name_root = np->prev;
  5192. X    str_free(np->name);
  5193. X    free(np);
  5194. X    trace((/*{*/"}\n"));
  5195. X}
  5196. X
  5197. X
  5198. Xstatic string_ty *get_name _((void));
  5199. X
  5200. Xstatic string_ty *
  5201. Xget_name()
  5202. X{
  5203. X    return str_copy(name_root->name);
  5204. X}
  5205. X
  5206. X
  5207. Xstatic void define_type _((string_ty *, type_ty *));
  5208. X
  5209. Xstatic void
  5210. Xdefine_type(name, type)
  5211. X    string_ty *name;
  5212. X    type_ty    *type;
  5213. X{
  5214. X    trace(("define_type(name = \"%s\")\n{\n"/*}*/, name->str_text));
  5215. X    type->included_flag = lex_in_include_file();
  5216. X    pl_append(&type_root, name);
  5217. X    trace((/*{*/"}\n"));
  5218. X}
  5219. X
  5220. X
  5221. Xstatic char *basename _((char *));
  5222. X
  5223. Xstatic char *
  5224. Xbasename(s)
  5225. X    char        *s;
  5226. X{
  5227. X    static char    buffer[256];
  5228. X    char        *cp;
  5229. X
  5230. X    cp = strrchr(s, '/');
  5231. X    if (cp)
  5232. X        ++cp;
  5233. X    else
  5234. X        cp = s;
  5235. X    strcpy(buffer, cp);
  5236. X    cp = strrchr(buffer, '.');
  5237. X    if (cp)
  5238. X        *cp = 0;
  5239. X    for (cp = buffer; *cp; ++cp)
  5240. X    {
  5241. X        if (!isalnum(*cp))
  5242. X            *cp = '_';
  5243. X    }
  5244. X    return buffer;
  5245. X}
  5246. X
  5247. X
  5248. Xvoid
  5249. Xparse(definition_file, code_file, include_file)
  5250. X    char        *definition_file;
  5251. X    char        *code_file;
  5252. X    char        *include_file;
  5253. X{
  5254. X    string_ty    *s;
  5255. X    char        *cp1;
  5256. X    parse_list_ty    *tnp;
  5257. X
  5258. X    trace(("parse(def = \"%s\", c = \"%s\", h = \"%s\")\n{\n"/*}*/,
  5259. X        definition_file, code_file, include_file));
  5260. X#ifdef DEBUG
  5261. X    yydebug = trace_pretest_;
  5262. X#endif
  5263. X
  5264. X    s = str_from_c(basename(definition_file));
  5265. X    push_name_abs(s);
  5266. X
  5267. X    lex_open(definition_file);
  5268. X    trace(("yyparse()\n{\n"/*}*/));
  5269. X    yyparse();
  5270. X    trace((/*{*/"}\n"));
  5271. X    lex_close();
  5272. X
  5273. X    pop_name();
  5274. X
  5275. X    indent_open(include_file);
  5276. X    cp1 = basename(include_file);
  5277. X    indent_putchar('\n');
  5278. X    indent_printf("#ifndef %s_H\n", cp1);
  5279. X    indent_printf("#define %s_H\n", cp1);
  5280. X    indent_putchar('\n');
  5281. X    indent_printf("#include <main.h>\n");
  5282. X    indent_printf("#include <type.h>\n");
  5283. X    indent_printf("#include <str.h>\n");
  5284. X    indent_printf("#include <parse.h>\n");
  5285. X    for (tnp = type_root; tnp; tnp = tnp->next)
  5286. X    {
  5287. X        type_ty    *tp;
  5288. X
  5289. X        if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  5290. X            fatal("type \"%s\" lost!", tnp->name->str_text);
  5291. X        type_gen_include(tp, tnp->name);
  5292. X    }
  5293. X    indent_putchar('\n');
  5294. X    indent_printf
  5295. X    (
  5296. X        "void %s_write_file _((char *filename, %s value));\n",
  5297. X        s->str_text,
  5298. X        s->str_text
  5299. X    );
  5300. X    indent_printf
  5301. X    (
  5302. X        "%s %s_read_file _((char *filename));\n",
  5303. X        s->str_text,
  5304. X        s->str_text
  5305. X    );
  5306. X    indent_putchar('\n');
  5307. X    indent_printf("#endif /* %s_H */\n", cp1);
  5308. X    indent_close();
  5309. X
  5310. X    cp1 = strrchr(include_file, '/');
  5311. X    if (cp1)
  5312. X        cp1++;
  5313. X    else
  5314. X        cp1 = include_file;
  5315. X
  5316. X    indent_open(code_file);
  5317. X    indent_putchar('\n');
  5318. X    indent_printf("#include <stddef.h>\n");
  5319. X    indent_printf("#include <stdio.h>\n");
  5320. X    indent_putchar('\n');
  5321. X    indent_printf("#include <%s>\n", cp1);
  5322. X    indent_printf("#include <error.h>\n");
  5323. X    indent_printf("#include <indent.h>\n");
  5324. X    indent_printf("#include <io.h>\n");
  5325. X    indent_printf("#include <mem.h>\n");
  5326. X    indent_printf("#include <os.h>\n");
  5327. X    indent_printf("#include <trace.h>\n");
  5328. X    indent_printf("#include <type.h>\n");
  5329. X    cp1 = basename(code_file);
  5330. X    for (tnp = type_root; tnp; tnp = tnp->next)
  5331. X    {
  5332. X        type_ty    *tp;
  5333. X
  5334. X        if (!id_search(tnp->name, ID_CLASS_TYPE, (long *)&tp))
  5335. X            fatal("type \"%s\" lost!", tnp->name->str_text);
  5336. X        if (tp->included_flag)
  5337. X            continue;
  5338. X        type_gen_code(tp, tnp->name);
  5339. X    }
  5340. X    indent_putchar('\n');
  5341. X    indent_printf("%s\n", cp1);
  5342. X    indent_printf("%s_read_file(filename)\n", s->str_text);
  5343. X    indent_more();
  5344. X    indent_printf("%s\1*filename;\n", "char");
  5345. X    indent_less();
  5346. X    indent_printf("{\n"/*}*/);
  5347. X    indent_printf("%s\1result;\n\n", cp1);
  5348. X    indent_printf("trace((\"%s_read_file(filename = \\\"%%s\\\")\\n{\\n\"/*}*/, filename));\n", cp1);
  5349. X    indent_printf("os_become_must_be_active();\n");
  5350. X    indent_printf
  5351. X    (
  5352. X        "result = (%s)parse(filename, &%s_type);\n",
  5353. X        s->str_text,
  5354. X        s->str_text
  5355. X    );
  5356. X    indent_printf("trace((\"return %%08lX;\\n\", result));\n");
  5357. X    indent_printf("trace((/*{*/\"}\\n\"));\n");
  5358. X    indent_printf("return result;\n");
  5359. X    indent_printf(/*{*/"}\n");
  5360. X    indent_putchar('\n');
  5361. X    indent_printf("void\n");
  5362. X    indent_printf("%s_write_file(filename, value)\n", s->str_text);
  5363. X    indent_more();
  5364. X    indent_printf("%s\1*filename;\n", "char");
  5365. X    indent_printf("%s\1value;\n", s->str_text);
  5366. X    indent_less();
  5367. X    indent_printf("{\n"/*}*/);
  5368. X    indent_printf("trace((\"%s_write_file(filename = \\\"%%s\\\", value = %%08lX)\\n{\\n\"/*}*/, filename, value));\n", cp1);
  5369. X    indent_printf("if (filename)\n");
  5370. X    indent_more();
  5371. X    indent_printf("os_become_must_be_active();\n");
  5372. X    indent_less();
  5373. X    indent_printf("indent_open(filename);\n");
  5374. X    indent_printf("%s_write(value);\n", s->str_text);
  5375. X    indent_printf("indent_close();\n");
  5376. X    indent_printf("trace((/*{*/\"}\\n\"));\n");
  5377. X    indent_printf(/*{*/"}\n");
  5378. X    indent_close();
  5379. X
  5380. X    str_free(s);
  5381. X    trace((/*{*/"}\n"));
  5382. X}
  5383. X
  5384. X%}
  5385. X
  5386. X%%
  5387. X
  5388. Xdescription
  5389. X    : typedef_list field_list
  5390. X        {
  5391. X            string_ty    *s;
  5392. X            type_ty        *type;
  5393. X
  5394. X            s = get_name();
  5395. X            type = type_create_struct(s, $2, 1);
  5396. X            define_type(s, type);
  5397. X        }
  5398. X    ;
  5399. X
  5400. Xtypedef_list
  5401. X    : /* empty */
  5402. X    | typedef_list typedef
  5403. X    ;
  5404. X
  5405. Xtypedef
  5406. X    : TYPE type_name '=' type ';'
  5407. X        {
  5408. X            str_free($2);
  5409. X            pop_name();
  5410. X        }
  5411. X    | '#' INCLUDE STRING_CONSTANT
  5412. X        {
  5413. X            lex_open($3->str_text);
  5414. X            str_free($3);
  5415. X        }
  5416. X    ;
  5417. X
  5418. Xtype_name
  5419. X    : NAME
  5420. X        {
  5421. X            $$ = $1;
  5422. X            push_name_abs($1);
  5423. X        }
  5424. X    ;
  5425. X
  5426. Xfield
  5427. X    : field_name '=' type ';'
  5428. X        {
  5429. X            id_assign($1, ID_CLASS_FIELD, (long)$3);
  5430. X            $$ = $1;
  5431. X            pop_name();
  5432. X        }
  5433. X    ;
  5434. X
  5435. Xfield_name
  5436. X    : NAME
  5437. X        {
  5438. X            push_name($1);
  5439. X            $$ = $1;
  5440. X        }
  5441. X    ;
  5442. X
  5443. Xtype
  5444. X    : STRING
  5445. X        {
  5446. X            $$ = type_create_string();
  5447. X        }
  5448. X    | INTEGER
  5449. X        {
  5450. X            $$ = type_create_integer();
  5451. X        }
  5452. X    | NAME
  5453. X        {
  5454. X            type_ty        *tp;
  5455. X
  5456. X            if (id_search($1, ID_CLASS_TYPE, (long *)&tp))
  5457. X            {
  5458. X                /* $$ = type_create_ref(get_name(), $1); */
  5459. X                $$ = tp;
  5460. X            }
  5461. X            else
  5462. X            {
  5463. X                yyerror("type \"%s\" undefined", $1->str_text);
  5464. X                $$ = type_create_integer();
  5465. X            }
  5466. X            str_free($1);
  5467. X        }
  5468. X    | structure
  5469. X        { $$ = $1; }
  5470. X    | list
  5471. X        { $$ = $1; }
  5472. X    | enumeration
  5473. X        { $$ = $1; }
  5474. X    ;
  5475. X
  5476. Xstructure
  5477. X    : '{' field_list '}'
  5478. X        {
  5479. X            string_ty    *s;
  5480. X
  5481. X            s = get_name();
  5482. X            $$ = type_create_struct(s, $2, 0);
  5483. X            define_type(s, $$);
  5484. X        }
  5485. X    ;
  5486. X
  5487. Xfield_list
  5488. X    : /* empty */
  5489. X        {
  5490. X            $$ = 0;
  5491. X        }
  5492. X    | field_list field
  5493. X        {
  5494. X            $$ = $1;
  5495. X            pl_append(&$$, $2);
  5496. X        }
  5497. X    ;
  5498. X
  5499. Xlist
  5500. X    : '[' type ']'
  5501. X        {
  5502. X            string_ty    *s;
  5503. X            static string_ty    *list;
  5504. X
  5505. X            if (!list)
  5506. X                list = str_from_c("list");
  5507. X            push_name(list);
  5508. X            s = get_name();
  5509. X            $$ = type_create_list(s, $2);
  5510. X            define_type(s, $$);
  5511. X            pop_name();
  5512. X        }
  5513. X    ;
  5514. X
  5515. Xenumeration
  5516. X    : '(' enum_list optional_comma ')'
  5517. X        {
  5518. X            string_ty *s;
  5519. X
  5520. X            s = get_name();
  5521. X            $$ = type_create_enum(s, $2);
  5522. X            define_type(s, $$);
  5523. X        }
  5524. X    ;
  5525. X
  5526. Xoptional_comma
  5527. X    : /* empty */
  5528. X    | ','
  5529. X    ;
  5530. X
  5531. Xenum_list
  5532. X    : enum_name
  5533. X        {
  5534. X            $$ = 0;
  5535. X            pl_append(&$$, $1);
  5536. X        }
  5537. X    | enum_list ',' enum_name
  5538. X        {
  5539. X            $$ = $1;
  5540. X            pl_append(&$$, $3);
  5541. X        }
  5542. X    ;
  5543. X
  5544. Xenum_name
  5545. X    : NAME
  5546. X        {
  5547. X            string_ty *s;
  5548. X
  5549. X            push_name($1);
  5550. X            s = get_name();
  5551. X            pop_name();
  5552. X            id_assign(s, ID_CLASS_ENUMEL, (long)$1);
  5553. X            $$ = s;
  5554. X        }
  5555. X    ;
  5556. END_OF_FILE
  5557. if test 9538 -ne `wc -c <'fmtgen/parse.y'`; then
  5558.     echo shar: \"'fmtgen/parse.y'\" unpacked with wrong size!
  5559. fi
  5560. # end of 'fmtgen/parse.y'
  5561. fi
  5562. if test -f 'test/00/t0006a.sh' -a "${1}" != "-c" ; then 
  5563.   echo shar: Will not clobber existing file \"'test/00/t0006a.sh'\"
  5564. else
  5565. echo shar: Extracting \"'test/00/t0006a.sh'\" \(8528 characters\)
  5566. sed "s/^X//" >'test/00/t0006a.sh' <<'END_OF_FILE'
  5567. X#! /bin/sh
  5568. X#
  5569. X#    aegis - project change supervisor
  5570. X#    Copyright (C) 1991, 1992, 1993 Peter Miller.
  5571. X#    All rights reserved.
  5572. X#
  5573. X#    This program is free software; you can redistribute it and/or modify
  5574. X#    it under the terms of the GNU General Public License as published by
  5575. X#    the Free Software Foundation; either version 2 of the License, or
  5576. X#    (at your option) any later version.
  5577. X#
  5578. X#    This program is distributed in the hope that it will be useful,
  5579. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  5580. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  5581. X#    GNU General Public License for more details.
  5582. X#
  5583. X#    You should have received a copy of the GNU General Public License
  5584. X#    along with this program; if not, write to the Free Software
  5585. X#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5586. X#
  5587. X# MANIFEST: Test 'aegis -DIFFerence' when the edit number is out-of-date.
  5588. X#
  5589. X# The bug results in a string of length 0 being passed.
  5590. X#
  5591. X
  5592. Xunset AEGIS_PROJECT
  5593. Xunset AEGIS_CHANGE
  5594. Xumask 022
  5595. X
  5596. XUSER=${USER:-${LOGNAME:-`whoami`}}
  5597. X
  5598. XPAGER=cat
  5599. Xexport PAGER
  5600. Xwork=${AEGIS_TMP:-/tmp}/$$
  5601. X
  5602. Xfail()
  5603. X{
  5604. X    set +x
  5605. X    echo "FAILED test of 'aegis -DIFFerence' when the edit number is out-of-date" 1>&2
  5606. X    find $work -type d -user $USER -exec chmod u+w {} \;
  5607. X    rm -rf $work
  5608. X    exit 1
  5609. X}
  5610. Xpass()
  5611. X{
  5612. X    set +x
  5613. X    echo PASSED 1>&2
  5614. X    find $work -type d -user $USER -exec chmod u+w {} \;
  5615. X    rm -rf $work
  5616. X    exit 0
  5617. X}
  5618. Xtrap "fail" 1 2 3 15
  5619. X
  5620. X#
  5621. X# some variable to make things earier to read
  5622. X#
  5623. Xworklib=$work/lib
  5624. Xworkproj=$work/foo.proj
  5625. Xworkchan=$work/foo.chan
  5626. Xworkchan3=$work/foo.chan3
  5627. Xtmp=$work/tmp
  5628. X
  5629. X#
  5630. X# echo commands so we can tell what failed
  5631. X#
  5632. Xset -x
  5633. X
  5634. X#
  5635. X# make the directories
  5636. X#
  5637. Xmkdir $work
  5638. X
  5639. X#
  5640. X# make a new project
  5641. X#    and check files it should have made
  5642. X#
  5643. X./bin/aegis -newpro foo -dir $workproj -v -lib $worklib
  5644. Xif test $? -ne 0 ; then fail; fi
  5645. X
  5646. X#
  5647. X# change project attributes
  5648. X#
  5649. Xcat > $tmp << 'end'
  5650. Xdescription = "A bogus project created to test things.";
  5651. Xdeveloper_may_review = true;
  5652. Xdeveloper_may_integrate = true;
  5653. Xreviewer_may_integrate = true;
  5654. Xend
  5655. X./bin/aegis -proatt $tmp -proj foo -v -lib $worklib
  5656. Xif test $? -ne 0 ; then fail; fi
  5657. X
  5658. X#
  5659. X# create a new change
  5660. X#    make sure it creates the files it should
  5661. X#
  5662. Xcat > $tmp << 'end'
  5663. Xbrief_description = "This change is used to test the aegis functionality \
  5664. Xwith respect to change descriptions.";
  5665. Xcause = internal_bug;
  5666. Xend
  5667. X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
  5668. Xif test $? -ne 0 ; then fail; fi
  5669. X
  5670. X#
  5671. X# create a second change
  5672. X#    make sure it creates the files it should
  5673. X#
  5674. Xcat > $tmp << 'end'
  5675. Xbrief_description = "This change was added to make the various listings \
  5676. Xmuch more interesting.";
  5677. Xcause = internal_bug;
  5678. Xend
  5679. X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
  5680. Xif test $? -ne 0 ; then fail; fi
  5681. X
  5682. X#
  5683. X# create a third change
  5684. X#
  5685. Xcat > $tmp << 'end'
  5686. Xbrief_description = "change three";
  5687. Xcause = internal_bug;
  5688. Xend
  5689. X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
  5690. Xif test $? -ne 0 ; then fail; fi
  5691. X
  5692. X#
  5693. X# add a new developer
  5694. X#
  5695. X./bin/aegis -newdev $USER -p foo -v -lib $worklib
  5696. Xif test $? -ne 0 ; then fail; fi
  5697. X
  5698. X#
  5699. X# begin development of a change
  5700. X#    check it made the files it should
  5701. X#
  5702. X./bin/aegis -devbeg 1 -p foo -dir $workchan -v -lib $worklib
  5703. Xif test $? -ne 0 ; then fail; fi
  5704. X
  5705. X#
  5706. X# add a new files to the change
  5707. X#
  5708. X./bin/aegis -new_file $workchan/main.c -nl -v -lib $worklib -p foo
  5709. Xif test $? -ne 0 ; then fail; fi
  5710. X./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
  5711. Xif test $? -ne 0 ; then fail; fi
  5712. Xcat > $workchan/main.c << 'end'
  5713. Xvoid
  5714. Xmain()
  5715. X{
  5716. X    exit(0);
  5717. X}
  5718. Xend
  5719. Xcat > $workchan/config << 'end'
  5720. Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$version\"' main.c";
  5721. Xlink_integration_directory = true;
  5722. X
  5723. Xhistory_get_command =
  5724. X    "co -u'$e' -p $h,v > $o";
  5725. Xhistory_create_command =
  5726. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  5727. Xhistory_put_command =
  5728. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  5729. Xhistory_query_command =
  5730. X    "rlog -r $h,v | awk '/^head:/ {print $$2}'";
  5731. X
  5732. Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  5733. X
  5734. Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
  5735. X    echo '1,$$p' ) | ed - $mr > $out";
  5736. Xend
  5737. X
  5738. X#
  5739. X# create a new test
  5740. X#
  5741. X./bin/aegis -nt -l -v -lib $worklib -p foo
  5742. Xif test $? -ne 0 ; then fail; fi
  5743. X./bin/aegis -nt -v -lib $worklib -p foo
  5744. Xif test $? -ne 0 ; then fail; fi
  5745. Xcat > $workchan/test/00/t0001a.sh << 'end'
  5746. X#!/bin/sh
  5747. X#
  5748. X# Project: "foo"
  5749. X# Change: 1
  5750. X#
  5751. X
  5752. Xfail()
  5753. X{
  5754. X    echo SHUZBUTT 1>&2
  5755. X    exit 1
  5756. X}
  5757. Xpass()
  5758. X{
  5759. X    exit 0
  5760. X}
  5761. Xtrap "fail" 1 2 3 15
  5762. X
  5763. X./foo
  5764. Xq=$?
  5765. X
  5766. X# check for signals
  5767. Xif test $q -ge 128 
  5768. Xthen
  5769. X    fail
  5770. Xfi
  5771. X
  5772. X# should not complain
  5773. Xif test $q -ne 0 
  5774. Xthen
  5775. X    fail
  5776. Xfi
  5777. X
  5778. X# it probably worked
  5779. Xpass
  5780. Xend
  5781. X
  5782. X#
  5783. X# let the clock tick over, so the build will be happy
  5784. X#
  5785. Xsleep 1
  5786. X
  5787. X#
  5788. X# build the change
  5789. X#
  5790. X./bin/aegis -build -nl -v -lib $worklib -p foo
  5791. Xif test $? -ne 0 ; then fail; fi
  5792. X
  5793. X#
  5794. X# difference the change
  5795. X#
  5796. X./bin/aegis -diff -nl -v -lib $worklib -p foo
  5797. Xif test $? -ne 0 ; then fail; fi
  5798. X
  5799. X#
  5800. X# test the change
  5801. X#
  5802. X./bin/aegis -test -nl -v -lib $worklib -p foo
  5803. Xif test $? -ne 0 ; then fail; fi
  5804. X
  5805. X#
  5806. X# finish development of the change
  5807. X#
  5808. X./bin/aegis -dev_end -v -lib $worklib -p foo
  5809. Xif test $? -ne 0 ; then fail; fi
  5810. X
  5811. X#
  5812. X# add a new reviewer
  5813. X#
  5814. X./bin/aegis -newrev $USER -p foo -v -lib $worklib
  5815. Xif test $? -ne 0 ; then fail; fi
  5816. X
  5817. X#
  5818. X# pass the review
  5819. X#
  5820. X./bin/aegis -review_pass -chan 1 -proj foo -v -lib $worklib
  5821. Xif test $? -ne 0 ; then fail; fi
  5822. X
  5823. X#
  5824. X# add an integrator
  5825. X#
  5826. X./bin/aegis -newint $USER -p foo -v -lib $worklib
  5827. Xif test $? -ne 0 ; then fail; fi
  5828. X
  5829. X#
  5830. X# start integrating
  5831. X#
  5832. X./bin/aegis -intbeg 1 -p foo -v -lib $worklib
  5833. Xif test $? -ne 0 ; then fail; fi
  5834. X
  5835. X#
  5836. X# integrate build
  5837. X#
  5838. Xsleep 1
  5839. X./bin/aegis -build -nl -v -lib $worklib -p foo
  5840. Xif test $? -ne 0 ; then fail; fi
  5841. X./bin/aegis -test -nl -v -lib $worklib -p foo
  5842. Xif test $? -ne 0 ; then fail; fi
  5843. X
  5844. X#
  5845. X# pass the integration
  5846. X#
  5847. X./bin/aegis -intpass -nl -v -lib $worklib -p foo
  5848. Xif test $? -ne 0 ; then fail; fi
  5849. X
  5850. X#
  5851. X# start work on change 2
  5852. X#
  5853. X./bin/aegis -devbeg 2 -p foo -v -dir $workchan -lib $worklib
  5854. Xif test $? -ne 0 ; then fail; fi
  5855. X
  5856. X#
  5857. X# start work on change 3
  5858. X#
  5859. X./bin/aegis -devbeg 3 -p foo -v -dir $workchan3 -lib $worklib
  5860. Xif test $? -ne 0 ; then fail; fi
  5861. X
  5862. X#
  5863. X# copy a file into change 2
  5864. X#
  5865. X./bin/aegis -cp $workchan/main.c -nl -v -lib $worklib -c 2 -p foo
  5866. Xif test $? -ne 0 ; then fail; fi
  5867. X
  5868. X#
  5869. X# copy a file into change 3
  5870. X#
  5871. X./bin/aegis -cp $workchan3/main.c -nl -v -lib $worklib -c 3 -p foo
  5872. Xif test $? -ne 0 ; then fail; fi
  5873. X
  5874. X#
  5875. X# change the file
  5876. X#
  5877. Xcat > $workchan/main.c << 'end'
  5878. X
  5879. X#include <stdio.h>
  5880. X
  5881. Xvoid
  5882. Xmain(argc, argv)
  5883. X    int    argc;
  5884. X    char    **argv;
  5885. X{
  5886. X    if (argc != 1)
  5887. X    {
  5888. X        fprintf(stderr, "usage: %s\n", argv[0]);
  5889. X        exit(1);
  5890. X    }
  5891. X    printf("hello, world\n");
  5892. X    exit(0);
  5893. X}
  5894. Xend
  5895. X
  5896. X#
  5897. X# need another test
  5898. X#
  5899. X./bin/aegis -nt -v -lib $worklib -c 2 -p foo
  5900. Xif test $? -ne 0 ; then fail; fi
  5901. Xcat > $workchan/test/00/t0002a.sh << 'end'
  5902. X#!/bin/sh
  5903. X#
  5904. X# Project: "foo"
  5905. X# Change: 2
  5906. X#
  5907. X
  5908. Xfail()
  5909. X{
  5910. X    echo SHUZBUTT 1>&2
  5911. X    exit 1
  5912. X}
  5913. Xpass()
  5914. X{
  5915. X    exit 0
  5916. X}
  5917. Xtrap "fail" 1 2 3 15
  5918. X
  5919. X./foo ickky
  5920. Xq=$?
  5921. X
  5922. X# check for signals
  5923. Xif test $q -ge 128 
  5924. Xthen
  5925. X    fail
  5926. Xfi
  5927. X
  5928. X# should have complained
  5929. Xif test $q -eq 0 
  5930. Xthen
  5931. X    fail
  5932. Xfi
  5933. X
  5934. X# it probably worked
  5935. Xpass
  5936. Xend
  5937. X
  5938. X#
  5939. X# tick over clock to keep build happy
  5940. X#
  5941. Xsleep 1
  5942. X
  5943. X#
  5944. X# build the change
  5945. X# diff the change
  5946. X# test the change
  5947. X#
  5948. X./bin/aegis -b -nl -v -lib $worklib -c 2 -p foo
  5949. Xif test $? -ne 0 ; then fail; fi
  5950. X./bin/aegis -diff -nl -v -lib $worklib -c 2 -p foo
  5951. Xif test $? -ne 0 ; then fail; fi
  5952. X./bin/aegis -test -nl -v -lib $worklib -c 2 -p foo
  5953. Xif test $? -ne 0 ; then fail; fi
  5954. X./bin/aegis -test -bl -nl -v -lib $worklib -c 2 -p foo
  5955. Xif test $? -ne 0 ; then fail; fi
  5956. X
  5957. X#
  5958. X# end development
  5959. X# review pass
  5960. X# start integrating
  5961. X#
  5962. X./bin/aegis -devend -v -lib $worklib -c 2 -p foo
  5963. Xif test $? -ne 0 ; then fail; fi
  5964. X./bin/aegis -revpass -v -c 2 -p foo -lib $worklib
  5965. Xif test $? -ne 0 ; then fail; fi
  5966. X./bin/aegis -intbeg -v -c 2 -p foo -lib $worklib
  5967. Xif test $? -ne 0 ; then fail; fi
  5968. X
  5969. X#
  5970. X# build the integration
  5971. X# test the integration
  5972. X# test the integration against the baseline
  5973. X#
  5974. Xsleep 1
  5975. X./bin/aegis -b -nl -v -lib $worklib -c 2 -p foo
  5976. Xif test $? -ne 0 ; then fail; fi
  5977. X./bin/aegis -t -nl -v -lib $worklib -c 2 -p foo
  5978. Xif test $? -ne 0 ; then fail; fi
  5979. X./bin/aegis -t -bl -nl -v -lib $worklib -c 2 -p foo
  5980. Xif test $? -ne 0 ; then fail; fi
  5981. X
  5982. X#
  5983. X# pass the integration
  5984. X#    make sure it create the files, etc
  5985. X#
  5986. X./bin/aegis -intpass -nl -lib $worklib -c 2 -p foo
  5987. Xif test $? -ne 0 ; then fail; fi
  5988. X
  5989. X#
  5990. X# difference change 3
  5991. X#
  5992. X./bin/aegis -diff -nl -c 3 -lib $worklib -p foo
  5993. Xif test $? -ne 0 ; then fail; fi
  5994. X
  5995. X# should be no automatic logging
  5996. Xif test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
  5997. X
  5998. X#
  5999. X# the things tested in this test, worked
  6000. X#
  6001. Xpass
  6002. END_OF_FILE
  6003. if test 8528 -ne `wc -c <'test/00/t0006a.sh'`; then
  6004.     echo shar: \"'test/00/t0006a.sh'\" unpacked with wrong size!
  6005. fi
  6006. # end of 'test/00/t0006a.sh'
  6007. fi
  6008. if test -f 'test/00/t0009a.sh' -a "${1}" != "-c" ; then 
  6009.   echo shar: Will not clobber existing file \"'test/00/t0009a.sh'\"
  6010. else
  6011. echo shar: Extracting \"'test/00/t0009a.sh'\" \(8705 characters\)
  6012. sed "s/^X//" >'test/00/t0009a.sh' <<'END_OF_FILE'
  6013. X#! /bin/sh
  6014. X#
  6015. X#    aegis - project change supervisor
  6016. X#    Copyright (C) 1991, 1992, 1993 Peter Miller.
  6017. X#    All rights reserved.
  6018. X#
  6019. X#    This program is free software; you can redistribute it and/or modify
  6020. X#    it under the terms of the GNU General Public License as published by
  6021. X#    the Free Software Foundation; either version 2 of the License, or
  6022. X#    (at your option) any later version.
  6023. X#
  6024. X#    This program is distributed in the hope that it will be useful,
  6025. X#    but WITHOUT ANY WARRANTY; without even the implied warranty of
  6026. X#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  6027. X#    GNU General Public License for more details.
  6028. X#
  6029. X#    You should have received a copy of the GNU General Public License
  6030. X#    along with this program; if not, write to the Free Software
  6031. X#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  6032. X#
  6033. X# MANIFEST: Test -New_ReLeaSe functionality.
  6034. X#
  6035. X
  6036. Xunset AEGIS_PROJECT
  6037. Xunset AEGIS_CHANGE
  6038. Xumask 022
  6039. X
  6040. XUSER=${USER:-${LOGNAME:-`whoami`}}
  6041. X
  6042. XPAGER=cat
  6043. Xexport PAGER
  6044. Xwork=${AEGIS_TMP:-/tmp}/$$
  6045. X
  6046. Xfail()
  6047. X{
  6048. X    set +x
  6049. X    echo FAILED test of -New_ReLeaSe functionality 1>&2
  6050. X    find $work -type d -user $USER -exec chmod u+w {} \;
  6051. X    rm -rf $work
  6052. X    exit 1
  6053. X}
  6054. Xpass()
  6055. X{
  6056. X    set +x
  6057. X    echo PASSED 1>&2
  6058. X    find $work -type d -user $USER -exec chmod u+w {} \;
  6059. X    rm -rf $work
  6060. X    exit 0
  6061. X}
  6062. Xtrap "fail" 1 2 3 15
  6063. X
  6064. X#
  6065. X# some variable to make things earier to read
  6066. X#
  6067. Xworklib=$work/lib
  6068. Xworkproj=$work/foo.proj
  6069. Xworkproj2=$work/foo.proj2
  6070. Xworkchan=$work/foo.chan
  6071. Xtmp=$work/tmp
  6072. X
  6073. X#
  6074. X# echo commands so we can tell what failed
  6075. X#
  6076. Xset -x
  6077. X
  6078. X#
  6079. X# make the directories
  6080. X#
  6081. Xmkdir $work
  6082. X
  6083. X#
  6084. X# make a new project
  6085. X#    and check files it should have made
  6086. X#
  6087. X./bin/aegis -newpro foo -dir $workproj -v -lib $worklib
  6088. Xif test $? -ne 0 ; then fail; fi
  6089. X
  6090. X#
  6091. X# change project attributes
  6092. X#
  6093. Xcat > $tmp << 'end'
  6094. Xdescription = "A bogus project created to test things.";
  6095. Xdeveloper_may_review = true;
  6096. Xdeveloper_may_integrate = true;
  6097. Xreviewer_may_integrate = true;
  6098. Xend
  6099. X./bin/aegis -proatt $tmp -proj foo -v -lib $worklib
  6100. Xif test $? -ne 0 ; then fail; fi
  6101. X
  6102. X#
  6103. X# create a new change
  6104. X#
  6105. Xcat > $tmp << 'end'
  6106. Xbrief_description = "This change is used to test the aegis functionality \
  6107. Xwith respect to change descriptions.";
  6108. Xcause = internal_bug;
  6109. Xend
  6110. X./bin/aegis -new_change $tmp -project foo -v -lib $worklib
  6111. Xif test $? -ne 0 ; then fail; fi
  6112. X
  6113. X#
  6114. X# add a new developer
  6115. X#
  6116. X./bin/aegis -newdev $USER -p foo -v -lib $worklib
  6117. Xif test $? -ne 0 ; then fail; fi
  6118. X
  6119. X#
  6120. X# begin development of a change
  6121. X#
  6122. X./bin/aegis -devbeg 1 -p foo -dir $workchan -v -lib $worklib
  6123. Xif test $? -ne 0 ; then fail; fi
  6124. X
  6125. X#
  6126. X# add a new files to the change
  6127. X#
  6128. X./bin/aegis -new_file $workchan/main.c -nl -v -lib $worklib -p foo
  6129. Xif test $? -ne 0 ; then fail; fi
  6130. X./bin/aegis -new_file $workchan/config -nl -v -lib $worklib -p foo
  6131. Xif test $? -ne 0 ; then fail; fi
  6132. Xcat > $workchan/main.c << 'end'
  6133. Xvoid
  6134. Xmain()
  6135. X{
  6136. X    exit(0);
  6137. X}
  6138. Xend
  6139. Xif test $? -ne 0 ; then fail; fi
  6140. Xcat > $workchan/config << 'end'
  6141. Xbuild_command = "rm -f foo; cc -o foo -D'VERSION=\"$v\"' main.c";
  6142. Xlink_integration_directory = true;
  6143. X
  6144. Xhistory_get_command =
  6145. X    "co -u'$e' -p $h,v > $o";
  6146. Xhistory_create_command =
  6147. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  6148. Xhistory_put_command =
  6149. X    "ci -u -m/dev/null -t/dev/null $i $h,v; rcs -U $h,v";
  6150. Xhistory_query_command =
  6151. X    "rlog -r $h,v | awk '/^head:/ {print $$2}'";
  6152. X
  6153. Xdiff_command = "set +e; diff $orig $i > $out; test $$? -le 1";
  6154. X
  6155. Xdiff3_command = "(diff3 -e $mr $orig $i | sed -e '/^w$$/d' -e '/^q$$/d'; \
  6156. X    echo '1,$$p' ) | ed - $mr > $out";
  6157. Xend
  6158. Xif test $? -ne 0 ; then fail; fi
  6159. X
  6160. X#
  6161. X# create a new test
  6162. X#
  6163. X./bin/aegis -nt -v -lib $worklib -p foo
  6164. Xif test $? -ne 0 ; then fail; fi
  6165. Xcat > $workchan/test/00/t0001a.sh << 'end'
  6166. X#!/bin/sh
  6167. X#
  6168. X# Project: "foo"
  6169. X# Change: 1
  6170. X#
  6171. X
  6172. Xfail()
  6173. X{
  6174. X    echo SHUZBUTT 1>&2
  6175. X    exit 1
  6176. X}
  6177. Xpass()
  6178. X{
  6179. X    exit 0
  6180. X}
  6181. Xtrap "fail" 1 2 3 15
  6182. X
  6183. X./foo
  6184. Xq=$?
  6185. X
  6186. X# check for signals
  6187. Xif test $q -ge 128 
  6188. Xthen
  6189. X    fail
  6190. Xfi
  6191. X
  6192. X# should not complain
  6193. Xif test $q -ne 0 
  6194. Xthen
  6195. X    fail
  6196. Xfi
  6197. X
  6198. X# it probably worked
  6199. Xpass
  6200. Xend
  6201. Xif test $? -ne 0 ; then fail; fi
  6202. X
  6203. X#
  6204. X# let the clock tick over, so the build will be happy
  6205. X#
  6206. Xsleep 1
  6207. X
  6208. X#
  6209. X# build the change
  6210. X#
  6211. X./bin/aegis -build -nl -v -lib $worklib -p foo
  6212. Xif test $? -ne 0 ; then fail; fi
  6213. X
  6214. X#
  6215. X# difference the change
  6216. X#
  6217. X./bin/aegis -diff -nl -v -lib $worklib -p foo
  6218. Xif test $? -ne 0 ; then fail; fi
  6219. X
  6220. X#
  6221. X# test the change
  6222. X#
  6223. X./bin/aegis -test -nl -v -lib $worklib -p foo
  6224. Xif test $? -ne 0 ; then fail; fi
  6225. X
  6226. X#
  6227. X# finish development of the change
  6228. X#
  6229. X./bin/aegis -dev_end -v -lib $worklib -p foo
  6230. Xif test $? -ne 0 ; then fail; fi
  6231. X
  6232. X#
  6233. X# add a new reviewer
  6234. X#
  6235. X./bin/aegis -newrev $USER -p foo -v -lib $worklib
  6236. Xif test $? -ne 0 ; then fail; fi
  6237. X
  6238. X#
  6239. X# pass the review
  6240. X#
  6241. X./bin/aegis -review_pass -chan 1 -proj foo -v -lib $worklib
  6242. Xif test $? -ne 0 ; then fail; fi
  6243. X
  6244. X#
  6245. X# add an integrator
  6246. X#
  6247. X./bin/aegis -newint $USER -p foo -v -lib $worklib
  6248. Xif test $? -ne 0 ; then fail; fi
  6249. X
  6250. X#
  6251. X# start integrating
  6252. X#
  6253. X./bin/aegis -intbeg 1 -p foo -v -lib $worklib
  6254. Xif test $? -ne 0 ; then fail; fi
  6255. X
  6256. X#
  6257. X# integrate build
  6258. X#
  6259. Xsleep 1
  6260. X./bin/aegis -build -nl -v -lib $worklib -p foo
  6261. Xif test $? -ne 0 ; then fail; fi
  6262. X./bin/aegis -test -nl -v -lib $worklib -p foo
  6263. Xif test $? -ne 0 ; then fail; fi
  6264. X
  6265. X#
  6266. X# pass the integration
  6267. X#
  6268. X./bin/aegis -intpass -nl -v -lib $worklib -p foo
  6269. Xif test $? -ne 0 ; then fail; fi
  6270. X
  6271. X#
  6272. X# create the new release
  6273. X#
  6274. X./bin/aegis -nrls -l -v -lib $worklib
  6275. Xif test $? -ne 0 ; then fail; fi
  6276. X./bin/aegis -nrls -v foo -dir $workproj2 -lib $worklib -nl
  6277. Xif test $? -ne 0 ; then fail; fi
  6278. Xls -lRA $workproj2
  6279. Xcat $workproj2/info/change/0/001
  6280. Xif test $? -ne 0 ; then fail; fi
  6281. Xcat $workproj2/info/state
  6282. Xif test $? -ne 0 ; then fail; fi
  6283. Xls -lgRA $worklib
  6284. X./bin/aegis -nrls -l -v -lib $worklib
  6285. Xif test $? -ne 0 ; then fail; fi
  6286. X
  6287. X#
  6288. X# create a second change
  6289. X#    make sure it creates the files it should
  6290. X#
  6291. Xcat > $tmp << 'end'
  6292. Xbrief_description = "Second change of second project";
  6293. Xcause = internal_enhancement;
  6294. Xend
  6295. X./bin/aegis -new_change $tmp -project foo.1.1 -v -lib $worklib
  6296. Xif test $? -ne 0 ; then fail; fi
  6297. Xcat $workproj2/info/change/0/002
  6298. Xif test $? -ne 0 ; then fail; fi
  6299. X
  6300. X#
  6301. X# start work on change 2 of foo.1.1
  6302. X#
  6303. X./bin/aegis -devbeg 2 -p foo.1.1 -v -dir $workchan -lib $worklib
  6304. Xif test $? -ne 0 ; then fail; fi
  6305. X
  6306. X#
  6307. X# copy a file into the change
  6308. X#
  6309. X./bin/aegis -cp $workchan/main.c -v -nl -lib $worklib -p foo.1.1
  6310. Xif test $? -ne 0 ; then fail; fi
  6311. Xcat $workproj2/info/change/0/002
  6312. Xif test $? -ne 0 ; then fail; fi
  6313. Xcat $workproj2/info/state
  6314. Xif test $? -ne 0 ; then fail; fi
  6315. Xcat $worklib/user/$USER
  6316. Xif test $? -ne 0 ; then fail; fi
  6317. Xls -lRA $work
  6318. X
  6319. X#
  6320. X# change the file
  6321. X#
  6322. Xcat > $workchan/main.c << 'end'
  6323. X
  6324. X#include <stdio.h>
  6325. X
  6326. Xvoid
  6327. Xmain(argc, argv)
  6328. X    int    argc;
  6329. X    char    **argv;
  6330. X{
  6331. X    if (argc != 1)
  6332. X    {
  6333. X        fprintf(stderr, "usage: %s\n", argv[0]);
  6334. X        exit(1);
  6335. X    }
  6336. X    printf("hello, world\n");
  6337. X    exit(0);
  6338. X}
  6339. Xend
  6340. X
  6341. X#
  6342. X# need another test
  6343. X#
  6344. X./bin/aegis -nt -v -lib $worklib -p foo.1.1
  6345. Xif test $? -ne 0 ; then fail; fi
  6346. Xcat > $workchan/test/00/t0002a.sh << 'end'
  6347. X#!/bin/sh
  6348. X#
  6349. X# Project: "foo.1.1"
  6350. X# Change: 2
  6351. X#
  6352. X
  6353. Xfail()
  6354. X{
  6355. X    echo SHUZBUTT 1>&2
  6356. X    exit 1
  6357. X}
  6358. Xpass()
  6359. X{
  6360. X    exit 0
  6361. X}
  6362. Xtrap "fail" 1 2 3 15
  6363. X
  6364. X./foo ickky
  6365. Xif test $? -ne 1 ; then fail; fi
  6366. X
  6367. X# it probably worked
  6368. Xpass
  6369. Xend
  6370. X
  6371. X#
  6372. X# tick over clock to keep build happy
  6373. X#
  6374. Xsleep 1
  6375. X
  6376. X#
  6377. X# build the change
  6378. X# diff the change
  6379. X# test the change
  6380. X#
  6381. X./bin/aegis -b -nl -v -lib $worklib -p foo.1.1
  6382. Xif test $? -ne 0 ; then fail; fi
  6383. X./bin/aegis -diff -nl -v -lib $worklib -p foo.1.1
  6384. Xif test $? -ne 0 ; then fail; fi
  6385. X./bin/aegis -test -nl -v -lib $worklib -p foo.1.1
  6386. Xif test $? -ne 0 ; then fail; fi
  6387. X./bin/aegis -test -bl -nl -v -lib $worklib -p foo.1.1
  6388. Xif test $? -ne 0 ; then fail; fi
  6389. Xcat $workchan/main.c,D
  6390. Xif test $? -ne 0 ; then fail; fi
  6391. X
  6392. X
  6393. X#
  6394. X# end development
  6395. X# review pass
  6396. X# start integrating
  6397. X#
  6398. X./bin/aegis -devend -v -lib $worklib -p foo.1.1
  6399. Xif test $? -ne 0 ; then fail; fi
  6400. X./bin/aegis -revpass -v -c 2 -p foo.1.1 -lib $worklib
  6401. Xif test $? -ne 0 ; then fail; fi
  6402. X./bin/aegis -intbeg -v -c 2 -p foo.1.1 -lib $worklib
  6403. Xif test $? -ne 0 ; then fail; fi
  6404. X
  6405. X#
  6406. X# build the integration
  6407. X# test the integration
  6408. X# test the integration against the baseline
  6409. X#
  6410. Xsleep 1
  6411. X./bin/aegis -b -nl -v -lib $worklib -p foo.1.1
  6412. Xif test $? -ne 0 ; then fail; fi
  6413. X./bin/aegis -t -nl -v -lib $worklib -p foo.1.1
  6414. Xif test $? -ne 0 ; then fail; fi
  6415. X./bin/aegis -t -bl -nl -v -lib $worklib -p foo.1.1
  6416. Xif test $? -ne 0 ; then fail; fi
  6417. X
  6418. X#
  6419. X# pass the integration
  6420. X#    make sure it create the files, etc
  6421. X#
  6422. X./bin/aegis -intpass -nl -lib $worklib -p foo.1.1
  6423. Xif test $? -ne 0 ; then fail; fi
  6424. Xcat $workproj2/info/change/0/002
  6425. Xif test $? -ne 0 ; then fail; fi
  6426. Xcat $workproj2/info/state
  6427. Xif test $? -ne 0 ; then fail; fi
  6428. Xcat $worklib/user/$USER
  6429. Xif test $? -ne 0 ; then fail; fi
  6430. Xls -lR $work
  6431. X./bin/aegis -l projhist -v -p foo.1.1 -lib $worklib
  6432. Xif test $? -ne 0 ; then fail; fi
  6433. X
  6434. X# should be no automatic logging
  6435. Xif test "`find $work -name 'aegis.log' -print`" != "" ; then fail; fi
  6436. X
  6437. X#
  6438. X# the things tested in this test, worked
  6439. X#
  6440. Xpass
  6441. END_OF_FILE
  6442. if test 8705 -ne `wc -c <'test/00/t0009a.sh'`; then
  6443.     echo shar: \"'test/00/t0009a.sh'\" unpacked with wrong size!
  6444. fi
  6445. # end of 'test/00/t0009a.sh'
  6446. fi
  6447. echo shar: End of archive 7 \(of 19\).
  6448. cp /dev/null ark7isdone
  6449. MISSING=""
  6450. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  6451.     if test ! -f ark${I}isdone ; then
  6452.     MISSING="${MISSING} ${I}"
  6453.     fi
  6454. done
  6455. if test "${MISSING}" = "" ; then
  6456.     echo You have unpacked all 19 archives.
  6457.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  6458. else
  6459.     echo You still need to unpack the following archives:
  6460.     echo "        " ${MISSING}
  6461. fi
  6462. ##  End of shell archive.
  6463. exit 0
  6464.