1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1985 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 
 14 
 15 /****^  HISTORY COMMENTS:
 16   1) change(1986-03-05,LJAdams), approve(1986-03-05,MCR7327),
 17      audit(1986-03-10,Lippard), install(1986-04-24,MR12.0-1048):
 18      There are three main programs used in help they are: help, help_, and
 19      help_rql_.
 20 
 21      Some of the changes made include:
 22 
 23         restructuring the programs to  use line parsing
 24 
 25         change the help command to use ssu_$create_standalone_invocation, and
 26         to be callable as a request from within ssu_
 27 
 28         withdraw support of old format info segs (those containing "\006" as
 29         paragraph indicators)
 30 
 31         make help -bf always return some information
 32 
 33         allow "List of" sections to have multiple consecutive list item lines
 34         starting in the left margin.  Item descriptions are no longer required
 35         but if present, must be indented three spaces
 36   2) change(1987-04-27,LJAdams), approve(1987-09-03,MCR7766),
 37      audit(1988-08-07,GDixon), install(1988-09-13,MR12.2-1109):
 38      Changed version to Vhelp_args_3.
 39      Added support for -cs (case_sensitive) and -ncs (non_case_sensitive).
 40   3) change(1988-02-17,LJAdams), approve(1988-03-07,MCR7857),
 41      audit(1988-08-07,GDixon), install(1988-09-13,MR12.2-1109):
 42      The cleanup procedure was not deleting all the temporary segments.
 43      Changed cleanup to use the help_args.help_data_ptr which points to a
 44      second help_args structure that is used only for the list_request
 45      operation.
 46   4) change(2020-08-12,GDixon), approve(2021-02-23,MCR10089),
 47      audit(2021-03-31,Swenson), install(2021-03-31,MR12.6g-0053):
 48      A) Add -info control argument to permit use of help command
 49         to test locating subsystem topics using :[Info]: divider.
 50                Syntax: help HELP_INFO_NAME -Info TOPIC
 51         where TOPIC gives a name in the :[Info]: divider line.
 52      B) Allow -cs to be given with -ca (as well as -scn and -srh).
 53      C) Reorder internal arrays holding names of supported control argument.
 54      D) Allow other control arguments to be given with: -brief or -control_arg
 55      E) Add hidden control arguments: -no_video (-nv) and -debug (-db)
 56          -no_video: disables help_ code that overwrites prompt and user response
 57            after user replies "yes" to the prompt.
 58          -debug OP: turns on special debugging code in help_.  OP may be an
 59            integer between 1 and 14 inclusive.  Only values 1, 2, 3 were defined
 60                 as of this writing.
 61                  OP=1: enable debug_prompt and debug_print calls in help_listen_util_.
 62                        These show factors affect next prompt, and next text printed;
 63                  OP=2: enable print stmts in help_util_$format_LIST showing how number
 64                        of columns and rows were determined in the formatted LIST.
 65                  OP=3: print iFile.caseI and .structure values seen by help_ after
 66                        info segment has been parsed.
 67            The OP value is stored in help_args.pad2(6) array element.
 68                                                    END HISTORY COMMENTS */
 69 
 70 
 71 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
 72 /*                                                                                        */
 73 /* Name:  help                                                                            */
 74 /*                                                                                        */
 75 /* This is the command interface to the Multics help facility.  It does the following.    */
 76 /*                                                                                        */
 77 /* 1) call help_$init to obtain a help_args structure in which arguments and control      */
 78 /*    arguments can be stored.                                                            */
 79 /* 2) process caller-supplied arguments, filling in the help_args structure.              */
 80 /* 3) call help_ with the help_args structure to actually find and print the info segs.   */
 81 /* 4) call help_$term to release the help_args structure.                                 */
 82 /*                                                                                        */
 83 /* help searches for info segments (having a suffix of info) in the directories given in  */
 84 /* the search paths of the info_segments (info_segs or infos) search list, which          */
 85 /* is maintained by the Multics search facility.                                          */
 86 /*                                                                                        */
 87 /* Status                                                                                 */
 88 /*                                                                                        */
 89 /* 0) Created:   November, 1969   by T. H. VanVleck                                       */
 90 /* 1) Modified:  February, 1975   by T. H. VanVleck - complete rewrite                    */
 91 /* 2) Modified:  September,1976   by Steve Herbst - accept -pathname ctl_arg              */
 92 /* 3) Modified:  June, 1977       by Paul Green - diagnose zero-length info segs          */
 93 /* 4) Modified:  October, 1978    by Gary Dixon - complete rewrite; split into help       */
 94 /*                                      command and separate help_ subroutine.            */
 95 /* 5) Modified:  June, 1983       by Gary Dixon - add ssu_help_request entrypoint.        */
 96 /*                                                                                        */
 97 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
 98 %page;
 99 /* format: style2,ind2,ll131,dclind4,idind15,comcol41,linecom,ifthen */
100 help:
101   procedure;
102 
103     dcl (Iarg, Iarg_end_ca, Iarg_end_scn, Iarg_start_ca, Iarg_start_scn, Iarg_start_srh, Ipath)
104                        fixed bin,
105         (Larg, Lop)    fixed bin (21),
106         Nargs          fixed bin,
107         Nctl_args      fixed bin,
108         (Parg, Pop)    ptr,
109         Serror         bit (1),
110         Stopics        bit (1),
111         Sstandalone_invocation
112                        bit (1),
113         (cleanup, conversion, size)
114                        condition,
115         code           fixed bin (35),
116         error_type     fixed bin,
117         j              fixed bin,
118         sci_ptr        ptr;
119 
120     dcl arg            char (Larg) based (Parg),
121         op             char (Lop) based (Pop);
122 
123     dcl (bin, convert, dim, index, maxlength, null, substr)
124                        builtin;
125 
126     dcl com_err_       entry options (variable),
127         cu_$arg_count  entry (fixed bin, fixed bin (35)),
128         ssu_$abort_line
129                        entry () options (variable),
130         ssu_$arg_count entry (ptr, fixed bin),
131         ssu_$arg_ptr   entry (ptr, fixed bin, ptr, fixed bin (21)),
132         ssu_$destroy_invocation
133                        entry (ptr),
134         ssu_$get_subsystem_and_request_name
135                        entry (ptr) returns (char (72) var),
136         ssu_$standalone_invocation
137                        entry (ptr, char (*), char (*), ptr, entry, fixed bin (35));
138 
139     dcl (
140         FALSE          init ("0"b),
141         TRUE           init ("1"b)
142         )              bit (1) aligned int static options (constant);
143 
144 /* format: off */
145     dcl (
146         ctl_abbrev     (19) char (6) varying int static options (constant) init (
147                        "-scn",          /* 1 */
148                        "-srh",          /* 2 */
149                        "-bf",           /* 3 */
150                        "-ca",           /* 4 */
151                        "-ep",           /* 5 */
152                        "-he",           /* 6 */
153                        "-bfhe",         /* 7 */
154                        "-pn",           /* 8 */
155                        "-a",            /* 9 */
156                        "-title",        /*10 */
157                        "-topic",        /*11 ssu_ only */
158                        "-lep",          /*12 */
159                        "-cs",           /*13 */
160                        "-ncs",          /*14 */
161                        "-Info",         /*15 */
162                        "-mln",          /*16 */
163                        "-minln",        /*17 hidden control arg */
164                        "-nv",           /*18 hidden control arg */
165                        "-db"),          /*19 hidden control arg */
166         ctl_word       (19) char (20) varying int static options (constant) init (
167                        "-section",      /* 1 */
168                        "-search",       /* 2 */
169                        "-brief",        /* 3 */
170                        "-control_arg",  /* 4 */
171                        "-entry_point",  /* 5 */
172                        "-header",       /* 6 */
173                        "-brief_header", /* 7 */
174                        "-pathname",     /* 8 */
175                        "-all",          /* 9 */
176                        "-titles",       /*10 */
177                        "-topics",       /*11 ssu_ only */
178                        "-list_entry_points",
179                                         /*12 */
180                        "-case_sensitive",
181                                         /*13 */
182                        "-non_case_sensitive",
183                                         /*14 */
184                        "-info",         /*15 */
185                        "-maxlines",     /*16 */
186                        "-minlines",     /*17 hidden control arg */
187                        "-no_video",     /*18 hidden control arg */
188                        "-debug"),       /*19 hidden control arg */
189         ctl_obsolete   (2) char (3) varying int static options (constant) init (
190                        "-sc",           /* 1 */
191                        "-sh")           /* 2 */
192         );
193 /* format: on */
194 
195     dcl (
196         error_table_$active_function,
197         error_table_$bad_arg,
198         error_table_$badopt,
199         error_table_$bigarg,
200         error_table_$inconsistent,
201         error_table_$noarg,
202         error_table_$noentry,
203         error_table_$unimplemented_version
204         )              fixed bin (35) ext static;
205 %page;
206 %include help_args_;
207 %page;
208 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  **  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */
209 
210 
211     call cu_$arg_count (Nargs, code);   /* help cannot be invoked as active function.     */
212     if code = error_table_$active_function then
213       do;
214         call com_err_ (code, "help");
215         return;
216       end;
217 
218     Sstandalone_invocation = TRUE;
219     sci_ptr = null;
220     Phelp_args = null;
221     on cleanup call janitor ();         /* Cleanup help arg segment if help aborted.      */
222 
223     call ssu_$standalone_invocation (sci_ptr, "help", "1", null, abort_help_command, code);
224     if code ^= 0 then
225       do;
226         call com_err_ (code, "help", "Calling ssu_$standalone_invocation");
227         return;
228       end;
229     go to COMMON;
230 
231 ssu_help_request:
232   entry (Asci_ptr, AStopics, find_subsystem_info_file);
233 
234     dcl Asci_ptr       ptr,
235         AStopics       bit (1),
236         find_subsystem_info_file
237                        entry (ptr, char (*)) returns (char (300) var);
238 
239     sci_ptr = Asci_ptr;
240     AStopics = FALSE;
241     Sstandalone_invocation = FALSE;
242     Phelp_args = null;
243     on cleanup call janitor ();
244 
245 COMMON:
246     call help_$init (ssu_$get_subsystem_and_request_name (sci_ptr), "info_segments", "", Vhelp_args_3, Phelp_args, code);
247     if Phelp_args = null then           /* get help input arguments.                      */
248       go to ARG_STRUC_ERR;
249     if help_args.version ^= Vhelp_args_3 then
250       do;                               /* check version of structure for validity.       */
251         code = error_table_$unimplemented_version;
252         go to ARG_STRUC_ERR;
253       end;
254     help_args.sci_ptr = sci_ptr;
255 %page;
256     call ssu_$arg_count (sci_ptr, Nargs);
257                                         /* get count of input arguments.                  */
258     Serror = FALSE;                     /* Remember if error encountered in args.         */
259     Iarg_start_srh = Nargs + 1;         /* -search not encountered so far.                */
260     Iarg_start_ca = Nargs + 1;          /* Same for -control_arg.                         */
261     Iarg_start_scn = Nargs + 1;         /* Same for -section                              */
262     Iarg_end_ca = 0;
263     Iarg_end_scn = 0;
264     if Sstandalone_invocation then
265       help_args.Sctl.he_pn = TRUE;      /* Output long heading by default.                */
266     help_args.Sctl.he_counts = TRUE;
267     Stopics = FALSE;
268     Nctl_args = 0;
269     do Iarg = 1 to Nargs;               /* Process args.                                  */
270       call ssu_$arg_ptr (sci_ptr, Iarg, Parg, Larg);
271       if index (arg, "-") = 1 then
272 PROCESS_CONTROL_ARG:
273         do;
274           Nctl_args = Nctl_args + 1;
275           do j = 1 to dim (ctl_abbrev, 1) while (arg ^= ctl_abbrev (j));
276           end;
277           if j > dim (ctl_abbrev, 1) then
278             do;
279               do j = 1 to dim (ctl_word, 1) while (arg ^= ctl_word (j));
280               end;
281               if j > dim (ctl_word, 1) then
282                 do;
283                   do j = 1 to dim (ctl_obsolete, 1) while (arg ^= ctl_obsolete (j));
284                   end;
285                   if j > dim (ctl_obsolete, 1) then
286                     do;
287                       Serror = TRUE;
288                       call ssu_$abort_line (sci_ptr, error_table_$badopt, arg);
289                       go to NEXT_ARG;
290                     end;
291                 end;
292             end;
293           go to DO_ARG (j);
294 %page;
295 DO_ARG (1):
296           if Iarg = Nargs then
297             go to NO_OPERAND;
298           call ssu_$arg_ptr (sci_ptr, Iarg + 1, Pop, Lop);
299           if Lop >= 1 then
300             if substr (op, 1, 1) = "-" then
301               go to NO_OPERAND;
302           help_args.Sctl.scn = TRUE;
303           Iarg = Iarg + 1;              /* -section:  next arg guaranteed part of         */
304           Iarg_start_scn = Iarg;        /*   section name.                                */
305           Iarg_end_scn = Iarg;
306           do Iarg = Iarg + 1 to Nargs;  /* Remaining args not starting with - are part    */
307                                         /*   of section name too.                         */
308             call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
309             if Lop >= 1 then
310               if substr (op, 1, 1) = "-" then
311                 do;
312                   Iarg = Iarg - 1;
313                   go to NEXT_ARG;
314                 end;
315             Iarg_end_scn = Iarg;
316           end;
317           go to NEXT_ARG;
318 %page;
319 DO_ARG (2):
320           if Iarg = Nargs then
321             go to NO_OPERAND;
322           help_args.Sctl.srh = TRUE;    /* -search:  All remaining args are search        */
323                                         /*   strings.  Last arg could be -cs/-ncs         */
324           Iarg_start_srh = Iarg + 1;    /* Remember where search args begin.              */
325           Iarg = Nargs;
326           go to NEXT_ARG;
327 
328 DO_ARG (3):
329           help_args.Sctl.bf = TRUE;     /* -brief                                         */
330           go to NEXT_ARG;
331 
332 DO_ARG (4):
333           if Iarg = Nargs then
334             go to NO_OPERAND;
335           Iarg = Iarg + 1;              /* -control_arg:  args not starting with - are    */
336                                         /*   control argument names.                      */
337           Iarg_start_ca = Iarg;         /* Remember where ca names start.                 */
338           Iarg_end_ca = Iarg;           /* Remember where last ca name is.                */
339           help_args.Sctl.ca = TRUE;     /* -ca                                            */
340           do Iarg = Iarg + 1 to Nargs;
341             call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
342             if Lop >= 1 then
343               if substr (op, 1, 1) = "-" then
344                 do;
345                   Iarg = Iarg - 1;
346                   go to NEXT_ARG;
347                 end;
348             Iarg_end_ca = Iarg;
349           end;
350           go to NEXT_ARG;
351 %page;
352 DO_ARG (5):
353           help_args.Sctl.ep = TRUE;     /* -entry_point                                   */
354           go to NEXT_ARG;
355 
356 DO_ARG (6):
357           help_args.Sctl.he_only = TRUE;/* -header (print only heading)                   */
358           go to NEXT_ARG;
359 
360 DO_ARG (7):
361           help_args.Sctl.he_pn = FALSE; /* -brief_header (output brief headings)          */
362           go to NEXT_ARG;
363 
364 DO_ARG (8):
365           if Iarg = Nargs then
366             go to NO_OPERAND;           /* -pathname:  following arg is a pathname,       */
367           Iarg = Iarg + 1;              /*   no matter what it looks like.                */
368           call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
369           j = 1;
370           if maxlength (help_args.path (j).value) < Lop then
371             do;
372               call ssu_$abort_line (sci_ptr, error_table_$bigarg, " ^a ^a", arg, op);
373               Serror = TRUE;
374             end;
375           else
376             do;
377               help_args.Npaths, j = help_args.Npaths + 1;
378               help_args.path (j).S = "0"b;
379               help_args.path (j).S.pn_ctl_arg = TRUE;
380               help_args.path (j).value = op;
381               help_args.path (j).info_name = "";
382             end;
383           go to NEXT_ARG;
384 %page;
385 DO_ARG (9):
386           help_args.Sctl.all = TRUE;    /* -all                                           */
387           go to NEXT_ARG;
388 
389 DO_ARG (10):
390           help_args.Sctl.title = TRUE;  /* -title                                         */
391           go to NEXT_ARG;
392 
393 DO_ARG (11):
394           Stopics = TRUE;               /* -topics - This arg is allowed only in the      */
395           go to NEXT_ARG;               /*   ssu_ help request, not in help command.      */
396                                         /*   It supports obsolete function of listing     */
397                                         /*   all available subsystem info segs.  Proper   */
398                                         /*   method of doing this is list_help request.   */
399 
400 DO_ARG (12):
401           help_args.Sctl.lep = TRUE;    /* -list_entrypoints                              */
402           goto NEXT_ARG;
403 
404 DO_ARG (13):
405           help_args.Sctl.cs = TRUE;     /* -case_sensitive                                */
406           goto NEXT_ARG;
407 
408 DO_ARG (14):
409           help_args.Sctl.cs = FALSE;    /* -non_case_sensitive                            */
410           goto NEXT_ARG;
411 
412 DO_ARG (15):
413           if Iarg = Nargs then
414             go to NO_OPERAND;           /* -Info NAME                                     */
415           Iarg = Iarg + 1;
416           call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
417           j = 1;
418           if maxlength (help_args.path (j).info_name) < Lop then
419             do;
420               call ssu_$abort_line (sci_ptr, error_table_$bigarg, " -info ^a", op);
421               Serror = TRUE;
422             end;
423           else
424             do;
425               j = help_args.Npaths;
426               if j = 0 then
427                 call ssu_$abort_line (sci_ptr, error_table_$inconsistent, " -info must follow an info segment name.");
428               help_args.path (j).info_name = op;
429               if op = "?" then
430                    help_args.path (j).info_name_not_starname = TRUE;
431               help_args.Sctl.he_info_name = TRUE;
432             end;
433           go to NEXT_ARG;
434 
435 DO_ARG (16):
436           if Iarg = Nargs then
437             go to NO_OPERAND;           /* -maxlines N                                    */
438           Iarg = Iarg + 1;
439           call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
440           on conversion, size go to BAD_MAX_OPERAND;
441           help_args.max_Lpgh = convert (help_args.max_Lpgh, op);
442           revert conversion, size;
443           if help_args.max_Lpgh < 1 | help_args.max_Lpgh > 200 then
444             go to BAD_MAX_OPERAND;
445           go to NEXT_ARG;
446 
447 DO_ARG (17):
448           if Iarg = Nargs then
449             go to NO_OPERAND;           /* -minlines N                                    */
450           Iarg = Iarg + 1;
451           call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
452           on conversion, size go to BAD_MIN_OPERAND;
453           help_args.min_Lpgh = convert (help_args.min_Lpgh, op);
454           revert conversion, size;
455           if help_args.min_Lpgh < 1 | help_args.min_Lpgh > 50 then
456             go to BAD_MIN_OPERAND;
457           go to NEXT_ARG;
458 
459 DO_ARG (18):
460           help_args.Sctl.no_video = TRUE;
461           goto NEXT_ARG;                /* -no_video, -nv                                 */
462 
463 DO_ARG (19):
464           help_args.Sctl.mbz1 = FALSE;  /* -debug N, -db N                                */
465           if Iarg = Nargs then
466             go to NO_OPERAND;
467           Iarg = Iarg + 1;
468           call ssu_$arg_ptr (sci_ptr, Iarg, Pop, Lop);
469   dcl  db_op fixed bin(4) unsigned;
470           on conversion, size go to BAD_DB_OPERAND;
471           db_op = convert (db_op, op);
472           revert conversion, size;
473           if db_op < 0 | db_op > 15 then
474             go to BAD_DB_OPERAND;
475           help_args.pad2 (6) = db_op;
476           go to NEXT_ARG;
477 
478 NO_OPERAND:
479           Serror = TRUE;                /* No operand given with -scn, -srh, -ca, -pn     */
480           call ssu_$abort_line (sci_ptr, error_table_$noarg, "No operand given following ^a.", arg);
481           go to NEXT_ARG;
482 
483 BAD_DB_OPERAND:
484           Serror = TRUE;                /* Bad numeric operand with -debug.     */
485           call ssu_$abort_line (sci_ptr, error_table_$bad_arg, " ^a ^a^/  Operand must be an integer from 0 to 15.", arg, op);
486           go to NEXT_ARG;
487 
488 BAD_MAX_OPERAND:
489           Serror = TRUE;                /* Bad numeric operand with -maxlines.  */
490           call ssu_$abort_line (sci_ptr, error_table_$bad_arg, " ^a ^a^/Operand must be an integer from 1 to 200.", arg, op);
491           go to NEXT_ARG;
492 
493 BAD_MIN_OPERAND:
494           Serror = TRUE;                /* Bad numeric operand with -minlines.  */
495           call ssu_$abort_line (sci_ptr, error_table_$bad_arg, " ^a ^a^/Operand must be an integer from 1 to 50.", arg, op);
496           go to NEXT_ARG;
497 
498         end PROCESS_CONTROL_ARG;
499       else
500 PROCESS_ONE_POSITIONAL_ARG:
501         do;
502           j = 1;
503           if maxlength (help_args.path (j).value) < Larg then
504             do;
505               call ssu_$abort_line (sci_ptr, error_table_$bigarg, " ^a", arg);
506               Serror = TRUE;
507             end;
508           else
509             do;
510               help_args.Npaths, j = help_args.Npaths + 1;
511               help_args.path (j).S = "0"b;
512               help_args.path (j).info_name = "";
513               if Sstandalone_invocation then
514                 help_args.path (j).value = arg;
515               else help_args.path (j).value = find_subsystem_info_file (sci_ptr, arg);
516             end;
517         end PROCESS_ONE_POSITIONAL_ARG;
518 NEXT_ARG:
519     end;
520 %page;
521     if Stopics then
522       do;
523         if Nctl_args ^= 1 | help_args.Npaths ^= 0 then
524           call ssu_$abort_line (sci_ptr, error_table_$inconsistent, "-topics and any other arguments");
525         AStopics = TRUE;
526         go to RETURN;
527       end;
528 
529     if help_args.Sctl.he_only then
530       if help_args.Sctl.title | help_args.Sctl.bf | help_args.Sctl.all | help_args.Sctl.ca |  help_args.Sctl.lep
531            then
532         do;
533           Serror = TRUE;
534           call ssu_$abort_line (sci_ptr, error_table_$inconsistent, "
535 -header may not be given with: ^[ -brief^]^[ -title^]^[ -control_arg^]^[ -all^]^[ -lep^].", help_args.Sctl.bf,
536                help_args.Sctl.title, help_args.Sctl.ca, help_args.Sctl.all, help_args.Sctl.lep);
537         end;
538     if help_args.Sctl.cs then           /* complain if cs given without scn or srh        */
539       if ^help_args.Sctl.srh & ^help_args.Sctl.scn & ^help_args.Sctl.ca then
540         do;
541           Serror = TRUE;
542           call ssu_$abort_line (sci_ptr, error_table_$inconsistent, "
543 ^[-cs^] may only be used with the -srh, -scn or -ca arguments.", help_args.Sctl.cs);
544         end;
545     if help_args.Sctl.lep then          /* Complain if scn or srh given with lep          */
546       if help_args.Sctl.srh | help_args.Sctl.scn then
547         do;
548           Serror = TRUE;
549           call ssu_$abort_line (sci_ptr, error_table_$inconsistent, "-lep may not be given with : ^[ -srh^]^[ -scn^].",
550                help_args.Sctl.srh, help_args.Sctl.scn);
551         end;
552     if help_args.Npaths = 0 then
553       do;                               /* Supply default pathname of help_system.gi.info.*/
554         if Sstandalone_invocation then
555           do;
556             help_args.Npaths = 1;
557             help_args.path (1).value = "help_system.gi.info";
558                                         /* Give info for installed help command.          */
559             help_args.path (1).info_name = "";
560             help_args.path (1).S = "0"b;
561           end;
562         else call ssu_$abort_line (sci_ptr, error_table_$noarg, "One or more topic names.");
563       end;
564 %page;
565     do Iarg = Iarg_start_ca to Iarg_end_ca;
566                                         /* Add control arg names to arg structure.        */
567       call ssu_$arg_ptr (sci_ptr, Iarg, Parg, Larg);
568       j = 1;
569       if maxlength (help_args.ca (j)) < Larg then
570         do;
571           Serror = TRUE;
572           call ssu_$abort_line (sci_ptr, error_table_$bigarg, " -ca ^a
573 Maximum length is ^d characters.", arg, maxlength (help_args.ca (j)));
574         end;
575       else
576         do;
577           help_args.Ncas, j = help_args.Ncas + 1;
578           help_args.ca (j) = arg;
579         end;
580     end;
581     do Iarg = Iarg_start_scn to Iarg_end_scn;
582                                         /* Add -section substrings to arg structure.      */
583       call ssu_$arg_ptr (sci_ptr, Iarg, Parg, Larg);
584       j = 1;
585       if maxlength (help_args.scn (j)) < Larg then
586         do;
587           Serror = TRUE;
588           call ssu_$abort_line (sci_ptr, error_table_$bigarg, " -scn ^a
589 Maximum length is ^d characters.", arg, maxlength (help_args.scn (j)));
590         end;
591       else
592         do;
593           help_args.Nscns, j = help_args.Nscns + 1;
594           help_args.scn (j) = arg;
595         end;
596     end;
597     do Iarg = Iarg_start_srh to Nargs;  /* Add -search args to control structure.         */
598       call ssu_$arg_ptr (sci_ptr, Iarg, Parg, Larg);
599       j = 1;
600       if maxlength (help_args.srh (j)) < Larg then
601         do;
602           Serror = TRUE;
603           call ssu_$abort_line (sci_ptr, error_table_$bigarg, " -srh ^a
604 Maximum length is ^d characters.", arg, maxlength (help_args.srh (j)));
605         end;
606       else
607         do;
608           help_args.Nsrhs, j = help_args.Nsrhs + 1;
609           help_args.srh (j) = arg;
610         end;
611     end;
612     if Serror then
613       goto RETURN;
614 
615     call help_ (ssu_$get_subsystem_and_request_name (sci_ptr), Phelp_args, "info", error_type, code);
616     go to ERROR (error_type);
617 %page;
618 ARG_STRUC_ERR:
619 ERROR (1):                              /* bad help_args version.                         */
620 ERROR (2):                              /* No pathnames given in help_args.               */
621     call ssu_$abort_line (sci_ptr, code, "^/Processing the argument structure used by help_.");
622     goto RETURN;
623 
624 ERROR (3):                              /* Error encountered in processing one or more    */
625                                         /* of the pathnames given in help_args.           */
626     do Ipath = 1 to help_args.Npaths;
627       if help_args.path (Ipath).code ^= 0 then
628         call ssu_$abort_line (sci_ptr, help_args.path (Ipath).code, " ^[-pn ^]^a", help_args.path (Ipath).S.pn_ctl_arg,
629              help_args.path (Ipath).value);
630     end;
631     goto RETURN;
632 
633 ERROR (5):                              /* If a nonzero error code is returned, it means  */
634                                         /* than -section and -search failed to find any   */
635                                         /* matching info segs to print.  This error must  */
636                                         /* be reported to the user.                       */
637     if code ^= 0 then
638       call ssu_$abort_line (sci_ptr, error_table_$noentry,
639            "
640 Looking for infos matching info_name^[s^]^[^; and -search criteria^; and -section criteria^;"
641            || ", plus -section and -search criteria^].", (help_args.Npaths > 1),
642            (1 + 2 * bin (help_args.Sctl.scn, 1) + bin (help_args.Sctl.srh, 1)));
643 
644 ERROR (4):                              /* No fatal errors encountered.  Most nonfatal    */
645 RETURN:                                 /*   errors have been reported by help_.          */
646     call janitor ();
647     return;
648 
649 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
650 
651 
652 abort_help_command:
653   procedure ();
654 
655     go to RETURN;
656 
657   end abort_help_command;
658 
659 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  **  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */
660 
661 
662 janitor:
663   procedure;
664 
665     dcl Acode          fixed bin (35);
666 
667     if Phelp_args ^= null then
668       call help_$term (ssu_$get_subsystem_and_request_name (sci_ptr), Phelp_args, Acode);
669     if Sstandalone_invocation then
670       call ssu_$destroy_invocation (sci_ptr);
671 
672   end janitor;
673 
674 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  **  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  */
675 
676   end help;