1 
   2 /****^  HISTORY COMMENTS:
   3   1) change(2019-08-17,GDixon), approve(2019-10-23,MCR10069),
   4      audit(2020-01-20,Swenson), install(2020-01-20,MR12.6g-0035):
   5      Command to invoke the mbuild Subsystem.  For details, see:  MTB-1003
   6      mbuild Subsystem
   7   2) change(2020-01-25,GDixon), approve(2020-01-25,MCR10079),
   8      audit(2020-02-02,Swenson), install(2020-02-02,MR12.6g-0045):
   9       A) Add mbuild -scan_read control argument as default mode of operation.
  10       B) Change existing -scan control argument to omit build_script read.
  11   3) change(2020-02-10,GDixon), approve(2020-02-10,MCR10079),
  12      audit(2020-04-30,Swenson), install(2020-04-30,MR12.6g-0046):
  13       A) Change mbuild version number to mbuild__1.02
  14   4) change(2020-07-30,GDixon), approve(2021-02-22,MCR10086),
  15      audit(2021-03-17,Swenson), install(2021-03-17,MR12.6g-0051):
  16       A) Change mbuild version number to mbuild__1.03
  17   5) change(2021-02-22,GDixon), approve(2021-02-22,MCR10086),
  18      audit(2021-03-31,Swenson), install(2021-03-31,MR12.6g-0054):
  19       A) Change mbuild version number to mbuild_1.04
  20   6) change(2021-11-21,GDixon), approve(2021-11-24,MCR10102),
  21      audit(2021-12-07,Swenson), install(2021-12-08,MR12.8-1012):
  22       A) Add support for -debug control arg: turns on build_data.info.pad
  23          hidden parameter enabling DEBUG code in mbuild_data_$get_XXX entry
  24          points.
  25   7) change(2022-08-03,GDixon), approve(2022-09-05,MCR10126),
  26      audit(2022-10-11,Swenson), install(2022-10-12,MR12.8-1042):
  27      mbuild_2.00 w/ mbuild_data_0004 --
  28       A) Replace references to bld.pad = "-db" with bld.debugS = T.
  29       B) Change command syntax to include an optional BUILD_SCRIPT_PATH,
  30          and accept new control_arg -read_analyze (-rdaz).
  31       C) Add monitor_ subsystem to: check mbuild's runtime environmental
  32          dependencies before each request line is processed; and to
  33          auto-update mbuild's internal view of build script sections
  34          when they are edited externally while mbuild is running.
  35       D) Add new -developing, -auditing and -installing control arguments
  36          to change build phase value.
  37       E) Add new -approve and -install control arguments to specify
  38          Information --  section attributes likely to be known/set when
  39          mbuild is invoked.
  40   8) change(2022-10-13,GDixon), approve(2022-10-13,MCR10126a),
  41      audit(2022-10-25,Swenson), install(2022-10-25,MR12.8-1043):
  42      mbuild_2.01 --
  43       A) Use new mbuild_script_info_attr.incl.pl1 to get verification
  44          routines: approve_ID  install_ID
  45          and attribute descriptions:  valid_Approve_ID  valid_Install_ID
  46       B) Change all formerly-ignored -ctl_arg errors to be fatal errors
  47          causing mbuild subsystem invocation to be aborted.
  48       C) Use new mbuild_set_$set_phase to set any Phase, Approve_ID or
  49          Install_ID values given in mbuild command args.
  50                                                    END HISTORY COMMENTS */
  51 
  52 /*  SEE NEAR END OF SOURCE: OVERVIEW of the AUTOMATION embodied in the mbuild SUBSYSTEM. */
  53 %page;
  54 mbuild:
  55 mb:
  56      proc options(variable);
  57 
  58                                                             /* Constant variables.                                    */
  59   dcl  NL char(1) int static options(constant) init("
  60 ");
  61   dcl  PROC char(6) int static options(constant) init("mbuild");
  62   dcl  VERSION char(12) internal static options(constant) init("mbuild_2.01 ");
  63   dcl  no_info_directory char(0) int static options(constant) init("");
  64 
  65   dcl  iox_$user_input ptr ext static;                      /* Subsystem accepts terminal input.                      */
  66 
  67                                                             /* Supporting subroutines.                                */
  68   dcl  mbuild_$banner entry  options(variable);
  69   dcl  mbuild_$request entry options(variable);
  70 
  71   dcl  mbuild_data_$get_build_progress entry (ptr) returns(bit(*) aligned);
  72   dcl  mbuild_data_$initialize_build_lists entry (ptr);
  73 
  74   dcl  mbuild_info_find_$suffix_for_build_type entry (char(*)) returns(char(12) var);
  75 
  76   dcl  mbuild_library_$get_descriptor_path entry() returns(char(168) var);
  77   dcl  mbuild_library_$get_process_user_id entry() returns(char(32) var);
  78 
  79   dcl  mbuild_monitor_$setup entry (ptr, char(168), fixed bin(21), char(32), entry, entry, entry, fixed bin(35));
  80 
  81   dcl  mbuild_request_parms_ entry (ptr) returns(bit(1) aligned);
  82   dcl  mbuild_request_tables_$user_requests bit(36) aligned external;
  83 
  84   dcl  mbuild_scan_$segs_matching_starname entry (ptr, char(*), (*) char(32), fixed bin);
  85 
  86   dcl  mbuild_script_$read_all_sections_but_changes entry (ptr, ptr, bit(1) aligned, bit(1) aligned, fixed bin(21),
  87           fixed bin(35));
  88 
  89   dcl  mbuild_set_$description_stored entry (ptr) returns(bit(1) aligned);
  90   dcl  mbuild_set_$store_phase entry (ptr, char(*), char(*), fixed bin, (*) char(32) var, char(20) var)
  91           returns(bit(1) aligned);
  92 
  93 
  94 
  95                                                             /* External subroutines.                                  */
  96   dcl  check_star_name_ entry (char(*), bit(36), fixed bin(2), fixed bin(35));
  97   dcl  com_err_ entry() options(variable);
  98   dcl  command_query_$yes_no entry() options(variable);
  99   dcl  change_wdir_ entry (char(168), fixed bin(35));
 100   dcl  expand_pathname_ entry (char(*), char(*), char(*), fixed bin(35));
 101   dcl  expand_pathname_$add_suffix entry (char(*), char(*), char(*), char(*), fixed bin(35));
 102   dcl  get_shortest_path_ entry (char(*)) returns(char(168));
 103   dcl  get_wdir_ entry() returns(char(168));
 104   dcl  hcs_$get_uid_file entry (char(*), char(*), bit(36) aligned, fixed bin(35));
 105   dcl  ioa_ entry() options(variable);
 106   dcl  ioa_$rsnnl entry() options(variable);
 107   dcl  lib_descriptor_$set_name entry (char(168) var, fixed bin(35));
 108   dcl  pathname_ entry (char(*), char(*)) returns(char(168));
 109   dcl  translator_temp_$release_all_segments entry (ptr, fixed bin(35));
 110 
 111   dcl (error_table_$badopt,
 112        error_table_$empty_search_list,
 113        error_table_$fatal_error,
 114        error_table_$noentry,
 115        error_table_$nostars,
 116        mbuild_et_$argument_error,
 117        mbuild_et_$bad_phase_installing,
 118        mbuild_et_$no_build_script,
 119        mbuild_et_$no_operand,
 120        mbuild_et_$many_build_scripts
 121        ) fixed bin(35) ext static;
 122 
 123   dcl (addr, after, before, dimension, length, maxlength,  null, rtrim, string, substr, verify) builtin;
 124 %page;
 125 /* ----------------------------------------------------------------------
 126     Structure to hold mbuild command arguments.
 127  * ---------------------------------------------------------------------- */
 128 
 129   dcl 1 CMD aligned,
 130       2 sciP ptr,
 131       2 request_lineP ptr,
 132       2 request_lineL fixed bin(21),
 133       2 info,
 134         3 build_script_dir char(168) unal,
 135         3 build_script_ent char(32) unal,
 136         3 prompt char(64) var,
 137         3 abbrev_profile char(168) unal,
 138         3 scan_read char(4),
 139         3 phase char(20) var,
 140         3 log_dir char(168) var,
 141         3 Approve_ID char(20) var,
 142         3 Install_ID char(20) var,
 143       2 S aligned,
 144         3 (abbrevS,                                         /* T: Turn on abbrev processing within request lines.     */
 145            promptS,                                         /* T: Change mbuild's request line prompt string.         */
 146            request_loopS,                                   /* T: Entry mbuild's listen, which prompts for requests.  */
 147            debugS                                           /* T: Turn on -debug output in mbuild_data_.pl1           */
 148             ) bit(1) unal;
 149   dcl  request_line char (CMD.request_lineL) based (CMD.request_lineP);
 150 
 151 
 152 /* ----------------------------------------------------------------------
 153     Initialize CMD control structure.
 154  * ---------------------------------------------------------------------- */
 155 
 156      CMD.sciP = null();
 157      CMD.request_lineP = null();
 158      CMD.request_lineL = 0;
 159      CMD.info = "";
 160      CMD.S = F;
 161 
 162      CMD.promptS = T;                                       /* Set default control arg values when invoking mbuild.   */
 163      CMD.request_loopS = T;
 164      CMD.scan_read = "dft";                                 /* = "" means -no_scan, so set special "dft" start value  */
 165 
 166 
 167 /* ----------------------------------------------------------------------
 168     Initialize some parts of the mbuild_data_ structure: build_data
 169 
 170      - This must be done very early, in case standalone invocation
 171        branches to the EXIT label.
 172         - build_data.ptrs elements are referenced at EXIT label
 173           (by the SUBSYS_cleanup_handler call).
 174 
 175     The build_data structure is automatic storage kept in mbuild's stack
 176     frame.  A pointer to this structure (Abuild_dataP) is passed by
 177     ssu_ to all request subroutines, and is available via the ssu_$get_data()
 178     subroutine to non-request subroutines.
 179 
 180      A) Initialize control data with starting values (as for empty build directory).
 181 
 182     Remaining substructures of build_data are initialized below by the
 183     call to mbuild_data_$initialize_build_lists.
 184  * ---------------------------------------------------------------------- */
 185 
 186      build_data.header = "";
 187      build_data.header.version = mbuild_data_version_4;
 188      build_data.progress = F;
 189 
 190      build_data.script_info.scalars = "";
 191      build_data.script_info.phase         = default_Phase;
 192      build_data.script_info.descriptor    = mbuild_library_$get_descriptor_path();
 193                                                             /* Use process' current library descriptor as the         */
 194                                                             /*  initial value.  It may later be overridden by value   */
 195                                                             /*  specified in build script.                            */
 196      build_data.script_info.log_dir       = BS_log_dir_default;
 197      build_data.script_info.counts        = 1;
 198      build_data.script_info.arrays        = "";
 199      build_data.script_info.devs(1)       = mbuild_library_$get_process_user_id();
 200 
 201      build_data.switches = F;
 202 
 203      build_data.ptrs = null();                              /* All services using these pointers are not enabled yet  */
 204 
 205 
 206 
 207 /* ----------------------------------------------------------------------
 208     Process command arguments using an ssu_ standalone invocation.
 209     It will later be replaced by a standard subsystem invocation.
 210 
 211     NOTE: When ssu_$standalone_invocation returns, any errors are
 212           reported via this standalone ssu_$print_message or
 213           $abort_subsystem routines using CMD.sciP (or aCMD.sciP
 214           used by controlArgs subroutine).
 215  * ---------------------------------------------------------------------- */
 216 
 217      isStandalone = T;
 218      on cleanup call standalone_cleanup_handler (isStandalone, CMD.sciP);
 219                                                             /* On-unit to cleanup the standalone invocation.          */
 220 
 221      call ssu_$standalone_invocation (CMD.sciP, PROC, VERSION, cu_$arg_list_ptr(), abort_to_EXIT, code);
 222      if code ^= 0 then goto EXIT;
 223 
 224      call arg_setup (CMD.sciP);                             /* Process mbuild command arguments.                      */
 225      if args_remain() then
 226           call controlArgs (CMD);
 227 
 228      call standalone_cleanup_handler (isStandalone, CMD.sciP);
 229      revert cleanup;                                        /* CMD.sciP is null beyond this point.                    */
 230 
 231 
 232 /* ----------------------------------------------------------------------
 233     Create the interactive subsystem invocation now.
 234 
 235     NOTE: When ssu_$create_invocation returns, any errors
 236           must be reported via using build_data.sciP.
 237  * ---------------------------------------------------------------------- */
 238 
 239      on cleanup call SUBSYS_cleanup_handler (addr(build_data));
 240                                                             /* On-unit to cleanup the full ssu_ invocation.           */
 241 
 242      call ssu_$create_invocation (PROC, VERSION, addr(build_data),
 243           addr(mbuild_request_tables_$user_requests), no_info_directory,
 244           build_data.sciP, code);
 245      if code ^= 0 then goto ERROR;
 246 
 247 
 248 /* ----------------------------------------------------------------------
 249     Verify that all routines of mbuild have been compiled with latest
 250      version of the mbuild_data_ data structures.
 251  * ---------------------------------------------------------------------- */
 252 
 253      if ^mbuild_request_parms_(addr(build_data)) then goto EXIT;
 254 
 255 
 256 /* ----------------------------------------------------------------------
 257     Continue initializing build_data structure.
 258      - Done after creating subsystem, so any errors can be reported thru ssu_.
 259 
 260     B) Initialize build_data threads, etc.
 261  * ---------------------------------------------------------------------- */
 262 
 263      if  CMD.debugS  then                                   /* Turn on -debug option for this initialization and for  */
 264           build_data.switches.debugS = T;                   /*  later code.                                           */
 265 
 266      call mbuild_data_$initialize_build_lists (addr(build_data));
 267 %page;
 268 
 269 /* ----------------------------------------------------------------------
 270     Use BUILD_SCRIPT argument to find:
 271                       build directory:  bld.directory
 272      build script segment in that dir:  bld.build_script_prefix
 273 
 274     See comment at end of the source titled:
 275       "Consider the following mbuild  BUILD SCRIPT (.mb seg)  USE CASES --"
 276     for a discussion of cases that need to be handled for this step.
 277  * ---------------------------------------------------------------------- */
 278 
 279   dcl  dirname char(168),
 280        entryname char(32);
 281 
 282   dcl  build_script_suffix char(20) var;
 283      build_script_suffix = mbuild_info_find_$suffix_for_build_type ("Build_script");
 284                                                             /* Suffix includes leading dot (e.g., .mb)                */
 285 
 286      if  CMD.build_script_dir ^= ""  then do;               /* Exact BUILD_SCRIPT arg stored in CMD.build_script_dir  */
 287           call expand_pathname_$add_suffix (CMD.build_script_dir, after(build_script_suffix, "."),
 288                dirname, entryname, code);                   /*  - split it into dirname and entryname portions        */
 289 
 290           if  code ^= 0  then                               /*     Diagnose any pathname construction errors.         */
 291                call ssu_$print_message (build_data.sciP, code, "BUILD_SCRIPT: ^a", CMD.build_script_dir);
 292           else do;                                          /*     Save split value in CMD structure.                 */
 293 
 294                if  uid_file(get_wdir_()) = uid_file(dirname)  then
 295                     dirname = "";                           /* Does dir part of BUILD_SCRIPT identify working dir?    */
 296                                                             /*  Yes: store "" as dirname.                             */
 297                CMD.build_script_dir = dirname;
 298                CMD.build_script_ent = entryname;
 299                end;
 300           end;
 301 
 302 
 303      if  CMD.build_script_dir = ""  then                    /* Get shortest path for build directory...               */
 304           build_data.directory = get_shortest_path_ (get_wdir_());
 305                                                             /*   It is usually the working directory                  */
 306      else build_data.directory = get_shortest_path_ (CMD.build_script_dir);
 307                                                             /*   unless BUILD_SCRIPT_PATH included absolute or        */
 308                                                             /*   relative directory portion.                          */
 309 
 310 
 311   dcl  build_scripts (5) char(32),                          /* possible build script segments found in build dir.     */
 312        build_scriptsN fixed bin;                            /* count of build script segments found in build dir.     */
 313   dcl (script_foundS, script_needs_updateS) bit(1) aligned;
 314   dcl  star_type fixed bin(2);
 315   dcl  yesS bit(1) aligned;
 316 
 317      script_foundS = F;
 318      if  CMD.build_script_ent = ""  then do;                /* Most usual case:  no BUILD_SCRIPT arg given            */
 319 
 320           call mbuild_scan_$segs_matching_starname( addr(build_data), "*.**" || build_script_suffix,
 321                build_scripts, build_scriptsN );             /*  - search for build script segs in build directory.    */
 322 
 323           if       build_scriptsN = 1  then do;             /*    If only 1 .mb was found, that's our build script.   */
 324                build_data.build_script_prefix = before( build_scripts(1), build_script_suffix );
 325                call ioa_( "^/Build script segment:^23t ^a", build_scripts(1) );
 326                script_foundS = T;
 327                end;
 328 
 329           else if  build_scriptsN = 0  then do;             /*    If none were found, ask user to supply a name.      */
 330                call ssu_$print_message( build_data.sciP, mbuild_et_$no_build_script,
 331                     " ^a^/  Please name the build script using:  mbuild BUILD_SCRIPT",
 332                     build_data.directory );
 333                goto EXIT;
 334                end;
 335 
 336           else do;                                          /*    If more than one found, ask user to choose one.     */
 337                call ssu_$print_message( build_data.sciP, mbuild_et_$many_build_scripts, " ^a", build_data.directory );
 338                call mbuild_$request( build_data.sciP, "list ^a>*.**^a -name -dtcm", F,
 339                     build_data.directory, build_script_suffix );
 340                call ioa_( "  Please select the build script using:  mbuild BUILD_SCRIPT" );
 341                goto EXIT;
 342                end;
 343           end;
 344 
 345      else do;                                               /* BUILD_SCRIPT arg given.  Is it a starname?             */
 346                                                             /*   How many potential build script segs does it match?  */
 347 
 348           call mbuild_scan_$segs_matching_starname( addr(build_data), CMD.build_script_ent,
 349                build_scripts, build_scriptsN );             /*  - check existence of 1 build script seg in build dir. */
 350 
 351           if       build_scriptsN = 1  then do;             /*    If only 1 .mb is found, that's our build script     */
 352                                                             /*    and it exists.                                      */
 353                build_data.build_script_prefix = before( build_scripts(1), build_script_suffix );
 354                call ioa_( "^/Build script segment:^23t ^a", build_scripts(1) );
 355                script_foundS = T;
 356                end;
 357 
 358           else if  build_scriptsN = 0  then do;             /*    No matching .mb found, then we must create it.      */
 359 
 360                call check_star_name_( CMD.build_script_ent, CHECK_STAR_ENTRY_DEFAULT | CHECK_STAR_REJECT_WILD,
 361                     star_type, code);
 362                if  star_type ^= STAR_TYPE_USE_PL1_COMPARE   /*     - If our name is a starname, we cannot use that    */
 363                 |  code = error_table_$nostars  then do;    /*       name to create a file.                           */
 364                     call ssu_$print_message( build_data.sciP, 0,
 365                          "^a^/  Please give a build script to be created using:  mbuild BUILD_SCRIPT"
 366                         || "^/  where BUILD_SCRIPT gives a non-starname.", build_data.directory );
 367                     goto EXIT;
 368                     end;
 369                                                             /*     - Ask user if we should create this file.          */
 370                                                             /*       He may expect it exists, and will instead        */
 371                                                             /*       correct typo in the given entry name, etc.       */
 372                build_data.build_script_prefix = before( CMD.build_script_ent, build_script_suffix );
 373                call command_query_$yes_no( yesS, error_table_$noentry, PROC,
 374                     "Answer ""no"" to exit mbuild if you expected ^a>^a^a to exist.",
 375                     "Should mbuild create the build script segment: ^a>^a^a ?",
 376                     build_data.directory,
 377                     build_data.build_script_prefix, build_script_suffix);
 378                if  ^yesS  then
 379                     goto EXIT;
 380                call ioa_( "^/Build script segment:^23t ^a^a (being created)",
 381                     build_data.build_script_prefix, build_script_suffix);
 382                end;
 383 
 384           else do;                                          /*    If more than one found, ask user to choose one.     */
 385                call ssu_$print_message( build_data.sciP, mbuild_et_$many_build_scripts, "^a", build_data.directory );
 386                call mbuild_$request( build_data.sciP, "list ^a>^a -name -dtcm", F, build_data.directory, CMD.build_script_ent );
 387                call ioa_( "^/  Please select the build script using:  mbuild BUILD_SCRIPT_PATH" );
 388                goto EXIT;
 389                end;
 390           end;
 391 
 392 
 393      if  CMD.build_script_dir ^= ""  then do;               /* Must cwd to given build directory; use cleanup on-unit */
 394                                                             /*  to return back to current dir when EXITing mbuild.    */
 395           build_data.mbuild_cleanup.original_wdir = get_wdir_();
 396 
 397           call change_wdir_( build_data.directory, code);
 398           if  code ^= 0  then do;
 399                call ssu_$print_message( build_data.sciP, code, "Failed to cwd to the build directory: ^a", build_data.directory );
 400                goto EXIT;
 401                end;
 402           end;
 403 
 404      call ioa_ ("Build directory:^23t ^a", build_data.directory);
 405                                                             /* Confirm location of build directory to user.           */
 406 
 407 
 408 /* ----------------------------------------------------------------------
 409     Finish initializing build_data structure.
 410 
 411     C) Read sections of build script:  Description --
 412                                        Information --
 413                                        Status --
 414        Convert old-style script to new format, if needed.
 415 
 416     D) Apply mbuild -control_args to:  Information --  section
 417          -phase  -set_log_dir  -approve  -install
 418        Apply default to CMD.scan_read if not set.
 419 
 420     E) If build script was found, and specified a library descriptor
 421        other than the process' current descriptor, change the descriptor
 422        now, remembering path of current descriptor to be restored when
 423        mbuild exits.
 424 
 425     F) If build script was not found, create it.
 426 
 427     G) Setup build monitor_ subsystem: build script, working dir,
 428                                        library descriptor,
 429                                        translator search paths
 430  * ---------------------------------------------------------------------- */
 431 
 432   dcl  script_changesL fixed bin(21);
 433   dcl  tI fixed bin;
 434   dcl  current_lib_descriptor char(168);
 435 
 436      if  ^script_foundS  then do;
 437           if  CMD.phase ^= ""  then do;
 438                call ioa_( "" );
 439                call ssu_$print_message( build_data.sciP, mbuild_et_$no_build_script,
 440                     "^/^- Cannot change phase before build script has been created: -^a", CMD.phase );
 441                goto EXIT;
 442                end;
 443           end;
 444 
 445      else do;
 446           call mbuild_script_$read_all_sections_but_changes( build_data.sciP, addr(build_data),
 447                script_foundS, script_needs_updateS, script_changesL, code );
 448           if  code ^= 0  then                               /* mbuild_script_ already displayed error msgs.  But      */
 449                goto EXIT;                                   /*  any nonzero code is a fatal error.                    */
 450           end;
 451 
 452      if  script_foundS  &  script_needs_updateS  then do;   /* If old-style build script, convert it before           */
 453                                                             /*   any updating just below.                             */
 454           call mbuild_$banner (build_data.sciP, "^2/mbuild(save): now converting ^a^a to new format.", T,
 455                build_data.build_script_prefix, build_script_suffix);
 456           call mbuild_$request( build_data.sciP, "save", F );
 457           script_needs_updateS = F;
 458           end;
 459 
 460 
 461      if  CMD.log_dir ^= ""  then do;                        /* -set_log_dir                                           */
 462           build_data.script_info.log_dir = CMD.log_dir;
 463           script_needs_updateS = T;
 464           end;
 465 
 466      if  script_foundS  then do;                            /* Check whether the process' current library descriptor  */
 467                                                             /*  differs from descriptor specified in build script.    */
 468           current_lib_descriptor = mbuild_library_$get_descriptor_path();
 469           if  uid_file( (build_data.script_info.descriptor) ) ^= uid_file( current_lib_descriptor )  then do;
 470                build_data.mbuild_cleanup.original_descriptor = current_lib_descriptor;
 471 
 472                call lib_descriptor_$set_name( build_data.script_info.descriptor, code );
 473                if  code ^= 0  then do;
 474                     call ssu_$print_message( build_data.sciP, code, "Failed to change to library descriptor: ^a",
 475                          build_data.script_info.descriptor );
 476                     goto EXIT;
 477                     end;
 478                call ioa_ ("Library descriptor:^23t ^a", build_data.script_info.descriptor );
 479                end;
 480           end;
 481 
 482 
 483      if  CMD.phase ^= ""                                    /* Set Phase, Approve_ID & Install_ID from any -ctl_args  */
 484       |  CMD.Install_ID ^= ""
 485       |  CMD.Approve_ID ^= ""  then do;
 486 
 487           if  CMD.phase = ""  then                          /* Use current Phase value if no Phase -ctl_arg given.    */
 488                CMD.phase =  build_data.script_info.phase;
 489 
 490   dcl  Approve_ID_count fixed bin,
 491        Approve_ID (1) char(32) var;
 492   dcl  set_performedS bit(1) aligned;
 493 
 494           if  CMD.Approve_ID = ""  then do;                 /* mbuild command only supports one new Approve_ID, but   */
 495                Approve_ID_count = 0;                        /*  mbuild_set_$set_phase supports an array of IDs.       */
 496                Approve_ID(1) = "";                          /*  Convert our possible scalar ID to a 1-element array.  */
 497                end;
 498           else do;
 499                Approve_ID_count = 1;
 500                Approve_ID(1) = CMD.Approve_ID;
 501                end;
 502 
 503           set_performedS =
 504                mbuild_set_$store_phase( addr(build_data), "mbuild", (CMD.phase),
 505                                         Approve_ID_count, Approve_ID, CMD.Install_ID );
 506                                                             /* This function updates Phase, Approve_ID & Install_ID   */
 507                                                             /*  & appends an add-on line to  Description --  section  */
 508                                                             /*  IFF   Phase = "installing".                           */
 509 
 510           if  set_performedS  then                          /* mbuild_set_ does a save request if it succeeds.        */
 511                script_needs_updateS = F;
 512           else  goto EXIT;                                  /* If function fails, it diagnoses error.                 */
 513           end;
 514 
 515 
 516      if  ^script_foundS  |  script_needs_updateS  then      /*  Create new build script, or save any changes to       */
 517                                                             /*   existing build script.                               */
 518           call mbuild_$request( build_data.sciP, "save", F );
 519 
 520 
 521                                                             /* Now that any -phase  value has been set...             */
 522      if  CMD.scan_read = "dft"  then                        /*  Set default for -scan_read, -scan, -no_scan and       */
 523                                                             /*                  -read_analyze                         */
 524           if  build_data.script_info.phase = "developing"  then
 525                CMD.scan_read = "scrd";
 526           else CMD.scan_read = "rdaz";
 527 
 528 
 529 
 530      if  CMD.request_loopS  then do;                        /* If entering mbuild subsystem, setup monitor.           */
 531           call mbuild_monitor_$setup( build_data.sciP,
 532                rtrim(build_data.directory) || ">" || build_data.build_script_prefix || build_script_suffix,
 533                script_changesL, "translator",
 534                mbuild_wdir_did_change, mbuild_lib_desc_did_change, mbuild_script_did_change,
 535                code );                                      /*  Monitoring enabled; begins when request loop starts.  */
 536           if  code ^= 0  then                               /*   - Any error was reported by $setup subsystem.        */
 537                goto EXIT;
 538           end;
 539 
 540 
 541 /* ----------------------------------------------------------------------
 542     Apply -control_args affecting ssu_ settings.
 543      -prompt
 544      -abbrev
 545      -request REQUEST_LINE
 546      -no_request_loop
 547  * ---------------------------------------------------------------------- */
 548 
 549      if  ^CMD.promptS  then
 550           call ssu_$set_prompt_mode (build_data.sciP, DONT_PROMPT);
 551      else if CMD.prompt ^= "" then
 552           call ssu_$set_prompt (build_data.sciP, CMD.prompt);
 553 
 554      if  CMD.abbrevS  then do;
 555           call mbuild_$request (build_data.sciP, "abbrev -on", F);
 556           if  CMD.abbrev_profile ^= ""  then
 557                call mbuild_$request (build_data.sciP, ".use ^a", F, CMD.abbrev_profile);
 558           end;                                              /* This method asks to create new profile, if not found   */
 559 
 560      if CMD.request_lineL > 0  &  CMD.request_lineP ^= null()  then do;
 561           call ssu_$execute_line (build_data.sciP, CMD.request_lineP, CMD.request_lineL, code);
 562           if code ^= 0 then
 563                call ssu_$print_message (build_data.sciP, code, "Executing request line: ^a",
 564                     request_line);
 565           end;
 566 
 567      if ^CMD.request_loopS then goto EXIT;
 568 
 569 
 570 /* ----------------------------------------------------------------------
 571     Do mbuild setup commands requested by user, or default for current phase.
 572  * ---------------------------------------------------------------------- */
 573 
 574      if  CMD.scan_read = "scrd" then do;
 575           call ioa_( "^/^- Scanning build directory, with read of any build_script...^/" );
 576           call mbuild_$request( build_data.sciP, "scan", F );
 577           end;
 578 
 579      else if  CMD.scan_read = "rdaz" then do;
 580           call ioa_( "^/^- Reading and analyzing the build script...^/" );
 581           call mbuild_$request( build_data.sciP,
 582                "read -no_print; analyze; print -new; print -desc -changes -info -status", F );
 583           end;
 584 
 585      else if  CMD.scan_read = "scan" then do;
 586           call ioa_ ("^/^- Scanning build directory...^/");
 587           call mbuild_$request (build_data.sciP, "scan -no_query", F);
 588           end;
 589 
 590      else call ioa_ ("");
 591 
 592      if  CMD.scan_read = "scan"  |  CMD.scan_read = ""  then
 593      if  mbuild_set_$description_stored( addr(build_data) )  then do;
 594           call mbuild_$request (build_data.sciP, "^2/print -desc -info -status", T);
 595           end;
 596 
 597 
 598 /* ----------------------------------------------------------------------
 599     Enter ssu_ request loop.
 600  * ---------------------------------------------------------------------- */
 601 
 602 LISTEN:
 603      call ssu_$listen (build_data.sciP, iox_$user_input, code);
 604      if code ^= ssu_et_$subsystem_aborted then              /* ssu_$listen returns when user issue quit request, or   */
 605           goto ERROR;                                       /*  if a serious error is reported.                       */
 606 
 607 
 608 /* ----------------------------------------------------------------------
 609     Normal exit from the subsystem.
 610  * ---------------------------------------------------------------------- */
 611 
 612 EXIT:
 613      call standalone_cleanup_handler (isStandalone, CMD.sciP);
 614      call SUBSYS_cleanup_handler (addr(build_data));
 615      return;                                                /* Normal return point.                                   */
 616 
 617 
 618 ERROR:                                                      /* Error exit from subsystem.                             */
 619      call com_err_ (code, PROC);                            /*  - Report error entering/exiting ssu_ subsystem.       */
 620      goto EXIT;
 621 %page;
 622 /* ----------------------------------------------------------------------
 623     cleanup on-unit for subsystem invocation.
 624  * ---------------------------------------------------------------------- */
 625 
 626 SUBSYS_cleanup_handler:
 627      proc (Abuild_dataP);
 628 
 629   dcl  Abuild_dataP ptr,
 630       1 bld aligned like build_data based (Abuild_dataP);
 631 
 632      if  string(bld.mbuild_cleanup) ^= ""  then  call ioa_( "" );
 633 
 634      if  bld.mbuild_cleanup.original_wdir ^= ""  then do;   /* Return to user's working directory.                    */
 635           call change_wdir_( bld.mbuild_cleanup.original_wdir, code );
 636           call ssu_$print_message( bld.sciP, 0, "Returning to working directory: ^a",
 637                bld.mbuild_cleanup.original_wdir );
 638           bld.mbuild_cleanup.original_wdir = "";
 639           end;
 640 
 641      if  bld.mbuild_cleanup.original_descriptor ^= ""  then do;
 642                                                             /* Return process to original library descriptor.         */
 643           call lib_descriptor_$set_name( rtrim(build_data.mbuild_cleanup.original_descriptor), code );
 644           call ssu_$print_message( build_data.sciP, code, "Returning to library descriptor: ^a",
 645                build_data.mbuild_cleanup.original_descriptor );
 646           end;
 647 
 648      if bld.areaP ^= null then                              /* release area temp segments.                            */
 649           call translator_temp_$release_all_segments (bld.areaP, code);
 650 
 651      if bld.sciP ^= null then                               /* if there is an ssu_ invocation                         */
 652           call ssu_$destroy_invocation (bld.sciP);
 653 
 654      end SUBSYS_cleanup_handler;
 655 %page;
 656           /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
 657           /*                                                                                                */
 658           /*        C O - R O U T I N E S   for the  mbuild_monitor_ Subsystem                              */
 659           /*                                                                                                */
 660           /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
 661 
 662   dcl (DECISION_MONITOR_OLD_DATA init(1),                   /* decision constants                                     */
 663        DECISION_MONITOR_NEW_DATA init(2)
 664        ) fixed bin int static options(constant);
 665 
 666 
 667 mbuild_wdir_did_change:                                     /* Ensure mbuild always working in the build directory.   */
 668      proc( AsciP, Abuild_dataP, Apath_old, Apath_new, Adecision);
 669 
 670   dcl  AsciP ptr;                                           /* pointer to ssu_ invocation structure              (In) */
 671   dcl  Abuild_dataP ptr;                                    /* pointer to mbuild's build_data (bld) structure.   (In) */
 672   dcl  Apath_old char(168);                                 /* expected wdir (the build directory)               (In) */
 673   dcl  Apath_new char(168);                                 /* current  wdir  (got there via non-mbuild cmds)    (In) */
 674   dcl  Adecision fixed bin;                                 /* tell monitor: keep new vs. return to old  wdir   (Out) */
 675 
 676   dcl 1 bld aligned like build_data based(Abuild_dataP);
 677 
 678      call ioa_( "^/mbuild monitor: build resumes back in working directory: ^a^/", Apath_old );
 679      Adecision = DECISION_MONITOR_OLD_DATA;                 /* tell monitor of this action.                           */
 680 
 681      end mbuild_wdir_did_change;
 682 
 683 
 684 mbuild_lib_desc_did_change:                                 /* Ask user if really intends to change lib descriptor.   */
 685                                                             /*  required for this build change set.                   */
 686      proc( AsciP, Abuild_dataP, Apath_old, Apath_new, Adecision);
 687                                                             /*  If yes, warns of resetting all progress, so build     */
 688                                                             /*  must then restart from scan and/or read request.      */
 689 
 690   dcl  AsciP ptr;                                           /* pointer to ssu_ invocation structure              (In) */
 691   dcl  Abuild_dataP ptr;                                    /* pointer to mbuild's build_data (bld) structure.   (In) */
 692   dcl  Apath_old char(168);                                 /* expected library descriptor for build             (In) */
 693   dcl  Apath_new char(168);                                 /* current  library descriptor                       (In) */
 694   dcl  Adecision fixed bin;                                 /* tell monitor: keep new vs. return to old  descr  (Out) */
 695 
 696   dcl 1 bld aligned like build_data based(Abuild_dataP);
 697 
 698   dcl  PROC char(26) int static options(constant) init("mbuild_lib_desc_did_change");
 699 
 700   dcl  code_ignored fixed bin(35);
 701   dcl  yesS bit(1) aligned;
 702 
 703      call ioa_( "^/mbuild monitor: Build has set segment attributes (containing library, bound object, etc.)"
 704             ||  "^/    using information from library descriptor: ^a"
 705             ||  "^/  but process is now using library descriptor: ^a", Apath_old, Apath_new );
 706 
 707      call command_query_$yes_no (yesS, 0, PROC,
 708           "Do you want to restart build steps using the new library descriptor?",
 709           "Do you want to restart build steps using the new library descriptor?" );
 710 
 711      if  yesS  then do;                                     /* Use the new library descriptor...                      */
 712           string(bld_progress) = mbuild_data_$get_build_progress( addr(bld) );
 713           if  bld_progress.analyzedS  then                  /*  - Don't force an analyze request now, but do clean if */
 714                                                             /*    analyze has been done.                              */
 715                call mbuild_$request( AsciP, "^2/clean -all", T );
 716                                                             /*  - Delete all derived objects.                         */
 717 
 718           call mbuild_data_$initialize_build_lists( addr(bld) );
 719                                                             /*  - Reset mbuild internal Seg data as if mbuild just    */
 720                                                             /*    invoked.                                            */
 721 
 722           bld.script_info.descriptor = rtrim(Apath_new);
 723           call mbuild_$request( AsciP, "save", F );         /* Save changed descriptor path in build script.          */
 724 
 725           call ioa_( "^/^a: Please begin the build again with a scan and/or read request.^/", PROC );
 726           Adecision = DECISION_MONITOR_NEW_DATA;            /*  - Monitor new lib descriptor after future requests.   */
 727           end;
 728 
 729      else do;                                               /* Return back to original library descriptor...          */
 730           call ioa_( "    Resuming build using the original library descriptor.^/" );
 731           Adecision = DECISION_MONITOR_OLD_DATA;
 732           end;
 733 
 734      end mbuild_lib_desc_did_change;
 735 
 736 
 737 mbuild_script_did_change:                                   /* Build script changed.  Check for changes in sections:  */
 738      proc( AsciP, Abuild_dataP, AchangesL_old, AchangesL_new,
 739            Adescriptor_path_new, Adecision);                /*   Description --  Information --  Status --            */
 740                                                             /* and tell monitor new length of section:  Changes --    */
 741                                                             /* to record for future monitoring.                       */
 742 
 743   dcl  AsciP ptr;                                           /* pointer to ssu_ invocation structure              (In) */
 744   dcl  Abuild_dataP ptr;                                    /* pointer to mbuild's build_data (bld) structure.   (In) */
 745   dcl  AchangesL_old fixed bin(21);                         /* previous length of  Changes --  section           (In) */
 746   dcl  AchangesL_new fixed bin(21);                         /* current  length of  Changes --  section          (Out) */
 747   dcl  Adescriptor_path_new char(168);                      /* new      library descriptor to monitor           (Out) */
 748   dcl  Adecision fixed bin;                                 /* tell monitor: keep new vs. return to old  descr  (Out) */
 749 
 750   dcl  code fixed bin(35);
 751 
 752   dcl 1 bld aligned like build_data based(Abuild_dataP);
 753 
 754   dcl  PROC char(24) int static options(constant) init( "mbuild_script_did_change" );
 755 
 756 
 757   dcl  descriptor_path_old char(168);                       /* previous library descriptor                            */
 758   dcl  descriptor_path_new char(168);                       /* current  library descriptor                            */
 759 
 760   dcl (script_foundS, script_needs_saveS) bit(1) aligned;
 761 
 762 
 763      descriptor_path_old = bld.script_info.descriptor;
 764 
 765      call mbuild_script_$read_all_sections_but_changes( AsciP, addr(bld),
 766           script_foundS, script_needs_saveS, AchangesL_new, code );
 767      if  code ^= 0  then do;
 768           call ioa_("");
 769           call ssu_$print_message( AsciP, code, "^a: build script monitor failed.", PROC );
 770           Adecision = DECISION_MONITOR_OLD_DATA;
 771           return;
 772           end;
 773 
 774      descriptor_path_new = bld.script_info.descriptor;
 775 
 776      Adecision = DECISION_MONITOR_NEW_DATA;
 777 
 778      if  AchangesL_old ^= AchangesL_new  then do;
 779           call ioa_("");
 780           call ssu_$print_message( AsciP, 0,
 781                "Changes --  section modified.  When ready to use revised data, please issue request:  read" );
 782           end;
 783 
 784 
 785   dcl (uid_old, uid_new) bit(36) aligned;
 786 
 787      uid_old = uid_file( descriptor_path_old );
 788      uid_new = uid_file( descriptor_path_new );
 789 
 790      if  uid_old ^= uid_new  then do;                       /* Descriptor property DID CHANGE                         */
 791           Adescriptor_path_new = descriptor_path_new;       /*  Then monitor the new path.                            */
 792 
 793           if  uid_file( (mbuild_library_$get_descriptor_path()) ) ^= uid_new  then do;
 794                                                             /* If    process' descriptor is NOT the new Descriptor    */
 795                call ioa_ ("^/Library descriptor:^23t ^a", descriptor_path_new );
 796                end;                                         /*  monitor_ will do switch to new process descriptor.    */
 797           end;
 798      else Adescriptor_path_new = descriptor_path_old;
 799 
 800      end mbuild_script_did_change;
 801 %page;
 802 /* ----------------------------------------------------------------------
 803     Process mbuild control args passed to the ssu_ standalone invocation.
 804  * ---------------------------------------------------------------------- */
 805 
 806 controlArgs:
 807      proc (aCMD);
 808 
 809   dcl 1 aCMD aligned like CMD;
 810 
 811   dcl  UNSET char(7) int static options(constant) init("(UNSET)");
 812   dcl  dirname char(168),
 813        entryname char(32);
 814   dcl  fatalS bit(1) aligned init(F);
 815 
 816      do while (args_remain());
 817           call ssu_$arg_ptr (aCMD.sciP, argI+1, argP, argL); /* Conditionally read next arg to command/af/request     */
 818 
 819           if isControlArg(arg) then do;
 820 
 821                if  aCMD.abbrev_profile = UNSET                      then aCMD.abbrev_profile = missing_operand( "-abbrev" );
 822                if  aCMD.log_dir        = UNSET                      then aCMD.log_dir        = missing_operand( "-set_log_dir" );
 823                if  aCMD.Approve_ID     = UNSET                      then aCMD.Approve_ID     = missing_operand( "-approve" );
 824                if  aCMD.Install_ID     = UNSET                      then aCMD.Install_ID     = missing_operand( "-install" );
 825 
 826                if       arg = "-dev"    | arg = "-developing"       then     aCMD.phase = "developing";
 827                else if  arg = "-aud"    | arg = "-auditing"         then     aCMD.phase = "auditing";
 828                else if  arg = "-inst"   | arg = "-installing"       then     aCMD.phase = "installing";
 829 
 830 
 831                else if  arg = "-nsc"    | arg = "-no_scan"          then     CMD.scan_read = "";
 832                else if  arg = "-rdaz"   | arg = "-read_analyze"     then     CMD.scan_read = "rdaz";
 833                else if  arg = "-sc"     | arg = "-scan"             then     CMD.scan_read = "scan";
 834                else if  arg = "-scrd"   | arg = "-scan_read"        then     CMD.scan_read = "scrd";
 835 
 836 
 837                else if  arg = "-apv"    | arg = "-approve"          then     aCMD.Approve_ID = UNSET;
 838                else if  arg = "-in"     | arg = "-install"          then     aCMD.Install_ID = UNSET;
 839 
 840 
 841                else if  arg = "-sld"    | arg = "-set_log_dir"      then     aCMD.log_dir = UNSET;
 842                else if  arg = "-db"     | arg = "-debug"            then     aCMD.debugS = T;
 843 
 844 
 845 
 846                else if  arg = "-rq"     | arg = "-request"          then     aCMD.request_lineL = -1;
 847                else if  arg = "-rql"    | arg = "-request_loop"     then     aCMD.request_loopS = T;
 848                else if  arg = "-nrql"   | arg = "-no_request_loop"  then     aCMD.request_loopS = F;
 849 
 850 
 851                else if  arg = "-ab"     | arg = "-abbrev"           then     aCMD.abbrevS = T;
 852                else if  arg = "-pf"     | arg = "-profile"          then do; aCMD.abbrevS = T;
 853                                                                              aCMD.abbrev_profile = UNSET;
 854                                                                              end;
 855                else if  arg = "-nab"    | arg = "-no_abbrev"        then     aCMD.abbrevS = F;
 856 
 857                else if  arg = "-pmt"    | arg = "-prompt"           then do; CMD.prompt = UNSET;
 858                                                                              CMD.promptS = T;
 859                                                                              end;
 860                else if  arg = "-npmt"   | arg = "-no_prompt"        then do; CMD.prompt = "";
 861                                                                              CMD.promptS = F;
 862                                                                              end;
 863 
 864                else do;
 865                     call ssu_$print_message (aCMD.sciP, error_table_$badopt,
 866                          " Unsupported control arg: ^a", arg);
 867                     fatalS = T;
 868                     end;
 869                end;
 870 
 871 
 872           else if  aCMD.Approve_ID = UNSET  then do;
 873                if  ^approve_ID()  then do;
 874                     call ssu_$print_message ( aCMD.sciP, error_table_$badopt, " -approve ^a^/^- ^a",
 875                          arg, valid_Approve_ID );
 876                     aCMD.Approve_ID = "";
 877                     fatalS = T;
 878                     end;
 879                else aCMD.Approve_ID = arg;
 880                end;
 881 
 882           else if  aCMD.Install_ID = UNSET  then do;
 883                if  ^install_ID()  then do;
 884                     call ssu_$print_message (aCMD.sciP, error_table_$badopt, " -install ^a^/^- ^a",
 885                          arg, valid_Install_ID);
 886                     aCMD.Install_ID = "";
 887                     fatalS = T;
 888                     end;
 889                else aCMD.Install_ID = arg;
 890                end;
 891 
 892 
 893           else if  aCMD.promptS & aCMD.prompt = UNSET  then
 894                aCMD.prompt = arg;
 895 
 896           else if  aCMD.request_lineL = -1  then do;
 897                aCMD.request_lineP = addr(arg);
 898                aCMD.request_lineL = length(arg);
 899                end;
 900 
 901           else if  aCMD.log_dir = UNSET  then do;
 902                call expand_pathname_ (arg, dirname, entryname, code);
 903                if  code ^= 0  then do;
 904                     call ssu_$print_message (aCMD.sciP, code, " -set_log_dir ^a", arg);
 905                     fatalS = T;
 906                     end;
 907                else aCMD.log_dir = pathname_ (dirname, entryname);
 908                end;
 909 
 910           else if  aCMD.abbrevS & aCMD.abbrev_profile = UNSET  then
 911                aCMD.abbrev_profile = arg;
 912 
 913 
 914           else if  aCMD.build_script_dir = ""  then         /* Capture just the raw argument.                         */
 915                aCMD.build_script_dir = arg;
 916 
 917 
 918           else do;                                          /* If arg not a -control_arg                              */
 919                call ssu_$print_message (aCMD.sciP, error_table_$badopt,
 920                     " Unsupported argument: ^a", arg);
 921                fatalS = T;
 922                end;
 923 
 924           argI = argI + 1;                                  /* Record that we processed the arg just examined above.  */
 925           end;
 926 
 927      if  aCMD.request_lineL  = -1     then aCMD.request_lineL = 0;
 928 
 929      if  aCMD.abbrev_profile = UNSET  then aCMD.abbrev_profile = missing_operand( "-abbrev" );
 930      if  aCMD.log_dir        = UNSET  then aCMD.log_dir        = missing_operand( "-set_log_dir" );
 931      if  aCMD.Approve_ID     = UNSET  then aCMD.Approve_ID     = missing_operand( "-approve" );
 932      if  aCMD.Install_ID     = UNSET  then aCMD.Install_ID     = missing_operand( "-install" );
 933 
 934      if  fatalS  then
 935           call ssu_$abort_subsystem( aCMD.sciP, mbuild_et_$argument_error );
 936 
 937      return;
 938 %page;
 939 missing_operand:
 940      proc(control_arg) returns (char(1) var);
 941 
 942   dcl  control_arg char(*);
 943 
 944      call ssu_$print_message( aCMD.sciP, mbuild_et_$no_operand, " ^a", control_arg );
 945      fatalS = T;
 946      return ( "" );
 947 
 948      end missing_operand;
 949 
 950      end controlArgs;
 951 
 952 
 953 
 954   dcl  token_value char(argL) based(argP);                  /* overlay for ssu_$arg_ptr arg variable.  The overlay    */
 955                                                             /*  is used by the  approve_ID()  install_ID()  phase()   */
 956                                                             /*  and  user_ID()  functions which are declared below    */
 957                                                             /*  in mbuild_script_info_attr.incl.pl1  file.            */
 958 
 959 %include mbuild_script_info_attr;
 960 
 961 %page;
 962           /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
 963           /*                                                                                                */
 964           /*                  S U P P O R T     R O U T I N E S                                             */
 965           /*                                                                                                */
 966           /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
 967 
 968 uid_file: proc (path) returns (bit(36) aligned);
 969 
 970   dcl  path char(*);
 971   dcl  uid bit(36) aligned;
 972   dcl  code fixed bin(35);
 973 
 974      call hcs_$get_uid_file( path, "", uid, code );
 975      if  code = 0  then
 976           return ( uid );
 977      else return ( ""b );
 978 
 979      end uid_file;
 980 %page;
 981 %include ssu_standalone_command_;
 982 %include ssu_prompt_modes;
 983 %page;
 984 %include mbuild_Tlist_dcls_;
 985 %page;
 986 %include mbuild_data_;
 987 %page;
 988 %include check_star_name;
 989 %page;
 990 %include sl_info;
 991 %page;
 992 /* ----------------------------------------------------------------------------------------------------
 993 
 994 OVERVIEW of the AUTOMATION embodied in the mbuild SUBSYSTEM.
 995 
 996 
 997 Consider the following mbuild  BUILD SCRIPT (.mb seg)  USE CASES --
 998 
 999 * When mbuild is invoked, how it responds:
1000 
1001   CASE:  User issues command:  mbuild
1002     - mbuild:
1003       - finds no .mb segment in working dir
1004         - prompts for name of .mb segment
1005         - sets: bld.build_script_prefix to entryname given in response
1006         - issues: read -description -information -status
1007         - creates: build script segment with that name,
1008                    phase = developing, and empty  Changes --  section.
1009         - since default is script_info.phase = developing
1010           THEN issues request:  scan
1011 
1012       OR IF mbuild:
1013       - finds one .mb segment in working dir
1014         - issues: read -desc -info -status
1015         - if script_info.phase = developing
1016           THEN issues request: scan
1017           ELSE (for script_info.phase = auditing or installing)
1018                issues request: read; analyze
1019 
1020       OR IF mbuild:
1021       - finds several .mb segments in working dir
1022         - exits mbuild with error: listing those .mb segments, and
1023                                    asking user to select one script
1024                                    using command:  mbuild BUILD_SCRIPT_NAME
1025 
1026 
1027   CASE:  User issues command:  mbuild BUILD_SCRIPT_NAME
1028     - mbuild checks:
1029       - if [directory BUILD_SCRIPT_NAME] ^= [wd]
1030         THEN  mbuild temporarily cd's to [directory BUILD_SCRIPT_NAME]
1031               with cleanup on-unit to return to original working_dir.
1032       - if [entry BUILD_SCRIPT_NAME] exists in [wd]
1033         THEN mbuild:
1034               - sets: bld.build_script_prefix to entryname of BUILD_SCRIPT_NAME
1035               - issues request:  read -desc -info -status
1036               - if script_info.phase = developing
1037                 THEN issues request: scan
1038                 ELSE (for script_info.phase = auditing or installing)
1039                      issues request: read; analyze
1040         ELSE mbuild:
1041              - issues request:  save
1042                which creates build script with default info:
1043                  Description --  description_instructions
1044                  Changes --      empty
1045                  Information --  default values for every field
1046                  Status --       status_instructions || status_template
1047             - since script_info.phase = developing
1048               issues request: scan
1049 
1050   The above cases imply: .mb seg always exists in build directory,
1051                          always has all 4 sections, though some are blank.
1052                          Any old-style build script segment is converted
1053                          to new format before first mbuild prompts user
1054                          for first interactive request line.
1055 
1056 
1057 * When running in mbuild subsystem, how it auto-updates build script:
1058 
1059   CASE:  Modification of .mb segment outside of mbuild (via emacs, etc)
1060     From inside mbuild subsystem, user edits .mb segment (to supply Description or Status data)
1061       - with request: ..emacs *.mb
1062 
1063     Upon return to the mbuild request loop, ssu_ invokes mbuild_monitor_$watch.
1064     $watch:
1065       - sees change in .mb date-time-contents-modified (dtcm) attribute.
1066       - issues request with banner:  read -descriptor -information -status -no_print
1067         - mbuild's internal knowledge of data in these sections is auto-updated.
1068         - mbuild does NOT do: read -changes
1069           since data in  Changes --  section can disrupt build steps
1070           the user might have been issuing before escaping out of mbuild
1071           to edit the build script.  The user can issue scan or read, followed by
1072           analyze if/when rereading any edited  Changes --  statements is needed.
1073 
1074 
1075   CASE:  Modification of current library descriptor (inside/outside of mbuild)
1076     From inside mbuild subsystem, user changes default library descriptor
1077      (to examine data in another library, etc.)
1078      - with request: ..lds set DESCRIPTOR
1079      - with request: lds set DESCRIPTOR
1080 
1081     Upon return to the mbuild request loop, ssu_ invokes mbuild_monitor_$watch.
1082     $watch:
1083       - calls lib_descriptor_$name to get name of default library descriptor
1084         (mbuild uses only the default library descriptor for its library searches).
1085       - gets ptr to that library descriptor
1086       - compares that ptr to value saved by mbuild_script_monitor_ when mbuild was started.
1087       - if pointers differ:
1088         - changes mbuild_script_monitor_'s ptr to the current library descriptor.
1089         - calls mbuild_set_$library_descriptor to save pathname of current descriptor.
1090           - mbuild_set_$library_descriptor
1091             - gets pathname associated with current descriptor
1092             - stores pathname in structure:  bld.script_info -> script_info.descriptor
1093             - to update .mb seg, issues request:  save -info
1094         - calls mbuild_data_$initialize_build_lists to forget all knowledge gained
1095           from prior library descriptor.  This resets all build progress, forcing
1096           mbuild_data_$get_build_progress to recompute actual progress by examining
1097           presence of derived objects in build directory, etc.
1098         - notifies user that mbuild is now using a different library descriptor,
1099           giving name of the new descriptor, and suggesting need to run default
1100           requests appropriate for current phase:
1101             for phase = developing:  scan; read; analyze
1102             for phase = (other):     read; analyze
1103 
1104 
1105   CASE:  Change working_directory while inside mbuild subsystem.
1106     Expectation: mbuild depends on working_dir always being set to the build directory.)
1107       From inside mbuild subsystem, user escape to external command or editor.
1108       For simplicity, assume user issues the request:  .. change_wdir <
1109     Upon return to the mbuild request loop, ssu_ invokes mbuild_monitor_$watch.
1110     $watch:
1111       - call get_wdir_, using that pathname to call hcs_$get_uid_file.
1112       - compares dir uid to that saved when mbuild was invoked in the build directory.
1113         - if uid's differ, mbuild:
1114           - change_wdir_ back to the build directory, reporting change to user.
1115 
1116 
1117   CASE:  User adds  Description --  or  Status --  section line(s)
1118     User issues one of requests:  set -desc {-no_print}
1119                                   add -desc {-no_print}
1120                                   set -status {-no_print}
1121                                   add -status {-no_print}
1122     - mbuild set/add request:
1123       - prompts user to input the new lines (up to 2000 chars of new data).
1124       - calls mbuild_set_$store_description or $store_status_text:
1125          - for add, passes:  current script_descrip.text, and the new lines read by the prompt.
1126          - for set, passes:  new lines read by the prompt.
1127       - issues request:  save
1128         - mbuild_script_$save:
1129           - saves all sections in existing .mb segment from mbuild internal data.
1130           - if  Changes --  section data has not be analyzed yet, that section
1131             of existing build script is preserved when build script is rewritten.
1132       unless -no_print option was given in set/add request:
1133         issues request:  print -desc  or  print -status
1134 
1135 
1136   CASE:  User sets/adds any attributes in Information section.
1137          NOTE: case above covers request: lds set DESCRIPTOR
1138     User issues any of requests:
1139       set -phase NEW_PHASE
1140       set -log_dir DIRECTORY_PATH
1141       set -install INSTALL_ID
1142       set -approve MCRnnnnn ...                   add -approve MCRnnnnn ...
1143       set -developer PERSON_ID.PROJECT_ID ...     add -developer PERSON_ID.PROJECT_ID ...
1144       set -auditor PERSON_ID.PROJECT_ID ...       add -auditor PERSON_ID.PROJECT_ID ...
1145       set -installer PERSON_ID.PROJECT_ID ...     add -installer PERSON_ID.PROJECT_ID ...
1146     - mbuild_set_:
1147       - changes scalar value  in mbuild's internal data: bld->script_infoP -> script_info.XXX
1148       - sets/adds array value in mbuild's internal data: bld->script_infoP -> script_info.XXX(i)
1149         (array may have to be enlarged)
1150       - issues request: save
1151         - mbuild_script_$save:
1152           - saves all sections in existing .mb segment from mbuild internal data.
1153           - if  Changes --  section data has not be analyzed yet, that section
1154             of existing build script is preserved when build script is rewritten.
1155 
1156 
1157 * When user adds segs to build directory, possibly updating Changes portion of build script,
1158   then issues a major request to update mbuild's internal data:
1159    - either mbuild's scan and/or read requests
1160   These two requests override each other; the last one performed controls which data
1161   is fed to the analyze request.
1162 
1163   Most development efforts begin by assembling segments in a build directory, then
1164   using a scan request to compare each segment in the dir with a matching segment
1165   found in the current library descriptor.  scan thereby learns which segments
1166   REPLACE something found in the library, versus other segments being ADDed to the
1167   library.  scan uses these library search findings to guess about operation to be
1168   performed on each segment, exact bound object and library dir for REPLACEd Seg,
1169   and default compiler and options, etc.  Segments not matching an existing library
1170   source are guessed to be sources of an Unbound_obj in an UNKNOWN library directory.
1171 
1172   CASE:  User issues request:  scan
1173          scan looks solely at segments actually appearing in build directory.
1174 
1175     - mbuild_scan_$scan_request:
1176       - releases all internal data from  Changes --  section of build script.
1177       - scans current segments in build directory (as if mbuild was just invoked) and
1178         matches them with segments in the current library descriptor.  This scan makes
1179         guesses about the operation being performed on each segment.
1180       - places Seg structures on scan_Tb thread recording its findings.
1181          - Each Seg structure assigns the segment:
1182            - to REPLACE a source component in the archive of an existing bound segment; or
1183            - to REPLACE an existing stand-alone source, or info or include segment in
1184              the library, etc.
1185            If no match is found for the segment via the current library descriptor,
1186            it is treated:
1187            - as a stand-alone source/info/include segment, etc.
1188            - being ADDed to an UNKNOWN library directory.
1189 
1190 
1191   After analyze request is done on scan results, scan's guesses can be stored as initial
1192   content of  Changes --  section in build script segment.
1193 
1194   User can then edit that build script for correct mistaken guesses.  For example,
1195   scan's guess that a new segment is being ADDed as source for an Unbound_obj.  It
1196   might really be intended as a new component being ADDed to an existing bound segment.
1197   In such case, the Unbound_obj statement from scan's guess can be edited to be a
1198   Bound_obj statement describing the desired target bound segment, with the source
1199   statement being placed under that Bound_obj statement and its operation changed to ADD.
1200 
1201   When returning from editor, mbuild notes that build script has changed and automatically
1202   reads the  Description --  and  Information --  and  Status --  sections to learn about
1203   the developer's editing.  If length of the  Changes --  section has changed, it will
1204   warn the user to issue another  read  request to make any Build Script Language
1205   statement changes known to mbuild.
1206 
1207 
1208   CASE:  User issues request:  read
1209                           or:  read -changes
1210          read looks solely at segments named by Build Script Language statement in the
1211          Changes --  section of the build script.
1212 
1213     - mbuild_script_$read_request:
1214       - releases most internal data from  Changes --  section of build script
1215         (including the scan_Tb thread created by any prior scan request) but retains
1216         Segs on Segs_Tb thread describing segments found earlier that do match items
1217         in the current library descriptor.
1218       - reads Build Script Language statements from Changes section of build script,
1219         again matching segments described on each statement with segments found via
1220         current library descriptor (possibly via Seg structures created by prior scan
1221         which were retained on the SegTb thread).  Each statement gives details about:
1222          - action operation envisioned by developer for that segment;
1223          - changes to a segment's location within the library or within a bound segment;
1224          - compiler options defaults, etc.
1225         These specific details in Build Script Language statements of  Changes --  section
1226         replace (override) any guesses made by an earlier scan request.
1227       - places Seg structures on scan_Tb thread recording its findings.
1228 
1229 
1230   CASE:  After issuing scan and/or read request, user issues request:  analyze
1231     - mbuild_analyze_$analyze_request
1232       - Walks down list of Seg structures on the scan_Tb thread.
1233       - For each list item, determines build steps necessary to:
1234         - compile
1235         - archive and bind
1236         - install the original-content sources and appropriate derived objects via the
1237           current library descriptor into appropriate library directory.
1238       - Constructs COMPILE structure to supervise each needed compilation.
1239       - Constructs BOUNDOBJ structure to supervise each source/object archive operation,
1240         bind operation, and install of components of that bound segment.
1241       - Constructs UNBOUNDOBJ structure to supervise naming and install of compoents for
1242         each unbound segment.
1243       - Threads other original-content sources onto appropriate lists of items not requiring
1244         compile or bind, but needed install operations.
1245       - If no errors are found, analyze issues request:  save
1246 
1247    The relationship information constructed by analyze is needed to store proper Build Script
1248    Language statements in the  Changes --  section of the build script segment.  Therefore,
1249    the build script is not updated with final details by a save request until the  analyze
1250    request completes successfully.
1251 
1252 
1253    ---------------------------------------------------------------------------------------------------- */
1254      end mbuild;