1 /* START OF: info_seg_dcls_.incl.pl1 * * * * * * * * * * * * * * * * * * * */ 2 3 /****^ HISTORY COMMENTS: 4 1) change(2020-07-30,GDixon), approve(2021-02-23,MCR10089), 5 audit(2021-03-31,Swenson), install(2021-03-31,MR12.6g-0053): 6 Initial version written for verify_info command and info_seg_ subroutine. 7 A) This version includes revised block divider keywords: :[Info]: and :hcom: 8 B) Add INFO_SECTION_NO_TITLE_FABRICATION constant. 9 2) change(2020-11-25,GDixon), approve(2021-02-23,MCR10089), 10 audit(2021-03-31,Swenson), install(2021-03-31,MR12.6g-0053): 11 A) Replace all references to iBlok_divider_Internal with iBlok_divider_hcom. 12 END HISTORY COMMENTS */ 13 14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 /* */ 16 /* Common sub-structures declared within major info segment structures (defined further below). */ 17 /* */ 18 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 19 20 dcl 1 iCommon aligned based(iCommonP), /* Substructure which begins many info_seg structures. */ 21 2 content, /* Content described by the major structure. */ 22 3 ID char(4), /* - content identifier */ 23 3 L fixed bin(21), /* - content length (in characters) */ 24 3 P ptr, /* - content pointer */ 25 2 sib like iSib, /* Pointers to next/prev items in list of major */ 26 iCommonP ptr; /* structures. All structures in list have same shape */ 27 /* and ID. */ 28 29 /* Values for iCommon.content.ID: */ 30 dcl (iFileID init("FILE"), /* iFile: info_seg file data structure */ 31 iBlokID init("BLOK"), /* iBlok: info_seg block-of-lines descriptor */ 32 iSectID init("SECT"), /* iSect: info_seg section-of-paragraphs descriptor */ 33 iListID init("LIST"), /* iList: info_seg Argument/Control_arg/Operation desc. */ 34 OListID init("OLST"), /* Operation_List: operation/control order list */ 35 iPghID init("PGH"), /* iPgh: info_seg paragraph descriptor */ 36 iLineID init("LINE") /* iLine: info_seg line descriptor */ 37 ) char(4) int static options(constant); 38 39 40 dcl 1 iChild aligned based(iChildP), /* Substructure declared within a major structure below. */ 41 /* It is the base of a list of child structs attached */ 42 /* to the parent structure. */ 43 2 firstP ptr, /* - points to first child structure in list. */ 44 2 lastP ptr, /* - points to final child structure in list. */ 45 iChildP ptr; 46 47 dcl 1 iSib aligned based(iSibP), /* Thread between structures in a list. All list members */ 48 /* have the same shape and ID. */ 49 2 nextP ptr, /* - points to next structure in list. */ 50 /* - null if declaring structure is last in the list. */ 51 2 prevP ptr, /* - points to prior structure in list. */ 52 /* - null if declaring structure is first in the list.*/ 53 iSibP ptr; 54 55 56 dcl entrynameL fixed bin int static options(constant) init(32); 57 /* NOTE: iNameXXX structures below hold words from */ 58 /* info seg heading lines, block divider names, and */ 59 /* external names on the info segment. Both heading */ 60 /* line names and block divider names can be a */ 61 /* subroutine entrypoint name; and such names are */ 62 /* PL/I identifiers whose max length is 256 characters. */ 63 /* info_seg_ limits such names to 32 chars in length */ 64 /* since no Multics subroutine uses entrypoint names */ 65 /* longer than 32 characters. */ 66 67 dcl 1 iName10 aligned, /* A 10-element name array. */ 68 2 N fixed bin, /* - number of array elements currently in use. */ 69 2 nm (10) char(entrynameL) var; /* - array holding names in the list. */ 70 71 dcl 1 iName100 aligned based, /* A 100-element name array */ 72 2 N fixed bin, /* - number of array elements currently in use. */ 73 2 nm (100) char(entrynameL) var; /* - array holding names in the list. */ 74 75 dcl 1 iName300 aligned based, /* A 300-element name array */ 76 2 N fixed bin, /* - number of array elements currently in use. */ 77 2 nm (300) char(entrynameL) var; /* - array holding names in the list. */ 78 79 dcl 1 Names aligned based (NamesP), /* Overlay for in-use portion of any name array. */ 80 2 N fixed bin, 81 2 nm (0 refer (Names.N)) char(entrynameL) var, 82 NamesP ptr; 83 84 85 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 86 * * 87 Notes on the following structures: 88 - List: an adjustable-sized array of items. 89 - Items may be: Argument names, Control argument names, List of ... item names, etc. 90 - Each item may have 1-4 name variants. 91 - Each list includes a pointer to the info section which describes those items. 92 - Operation_List: a kind of List whose items describe other info blocks. 93 - Items may be: operations supported by a multi-operation command (io_call, history_comment, etc.). 94 - Items share same List.common (or Lcom) substructure. 95 - Extra elements of an Operation_List: 96 - blok_name: name of the info block containing the section describing items in the Operation_List. 97 - per_operation_iBlokP: array of pointers to the info block references by each operation item. 98 - Lcom: overlay for the List.common substructure shared by List and Operation_List instances. 99 * * 100 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 101 102 dcl LENGTH_iList_item_name fixed bin init(80) int static options(constant); 103 dcl 1 iList aligned based, /* A 200-element array of Argument, Control_arg, or */ 104 /* List of ... items */ 105 2 content like iCommon.content, 106 2 parentSectP ptr, /* - points to iSect holding this data. */ 107 2 common, /* Common parts shared by: iList, List, Operation_List */ 108 3 N fixed bin, /* - number of array elements currently in use. */ 109 3 items (200), /* - array holding up to four long/short/variant names */ 110 4 nmN fixed bin, /* for the argument, control_arg, or operation. */ 111 4 nameP ptr unal, /* - iLineP for first line containing name of item. */ 112 4 defEndP ptr unal, /* - iLineP for final name/definition line of item. */ 113 4 nm (4) char(LENGTH_iList_item_name) var; /* All 4 are alternative names for the same item. */ 114 115 dcl 1 List aligned based (ListP), /* An N-element array of Argument, Control_arg, or */ 116 /* Operation names for a command/af/request/ar blok. */ 117 2 content like iCommon.content, 118 2 common, /* Common parts shared by: iList, List, Operation_List */ 119 3 parentSectP ptr, /* - points to iSect holding this data. */ 120 3 N fixed bin, /* - number of array elements currently in use. */ 121 3 items (ListN refer (List.N)), /* - array holding up to four long/short/variant names */ 122 4 nmN fixed bin, /* for the argument, control_arg, or operation. */ 123 4 nameP ptr unal, /* - iLineP for first line containing name of item. */ 124 4 defEndP ptr unal, /* - iLineP for final name/definition line of item. */ 125 4 nm (4) char(80) var, /* All 4 are alternative selectors for the same item. */ 126 (ListI, ListN) fixed bin, 127 ListP ptr, 128 List_item_names (ListP->List.items(ListI).nmN) char(80) var based(addr(ListP->List.items(ListI).nm(1))); 129 130 dcl 1 Operation_List aligned based (Operation_ListP), /* An N-element "List of operations" op names w/ pointers */ 131 /* to the iBlok describing each operation. */ 132 2 content like iCommon.content, 133 2 blok_name char(entrynameL) var, /* - ShortName of multi-operation command/af/request/ar */ 134 2 common, /* Common parts shared by: iList, List, Operation_List */ 135 3 parentSectP ptr, /* - points to multi_operations block iSect holding list */ 136 3 N fixed bin, /* - number of array elements currently in use. */ 137 3 items (Operation_ListN refer (Operation_List.N)), /* - array holding up to four long/short/variant names */ 138 4 nmN fixed bin, /* for the argument, control_arg, or operation. */ 139 4 nameP ptr unal, /* - iLineP for first line containing name of item. */ 140 4 defEndP ptr unal, /* - iLineP for final name/definition line of item. */ 141 4 nm (4) char(80) var, /* All 4 are alternative names for the same item. */ 142 2 per_operation_iBlokP (Operation_ListN refer (Operation_List.N)) ptr, 143 /* - array holding iBlokP values for block describing */ 144 /* each operation in the items array. */ 145 (Operation_ListI, Operation_ListN) fixed bin, 146 Operation_ListP ptr, 147 operation_names (Operation_ListP->Operation_List.items(Operation_ListI).nmN) char(80) var 148 based( addr(Operation_ListP->Operation_List.items(Operation_ListI).nm(1)) ); 149 150 dcl 1 Lcom aligned based (LcomP), 151 3 parentSectP ptr, /* - points to iSect holding this data. */ 152 3 N fixed bin, /* - number of array elements currently in use. */ 153 3 items (0 refer (Lcom.N)), /* - array holding up to four long/short/variant names */ 154 4 nmN fixed bin, /* for the argument, control_arg, or operation. */ 155 4 nameP ptr unal, /* - iLineP for first line containing name of item. */ 156 4 defEndP ptr unal, /* - iLineP for final name/definition line of item. */ 157 4 nm (4) char(80) var, /* All 4 are alternative names for the same item. */ 158 LcomP ptr, 159 LcomI fixed bin, 160 Lcom_item_names (LcomP->Lcom.items(LcomI).nmN) char(80) var based(addr(LcomP->Lcom.items(LcomI).nm(1))); 161 162 163 %page; 164 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 165 /* */ 166 /* Major structures defining components of an info segment, listed in order of smallest to */ 167 /* largest aggregate of characters in the info segment. */ 168 /* */ 169 /* - iLine defines content of one line of an info segment. */ 170 /* - iPgh defines lines in one paragraph of an info segment. */ 171 /* - iSect defines paragraphs combined into one titled section of an info segment. */ 172 /* - iBlok defines block divider (optional), header line, and sections in one block */ 173 /* of an info segment. A block describes one info topic, command/AF, subsystem */ 174 /* request, subroutine or subroutine entrypoint, etc. */ 175 /* - iFile defines one info segment, which may contain one or more blocks of data. */ 176 /* Each block can be located and displayed individually. */ 177 /* */ 178 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 179 180 /* -------------------------------------------------------------------------------- 181 DEFINITIONS for lines: 182 line of an info segment: 1 or more consecutive characters within the info 183 segment ending with a NL character. 184 185 STRUCTURE: iLine 186 187 Describes content of one line within an info segment, not including its ending 188 NL delimiter (character separating the line from data beyond end of that line). 189 190 Siblings: 191 An iLine may be threaded below (may be a child of) a structure describing a 192 higher-level aggregate within an info segment. Other members on this thread 193 are its siblings. 194 195 iFile: Each iLine is threaded below an iFile.lines structure describing lines 196 of an entire info segment. iLine structures are threaded in their 197 order of appearance of their line within that file; they are in 198 ascending line-number order. 199 iBlok: An iLine may be threaded below an iBlok.lines structure describing lines 200 within that block of the info segment. 201 - Blank lines preceding block dividers 202 (:Info: or :[Info]:, or :Entry:, or :hcom: or :Internal:) 203 are only threaded to the iFile; not to any iBlok structure. 204 iSect: An iLine may be threaded below an iSect.lines structure describing lines 205 contained in that section (group of paragraphs) within the block. 206 - Only 1 of the 2 blank lines preceding each paragraph is included in this 207 thread. This is how help displays consecutive paragraphs of a section 208 when user responds: rest -section 209 iPgh: An iLine may be threaded below an iPgh.lines structure describing 210 a group of lines preceded by two blank lines within the block. 211 - The two blank lines (separating a paragraph from its predecessor) 212 are not threaded to any iPgh structure. 213 214 Relatives: 215 sectP: points to any section of the info segment containing this line. 216 pghP: points to any paragraph containing this line. 217 -------------------------------------------------------------------------------- */ 218 219 dcl 1 iLine aligned based (iLineP), /* Structure describing one line of an info segment. */ 220 2 common like iCommon.content, /* - ID; pointer to, and length of chars in the line. */ 221 2 sibs, /* Line may be child of several higher-level structures. */ 222 3 file like iSib, /* - thread between adjacent lines of info seg iFile. */ 223 3 blok like iSib, /* - thread between adjacent lines of info seg iBlok. */ 224 3 sect like iSib, /* - thread between adjacent lines of info seg iSect. */ 225 3 pgh like iSib, /* - thread between adjacent lines of info seg paragraph.*/ 226 2 relatives, 227 3 sectP ptr, /* - Pointer to iSect containing this line. */ 228 3 pghP ptr, /* - Pointer to iPgh containing this line. */ 229 2 line_in_file fixed bin, /* - Line's position (sequence number) within info seg. */ 230 231 2 errors aligned, /* ERRORS detected while determining line content. */ 232 3 (NL_missingS, /* - Last line of info seg did not end with NL. */ 233 234 all_whitespaceS, /* - Line contains only whitespace chars. */ 235 ends_whitespaceS, /* - Line contains non-whitespace chars, but ends with 236 /* whitespace chars. */ 237 238 overlengthS, /* - Line length exceeds INFO_CHARS_PER_LINE. */ 239 240 backspaceS, /* - Line contains BS (backspace) characters. */ 241 unprintableS /* - Line contains characters not in INFO_PRINTABLE. */ 242 ) bit(1) unal, 243 iLineP ptr; /* Points to "current" line's iLine structure. */ 244 245 dcl Line char(iLineP->iLine.L) based(iLineP->iLine.P); /* Character content of line described by iLineP->iLine */ 246 /* (the "current" line). Does not include NL delimiter. */ 247 %page; 248 /* -------------------------------------------------------------------------------- 249 DEFINITIONS for paragraphs: 250 paragraph of an info segment: 1 or more consecutive lines within an info 251 segment, ending with either: 252 - two blank lines; or 253 - end of info seg block containing the paragraph. 254 The first paragraph of a block is preceded by 255 1 or 2 blank lines ending the block 256 header line(s). 257 STRUCTURE: iPgh 258 259 Describes content of one paragraph within an info segment, not including its ending 260 pair of blank lines. 261 262 Siblings: 263 An iPgh may be threaded to a structure describing a higher-level aggregate 264 within an info segment. Other members on this thread are its adjacent paragraph 265 siblings. 266 267 iBlok: A paragraph is threaded to iBlok.pghs listing paragraphs contained 268 in that block of the info segment. 269 iSect: A paragraph is threaded to iSect.pghs listing paragraphs contained 270 in that section of the info segment block. 271 272 Relatives: 273 .sectP: points to the iSect that contains this paragraph. 274 .lines: a threaded list of lines in this paragraph. 275 -------------------------------------------------------------------------------- */ 276 277 dcl 1 iPgh aligned based (iPghP), /* Structure describing one paragraph (group of lines) in */ 278 /* an info segment block. */ 279 2 common like iCommon.content, /* - ID; pointer to, and length of chars in paragraph */ 280 2 sibs, /* Paragraph may be child of higher-level structures. */ 281 3 blok like iSib, /* - thread between adjacent paragraphs of a block */ 282 3 sect like iSib, /* - thread between adjacent paragraphs of a section */ 283 2 relatives, 284 3 sectP ptr, /* - points to iSect containing this paragraph. */ 285 3 lines like iChild, /* - list of lines in this paragraph. */ 286 /* - follows the iLine.sibs.pghs thread. */ 287 2 line_in_file fixed bin, /* - paragraphs's position (starting line number) in seg */ 288 2 line_count fixed bin, /* - number of lines within this paragraph. */ 289 2 seenS bit(1) aligned, /* ^ paragraph has been displayed to user. */ 290 /* (^ - set by help_ when paragraph printed.) */ 291 292 2 errors aligned, /* ERRORS detected while locating paragraph content. */ 293 3 (long_paragraphS, /* - iPgh.line_count >INFO_LINES_PER_PARAGRAPH */ 294 few_blank_lines_before_paragraphS, /* - pgh preceded by <INFO_BLANK_LINES_BEFORE_PARAGRAPH */ 295 /* blank or all-white lines. */ 296 many_blank_lines_before_paragraphS /* - pgh preceded by >INFO_BLANK_LINES_BEFORE_PARAGRAPH */ 297 /* blank or all-white lines. */ 298 ) bit(1) unal, 299 3 pad_errors bit(33) unal, 300 iPghP ptr; 301 302 dcl Pgh char(iPghP->iPgh.L) based(iPghP->iPgh.P); /* Character content of iPghP->iPgh (current paragraph). */ 303 %page; 304 /* -------------------------------------------------------------------------------- 305 DEFINITIONS for sections: 306 section title: Characters within first line of the section that 307 precede a COLON (:) character. If first line 308 of any paragraph includes a COLON (after 1st char 309 of line), that paragraph begins a new section 310 of the info segment. 311 312 section of an info segment: 1 or more consecutive paragraphs within an info 313 segment, beginning with either: 314 - paragraph beginning with a non-blank section 315 title. 316 - paragraph with no section title, but which is 317 first paragraph of the block (it immediately 318 follows block header and 1 or more blank lines 319 ending that block header). 320 321 STRUCTURE: iSect 322 323 Describes the paragraph content of one section within an info segment. 324 The first paragraph of most sections begins with a line containing a non-blank 325 section title. Only the first section of a block may have no section title. 326 327 Siblings: 328 An iSect may be threaded to a structure describing a higher-level aggregate 329 within an info segment. 330 331 iBlok: A section is threaded to iBlok.sects list, containing sections 332 in that block of the info segment. 333 334 Relatives: 335 .blokP: points to info seg block containing this section. 336 .pghs: a threaded list of paragraphs contained in this section. 337 .lines: a threaded list of lines contained in this section. 338 -------------------------------------------------------------------------------- */ 339 340 dcl Syntax_MAX_PIECES fixed bin int static options(constant) init(10); 341 342 dcl 1 iSect aligned based (iSectP), /* Structure describing a titled group of paragraphs. */ 343 2 common like iCommon, /* - ID; pointer to, and length of chars in section; */ 344 /* pointers to next/prev sections within block. */ 345 2 relatives, /* Section may be child of higher-level structures. */ 346 3 blokP ptr, /* - points to iBlok containing this section. */ 347 3 listP ptr, /* - points to ListP (if any) summarizing Arguments, */ 348 /* Control_args, or Operation names defined in this */ 349 /* section. */ 350 3 help_listP ptr, /* ^ points to help_'s LIST (displayable form of listP) */ 351 /* (^ - defaults to null; set by help_) */ 352 3 pghs like iChild, /* - list of paragraphs contained in this section. */ 353 3 lines like iChild, /* - list of lines contained in this section. */ 354 355 2 line_in_file fixed bin, /* - line number (in info seg) on which section begins. */ 356 2 line_count fixed bin, /* - number of iLine structs in .relatives.lines list. */ 357 2 type fixed bin, /* - one of the iSect_XXX values below. Identifies */ 358 /* the section as one having known type and format */ 359 /* of information. */ 360 2 sequence fixed bin, /* - verify_info sequence in which section should appear.*/ 361 362 2 title, /* - section title for this section. */ 363 3 (in_file, /* - exactly as it appears in the block (w/o COLON) */ 364 case_adjusted, /* - with 1st word having initial-capital, and */ 365 /* subsequent words in lower case. */ 366 should_be /* - possibly restated with preferred wording or */ 367 /* capitalization. This length should be: */ 368 ) char(71) var, /* >INFO_CHARS_PER_TITLE to allow detection of long */ 369 /* titles. */ 370 2 syntax, /* - items found in a Syntax... section. */ 371 3 N fixed bin, /* - number of items found. */ 372 3 str (Syntax_MAX_PIECES) char(1000) var, /* - each item gives syntax for a command/request; */ 373 /* active function/request; or declare and call for */ 374 /* a subroutine, or declare and return value assign */ 375 /* for a function procedure. */ 376 377 2 errors aligned, /* ERRORS detected which locating section contents. */ 378 /* Error comments starting with - are diagnosed by */ 379 /* info_seg_ and its info_seg_parse_ helper. */ 380 /* Error comments starting with + are diagnosed by */ 381 /* verify_info and its info_seg_verify_ helper. */ 382 3 (bad_titleS, /* - Section title marked BAD (not preferred) */ 383 blank_titleS, /* - Section title is all whitespace. */ 384 long_titleS, /* - Section title length >INFO_CHARS_PER_TITLE */ 385 unrecognized_titleS, /* - Section title not known to info_seg_. */ 386 untitledS, /* - Section title not found in first section of block. */ 387 /* This is not an error, just an unusual circumstance */ 388 389 syntax_title_wrong_for_kindS, /* - Syntax... title wrong for block kind. */ 390 syntax_for_subroutine_invalidS, /* - Syntax: missing declare/dcl or call or = (assign) */ 391 syntax_missing_left_bracketS, /* - Syntax as an active... missing [ in line */ 392 syntax_missing_right_bracketS, /* - Syntax as an active... missing ] in line */ 393 syntax_missing_namesS, /* - Syntax... has none of words in block header. */ 394 syntax_missing_short_nameS, /* + Syntax... does not use shortest word in block header*/ 395 syntax_uses_control_argumentsS, /* - Syntax... uses -control_arguments */ 396 syntax_uses_control_argumentS, /* - Syntax... uses -control_argument */ 397 398 list_of_ops_bad_namesS, /* - List of ... operations: names non-unique or names */ 399 /* have non-descending length */ 400 list_of_ops_long_nameS, /* - List of ... operations: length(name) > 32 */ 401 list_of_ops_nonunique_namesS, /* - List of ... operations: all item names not unique */ 402 list_of_ops_op_not_documentedS, /* - List of ... operations: some op items have no op */ 403 /* documentation block */ 404 control_order_bad_listS, /* + Control order: line constructed badly. More than */ 405 /* 2 names, or nothing before comma. */ 406 control_order_bad_name_orderS, /* + Control order: name order differs from entry in */ 407 /* "List of control operations" section.*/ 408 409 /* error checks for Subroutine Introduction: */ 410 bad_entry_points_inS /* + "Entry points in" section formatted incorrectly. */ 411 ) bit(1) unal, 412 3 pad_errors bit(15) unal, 413 3 display_listS bit(1) unal, /* - verify_info displays iList to aid error msgs */ 414 iSectP ptr; 415 416 dcl Sect char(iSectP->iSect.L) based(iSectP->iSect.P); /* Character content of iSectP->iSect (current section) */ 417 /* as it appears in the info segment. */ 418 dcl 1 Syntax aligned based(SyntaxP), /* Overlay for just the actual items found in the */ 419 2 N fixed bin, /* iSect.syntax.str array. */ 420 2 str (0 refer (Syntax.N)) char(1000) var, 421 SyntaxP ptr; 422 /* The following table (in info_seg_specifications_.cds) */ 423 /* lists known section titles, and their preferred */ 424 /* wording (used when prior wordings go out-of-style, or */ 425 /* to detect common mistakes in wording). */ 426 dcl iSect_title_MAXLENGTH_KNOWN_TITLE fixed bin int static options(constant) init(44); 427 428 dcl 1 iSect_title aligned based (addr (info_seg_specifications_$section_titles)), 429 2 titles, 430 3 titleN fixed bin, 431 3 array (0 refer (iSect_title.titles.titleN)), 432 4 cmp fixed bin, /* EQUALS: .title must match exact title in info seg. */ 433 /* BEGINS: .title must match start of title in info seg. */ 434 4 title char(iSect_title_MAXLENGTH_KNOWN_TITLE) var, 435 /* Expected title string. */ 436 4 ilk fixed bin, /* PREF: preferred or "recommended" title according to */ 437 /* info segment standards. */ 438 /* BAD: titles used in the past, now disparaged. */ 439 /* Instead use title(sectionID), the */ 440 /* sectionIDth title in this array. */ 441 4 sectionID fixed bin; /* For PREF titles, this is a named constant whose value */ 442 /* is the index of this array entry. */ 443 /* For BAD titles, this is named constant identifying */ 444 /* the array element now preferred in place of */ 445 /* this title string. */ 446 dcl info_seg_specifications_$section_titles fixed bin external static; 447 448 dcl (EQUALS, PREF) fixed bin int static options(constant) init(0), 449 (BEGINS, BAD ) fixed bin int static options(constant) init(1); 450 451 452 /* The following table (in info_seg_specifications_.cds) */ 453 /* lists known section titles expected in each kind of */ 454 /* info block. */ 455 dcl iSect_sequence_MAX_TITLES fixed bin int static options(constant) init(25); 456 dcl iSect_sequence_MAX_POSITION fixed bin int static options(constant) init(13); 457 458 dcl 1 iSect_sequence aligned based (addr (info_seg_specifications_$section_sequence)), 459 2 sequence, 460 3 kindN fixed bin, /* Number of block kinds having "known" section titles */ 461 3 array (0 refer (iSect_sequence.sequence.kindN)), /* Array of sequence info, ordered by iBlok_kind_XXX */ 462 4 block_kind fixed bin, /* - iBlok_kind_XXX with this "preferred" sequence of */ 463 /* section titles */ 464 4 titleN fixed bin, /* - Number of "preferred" section titles for block kind */ 465 4 title_seq (iSect_sequence_MAX_TITLES), /* Array of substructures, each holding per-title data */ 466 5 type fixed bin, /* - An iSect_XXX title type */ 467 5 position fixed bin, /* - A sequence position in which this title appears */ 468 /* within the block. Titles with same position form a */ 469 /* position group; title may appear in any order */ 470 /* relative to other titles in that same group. */ 471 /* Rule: 1 <= position <= iSect_sequence_MAX_POSITION */ 472 5 cardinality fixed bin; /* - An iCard_XXX value giving requirements for this */ 473 /* type of title. */ 474 dcl info_seg_specifications_$section_sequence fixed bin external static; 475 476 dcl 1 iTitle_seq aligned based(iTitle_seqP), /* Overlay for the defined iSect_sequence.array */ 477 2 block_kind fixed bin, /* array for a particular kind of info block. */ 478 2 titleN fixed bin, 479 2 array (0 refer(iTitle_seq.titleN)) like iSect_sequence.title_seq, 480 iTitle_seqP ptr; 481 482 /* Values for iSect_sequence.cardinality(k, i); also */ 483 /* iTitle_seq.cardinality(i) */ 484 dcl (iCard_UNKNOWN init(-1), /* UNKNOWN cardinality (this should never occur) */ 485 iCard_0_ALLOWED init( 0), /* NOT_ALLOWED: title once used, now obsolete/ignored */ 486 iCard_1_REQUIRED init( 1), /* 1 required: title needed to identify block type, etc */ 487 iCard_1_ALLOWED init( 2), /* 1 allowed : not required, but 1 can be used */ 488 iCard_0_OR_MORE init( 3), /* 0 or more : any number of such titles may be used */ 489 iCard_1_OR_MORE init( 4), /* 1 or more : at least 1 such title should be used */ 490 iCard_1_IN_GROUP_REQUIRED init( 5), /* 1 required in group : only 1 of titles in pos group */ 491 /* can/must be given. */ 492 iCard_1_IN_GROUP_ALLOWED init( 6) /* 1 allowed in group : only 1 of titles in pos group */ 493 /* can be given. */ 494 ) fixed bin int static options(constant); 495 496 dcl iCard_string (-1:6) char(21) int static options(constant) init( 497 " UNKNOWN ", /* - Section title's cardinality not known. */ 498 "NOT ALLOWED", /* - Section title is not permitted in this kind of info */ 499 " 1 required", /* - Section title required in this kind of info block. */ 500 " 1 allowed ", /* - Section title not required, but 1 instance allowed. */ 501 " 0 or more ", /* - Any number of such section titles may be used. */ 502 " 1 or more ", /* - At least one instance of section title must be used */ 503 " 1 of ORDER required", 504 " 1 of ORDER allowed " 505 ); 506 /* Values for iSect.type element; also */ 507 /* for iSect_titles.sectionID(n) element; also */ 508 /* for iBlok_kind.method_or_title(n) element; and */ 509 /* for iBlok_kind.second_title(n) element. */ 510 dcl (iSect_ACCESS_REQUIRED init( 1), /* Access required: */ 511 iSect_ARGUMENTS init( 2), /* Arguments: */ 512 iSect_ARGUMENTS_FOR_IO_CALL init( 3), /* Arguments for io_call: */ 513 iSect_ARGUMENTS_FOR_IOX_CONTROL init( 4), /* Arguments for iox_$control: */ 514 iSect_ARGUMENTS_FOR init( 5), /* Arguments for ...: */ 515 iSect_ARGUMENTS_SUBSET init( 6), /* Arguments (...): */ 516 iSect_CONTROL_ARGUMENTS init( 7), /* Control arguments: */ 517 iSect_CONTROL_ARGUMENTS_AS_A_COMMAND init( 8), /* Control arguments as a command: */ 518 iSect_CONTROL_ARGUMENTS_AS_A_REQUEST init( 9), /* Control arguments as a request: */ 519 iSect_CONTROL_ARGUMENTS_AS_AN_ACTIVE_FUNCTION init(10), /* Control arguments as an active function: */ 520 iSect_CONTROL_ARGUMENTS_AS_AN_ACTIVE_REQUEST init(11), /* Control arguments as an active request: */ 521 iSect_CONTROL_ARGUMENTS_FOR_ATTACH_DESCRIPTION init(12), /* Control arguments for attach description: */ 522 iSect_CONTROL_ARGUMENTS_FOR_OPEN_DESCRIPTION init(13), /* Control arguments for open description: */ 523 iSect_CONTROL_ARGUMENTS_FOR_CLOSE_DESCRIPTION init(14), /* Control arguments for close description: */ 524 iSect_CONTROL_ARGUMENTS_FOR_DETACH_DESCRIPTION init(15), /* Control arguments for detach description: */ 525 iSect_CONTROL_ARGUMENTS_FOR init(16), /* Control arguments for ...: */ 526 iSect_CONTROL_ARGUMENTS_SUBSET init(17), /* Control arguments (...): */ 527 iSect_CONTROL_ORDER init(18), /* Control order: */ 528 iSect_ENTRY_POINTS_IN init(19), /* Entry points in SUBROUTINE_NAME: */ 529 /* (List is generated by the help command) */ 530 iSect_EXAMPLES init(20), /* Examples: */ 531 iSect_FUNCTION init(21), /* Function: */ 532 iSect_LIST_OF_CONTROL_OPERATIONS init(22), /* List of control operations: */ 533 iSect_LIST_OF_CONTROLS init(23), /* List of controls: */ 534 iSect_LIST_OF_ELEMENTS init(24), /* List of elements: */ 535 /* [after section "Arguments for iox_$control"] */ 536 iSect_LIST_OF_IO_OPERATIONS init(25), /* List of i/o operations: */ 537 iSect_LIST_OF_MODE_STRINGS init(26), /* List of mode strings: */ 538 iSect_LIST_OF_OPENING_MODES init(27), /* List of opening modes: */ 539 iSect_LIST_OF_OPERATIONS init(28), /* List of operations: */ 540 iSect_LIST_OF_REQUESTS init(29), /* List of requests: */ 541 iSect_LIST_OF_ACTIVE_REQUESTS init(30), /* List of active requests: */ 542 iSect_LIST_OF init(31), /* List of ...: */ 543 iSect_NOTES_ON_THE_INFO_PTR init(32), /* Notes on the info ptr: */ 544 iSect_NOTES init(33), /* Notes: */ 545 iSect_NOTES_ON init(34), /* Notes on ...: */ 546 iSect_SYNTAX init(35), /* Syntax: */ 547 /* [first section in SUBSYSTEM REQUEST INFO] */ 548 iSect_SYNTAX_AS_A_COMMAND init(36), /* Syntax as a command: */ 549 iSect_SYNTAX_AS_AN_ACTIVE_FUNCTION init(37), /* Syntax as an active function: */ 550 iSect_SYNTAX_AS_AN_ACTIVE_REQUEST init(38), /* Syntax as an active request: */ 551 iSect_SYNTAX_OF_ATTACH_DESCRIPTION init(39), /* Syntax of attach description: */ 552 iSect_SYNTAX_OF_OPEN_DESCRIPTION init(40), /* Syntax of open description: */ 553 iSect_SYNTAX_OF_CLOSE_DESCRIPTION init(41), /* Syntax of close description: */ 554 iSect_SYNTAX_OF_DETACH_DESCRIPTION init(42), /* Syntax of detach description: */ 555 556 iSect_Untitled init(43), /* [used when there is no section title.] */ 557 iSect_Another_Title init(44) /* [used if title other than one of those above */ 558 /* is present.] */ 559 ) fixed bin int static options (constant); 560 /* The next three dcls extend constant value range from */ 561 /* list above, but use different name/date convention */ 562 /* for the constants, to reflect their use as... */ 563 /* Values for iBlok_kind.method_or_title(n) element. */ 564 dcl (iBlok_method_REFINE_EARLIER_KIND init(50), /* Use 1st section title to possibly change */ 565 /* .kind = iBlok_kind_SUBROUTINE_INTRO to */ 566 /* iBlok_kind_SUBROUTINE_BRIEF_INTRO */ 567 iBlok_method_NAMES_MAY_TELL_KIND init(51), /* Use file/block names to possibly set iBlok.kind */ 568 iBlok_method_DATE_BEFORE_1985 init(52), /* Use block iso_date to possibly set iBlok.kind */ 569 iBlok_method_NAME_summary_topic init(53), /* Look for divider name: summary.topic */ 570 iBlok_method_PATH_subsystem init(54) /* Look for >subsystem> or >ss> in info seg directory*/ 571 ) fixed bin int static options (constant); 572 %page; 573 /* -------------------------------------------------------------------------------- 574 DEFINITIONS for blocks: 575 block: Portion of an info segment completely describing: 576 a command or active function; a subroutine or its entrypoints; 577 a subsystem request or active request; or some other 578 topic of general information; or a history comment for 579 the info segment. 580 581 block divider line: Line of an info segment that begins a new block. 582 The first character of each divider line is a COLON (:). 583 The divider line consists of two parts: 584 :Info: probe: pb: 2020-02-27 probe, pb 585 \--divider------/ \--header-----------/ 586 These parts may appear in 1 line as shown above; or 587 in 2 consecutive lines, with divider on first line and 588 full header on second line. 589 590 If the info segment includes only one block, the divider 591 portion of the block divider line may be omitted; only 592 the header portion is present. 593 594 block divider starter: One of the following strings that identify the purpose 595 of this block of the info segment: 596 :Info: begins a block in a multi-block info segment. 597 :[Info]: begins a block in a multi-block info segment 598 whose divider names are not names on info seg. 599 :Entry: begins subroutine entrypoint documentation 600 :hcom: begins a history comment describing past 601 updates to the info segment. 602 :Internal: obsolete history comment starter. 603 604 STRUCTURE: iBlok 605 606 Describes the content of one block within an info segment. Each info segment 607 contains one or more blocks. If a segment contains no divider starter, then the 608 entire segment contents is treated as its only block (a block without the divider 609 portion of the block divider line described above). 610 611 Therefore, the first block may begin with or without an :Info: divider section 612 in its block divider line. Subsequent blocks begin with a divider line of some type. 613 614 Siblings: 615 An iBlok is threaded to a structure describing a higher-level aggregate. 616 617 iFile: Each iBlok is threaded below an iFile.bloks structure describing blocks 618 within the entire info segment. 619 620 Relatives: 621 .fileP: points to iFile containing this block. 622 .sects: a threaded list of sections contained in this block. 623 .pghs: a threaded list of paragraphs contained in this block. 624 .lines: a threaded list of lines contained in this block. 625 -------------------------------------------------------------------------------- */ 626 627 dcl 1 iBlok aligned based (iBlokP), /* Structure describing one block of an info segment. */ 628 2 common like iCommon, /* - ID; pointer to, and length of chars in block; */ 629 /* pointers to next/prev blocks within info segment. */ 630 2 line_in_file fixed bin, /* - line number (in info seg) on which block starts. */ 631 2 line_count fixed bin, /* - number of iLine structs in .relatives.sects list, */ 632 /* + 1 header line & 1 blank line before each section */ 633 2 seenS bit(1) aligned, /* ^ some block paragraphs have been displayed to user . */ 634 /* (^ - set by help_ when paragraph printed.) */ 635 2 divider fixed bin, /* - records divider line starter string for block */ 636 /* (one of the iBlok_divider_XXX values below). */ 637 2 names like iName10, /* - names in divider part of the block divider line. */ 638 /* :Info: probe: pb: 2020-02-27 probe, pb */ 639 /* ^^^^^ ^^ */ 640 2 kind fixed bin, /* - classification of block by nature of its contents */ 641 /* (one of the iBlok_kind_XXX values below). */ 642 643 2 header aligned, /* Every iBlok begins with a header. */ 644 3 str char(100) var, /* - full header string as it appears in info segment. */ 645 /* <date> <rest-of-header> */ 646 /* length(str) must be >INFO_CHARS_PER_HEADER to show */ 647 /* over-long header string. */ 648 3 reformatted, /* - reformatted header with: */ 649 4 iso_date char(12) unal, /* - <date> portion formatted in iso_date format. */ 650 4 rest char(88) unal, /* - <rest-of-header> */ 651 3 wordN fixed bin, /* - count of initial words found in <rest-of-header> */ 652 3 word (5) char(72) var, /* - comma-delimited tokens in <rest-of-header>. */ 653 /* 2020-02-27 probe, pb */ 654 /* ^^^^^ ^^ */ 655 /* For command/AF and request info blocks: */ 656 /* - these words are the command/AF/request names. */ 657 /* - All of these words should be in iBlok.names */ 658 /* for such block kinds. */ 659 3 after_header_iLineP ptr unal, /* - points to first non-blank iLine that ended header */ 660 2 relatives, /* Block may be child of higher-level structures. */ 661 3 fileP ptr, /* - points to iFile containing this block. */ 662 3 multi_operation_listP ptr, /* - points to Operation_List describing operations */ 663 /* performed by command/AF/request/AR described in blok*/ 664 /* Should be non-null if syntax.multi_operationsS, */ 665 /* syntax.is_operationS is T ("1"b); or if */ 666 /* syntax.request_summaryS or syntax.isRequestS is T. */ 667 3 multi_control_listP ptr, /* - points to List describing controls performed by */ 668 /* I/O Module described in this blok. */ 669 /* Should be non-null if syntax.multi_controlsS or */ 670 /* syntax.is_controlS is T. */ 671 3 sects like iChild, /* - list of sections contained in this block. */ 672 3 pghs like iChild, /* - list of paragraphs contained in this block. */ 673 3 lines like iChild, /* - list of lines contained in this block. */ 674 675 2 syntax aligned, 676 3 (is_function_procedureS, /* SUBROUTINE ENTRYPOINT: function rather than subroutine */ 677 /* requires "Arguments" section even if has no parms */ 678 is_command_requestS, /* COMMAND or REQUEST */ 679 is_activeFunction_activeRequestS, /* ACTIVE FUNCTION (AF) or ACTIVE REQUEST (AR) */ 680 has_argumentsS, /* SUBROUTINE ENTRYPOINT, COMMAND or AF, REQUEST or AR: */ 681 /* requires 1 or more "Arguments" sections. */ 682 has_control_argsS, /* COMMAND or AF, REQUEST or AR: */ 683 /* requires 1 or more "Control arguments" sections. */ 684 has_ellipsisS, /* SUBROUTINE ENTRYPOINT, COMMAND or AF, REQUEST or AR: */ 685 /* ... requires 1 or more "Arguments" sections. */ 686 multi_operationsS, /* COMMAND or AF, REQUEST or AR, or IO_MODULE */ 687 /* (with associated IO_OPERATION) does several ops. */ 688 multi_controlsS, /* IO_MODULE does several controls doc'd as :Info: blocks */ 689 request_summaryS, /* SUBSYSTEM_SUMMARY documents a list of subsystem */ 690 /* request names (the operation_names). Look for */ 691 /* per-request blocks with header words same as */ 692 /* those operation_names. */ 693 is_operationS, /* COMMAND or AF, REQUEST or AR, or IO_OPERATION */ 694 /* documents one such op. */ 695 /* Its header line has the format: */ 696 /* SHORTEST_COMMAND_NAME LONG_OPERATION_NAME operation*/ 697 /* Get SHORTEST_OPERATION_NAME from divider (or from */ 698 /* "List of operations" List of multi_operationsS blok)*/ 699 /* and look in each Syntax line for: */ 700 /* SHORTEST_COMMAND_NAME SHORTEST_OPERATION_NAME ... */ 701 is_controlS, /* IO_CONTROL documents one I/O control operation. */ 702 /* Its header line has the format: */ 703 /* SHORTEST_COMMAND_NAME LONG_CONTROL_NAME control */ 704 /* Get SHORTEST_OPERATION_NAME from divider (or from */ 705 /* "List of control operations" List of */ 706 /* multi_controlsS blok. Look for "Control order:" */ 707 /* section giving just name(s) of control order. */ 708 is_requestS, /* REQUEST or AR that documents one of the requests in */ 709 /* a "List of requests" section of request_summaryS */ 710 /* blok. header words must equal operation_names. */ 711 has_subsystem_pathS /* REQUEST or AR residing in segment below substree with */ 712 /* path containing entryname: subsystem or ss */ 713 ) bit(1) unal, 714 3 syntax_pad bit(23) unal, 715 716 2 errors aligned, /* ERROR possibilities found while parsing for blocks. */ 717 /* Error comments starting with - are diagnosed by */ 718 /* info_seg_ and its info_seg_parse_ helper. */ 719 /* Error comments starting with + are diagnosed by */ 720 /* verify_info and its info_seg_verify_ helper. */ 721 722 3 (few_blank_lines_before_blockS, /* - Blok preceded by <INFO_BLANK_LINES_BEFORE_PARAGRAPH */ 723 /* blank or all-white lines. */ 724 many_blank_lines_before_blockS, /* - Blok preceded by >INFO_BLANK_LINES_BEFORE_PARAGRAPH */ 725 /* blank or all-white lines. */ 726 727 long_namesS, /* - Blok divider name(s) longer than 32 chars. */ 728 bad_namesS, /* - Blok divider name(s) quoted incorrectly. */ 729 no_namesS, /* - Blok divider contains no names. */ 730 many_namesS, /* - Blok divider contains too many names. */ 731 732 missing_headerS, /* - Blok header is missing (zero-length) */ 733 big_headerS, /* - Blok divider/header >INFO_LINES_PER_HEADER long. */ 734 long_headerS, /* - Blok header >INFO_CHARS_PER_HEADER in length. */ 735 missing_dateS, /* - Blok header does not begin with a date field. */ 736 bad_dateS, /* - Blok header contains token in date position with */ 737 /* DATE_CHARS rejected by convert_date_to_binary_ */ 738 non_iso_dateS, /* - Blok header date is not in iso_date format. */ 739 740 older_subr_intro_dateS, /* + Blok header date too old; violates rule: */ 741 /* subroutine_intro_date >= all entrypoint_dates */ 742 bad_subr_intro_headerS, /* + Blok header line for subroutine intro ^= REF_NAME_ */ 743 bad_subr_headerS, /* + Blok header line for subroutine entrypoint name(s) */ 744 bad_subr_epS, /* + Blok header subroutine entrypoint not found by */ 745 /* cv_entry_. */ 746 747 bad_cmd_af_req_headerS, /* + Blok header line for command/AF/request/AR is not a */ 748 /* comma-separated list of reference names */ 749 bad_io_module_headerS, /* + Blok header line for IO_Module is not: */ 750 /* IO_MODULE_NAME I/O Module */ 751 bad_request_headerS, /* - Header words not identical to operation_names in */ 752 /* "List of requests" item for per-request blok. */ 753 754 bad_dividerS, /* + Blok :[Info]: divider wrong for block kind */ 755 bad_divider_namesS, /* + Blok_words disagree with Blok_names */ 756 obsolete_dividerS, /* + Blok divider :Internal: obsolete; use :hcom: */ 757 order_divider_namesS, /* + Blok_words order differs from Blok_names order */ 758 759 no_paragraphsS, /* - Blok has header line, but no paragraphs. */ 760 no_Syntax_sectionS, /* - Blok is missing its "Syntax..." section. */ 761 many_Syntax_sectionsS, /* - Blok contains too many "Syntax..." sections. */ 762 needs_ArgumentsS, /* - Blok needs an "Arguments" section of some type. */ 763 needs_Control_argumentsS, /* - Blok needs "Control arguments" section of some type */ 764 765 /* Operation Format errors */ 766 multi_op_Arguments_missing_op_namesS, /* + Blok needs "Arguments" section that lists all */ 767 /* operation names for the syntax.is_operationS block */ 768 /* ordered same as they appear in "List of operations" */ 769 /* of associated syntax.multi_operationsS block. */ 770 multi_op_header_bad_cmdReqIOmod_nameS, /* + Header word(1) is not short name of cmd/req/IOmod */ 771 multi_op_header_bad_op_nameS, /* + Header word(2) is not 1st operation/control name */ 772 /* (in "List of ... operations" item of associated */ 773 /* syntax.multi_operationsS or .multi_controlsS blok).*/ 774 multi_op_name_not_listedS, /* + Header word(2) not in "List of ... operations". */ 775 776 bad_section_orderS /* - Blok section titles not in preferred order. */ 777 ) bit(1) unal, 778 3 error_pad bit(3) unal, 779 iBlokP ptr; 780 781 dcl Blok char(iBlokP->iBlok.L) based(iBlokP->iBlok.P); /* String of characters described by iBlokP->iBlok */ 782 /* (the current block). */ 783 784 dcl Blok_names (iBlokP->iBlok.names.N) char(entrynameL) var based(addr(iBlokP->iBlok.names.nm(1))); 785 /* Array of names found in current block's divider. */ 786 dcl Blok_words (iBlokP->iBlok.header.wordN) char(72) var based(addr(iBlokP->iBlok.header.word(1))); 787 /* Array of words found in current block's header. */ 788 789 790 /* The following table (in info_seg_specifications_.cds) */ 791 /* gives rules for mapping the 1st or 1st/2nd section */ 792 /* titles of a block onto a block kind value. */ 793 /* For example, a Command Info Block begins with a */ 794 /* section titled: Syntax as a command: */ 795 dcl 1 iBlok_kind aligned based (addr (info_seg_specifications_$block_kinds)), 796 2 kinds, 797 3 kindN fixed bin, /* Number of rules in the table array. */ 798 3 array (0 refer (iBlok_kind.kinds.kindN)), /* Elements of the array. */ 799 4 kindID fixed bin, /* - iBlok_kind_XXX value to use if block matches the */ 800 /* constraints of this rule. */ 801 802 4 method_or_title fixed bin, /* - Either an iSect_XXX value (section type constraint) */ 803 /* or an iBlok_method_XXX value (method for */ 804 /* refining an existing iBlok.kind value). */ 805 806 4 second_title fixed bin, /* - If .method_or_title = iBlok_method_XXX */ 807 /* this is a section title to look for in applying */ 808 /* that method. */ 809 /* If .method_or_title = iSect_XXX value: */ 810 /* this is a second iSect_XXX value constraint. */ 811 /* Both section titles must exist as sections 1 & 2 */ 812 /* of the block (though the two sections may appear */ 813 /* in either order). */ 814 /* 0: indicates there is no second_title constraint. */ 815 4 third_title fixed bin; /* - If .method_or_title = iBlok_method_XXX */ 816 /* this is another section title to look for in */ 817 /* applying that method. */ 818 /* If .method_or_title = iSect_XXX value: */ 819 /* this is 0 (no third_title constraint) */ 820 /* Both section titles must exist as sections 1 & 2 */ 821 /* of the block (though the two sections may appear */ 822 /* in either order). */ 823 dcl info_seg_specifications_$block_kinds fixed bin external static; 824 825 826 /* The following table (in info_seg_specifications_.cds) */ 827 /* gives rules for mapping info seg or block names onto */ 828 /* an iBlok_kind_XXX value. */ 829 /* For example, a name ending .gi.info maps to */ 830 /* iBlok_kind_GENERAL_INFO */ 831 dcl 1 iBlok_name aligned based (addr (info_seg_specifications_$block_kind_names)), 832 2 names, 833 3 nameN fixed bin, 834 3 array (0 refer (iBlok_name.names.nameN)), 835 4 name_type fixed bin, /* An iBlok_name_XXX constant: */ 836 /* iBlok_name_ENDS: compare name(i) with end portion */ 837 /* of info seg or block name. */ 838 4 name (2) char(entrynameL) var, /* name(1) is entryname with .info suffix - as it appears */ 839 /* on the info segment. */ 840 /* name(2) is entryname without .info suffix - as it */ 841 /* appears in a block divider name: field. */ 842 4 kindID fixed bin; /* iBlok_kind_XXX constant denoted by this name. */ 843 dcl info_seg_specifications_$block_kind_names fixed bin external static; 844 845 /* Values for iBlok_names.name_type(n) */ 846 dcl (iBlok_block_name_ENDS init(1), /* - block_name ends with given suffix. */ 847 iBlok_name_ENDS init(2) /* - file_name/block_name ends with given suffix. */ 848 ) fixed bin int static options(constant); 849 850 dcl ( /* Values for iBlok_names.name array index. */ 851 iBlok_NAME_WITH_info init(1), /* - use name that ends with .info suffix */ 852 iBlok_NAME_WITHOUT_info init(2) /* - use name not ending with .info suffix */ 853 ) fixed bin int static options(constant); 854 855 /* Values for iBlok.divider element. */ 856 /* - ID column below is (shorthand) for each divider */ 857 /* in the iFile_structure.spec strings below. */ 858 /* Also, see below: iBlok_token string array */ 859 860 dcl ( /* ID description */ 861 iBlok_divider_None init( 0), /* N No divider starter found. Only 1st block can have */ 862 /* no divider; any other blocks begin with a divider. */ 863 iBlok_divider_Entry init( 1), /* E Divider starter = :Entry: (subroutine entrypoint) */ 864 iBlok_divider_Info init( 2), /* I Divider starter = :Info: */ 865 iBlok_divider_Info_no_ext_names init( 3), /* [I] Divider starter = :[Info]: */ 866 iBlok_divider_hcom init( 4), /* H Divider starter = :hcom: */ 867 iBlok_divider_hcom_obsolete init( 5) /* H Divider starter = :Internal: (obsolete) */ 868 ) fixed bin int static options(constant); 869 870 /* Values for the iBlok.kind element. */ 871 dcl ( /* FIRST SECTION TITLE or Block Divider is: */ 872 iBlok_kind_COMMAND init( 1), /* Syntax as a command: */ 873 iBlok_kind_ACTIVE_FUNCTION init( 2), /* Syntax as an active function: */ 874 iBlok_kind_COMMAND_AF init( 3), /* [contains previous two kinds, in either order] */ 875 876 iBlok_kind_GENERAL_INFO init( 4), /* First title is not one of those specified above. */ 877 /* :Info: NAME.gi (or other suffixes) */ 878 /* Segment name: NAME.gi.info (or other suffixes) */ 879 880 iBlok_kind_SUBROUTINE_INTRO init( 5), /* Function: */ 881 iBlok_kind_SUBROUTINE_BRIEF_INTRO init( 6), /* Entry points in <subroutine_name_>: */ 882 /* (List is generated by the help command) */ 883 iBlok_kind_SUBROUTINE_ENTRY init( 7), /* :Entry: <ep_name>: ... */ 884 885 iBlok_kind_REQUEST init( 8), /* Syntax: */ 886 iBlok_kind_ACTIVE_REQUEST init( 9), /* Syntax as an active request: */ 887 iBlok_kind_REQUEST_AR init(10), /* [contains previous two kinds, in either order] */ 888 iBlok_kind_SUBSYSTEM_SUMMARY init(11), /* :Info: summary.topic: */ 889 /* ... */ 890 /* List of requests: */ 891 iBlok_kind_SUBSYSTEM_TOPIC init(12), /* :Info: NAME.topic: */ 892 /* or */ 893 /* Notes on... */ 894 895 iBlok_kind_IO_MODULE init(13), /* Syntax of attach description: */ 896 iBlok_kind_IO_OPERATION init(14), /* Syntax of open description: */ 897 /* or */ 898 /* Syntax of close description: */ 899 /* or */ 900 /* Syntax of detach description: */ 901 iBlok_kind_IO_CONTROL init(15), /* Control order: */ 902 903 iBlok_kind_HISTORY_COMMENT init(16), /* :hcom: (a history comment) */ 904 905 iBlok_kind_Header_Only init(17), /* Block consists only of a header line; no sections */ 906 /* or paragraphs. */ 907 908 iBlok_kind_Unknown init(18) /* Kind of block as yet undetermined. */ 909 ) fixed bin int static options(constant); 910 911 dcl iBlok_kind_display_string (18) char(36) var int static options(constant) init( 912 "Command", /* iBlok_kind_COMMAND */ 913 "Active Function", /* iBlok_kind_ACTIVE_FUNCTION */ 914 "Command/Active Function", /* iBlok_kind_COMMAND_AF */ 915 "General Info", /* iBlok_kind_GENERAL_INFO */ 916 "Subroutine Introduction", /* iBlok_kind_SUBROUTINE_INTRO */ 917 "Subroutine Brief Intro", /* iBlok_kind_SUBROUTINE_BRIEF_INTRO */ 918 "Subroutine Entrypoint", /* iBlok_kind_SUBROUTINE_ENTRY */ 919 "Subsystem Request", /* iBlok_kind_REQUEST */ 920 "Subsystem Active Request", /* iBlok_kind_ACTIVE_REQUEST */ 921 "Subsystem Request/Active Request", /* iBlok_kind_REQUEST_AR */ 922 "Subsystem Summary", /* iBlok_kind_SUBSYSTEM_SUMMARY */ 923 "Subsystem Topic", /* iBlok_kind_SUBSYSTEM_TOPIC */ 924 "I/O Module", /* iBlok_kind_IO_MODULE */ 925 "I/O Operation", /* iBlok_kind_IO_OPERATION */ 926 "I/O Control", /* iBlok_kind_IO_CONTROL */ 927 "History Comment", /* iBlok_kind_HISTORY_COMMENT */ 928 "HEADER ONLY Info", /* iBlok_kind_Header_Only */ 929 "UNKNOWN kind of information" /* iBlok_kind_Unknown */ 930 ); 931 932 933 dcl 1 iBloksN aligned, /* Count of blocks found in info segment (by divider) */ 934 2 version fixed bin, /* - Version 2 structure. */ 935 2 counts, 936 3 (all, /* - count of all blocks. */ 937 None, /* - count of blocks with no divider */ 938 Entry, /* - count of blocks with :Entry: divider */ 939 Info, /* - count of blocks with :Info: divider */ 940 Info_no_ext_names, /* - count of blocks with :[Info]: divider */ 941 hcom, /* - count of blocks with :hcom: divider */ 942 hcom_obsolete /* - count of blocks with :Internal: divider */ 943 ) fixed bin, 944 iBloksN_version_2 fixed bin int static options(constant) init(2); 945 %page; 946 /* -------------------------------------------------------------------------------- 947 STRUCTURE: iFile 948 949 Describes the content of one info segment. 950 951 Siblings: 952 An iFile is threaded to a structure describing a higher-level aggregate. 953 954 info_seg_data.files: Each iFile.sib is threaded to other iFile structures, 955 all being chained below the info_seg_data structure. 956 957 Relatives: 958 .bloks: a threaded list of blocks contained in this info segment. 959 .lines: a threaded list of lines contained in this info segment. 960 -------------------------------------------------------------------------------- */ 961 962 dcl 1 iFile aligned based (iFileP), /* Structure describing an info_seg to be parsed or */ 963 /* examined by info_seg_ entrypoints. */ 964 2 common like iCommon, /* - ID; pointer to, and length of chars in info seg; */ 965 /* pointers to next/prev info segs to be examined. */ 966 2 location, /* - location of info seg file in Multics file system: */ 967 3 dir char(168) unal, /* - containing directory pathname */ 968 3 ent char(entrynameL) unal, /* - entryname within this directory */ 969 3 uid bit (36), /* - unique ID for info segment */ 970 2 names like iName100, /* - array of all names on info_seg (including .info) */ 971 /* in the order they would be listed by status -names */ 972 /* or the list command. */ 973 2 relatives, /* This highest-level structure has child components: */ 974 3 bloks like iChild, /* - list of blocks contained in this info segment. */ 975 3 lines like iChild, /* - list of lines contained in this info segment. */ 976 2 caseI fixed bin, /* - classification of info seg by its pattern of block */ 977 /* kinds. caseI is index into iFile_structure.array, */ 978 /* which gives rules for matching file's blocks with */ 979 /* supported block patterns. */ 980 2 structure fixed bin, /* - iFile_structure_XXX or iFile_struc_err_XXX value */ 981 /* associated with this caseI classification. */ 982 /* This maps a supported pattern to a user-friendly */ 983 /* description. For example: */ 984 /* Info Segment - with History Comment */ 985 986 2 errors aligned, /* ERROR possibilities found while parsing for lines. */ 987 /* Error comments starting with - are diagnosed by */ 988 /* info_seg_ and its info_seg_parse_ helper. */ 989 /* Error comments starting with + are diagnosed by */ 990 /* verify_info and its info_seg_verify_ helper. */ 991 3 (all_nulS, /* - File contains only NUL (\000) characters. */ 992 all_white_nulS, /* - File contains only HT SP NUL and NL chars. */ 993 ends_nulS, /* - File ends with NUL characters. */ 994 zero_lengthS, /* - File contains no characters. */ 995 996 names_missing_info_suffixS, /* + File name does not end with .info */ 997 names_extraS, /* + File has names not expected from headers/dividers */ 998 names_missingS, /* + File missing some name(s) that are required. */ 999 name_order_warningS /* + File name order differs from order predicted */ 1000 /* from names in header lines/dividers. */ 1001 ) bit(1) unal, 1002 iFileP ptr; 1003 1004 dcl File char(iFileP->iFile.L) unal based(iFileP->iFile.P); 1005 /* Character contents of entire info segment. */ 1006 1007 dcl File_names (iFileP->iFile.names.N) char(entrynameL) var based(addr(iFileP->iFile.names.nm(1))); 1008 /* Array of names on current info segment. */ 1009 1010 dcl ( /* Values for the iFile.structure element: */ 1011 /* supported patterns of blocks within info segment. */ 1012 1013 iFile_structure_NO_DIVIDERS init( 1), /* - 1 iBlok [ A ] */ 1014 /* A) only iBlok.divider = iBlok_divider_None */ 1015 1016 1017 iFile_structure_SUBROUTINE init( 2), /* - 2 or more iBloks: [ A B... ] */ 1018 /* A) first iBlok.divider = iBlok_divider_None */ 1019 /* <subroutine intro description> */ 1020 /* B) all other iBlok.divider = iBlok_divider_Entry */ 1021 /* <subroutine entrypoint description> */ 1022 1023 iFile_structure_INFO_SUBROUTINE_HCOM init( 3), /* - 3 or more iBloks: [ A B... C ] */ 1024 /* A) first iBlok.divider = iBlok_divider_Info */ 1025 /* <subroutine intro description> */ 1026 /* B) middle iBlok.divider = iBlok_divider_Entry */ 1027 /* <subroutine entrypoint description> */ 1028 /* C) last iBlok.divider = iBlok_divider_hcom */ 1029 /* <history comments> */ 1030 1031 iFile_structure_INFO_SUBROUTINE init( 4), /* - 2 or more iBloks: [ A B... ] */ 1032 /* A) first iBlok.divider = iBlok_divider_Info */ 1033 /* <subroutine intro description> */ 1034 /* B) all other iBlok.divider = iBlok_divider_Entry */ 1035 /* <subroutine entrypoint description> */ 1036 1037 iFile_structure_INFO_HCOM init( 5), /* - 2 or more iBloks: [ A... B ] */ 1038 /* A) leading iBlok.divider = iBlok_divider_Info */ 1039 /* <info contents> */ 1040 /* B) last iBlok.divider = iBlok_divider_hcom */ 1041 /* <history comments> */ 1042 1043 iFile_structure_INFO init( 6), /* - 1 or more iBloks: [ A... ] */ 1044 /* A) all iBlok.divider = iBlok_divider_Info */ 1045 /* <info contents> */ 1046 1047 /* ERROR values for iFile.structure */ 1048 iFile_struc_err_UNSET init( 0), /* - structure not yet determined. */ 1049 iFile_struc_err_EMPTY_INFO init(-1), /* - 0 iBlok structures; or 1 iBlok.emptyS */ 1050 iFile_struc_err_HCOM_NOT_LAST init(-2), /* - History Comment block not last in info seg. */ 1051 iFile_struc_err_INFO_SUBROUTINE_MIX init(-3), /* - Unknown mixture of :Info: and :Entry: divider types.*/ 1052 iFile_struc_err_1st_INFO_no_ext_names init(-4), /* - 1st block :[Info]: -- it must be :Info: */ 1053 iFile_struc_err_MISSING_1st_INFO init(-5), /* - 1st block no divider; other blocks :Info: */ 1054 iFile_struc_err_MISSING_SUBROUTINE_INTRO init(-6), /* - all blocks :Entry: (1st block must have no divider) */ 1055 iFile_struc_err_MULTIPLE_HCOM init(-7), /* - 2 or more History Comments in info seg. */ 1056 iFile_struc_err_SUBROUTINE_INFO_MIX init(-8), /* - :Entry: followed by :Info: blocks */ 1057 iFile_struc_err_STRUCTURE_UNKNOWN init(-9) /* - Unsupported pattern of block kinds. */ 1058 ) fixed bin int static options(constant); 1059 1060 /* The following table (in info_seg_specifications_.cds) */ 1061 /* gives rules for known block order patterns within */ 1062 /* info segments. */ 1063 dcl 1 iFile_structure aligned based (addr (info_seg_specifications_$file_structures)), 1064 2 patterns, 1065 3 patternN fixed bin, 1066 3 array (0 refer (iFile_structure.patterns.patternN)), 1067 4 spec char(19) aligned, /* - String pictorially describing pattern of dividers. */ 1068 /* "3+ I E... H " */ 1069 /* | | | |_ last block is history comment */ 1070 /* | | |_______ 1 or more :Entry: blocks */ 1071 /* | |__________ first block is :Info: */ 1072 /* |_______________ 3 or more total blocks */ 1073 1074 4 display_label char(54) var, /* - User-oriented label for this pattern. */ 1075 4 structID fixed bin; /* - An iFile_structure_XXX or iFile_struc_err_XXX value */ 1076 /* identifying this block pattern. */ 1077 dcl info_seg_specifications_$file_structures fixed bin external static; 1078 1079 dcl (iFile_case_UNSET init( 0) /* Initial value assigned to iFile.caseI when structure */ 1080 ) fixed bin int static options(constant); /* is first initialized. */ 1081 1082 %page; 1083 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1084 /* */ 1085 /* Structures referenced by the info_seg_ subroutine interface. */ 1086 /* */ 1087 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 1088 1089 /* -------------------------------------------------------------------------------- 1090 STRUCTURE: info_seg_data 1091 1092 Describes data used by commands that invoke info_seg_$XXX routines to parse 1093 and examine info segments. 1094 1095 info_seg_ creates an ssu_ standalone invocation to manage storage and generate 1096 output on behalf of its caller commands. Its main data item is a list of 1097 info segments to be examined by info_seg_ (.files substructure). 1098 -------------------------------------------------------------------------------- */ 1099 1100 dcl 1 info_seg_data aligned based(info_seg_dataP), /* Structure to hold info_seg_ parser information. */ 1101 2 version char(11), /* - version of this structure: info_seg_data_version_01 */ 1102 2 standalone_invocationS bit(1) aligned, /* - T: info_seg_ provided the .sciP value. */ 1103 /* F: Caller provided the .sciP value. */ 1104 /* - info_seg_$initialize sets bit = (.sciP = null) */ 1105 /* so info_seg_$terminate knows whether to cleanup */ 1106 /* the ssu_ standalone invocation. */ 1107 2 ptrs, 1108 3 sciP ptr, /* - ssu_ invocation pointer. */ 1109 3 areaP ptr, /* - translator_temp_ extendable no-freeing area pointer.*/ 1110 3 std_areaP ptr, /* - standard Multics area (system free area). */ 1111 2 relatives, 1112 3 files like iChild, /* - threaded list of iFile structures. */ 1113 info_seg_dataP ptr; 1114 1115 dcl info_seg_data_version_01 char(11) int static options(constant) init("info_seg_01"); 1116 /* Currently supported version of info_seg_data structure */ 1117 %page; 1118 /* ----------------------------------------------------------------- 1119 CHARACTERISTICS of info segments. 1120 ----------------------------------------------------------------- */ 1121 1122 dcl info_seg_suffix char(4) int static options(constant) init("info"); 1123 1124 /* TOKEN beginning an info segment BLOCK divider. */ 1125 /* See above: iBlok_divider_XXX constants */ 1126 dcl iBlok_token (0:5) 1127 init ("", /* for block without a divider */ 1128 ":Entry:", /* for SUBROUTINE info seg: each documents 1 entrypoint */ 1129 ":Info:", /* for blocks in multi-block info segment. */ 1130 ":[Info]:", /* for blocks in multi-block info segment */ 1131 /* - divider names not copied onto info segment. */ 1132 ":hcom:", /* for history comment block at end of info segment. */ 1133 ":Internal:" /* for obsolete history comment block at end of info seg.*/ 1134 ) char(10) var int static options(constant); 1135 1136 dcl ( /* LIMIT VALUES for info segments */ 1137 INFO_CHARS_PER_LINE init(71), /* excludes NL line delimiter char */ 1138 INFO_CHARS_PER_HEADER init(71), /* excludes NL line delimiter ending info header */ 1139 INFO_CHARS_PER_SUBROUTINE_ENTRYPOINT_NAME /* PL/I allows 256 char entrypoint_name labels, but */ 1140 init(32), /* help only supports names up to 32 chars in length. */ 1141 INFO_CHARS_PER_TITLE init(70), /* excludes COLON section title delimiter char */ 1142 INFO_LINES_PER_HEADER init( 2), /* maximum lines in a block divider & header */ 1143 INFO_LINES_PER_PARAGRAPH init(15), /* maximum lines in a paragraph. */ 1144 INFO_BLANK_LINES_BEFORE_PARAGRAPH init( 2) /* required blank lines before a paragraph. */ 1145 ) fixed bin int static options (constant); 1146 1147 dcl ( /* CHARACTER TYPES/GROUPS found in info segments */ 1148 BS char (1) init ("^H"), /* backspace */ 1149 COLON char (1) init (":"), /* colon */ 1150 HT char (1) init (" "), /* horizontal tab */ 1151 INFO_DATE_CHARS 1152 char (12) init("0123456789/-"), /* digits plus slash and hyphen */ 1153 INFO_HEADER_WORD_BREAK 1154 char (2) init (" ,"), /* SP comma */ 1155 INFO_LIST_WORD_BREAK 1156 char (2) init (" ,"), /* SP comma */ 1157 INFO_LINE_INDENT 1158 char (2) init (" "), /* SP SP */ 1159 /* Note: many info segs use 3 spaces for indents of */ 1160 /* description parts of items in Arguments, */ 1161 /* Control arguements, and List of ... sections. */ 1162 INFO_REQUEST_NAME_CHARS 1163 char (2) init (".?"), /* period or question_mark (eg, requests like: ? .. .) */ 1164 1165 INFO_SECTION_NO_TITLE_FABRICATION /* An untitled first section of info block is referred */ 1166 char (12) init ("Introduction"), /* to (in titles response, etc) with this title. */ 1167 1168 INFO_SUBROUTINE_INTRO_ENTRY_POINTS_IN_CONTENTS /* Contents of subroutine introduction section entitled */ 1169 char (39) init ("(List is generated by the help command)"), 1170 1171 LEFT_BRACKET char (1) init ("["), /* left-bracket */ 1172 NL char (1) init (" 1173 " ), /* newline */ 1174 NUL char (1) init ("^@"), /* nul character */ 1175 QUOTE char (1) init (""""), /* quote-mark character */ 1176 RIGHT_BRACKET char (1) init ("]"), /* right-bracket */ 1177 SP char (1) init (" "), /* space character */ 1178 WHITE_SPACE char (2) init (" "), /* HT SP */ 1179 1180 LOWER_CASE char (26) init("abcdefghijklmnopqrstuvwxyz"), 1181 UPPER_CASE char (26) init("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1182 /* characters for translating from upper to lowercase */ 1183 1184 INFO_PRINTABLE char (98) /* characters that can be used in an info segment. */ 1185 init ("^H " /* begins with BS HT NL */ 1186 || " 1187 " || " !""#$%&'()*+,-./0123456789:;<=>?" /* includes SP, with double-quote (") char escaped */ 1188 || "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_" 1189 || "`abcdefghijklmnopqrstuvwxyz{|}~" /* ends without DEL char */ 1190 ) 1191 ) int static options (constant); 1192 1193 /* END OF: info_seg_dcls_.incl.pl1 * * * * * * * * * * * * * * * * * * * */