PNOTICE_dictionary.alm 11/14/89 1106.6r w 11/14/89 1106.5 3555 dec 1 "version 1 structure dec 2 "no. of pnotices dec 3 "no. of STIs dec 156 "lgth of all pnotices + no. of pnotices acc "Copyright, (C) Honeywell Information Systems Inc., 1989" acc "Copyright (c) 1989 by Massachusetts Institute of Technology and Honeywell Information Systems, Inc." aci "C1DCTM0B0000" aci "C2DCTM0B0000" aci "C3DCTM0B0000" end  add_dict_words.pl1 12/17/85 1304.8rew 12/16/85 1652.2 294174 /* *********************************************************** * * * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * * * *********************************************************** */ /****^ HISTORY COMMENTS: 1) change(85-09-13,Spitzer), approve(85-09-13,MCR6618), audit(85-10-30,Blair), install(85-12-16,MR12.0-1001): Allow to read/write MSFs. END HISTORY COMMENTS */ add_dict_words: adw: proc; /* This program contains five commands used to modify and examine dictionaries. A dictionary is represented as an indexed file. Each word in the dictionary is represented by a key in the file. A dictionary file is somewhat unusual in that it has no actual records. Instead, the record descriptor word for each key is used to store certain attributes (e.g. hyphenation points) for the associated key. The commands are: 1. add_dict_words adds words to a dictionary 2. delete_dict_words deletes words from a dictionary 3. list_dict_words lists words in a dictionary 4. count_dict_words reports the number of words in a dictionary 5. find_dict_words finds words in the dictionaries defined by . the "dict" search list */ /* Coded by J. Stern, 1/13/77 */ /* Modified 9/77 by J. Stern to upgrade for installation */ /* Modified 10/25/77 by J. Stern to add find_dict_words command */ /* Modified 08/19/80 by P. Benjamin to fix bug when dict not first arg */ /* Modified 12/17/80 by P. Benjamin to fix bug where ddw creates dict when not found */ /* Modified 07/13/81 by P. Benjamin to fix bug where bad dict in search list causes processing to halt */ /* Automatic */ dcl ring_brackets (3) fixed bin (6); dcl bc fixed bin (24); dcl max_seg_size fixed bin (35); dcl component fixed bin; dcl type fixed bin (2); dcl msf bit (1) aligned; dcl (add_cmd, delete_cmd, list_cmd, count_cmd, find_cmd) bit (1) aligned init ("0"b); dcl whoami char (20); dcl arg_syntax char (120); dcl (nargs, words) fixed bin; dcl (argno, pn_argno) fixed bin; dcl ap ptr; dcl al fixed bin; dcl code fixed bin (35); dcl (brief_opt, force_opt, raw_opt, output_file_opt, input_file_opt, count_opt, dictionary_opt) bit (1) aligned; dcl (pname, of_pname) char (168); dcl switch char (32); dcl atd char (256) varying; dcl atd_len fixed bin; dcl second_attach bit (1) aligned; dcl iocb_ptr ptr; dcl open_mode fixed bin; dcl (of_dname, if_dname) char (168); dcl (of_ename, if_ename) char (32); dcl (of_ptr, if_ptr, fcb_ptr) ptr; dcl (of_len, if_len) fixed bin (21); dcl word_count fixed bin; dcl dict_path char (168); dcl temp_ptr ptr; dcl bad_dict_ptr ptr; dcl complained_once bit (1); dcl 1 add_key_info, 2 flags aligned like ak_header.flags, 2 descrip aligned like descriptor_template, 2 key_len fixed bin, 2 key char (256); dcl 1 delete_key_info like add_key_info; dcl 1 get_key_info, 2 flags aligned like gk_header.flags, 2 descrip aligned like descriptor_template, 2 key_len fixed bin, 2 key char (256); dcl 1 reassign_key_info, 2 flags aligned like rk_header.flags, 2 old_descrip aligned like descriptor_template, 2 new_descrip aligned like descriptor_template, 2 key_len fixed bin, 2 key char (256); dcl 1 sh_info, 2 rel_type fixed bin, 2 head_len fixed bin, 2 key_head char (256); dcl 1 info aligned like indx_info; dcl 1 fdw_control aligned, 2 exact_match bit (1) unal, 2 mbz bit (35) unal; /* Based */ dcl arg char (al) based (ap); dcl of char (of_len) based (of_ptr); dcl if char (if_len) based (if_ptr); dcl if_vec (if_len) char (1) based (if_ptr); dcl 1 descriptor_template aligned based, 2 hpoints (32) bit (1) unal, 2 notrim bit (1) unal, 2 pad bit (3) unal; dcl 1 bad_dict aligned based (bad_dict_ptr), 2 n fixed bin, 2 entry (0 refer (bad_dict.n)), 3 ecode fixed bin (35), 3 path char (168) unal; /* Conditions */ dcl cleanup condition; /* Static */ dcl stream_input fixed bin int static options (constant) init (1); dcl keyed_sequential_input fixed bin int static options (constant) init (8); dcl keyed_sequential_update fixed bin int static options (constant) init (10); dcl error_table_$dirseg fixed bin(35) ext static; dcl error_table_$long_record fixed bin(35) ext static; dcl error_table_$short_record fixed bin(35) ext static; dcl error_table_$zero_length_seg fixed bin (35) ext; dcl error_table_$noarg fixed bin (35) ext; dcl error_table_$badopt fixed bin (35) ext; dcl error_table_$key_duplication fixed bin (35) ext; dcl error_table_$no_record fixed bin (35) ext; dcl error_table_$no_key fixed bin (35) ext; dcl error_table_$end_of_info fixed bin (35) ext; dcl error_table_$noentry fixed bin (35) ext; dcl error_table_$wrong_no_of_args fixed bin (35) ext; dcl error_table_$id_not_found fixed bin (35) ext; dcl error_table_$fatal_error fixed bin(35) ext static; dcl error_table_$recoverable_error fixed bin(35) ext static; dcl iox_$user_output ptr ext; dcl sys_info$max_seg_size fixed bin(35) ext static; dcl NL char (1) aligned int static options (constant) init (" "); /* Builtins */ dcl (addr, copy, divide, index, length, max, min, null, rtrim, substr, string, unspec) builtin; /* Entries */ dcl cu_$arg_count entry (fixed bin); dcl com_err_ entry options (variable); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl iox_$attach_name entry (char(*), ptr, char(*), ptr, fixed bin(35)); dcl iox_$open entry (ptr, fixed bin, bit (1) aligned, fixed bin (35)); dcl iox_$control entry (ptr, char (*), ptr, fixed bin (35)); dcl iox_$position entry (ptr, fixed bin, fixed bin (21), fixed bin (35)); dcl iox_$close entry (ptr, fixed bin (35)); dcl iox_$detach_iocb entry (ptr, fixed bin (35)); dcl iox_$destroy_iocb entry (ptr, fixed bin(35)); dcl ioa_ options (variable); dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); dcl hcs_$status_minf entry (char(*), char(*), fixed bin(1), fixed bin(2), fixed bin(24), fixed bin(35)); dcl hcs_$make_seg entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35)); dcl initiate_file_ entry (char(*), char(*), bit(*), ptr, fixed bin(24), fixed bin(35)); dcl terminate_file_ entry (ptr, fixed bin(24), bit(*), fixed bin(35)); dcl unique_chars_ entry (bit (*)) returns (char (15)); dcl absolute_pathname_$add_suffix entry (char (*), char (*), char (*), fixed bin (35)); dcl find_dict_word_ entry (char (*), bit (36) aligned, char (256), bit (36) aligned, char (168), ptr, fixed bin (35)); dcl get_temp_segment_ entry (char (*), ptr, fixed bin (35)); dcl release_temp_segment_ entry (char (*), ptr, fixed bin (35)); dcl iox_$put_chars entry (ptr, ptr, fixed bin (21), fixed bin (35)); dcl iox_$get_line entry (ptr, ptr, fixed bin(21), fixed bin(21), fixed bin(35)); dcl pathname_ entry (char(*), char(*)) returns(char(168)); dcl msf_manager_$open entry (char(*), char(*), ptr, fixed bin(35)); dcl msf_manager_$close entry (ptr); dcl msf_manager_$get_ptr entry (ptr, fixed bin, bit(1), ptr, fixed bin(24), fixed bin(35)); dcl make_msf_ entry (char(*), char(*), (3) fixed bin(6), fixed bin(35)); dcl unmake_msf_ entry (char(*), char(*), bit(1), (3) fixed bin(6), fixed bin(35)); %page; add_cmd = "1"b; whoami = "add_dict_words"; arg_syntax = "path words {-count} {-force} {-input_file path} {-raw} {-word word}"; go to join; delete_dict_words: ddw: entry; delete_cmd = "1"b; whoami = "delete_dict_words"; arg_syntax = "path words {-brief} {-count} {-input_file path} {-word word}"; go to join; list_dict_words: ldw: entry; list_cmd = "1"b; whoami = "list_dict_words"; arg_syntax = "path words {-brief} {-input_file path} {-output_file path} {-raw} {-word word}"; go to join; count_dict_words: cdw: entry; count_cmd = "1"b; whoami = "count_dict_words"; arg_syntax = "path"; go to join; find_dict_words: fdw: entry; find_cmd = "1"b; whoami = "find_dict_words"; arg_syntax = "words {-brief} {-dictionary} {-exact_match} {-input_file path} {-output_file path} {-raw} {-word word}"; /* find out how many arguments we have */ join: call cu_$arg_count (nargs); if list_cmd | count_cmd | find_cmd then if nargs < 1 then do; noarg: code = error_table_$noarg; usage: call com_err_ (code, whoami, "^/Usage: ^a ^a", whoami, arg_syntax); return; end; else; else if nargs < 2 then go to noarg; /* examine the arguments */ brief_opt, force_opt, raw_opt, output_file_opt, input_file_opt, count_opt, dictionary_opt = "0"b; if find_cmd then do; pn_argno = 0; string (fdw_control) = ""b; end; else pn_argno = -1; words = 0; do argno = 1 to nargs; call cu_$arg_ptr (argno, ap, al, code); if index (arg, "-") ^= 1 /* not a control argument */ then if pn_argno = -1 /* don't have dictionary path yet */ then do; /* so this must be it */ call absolute_pathname_$add_suffix (arg, "dict", pname, code); if code ^= 0 then do; call com_err_ (code, whoami, arg); return; end; pn_argno = argno; end; else if count_cmd then do; code = error_table_$wrong_no_of_args; go to usage; end; else words = words +1; /* not dictionary path, must be a word */ else do; /* control argument */ if (delete_cmd | list_cmd | find_cmd) & (arg = "-bf" | arg = "-brief") then brief_opt = "1"b; else if add_cmd & (arg = "-fc" | arg = "-force") then force_opt = "1"b; else if (list_cmd | find_cmd) & (arg = "-of" | arg = "-output_file") then do; argno = argno +1; if argno > nargs then go to noarg; call cu_$arg_ptr (argno, ap, al, code); of_pname = arg; output_file_opt = "1"b; end; else if ^count_cmd & (arg = "-if" | arg = "-input_file") then do; argno = argno +1; if argno > nargs then go to noarg; input_file_opt = "1"b; end; else if (add_cmd | list_cmd | find_cmd) & arg = "-raw" then raw_opt = "1"b; else if (add_cmd | delete_cmd) & (arg = "-ct" | arg = "-count") then count_opt = "1"b; else if find_cmd & (arg = "-dict" | arg = "-dictionary") then dictionary_opt = "1"b; else if find_cmd & (arg = "-exm" | arg = "-exact_match") then fdw_control.exact_match = "1"b; else if ^count_cmd & arg = "-word" then do; argno = argno + 1; if argno > nargs then go to noarg; words = words + 1; end; else do; call com_err_ (error_table_$badopt, whoami, "^a", arg); return; end; end; end; if pn_argno = -1 then go to noarg; if (add_cmd | delete_cmd | find_cmd) & ^input_file_opt & words = 0 then go to noarg; iocb_ptr, fcb_ptr, of_ptr, if_ptr, temp_ptr, bad_dict_ptr = null; max_seg_size = sys_info$max_seg_size * 4; on cleanup call cleaner; call get_temp_segment_ (whoami, bad_dict_ptr, code); if code ^= 0 then do; call com_err_ (code, whoami); goto clean_up; end; complained_once = "0"b; /* certain errors should be given only */ /* per command, not one per word */ if find_cmd then go to check_of; /* attach and open the dictionary */ second_attach = "0"b; switch = unique_chars_ (""b) || "." || whoami; /* use unique I/O switch name */ atd = "vfile_ " || rtrim (pname); atd = atd || " -share -old"; /* build attach description, assume dictionary exists */ if list_cmd then open_mode = keyed_sequential_input; else open_mode = keyed_sequential_update; attach: call iox_$attach_name (switch, iocb_ptr, (atd), null, code); if code ^= 0 then do; call com_err_ (code, whoami, "Cannot attach switch. ^a", switch); return; end; if count_cmd then go to get_count; if second_attach /* give warning of new dictionary creation */ then call ioa_ ("^a: Creating ^a", whoami, pname); call iox_$open (iocb_ptr, open_mode, "0"b, code); if code ^= 0 then if code = error_table_$noentry & open_mode = keyed_sequential_update & ^second_attach then do; /* no dictionary, warn user and then create one */ if delete_cmd /* but not for ddw! */ then do; call com_err_ (code, whoami, "^a", pname); goto clean_up; end; call close_file (iocb_ptr); atd_len = length (rtrim (atd)); substr (atd, atd_len-3, 4) = ""; /* remove "-old" from attach description */ second_attach = "1"b; go to attach; end; else do; call com_err_ (code, whoami, "Cannot open file. ^a", pname); go to clean_up; end; /* make output segment if requested */ if list_cmd | find_cmd then do; check_of: if output_file_opt then do; call expand_pathname_ (of_pname, of_dname, of_ename, code); if code ^= 0 then do; call com_err_ (code, whoami, "^a", of_pname); go to clean_up; end; call hcs_$status_minf (of_dname, of_ename, 1, type, bc, code); if code = 0 then if type = 2 /* entry exists */ then if bc = 0 /* DIR */ then do; /* really a DIR */ code = error_table_$dirseg; goto bad_of; end; else do; /* DIR & bc>0 = MSF */ call unmake_msf_ (of_dname, of_ename, "0"b, ring_brackets, code); if code ^= 0 then goto bad_of; end; else ; /* must be a SSF */ else if code ^= error_table_$noentry then goto bad_of; /* allowed to be non-existent */ call hcs_$make_seg (of_dname, of_ename, "", 01010b, of_ptr, code); if of_ptr = null then do; bad_of: call com_err_ (code, whoami, "^a", pathname_ (of_dname, of_ename)); go to clean_up; end; end; else do; /* get temp segment to buffer output */ call get_temp_segment_ (whoami, temp_ptr, code); if code ^= 0 then do; call com_err_ (code, whoami, "Cannot get temporary segment."); go to clean_up; end; of_ptr = temp_ptr; end; component = 0; end; /* initialize info for vfile_ control orders */ if delete_cmd then do; sh_info.rel_type = 0; sh_info.head_len = 256; /* max word size = 256 */ string (delete_key_info.flags) = ""b; end; else if add_cmd then do; string (add_key_info.flags) = ""b; add_key_info.input_key, add_key_info.input_desc = "1"b; if force_opt then do; string (reassign_key_info.flags) = ""b; reassign_key_info.input_new_desc = "1"b; end; go to gk_setup; end; else if list_cmd then if words = 0 & ^input_file_opt then unspec (get_key_info.flags) = ""b; else do; gk_setup: get_key_info.flags.input_key = "1"b; get_key_info.input_desc = "0"b; get_key_info.desc_code = 0; get_key_info.rel_type = 0; get_key_info.head_size = 256; get_key_info.reset_pos = "0"b; get_key_info.flags.pad = ""b; get_key_info.version = gk_info_version_0; end; /* get to work */ of_len, word_count = 0; if list_cmd & words = 0 & ^input_file_opt then call list_all; else do argno = 1 to nargs; /* look again for words and input files */ if argno = pn_argno then argno = argno + 1; if argno > nargs then goto get_out; call cu_$arg_ptr (argno, ap, al, code); if index (arg, "-") = 1 then do; if arg = "-if" | arg = "-input_file" then do; argno = argno +1; call cu_$arg_ptr (argno, ap, al, code); call read_input_file; end; else if arg = "-of" | arg = "-output_file" then argno = argno +1; else if arg = "-word" then do; argno = argno + 1; call cu_$arg_ptr (argno, ap, al, code); call process_word (arg); end; end; else call process_word (arg); get_out: end; /* print results for list and find */ if of_len > 0 then if output_file_opt then do; call terminate_file_ (of_ptr, of_len * 9, TERM_FILE_TRUNC_BC_TERM, code); if code ^= 0 then call com_err_ (code, whoami, "Setting bit count on ^a.", pathname_ (of_dname, of_ename)); end; else do; call iox_$put_chars (iox_$user_output, of_ptr, of_len, code); if code ^= 0 then call com_err_ (code, whoami, "Attempting to write on user_output switch."); end; /* report counts if requested */ if count_opt then do; call ioa_ ("number of words ^[added^;deleted^] = ^d", add_cmd, word_count); get_count: indx_info.info_version = vfs_version_1; call iox_$control (iocb_ptr, "file_status", addr (indx_info), code); if code ^= 0 then call com_err_ (code, whoami, "Cannot get dictionary word count."); else call ioa_ ("number of dictionary words = ^d", indx_info.num_keys); end; /* clean up and leave */ clean_up: call cleaner; return; cleaner: proc; /* cleanup procedure */ if iocb_ptr ^= null then call close_file (iocb_ptr); if of_ptr ^= null then if of_ptr = temp_ptr then call release_temp_segment_ (whoami, temp_ptr, (0)); else call terminate_file_ (of_ptr, 0, TERM_FILE_TERM, (0)); if if_ptr ^= null then if msf then call close_file (if_ptr); else call terminate_file_ (if_ptr, 0, TERM_FILE_TERM, (0)); if bad_dict_ptr ^= null then call release_temp_segment_ (whoami, bad_dict_ptr, (0)); if fcb_ptr ^= null then call msf_manager_$close (fcb_ptr); return; end cleaner; /* This procedure reads words from an input file whose pathname is given by the value of arg. Words are assumed to be separated by newlines. Each word read is submitted to process_word. */ read_input_file: proc; dcl (i, max_word_len, NL_index, word_len) fixed bin (21); dcl word char (word_len) based (word_ptr); dcl word_ptr ptr; dcl if_buffer char (257); msf = "0"b; if_ptr = null; call expand_pathname_ (arg, if_dname, if_ename, code); if code ^= 0 then do; call com_err_ (code, whoami, "Input file ignored. ^a", arg); return; end; call hcs_$status_minf (if_dname, if_ename, 1, type, bc, code); if code ^= 0 then do; bad_if: call com_err_ (code, whoami, "Input file ignored. ^a", pathname_ (if_dname, if_ename)); goto EOF; end; if type = 2 then if bc = 0 then do; code = error_table_$dirseg; goto bad_if; end; else msf = "1"b; else msf = "0"b; if msf then do; atd = "vfile_ " || rtrim (if_dname); atd = atd || ">"; atd = atd || rtrim (if_ename); atd = atd || " -old"; call iox_$attach_name (unique_chars_ ("0"b) || whoami, if_ptr, (atd), null, code); if code ^= 0 then goto bad_if; call iox_$open (if_ptr, stream_input, "0"b, code); if code ^= 0 then goto bad_if; word_ptr = addr (if_buffer); max_word_len = length (if_buffer); call iox_$get_line (if_ptr, word_ptr, max_word_len, word_len, code); end; else do; call initiate_file_ (if_dname, if_ename, R_ACCESS, if_ptr, bc, code); if if_ptr = null then go to bad_if; if_len = divide (bc, 9, 21, 0); if if_len = 0 then do; code = error_table_$zero_length_seg; go to bad_if; end; i = 1; end; do while ("1"b); if msf then if code ^= 0 then if code = error_table_$end_of_info then goto EOF; else if code = error_table_$long_record | code = error_table_$short_record then ; /* allowable errors */ else goto bad_if; else do; NL_index = index (word, NL); if NL_index > 0 then word_len = NL_index - 1; if word_len = -1 then goto read_next; end; else if i > if_len then goto EOF; else do; word_len = index (substr (if, i), NL) -1; if word_len = 0 then go to read_next; if word_len = -1 then word_len = if_len - i + 1; word_ptr = addr (if_vec (i)); end; call process_word (word); read_next: if msf then call iox_$get_line (if_ptr, word_ptr, max_word_len, word_len, code); else i = i + word_len +1; end; EOF: if if_ptr ^= null then if msf then call close_file (if_ptr); else do; call terminate_file_ (if_ptr, 0, TERM_FILE_TERM, code); if_ptr = null; end; return; end read_input_file; close_file: proc (iocbp); dcl iocbp ptr parameter; if iocbp ^= null then do; call iox_$close (iocbp, (0)); call iox_$detach_iocb (iocbp, (0)); call iox_$destroy_iocb (iocbp, (0)); iocbp = null; end; return; end close_file; %page; /* This procedure selects the proper subroutine to process the current word. */ process_word: proc (cur_word); dcl cur_word char (*); if add_cmd then call add; else if delete_cmd then call delete; else if list_cmd then call list; else call find; /* This procedure adds the current word to the dictionary. It first scans the word for hyphenation and/or notrim. If the word already exists in the dictionary, it is not added (reassigned) unless the force option was specified. */ add: proc; dcl (i, j) fixed bin; dcl keystr char (256) varying; dcl next_char char (1); /* examine word for hyphenation and notrim, isolate the key */ string (add_key_info.descrip) = ""b; if raw_opt then do; if length (cur_word) > 256 then do; big_word: call com_err_ (0, whoami, "Word size exceeds 256. Word ignored. ^a", cur_word); return; end; keystr = cur_word; go to add_key; end; keystr = ""; j = 1; if substr (cur_word, 1, 1) = "^" /* check for notrim */ then do; if length (cur_word) > 1 then next_char = substr (cur_word, 2, 1); else next_char = " "; if next_char ^= "=" /* must be a notrim sign */ then add_key_info.descrip.notrim = "1"b; if next_char = "=" | next_char = "^" /* must be a literal circumflex */ then do; keystr = "^"; j = 3; end; else j = 2; end; do j = j by 1 while (j <= length (cur_word)); i = index (substr (cur_word, j), "-") -1; if i = -1 then i = length (cur_word) - j + 1; if i > 0 /* add chars to key */ then do; if i + length (keystr) > 256 then go to big_word; keystr = keystr || substr (cur_word, j, i); j = j + i; /* j points to next hyphen or circumflex */ end; if j <= length (cur_word) /* something left */ then do; if j < length (cur_word) then next_char = substr (cur_word, j+1, 1); else next_char = " "; if next_char ^= "=" /* must be a hyphenation point */ then do; if length (keystr) = 0 then do; call com_err_ (0, whoami, "Hyphenation point precedes word. Word ignored. ^a", cur_word); return; end; if substr (keystr, length (keystr), 1) = "-" then do; call com_err_ (0, whoami, "Hyphenation point immediately follows hyphen. Word ignored. ^a", cur_word); return; end; if length (keystr) > 32 then do; call com_err_ (0, whoami, "Hyphenation point occurs beyond 33rd character. Word ignored. ^a", cur_word); return; end; add_key_info.descrip.hpoints (length (keystr)) = "1"b; /* indicate hyphenation point */ end; if next_char = "=" | next_char = "-" /* must be a literal hyphen */ then do; if length (keystr) = 256 then go to big_word; keystr = keystr || "-"; /* indicate literal hyphen */ j = j + 1; /* to skip over two character sequence */ end; end; end; if length (keystr) <= 32 then if add_key_info.descrip.hpoints (length (keystr)) then do; call com_err_ (0, whoami, "Hyphenation point follows word. Word ignored. ^a", cur_word); return; end; /* add the word to the dictionary */ add_key: add_key_info.key = keystr; add_key_info.key_len = length (keystr); call iox_$control (iocb_ptr, "add_key", addr (add_key_info), code); if code = 0 then do; word_count = word_count + 1; return; end; if code ^= error_table_$key_duplication then do; call com_err_ (code, whoami, "Cannot add ""^a"".", keystr); return; end; /* same word already in dictionary */ /* see if it has the same descriptor */ get_key_info.key = add_key_info.key; get_key_info.key_len = 256; call iox_$control (iocb_ptr, "get_key", addr (get_key_info), code); if code ^= 0 then do; call com_err_ (code, whoami, "Cannot determine if word already in dictionary. Word ignored. ^a", keystr); return; end; if string (get_key_info.descrip) = string (add_key_info.descrip) /* same descrip)tor */ then return; /* nothing to do */ if force_opt | get_key_info.descrip.pad ^= ""b then do; /* give word a new descriptor */ reassign_key_info.new_descrip = add_key_info.descrip; call iox_$control (iocb_ptr, "reassign_key", addr (reassign_key_info), code); if code ^= 0 then call com_err_ (code, whoami, "Cannot reassign ""^a"".", keystr); end; else call com_err_ (0, whoami, "Word already in dictionary with different ^[hyphenation^;notrim^]. Word ignored. ^a", (string (get_key_info.descrip.hpoints) ^= string (add_key_info.descrip.hpoints)), keystr); end add; /* A procedure to delete a word from the dictionary. */ delete: proc; if length (cur_word) > 256 then go to word_not_found; sh_info.key_head = cur_word; call iox_$control (iocb_ptr, "seek_head", addr (sh_info), code); if code = 0 then call iox_$control (iocb_ptr, "delete_key", addr (delete_key_info), code); if code ^= 0 then do; if code = error_table_$no_record | code = error_table_$no_key then word_not_found: if brief_opt then; else call com_err_ (0, whoami, "Word not in dictionary. ^a", cur_word); else call com_err_ (code, whoami, "Cannot delete ""^a"".", cur_word); return; end; word_count = word_count + 1; end delete; /* A procedure to list a word from the dictionary. */ list: proc; if length (cur_word) > 256 then go to word_not_found; get_key_info.key = cur_word; get_key_info.key_len = 256; call iox_$control (iocb_ptr, "get_key", addr (get_key_info), code); if code ^= 0 then do; if code = error_table_$no_record | code = error_table_$no_key then word_not_found: if brief_opt then; else call com_err_ (0, whoami, "Word not in dictionary. ^a", cur_word); else call com_err_ (code, whoami, "Cannot list ""^a"".", cur_word); return; end; call output_word (get_key_info.key, get_key_info.key_len, string (get_key_info.descrip)); end list; /* A procedure to find a word in the sequence of dictionaries defined by the "dict" search list. */ find: proc; dcl word_found char (256); dcl desc_found bit (36) aligned; dcl baddy fixed bin; bad_dict.n = 0; call find_dict_word_ ((cur_word), string (fdw_control), word_found, desc_found, dict_path, bad_dict_ptr, code); if ^complained_once /* for each command invocation */ then do baddy = 1 to bad_dict.n; /* report each bad dictionary */ call com_err_ (bad_dict.entry.ecode (baddy), whoami, "^a", bad_dict.entry.path (baddy)); end; if code ^= 0 then if code = error_table_$recoverable_error then do; /* print recoverable error message */ if ^complained_once /* only once per command invocation */ then do; /* and don't abort */ call com_err_ (code, whoami, "^/"); complained_once = "1"b; end; end; else do; if code = error_table_$id_not_found /* this guy gets printed each time */ then if brief_opt /* unless it's suppressed */ then; else call com_err_ (0, whoami, "Word not found. ^a", cur_word); else call com_err_ (code, whoami, "Cannot find ""^a"". ^[(Referencing dictionary ^a)^]", cur_word, ((dict_path ^= "") & (code ^= error_table_$fatal_error)), dict_path); complained_once = "1"b; return; end; call output_word (word_found, length (rtrim (word_found)), desc_found); end find; end process_word; /* A procedure to list all words in the dictionary in order. */ list_all: proc; dcl i fixed bin; i, code = 0; do while (code = 0); call iox_$control (iocb_ptr, "get_key", addr (get_key_info), code); if code = 0 then do; call output_word (get_key_info.key, get_key_info.key_len, string (get_key_info.descrip)); i = i +1; call iox_$position (iocb_ptr, 0, 1, code); end; end; if code ^= error_table_$end_of_info then call com_err_ (code, whoami, "Cannot list remaining words."); else if i = 0 then if ^brief_opt then call com_err_ (0, whoami, "No words in dictionary."); end list_all; /* This procedure outputs a word. If the raw option was not specified, the word is edited to display its hyphenation and notrim attributes. If an output segment was specified, the word is copied to that segment with a newline appended. Otherwise, the word is printed on the user's terminal. */ output_word: proc (word, word_len, word_desc); dcl word char (256); dcl word_len fixed bin; dcl word_desc bit (36) aligned; dcl 1 desc aligned like descriptor_template based (addr (word_desc)); dcl (i, i2, j) fixed bin; dcl out_buf char (300) varying; if raw_opt then out_buf = substr (word, 1, word_len); else do; j = 1; if desc.notrim then out_buf = "^"; else if substr (word, 1, 1) = "^" then do; out_buf = "^="; j = 2; end; else out_buf = ""; do while (j <= word_len); i = index (substr (word, j, word_len+1-j), "-") -1; /* find next hyphen */ if i = -1 then i = word_len + 1 - j; if j <= 32 then do; i2 = index (substr (string (desc.hpoints), j, 33-j), "1"b); /* find next hyphenation point */ if i2 = 0 then i2 = 257; end; else i2 = 257; i = min (i, i2); /* get index of closest hyphen or hyphenation point */ if i > 0 /* we've skipped a few chars */ then do; /* add them to output */ out_buf = out_buf || substr (word, j, i); j = j + i; if i2 <= i /* there is a hyphenation point */ then out_buf = out_buf || "-"; /* show it */ end; if j <= word_len /* haven't reached the end yet */ then if substr (word, j, 1) = "-" /* there's a real hyphen */ then do; /* put it in the output */ if i2 > i /* there is no hyphenation point */ then out_buf = out_buf || "-="; else out_buf = out_buf || "-"; j = j + 1; end; end; end; call output (out_buf); if dictionary_opt then do; call output (copy (" ", max (1, 19 - length (out_buf)))); call output (rtrim (dict_path)); end; call output ((NL)); return; output: proc (str) recursive; dcl str char (*) varying parameter; dcl (len, chars_that_fit) fixed bin (21); len = length (str); if of_len + len + 1 > max_seg_size then if output_file_opt then do; chars_that_fit = max_seg_size - of_len; substr (of, of_len+1, chars_that_fit) = str; if component = 0 then do; call terminate_file_ (of_ptr, max_seg_size * 9, TERM_FILE_BC | TERM_FILE_TERM, code); if code ^= 0 then goto bad_of; call make_msf_ (of_dname, of_ename, ring_brackets, code); if code ^= 0 then goto bad_of; call msf_manager_$open (of_dname, of_ename, fcb_ptr, code); if code ^= 0 then goto bad_of; call msf_manager_$get_ptr (fcb_ptr, 1, "1"b, of_ptr, bc, code); if code ^= 0 then goto bad_of; component = 1; end; else do; call terminate_file_ (of_ptr, max_seg_size * 9, TERM_FILE_BC | TERM_FILE_TERM, code); if code ^= 0 then goto bad_of; call msf_manager_$get_ptr (fcb_ptr, component+1, "1"b, of_ptr, bc, code); if code ^= 0 then goto bad_of; component = component + 1; end; of_len = 0; /* empty output file */ if len > chars_that_fit then call output (substr (str, chars_that_fit + 1)); return; end; else do; call iox_$put_chars (iox_$user_output, of_ptr, of_len, code); if code ^= 0 then do; call com_err_ (code, whoami, "attempting to write on user_output switch."); goto clean_up; end; of_len = 0; end; substr (of, of_len+1, len) = str; of_len = of_len + len; return; end output; end output_word; %page; /* include files */ %include vfs_info; %include ak_info; %include terminate_file; %include access_mode_values; end add_dict_words;  alphabetize_strings_.pl1 11/18/82 1707.6rew 11/18/82 1629.0 40230 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ alphabetize_strings_: proc (pm_data_p, pm_count); /* A procedure to sort a collection of strings into alphabetical order. */ /* Coded 10/19/77 by J. Stern */ /* Parameters */ dcl pm_data_p ptr; /* ptr to an array of string descriptors */ dcl pm_count fixed bin (21); /* number of strings to alphabetize */ /* Automatic */ dcl code fixed bin (35); dcl temp_ptrs (3) ptr; dcl (data_p, new_data_p) ptr; dcl buffer_p ptr; dcl max_seglen fixed bin (21); dcl buffer_len fixed bin (21); dcl str_p ptr; dcl str_len fixed bin (21); dcl i fixed bin (21); dcl saved_blen fixed bin (21); /* Based */ dcl 1 sort_data (pm_count) aligned based (data_p) like sort_entry; dcl 1 new_sort_data (pm_count) aligned based (new_data_p) like sort_entry; dcl 1 sort_entry aligned based, 2 string_p ptr unal, 2 string_len fixed bin (21); dcl buffer char (buffer_len) based (buffer_p); dcl buf_vector (buffer_len) char (1) based (buffer_p); dcl cstring char (str_len) based (str_p); /* Static */ dcl sys_info$max_seg_size fixed bin (21) ext; dcl error_table_$action_not_performed fixed bin (35) ext; dcl capital_letters char (26) int static options (constant) init ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); dcl small_letters char (26) int static options (constant) init ("abcdefghijklmnopqrstuvwxyz"); /* Conditions */ dcl cleanup condition; /* Builtins */ dcl (substr, addr, search, translate, null, verify) builtin; /* Entries */ dcl get_temp_segments_ entry (char (*), (*) ptr, fixed bin (35)); dcl release_temp_segments_ entry (char (*), (*) ptr, fixed bin (35)); dcl sub_err_ entry options (variable); dcl sort_strings_$indirect entry (ptr, fixed bin (21), ptr); dcl ascii_to_abcdef_ entry (char (*), char (*)); /* get some temporary segments */ temp_ptrs (*) = null; on cleanup call cleaner; retry: call get_temp_segments_ ("alphabetize_strings_", temp_ptrs, code); if code ^= 0 then do; call sub_err_ (code, "alphabetize_strings_", "h", null, (0), "Cannot get temporary segments."); go to retry; end; /* build a new array of string descriptors */ /* transform strings containing control chars or capital letters */ new_data_p = temp_ptrs (1); buffer_p = temp_ptrs (2); data_p = pm_data_p; max_seglen = 4 * sys_info$max_seg_size; buffer_len = 0; do i = 1 to pm_count; str_p = sort_data (i).string_p; str_len = sort_data (i).string_len; if verify (cstring, small_letters) = 0 then do; /* plain vanilla string, use in place */ new_sort_data (i) = sort_data (i); go to next_string; end; if buffer_len + 2*str_len + 1 > max_seglen /* buffer is full */ then do; /* switch to next temp seg */ if buffer_p = temp_ptrs (3) /* already used spare temp seg */ then call sub_err_ (error_table_$action_not_performed, "alphabetize_strings_", "s", null, (0), "Temporary storage limit exceeded."); call ascii_to_abcdef_ (buffer, buffer); /* rearrange char codes so letters precede all else */ buffer_p = temp_ptrs (3); buffer_len = 0; end; saved_blen = buffer_len; if search (cstring, capital_letters) ^= 0 then do; substr (buffer, buffer_len + 1, str_len + 1) = translate (cstring, small_letters, capital_letters); buffer_len = buffer_len + str_len + 1; /* extra +1 to insert SPACE */ end; substr (buffer, buffer_len+1, str_len) = cstring; buffer_len = buffer_len + str_len; new_sort_data (i).string_p = addr (buf_vector (saved_blen+1)); new_sort_data (i).string_len = buffer_len - saved_blen; next_string: end; call ascii_to_abcdef_ (buffer, buffer); /* rearrange char codes so letters precede all else */ call sort_strings_$indirect (new_data_p, pm_count, data_p); call cleaner; return; cleaner: proc; if temp_ptrs (1) ^= null then call release_temp_segments_ ("alphabetize_strings_", temp_ptrs, code); end cleaner; end alphabetize_strings_;  ascii_to_abcdef_.alm 11/18/82 1707.6rew 11/18/82 1626.3 24894 " *********************************************************** " * * " * * " * Copyright, (C) Honeywell Information Systems Inc., 1981 * " * * " * * " *********************************************************** "ALM subroutine to convert from 9 bit ASCII to 9 bit ABCDEF "ABCDEF is identical to ASCII except that the 400 bit is on for all non-alphabetic chars "input bytes must be valid ASCII characters whose octal values "fall in the range 000 <_ octal_value <_ 177 " "ARG 1: pointer to source string - data to be converted "ARG 2: pointer to target string - converted data " "PL/I Usage: " "dcl ascii_to_abcdef_ ext entry (char (*), char (*)); " call ascii_to_abcdef_ (input_string, output_string); " " "Note: the ASCII to ABCDEF mapping used is defined in the " text of this procedure. It is available to a user " program through the following declaration. " "dcl ascii_to_abcdef_$aa_table char (128) external static; " "The table consists of 128 ABCDEF characters which "correspond to the 128 ASCII characters. The first character "corresponds to 000, the 2nd to 001, ....., the 128th "to 177. " "Converted from ascii_to_ebcdic_ by J. Stern 11/2/77 name ascii_to_abcdef_ segdef ascii_to_abcdef_ segdef aa_table ascii_to_abcdef_: epp1 ap|2,* address of source string to pr1 epp3 ap|4,* address of target string to pr3 ldx3 0,du set x3 not to skip parent pointer if none lxl2 ap|0 load argument list code value canx2 =o000004,du check for code 4 - no parent pointer tnz *+2 transfer if no parent pointer ldx3 2,du parent pointer - set x3 to skip it lda ap|6,x3* load source string descriptor ldq ap|8,x3* load target string descriptor ana mask drop all but string size bits anq mask ditto even mvt (pr,rl),(pr,rl),fill(040) translate ascii to abcdef desc9a 1|0,al source string desc9a 3|0,ql target string arg aa_table short_return "exit mask: oct 000077777777 even aa_table: oct 400401402403,404405406407 oct 410411412413,414415416417 oct 420421422423,424425426427 oct 430431432433,434435436437 oct 000441442443,444445446447 oct 450451452453,454455456457 oct 460461462463,464465466467 oct 470471472473,474475476477 oct 500101102103,104105106107 oct 110111112113,114115116117 oct 120121122123,124125126127 oct 130131132533,534535536537 oct 540141142143,144145146147 oct 150151152153,154155156157 oct 160161162163,164165166167 oct 170171172573,574575576577 bss ,96 codes > 177 translate to 000 end  create_wordlist.pl1 01/23/89 1231.4rew 01/23/89 1229.7 383256 /****^ *********************************************************** * * * Copyright, (C) Honeywell Bull Inc., 1989 * * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * *********************************************************** */ /****^ HISTORY COMMENTS: 1) change(85-09-13,Spitzer), approve(85-09-13,MCR6618), audit(85-10-30,Blair), install(85-12-16,MR12.0-1001): Allow to read/write MSFs. 2) change(88-10-05,Lee), approve(88-11-14,MCR8018), audit(88-11-28,Flegel), install(89-01-23,MR12.3-1010): phx20562 (Commands 478) - fixed bug in locate_words when -lines control arg is specified. END HISTORY COMMENTS */ create_wordlist: cwl: proc; /* converted 7/12/77 by J. Stern from word_list to create_wordlist modified 05/28/80 by P. Benjamin to fix missing -li shortname for -lines and fix bug where -li has no arg and should default to 0 modified 05/29/80 by P. Benjamin to fix -lg bug where all lines not printed. */ /* Automatic */ dcl temp_dir char (168); dcl (uid_in, uid_out) bit (36) aligned; /* File UIDs */ dcl current_record fixed bin (24); dcl max_line_len fixed bin (21); /* size of read input buffer */ dcl changed_lines bit (1) aligned; /* =1b, changed input line */ dcl output_record_number fixed bin (35); /* record number in temp file */ dcl (inputp, outputp, sortp) ptr init (null); /* IOCB pointers */ dcl type fixed bin (2); /* 1=segment, 2=directory */ dcl msf bit (1) aligned; dcl (nmp, mpp, mlp, rlp, rpp, system_area_ptr) ptr init (null); dcl ap ptr; dcl al fixed bin; dcl (ldpp, ldcp) ptr init (null); dcl old_ptr ptr; dcl old_count fixed bin; dcl plip ptr init (null); dcl prevx fixed bin; dcl lines fixed bin (24) init (-1); dcl (argno, n_args, n_words, wordx) fixed bin; dcl no_sort_opt bit (1) aligned init ("0"b); dcl (brief_opt, long_opt) bit (1) aligned init ("0"b); dcl header_opt bit (1) aligned init ("0"b); dcl no_exclude_opt bit (1) aligned init ("0"b); dcl count_opt bit (1) aligned init ("0"b); dcl no_control_opt bit (1) aligned init ("0"b); dcl (cwl_cmd, lw_cmd, rw_cmd) bit (1) aligned init ("0"b); dcl got_pname bit (1) aligned init ("0"b); dcl invalid_sw bit (1) aligned; dcl ul_sw bit (1) aligned; dcl whoami char (16); dcl (ename, input_ename, sort_name) char (32); dcl (dname, input_dname, sort_dir) char (168); dcl arg_syntax char (120); dcl code fixed bin (35); dcl bc fixed bin (24); dcl temp_ptr_array (3) ptr init ((3) null); dcl (input_ptr, temp_ptr, output_ptr, sort_data_ptr) ptr init (null); dcl (input_len, output_len, temp_len) fixed bin (21); dcl line_ptr ptr; dcl strip_ptr ptr; dcl (to_line, from_line) fixed bin (24) init (0); dcl (delim_ix, delim_len, line_ix, line_len, ul_spaces) fixed bin (21); dcl (token_ix, token_len, strip_ix, strip_len, word_ix, word_len, ul_ix, ul_len) fixed bin (24); dcl (rev_line_ix, rev_line_len) fixed bin (24); dcl (i, j, n, line_diff, last, line, output_words) fixed bin (24); dcl ul_ptr ptr; dcl max_sort_entries fixed bin (24); /* Based */ dcl system_area area (65536) based (system_area_ptr); dcl arg char (al) based (ap); dcl match_word char (match_len (wordx)) based (match_ptr (wordx)); dcl match_len (n_words) based (mlp) fixed bin; dcl match_ptr (n_words) based (mpp) ptr; dcl rev_word char (rev_len (wordx)) based (rev_ptr (wordx)); dcl rev_len (n_words) based (rlp) fixed bin; dcl rev_ptr (n_words) based (rpp) ptr; dcl num_matches (n_words) based (nmp) fixed bin; dcl line_data_ptr (n_words) ptr based (ldpp); dcl line_data_count (n_words) fixed bin based (ldcp); dcl 1 line_data (line_data_count (wordx)) aligned based (line_data_ptr (wordx)), 2 line_num fixed bin, 2 line_index fixed bin (24); dcl line_data_kludge (2 * line_data_count (wordx)) fixed bin based (line_data_ptr (wordx)); dcl line_data_mover (old_count) fixed bin (71) based (old_ptr); dcl prev_line_ix (0 : lines-1) fixed bin (24) based (plip); dcl input_cs char (input_len) based (input_ptr); dcl input_vec (input_len) char (1) unal based (input_ptr); dcl input_line char (line_len) based (line_ptr); dcl output_cs char (output_len) based (output_ptr); dcl temp_cs char (temp_len) based (temp_ptr); dcl temp_vec (temp_len) char (1) unal based (temp_ptr); dcl strip_cs char (1048576) based (strip_ptr); dcl strip_vec (1048576) char (1) based (strip_ptr); dcl ul_cs char (ul_len) based (ul_ptr); dcl ul_vec (ul_len) char (1) based (ul_ptr); dcl 1 sort_data (max_sort_entries) aligned based (sort_data_ptr), 2 wordp ptr unal, 2 wordl fixed bin (24); /* Static */ dcl line_data_incr fixed bin int static init (50); dcl delims char (5) aligned int static init (" "); /* SPACE, HT, VT, FF, NL */ dcl NL char (1) aligned int static init (" "); dcl letters char (52) int static options (constant) init ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); dcl (error_table_$noarg, error_table_$dirseg, error_table_$key_duplication, error_table_$no_key, error_table_$no_record, error_table_$short_record, error_table_$end_of_info, error_table_$noentry, error_table_$wrong_no_of_args, error_table_$badopt, error_table_$inconsistent, error_table_$zero_length_seg, error_table_$entlong) fixed bin (35) ext; dcl sys_info$max_seg_size fixed bin (24) ext static; /* Conditions */ dcl cleanup condition; /* Builtins */ dcl (addr, divide, index, hbound, length, max, min, mod, null, reverse, rtrim, search, substr, unspec, verify) builtin; /* Entries */ dcl absolute_pathname_ entry (char(*), char(*), fixed bin(35)); dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl expand_pathname_ ext entry (char (*), char (*), char (*), fixed bin (35)); dcl get_system_free_area_ entry (ptr); dcl delete_$path entry (char(*), char(*), bit(36) aligned, char(*), fixed bin(35)); dcl initiate_file_ entry (char(*), char(*), bit(*), ptr, fixed bin(24), fixed bin(35)); dcl terminate_file_ entry (ptr, fixed bin(24), bit(*), fixed bin(35)); dcl com_err_ ext entry options (variable); dcl ioa_ ext entry options (variable); dcl get_wdir_ ext entry returns (char (168)); dcl hcs_$get_uid_file entry (char (*), char (*), bit (36) aligned, fixed bin (35)); dcl hcs_$make_seg ext entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35)); dcl hcs_$status_minf entry (char(*), char(*), fixed bin(1), fixed bin(2), fixed bin(24), fixed bin(35)); dcl cv_dec_check_ entry (char (*), fixed bin (35)) returns (fixed bin (24)); dcl alphabetize_strings_ entry (ptr, fixed bin (24)); dcl (get_temp_segments_, release_temp_segments_) entry (char (*), (*) ptr, fixed bin (35)); dcl unique_chars_ entry (bit(*)) returns(char(15)); dcl get_pdir_ entry() returns(char(168)); dcl pathname_ entry (char(*), char(*)) returns(char(168)); dcl iox_$attach_name entry (char(*), ptr, char(*), ptr, fixed bin(35)); dcl iox_$open entry (ptr, fixed bin, bit(1) aligned, fixed bin(35)); dcl iox_$close entry (ptr, fixed bin(35)); dcl iox_$detach_iocb entry (ptr, fixed bin(35)); dcl iox_$destroy_iocb entry (ptr, fixed bin(35)); dcl iox_$get_line entry (ptr, ptr, fixed bin(21), fixed bin(21), fixed bin(35)); dcl iox_$put_chars entry (ptr, ptr, fixed bin(21), fixed bin(35)); dcl iox_$position entry (ptr, fixed bin, fixed bin(21), fixed bin(35)); dcl iox_$control entry (ptr, char(*), ptr, fixed bin(35)); %page; cwl_cmd = "1"b; /* remember we came in via the create_wordlist entry */ whoami = "create_wordlist"; arg_syntax = "path {-brief} {-from N} {-to N} {-header} {-no_sort} {-no_exclude} {-no_control_lines}"; goto join; locate_words: lw: entry; lw_cmd = "1"b; /* remember we came in via the locate_words entry */ whoami = "locate_words"; arg_syntax = "path words {-from N} {-to N} {-header} {-lines N | -long | -count} {-word word}"; goto join; revise_words: rw: entry; rw_cmd = "1"b; /* remember we came in via the revise_words entry */ whoami = "revise_words"; arg_syntax = "path word1 rev1 ... wordN revN {-from N} {-to N} {-header} {-lines N | -long | -brief} {-word word rev}"; join: call cu_$arg_count (n_args); /* get number of arguments */ if cwl_cmd & n_args < 1 then do; noarg: code = error_table_$noarg; usage: call com_err_ (code, whoami, "^/Usage: ^a ^a", whoami, arg_syntax); return; end; if lw_cmd & n_args < 2 then goto noarg; if rw_cmd & n_args < 3 then goto noarg; if ^cwl_cmd then do; if lw_cmd then n_words = n_args; /* upper bound on number of words */ else n_words = divide (n_args, 2, 17, 0); on cleanup call cleaner; call get_system_free_area_ (system_area_ptr); allocate match_len in (system_area); allocate match_ptr in (system_area); if rw_cmd then do; allocate rev_len in (system_area); allocate rev_ptr in (system_area); end; end; temp_dir = get_pdir_ (); n_words = 0; do argno = 1 by 1 to n_args; call cu_$arg_ptr (argno, ap, al, code); if index (arg, "-") ^= 1 then do; /* not an option */ if ^got_pname then do; /* this should be a pathname */ call expand_pathname_ (arg, dname, ename, code); if code ^= 0 then do; call com_err_ (code, whoami, arg); return; end; got_pname = "1"b; end; else if cwl_cmd then do; code = error_table_$wrong_no_of_args; goto usage; end; else do; /* this should be a match word */ insert_word: do wordx = 1 to n_words while (match_word < arg); /* find place to insert arg. */ end; do j = n_words to wordx by -1; /* make room for insertion. */ match_ptr (j + 1) = match_ptr (j); match_len (j + 1) = match_len (j); if rw_cmd then do; rev_ptr (j + 1) = rev_ptr (j); rev_len (j + 1) = rev_len (j); end; end; match_ptr (wordx) = ap; /* save ptr to current word */ match_len (wordx) = al; /* save length of current word */ n_words = n_words + 1; if rw_cmd then do; call next_arg; rev_ptr (wordx) = ap; rev_len (wordx) = al; end; end; end; else if arg = "-word" then do; call next_arg; goto insert_word; end; else if cwl_cmd & (arg = "-no_sort" | arg = "-ns") then no_sort_opt = "1"b; else if ^lw_cmd & (arg = "-bf" | arg = "-brief") then brief_opt = "1"b; else if arg = "-he" | arg = "-header" then header_opt = "1"b; else if ^cwl_cmd & (arg = "-lg" | arg = "-long") then long_opt = "1"b; else if cwl_cmd & (arg = "-ne" | arg = "-no_exclude") then no_exclude_opt = "1"b; else if lw_cmd & (arg = "-ct" | arg = "-count") then count_opt = "1"b; else if ^lw_cmd & (arg = "-temp_dir" | arg = "-td") then do; call next_arg; call absolute_pathname_ (arg, temp_dir, code); if code ^= 0 then do; call com_err_ (code, whoami, "^a", arg); return; end; end; else if arg = "-ncl" | arg = "-no_control_lines" then no_control_opt = "1"b; else if arg = "-fm" | arg = "-from" then do; call next_arg_num (from_line); if code ^= 0 | from_line < 1 then do; bad_line: call com_err_ (0, whoami, "Invalid line number. ^a", arg); return; end; end; else if arg = "-to" then do; call next_arg_num (to_line); if code ^= 0 | to_line < 1 then goto bad_line; end; else if ^cwl_cmd & (arg = "-lines" | arg = "-li") then do; if argno + 1 > n_args then lines = 0; else do; argno = argno + 1; call cu_$arg_ptr (argno, ap, al, code); lines = cv_dec_check_ (arg, code); if code ^= 0 then do; lines = 0; code = 0; argno = argno - 1; end; end; if lines < 0 then do; call com_err_ (0, whoami, "Invalid line count. ^a", arg); return; end; end; else do; call com_err_ (error_table_$badopt, whoami, "^a", arg); return; end; end; if ^got_pname /* pathname missing */ | (^cwl_cmd & n_words = 0) /* match word(s) missing */ then goto noarg; if (long_opt | lines ^= -1) & (count_opt | brief_opt) then do; call com_err_ (error_table_$inconsistent, whoami, "^[-count^;-brief^] and ^[-long^;-lines^] are mutually exclusive.", count_opt, long_opt); return; end; if lines > -1 then long_opt = "1"b; else lines = 0; if ^cwl_cmd then do; /* check validity of word arguments */ invalid_sw = "0"b; /* assume all word arguments are valid */ do wordx = 1 to n_words; call validate_word (match_word); end; if invalid_sw then return; allocate num_matches in (system_area); num_matches (*) = 0; if ^count_opt then do; allocate line_data_ptr in (system_area); allocate line_data_count in (system_area); line_data_count (*) = 0; end; if lines > 0 then do; allocate prev_line_ix in (system_area); prev_line_ix (*) = 1; end; end; else on cleanup call cleaner; input_ename = ename; /* save for later */ input_dname = dname; call hcs_$status_minf (dname, ename, 1, type, bc, code); if code ^= 0 then call err_exit; if type = 2 then if bc = 0 /* directory */ then do; code = error_table_$dirseg; /* can't do anything with it */ call err_exit; end; else msf = "1"b; /* directory with bit count = MSF */ else msf = "0"b; /* If the input is an MSF, then we have to use vfile_ rather thanpointer I/O to read it. There is also a possibility that if we are doing a revise_words on a non-MSF, the changes could involve growing the input segment to an MSF. That is handled later. */ if msf then call open_file (dname, ename, inputp, Stream_input); else do; /* initiate input seg */ call initiate_file_ (dname, ename, R_ACCESS, input_ptr, bc, code); if input_ptr = null then call err_exit; input_len = divide (bc, 9, 21, 0); /* get character count */ if input_len = 0 then do; code = error_table_$zero_length_seg; call err_exit; end; end; if cwl_cmd then do; /* if create_wordlist entry */ call hcs_$get_uid_file (input_dname, input_ename, uid_in, code); if code ^= 0 then call err_exit; i = length (rtrim (ename)); if i > 29 then do; /* make sure we can add ".wl" suffix to entry name */ call com_err_ (error_table_$entlong, whoami, "^a.wl", ename); goto finish; end; substr (ename, i+1, 3) = ".wl"; dname = get_wdir_ (); call hcs_$get_uid_file (dname, ename, uid_out, code); if code ^= 0 then if code ^= error_table_$noentry then call err_exit; if uid_in = uid_out then do; call com_err_ (0, whoami, "Input and output files are the same. ^a and ^a.", pathname_ (input_dname, input_ename), pathname_ (dname, ename)); goto finish; end; if msf then do; call open_file (dname, ename, outputp, Stream_output); if ^no_sort_opt then do; call open_file ("", "", sortp, Keyed_sequential_update); sort_dir = dname; sort_name = ename; end; end; else do; call hcs_$make_seg (dname, ename, "", 01010b, output_ptr, code); /* create output seg in working dir */ if output_ptr = null then call err_exit; end; end; else if rw_cmd & msf then do; /* revise_words needs to change the source file */ call open_file ("", "", outputp, Stream_output); sort_dir = dname; /* save path for deletion */ sort_name = ename; end; call get_temp_segments_ (whoami, temp_ptr_array, code); if code ^= 0 then do; call com_err_ (code, whoami, "Cannot get temporary segments."); goto finish; end; ul_ptr = temp_ptr_array (1); /* place to assemble de-underlined words */ if msf then input_ptr, line_ptr = temp_ptr_array (2); /* place to read vfile_ input */ else do; sort_data_ptr = temp_ptr_array (2); /* used for sorting */ max_sort_entries = divide (sys_info$max_seg_size, 2, 24, 0); end; if rw_cmd then temp_ptr = temp_ptr_array (3); if header_opt then call ioa_ ("^/^-^a^/", pathname_ (input_dname, input_ename)); %page; prevx = lines -1; line_ix = 1; rev_line_ix = 1; line_diff = 0; output_words = 0; /* init word counter */ output_len = 0; temp_len = 0; /* init length of temp seg */ last = 0; /* init index of last input seg char moved to temp seg */ changed_lines = "0"b; /* didnt change anything yet for revise_words */ output_record_number = 0; if msf then do; max_line_len = sys_info$max_seg_size * 4; call iox_$get_line (inputp, line_ptr, max_line_len, input_len, code); end; do line = 1 by 1; /* scan input one line at a time */ if msf then if code ^= 0 then if code = error_table_$end_of_info then goto end_of_data; else if code = error_table_$short_record then goto msf_read; /* no trailing NL */ else call err_exit; else do; msf_read: line_ix = 1; /* fake indices so that later code works */ rev_line_ix = 1; /* for both cases */ output_len = 0; temp_len = 0; last = 0; end; else if line_ix > input_len then goto end_of_data; line_len = index (substr (input_cs, line_ix), NL) -1; if line_len = -1 /* input does not end with NL */ then line_len = input_len - line_ix + 1; /* do it anyway */ if line < from_line then goto next_line; if to_line ^= 0 & line > to_line then goto end_of_data; if line_len = 0 then goto next_line; line_ptr = addr (input_vec (line_ix)); if no_control_opt then if substr (input_line, 1, 1) = "." then goto next_line; strip_ptr = line_ptr; delim_ix = 1; /* prepare to look at first char of line */ do while (delim_ix <= line_len); /* scan until line exhausted */ delim_len = verify (substr (input_line, delim_ix), delims) -1; /* skip delimiters */ if delim_len = -1 then delim_len = line_len -delim_ix +1; token_ix = delim_ix + delim_len; /* advance index past delimiters */ if token_ix > line_len then goto next_line; else if token_ix = line_len then token_len = 1; else do; token_len = search (substr (input_line, token_ix+1), delims); /* find end-of-token delimiter */ if token_len = 0 then /* no delimiter */ token_len = line_len + 1 - token_ix; /* use end of line as delimiter */ end; strip_ix = token_ix; strip_len = token_len; call strip_punc; /* strip surrounding punctuation from token */ call check_ul; /* check for underlining */ if ul_sw then do; /* the word was underlined */ ul_ix = word_ix; ul_spaces = 0; strip_ptr = ul_ptr; /* prepare to strip words in ul_cs */ i = 1; do while (i <= ul_len); /* rescan token to pick out words */ n = verify (substr (ul_cs, i), " "); /* skip spaces */ if n = 0 then goto end_of_ul; i = i + n -1; /* advance index past spaces */ ul_spaces = ul_spaces + n -1; /* remember number of spaces seen */ n = index (substr (ul_cs, i), " ") -1; /* find next space */ if n = -1 then /* no more spaces */ n = ul_len +1 -i; /* use end of token as delimiter */ strip_ix = i; strip_len = n; call strip_punc; if cwl_cmd then call output_word; else call test_word; i = i + n; end; end_of_ul: if cwl_cmd then ul_ptr = addr (ul_vec (ul_len + 1)); /* move buffer ahead for next de-underlined word */ strip_ptr = line_ptr; end; else /* no underlining to worry about */ if cwl_cmd then call output_word; else call test_word; next_token: delim_ix = token_ix + token_len; /* advance index past current token */ end; next_line: if lines > 0 /* must remember previous line indices */ then do; /* use prev_line_ix array as circular buffer */ prevx = mod (prevx + 1, lines); /* advance circular buffer index */ if msf & rw_cmd then do; prev_line_ix (prevx) = output_record_number; output_record_number = output_record_number + 1; end; else do; /* fixed for phx20562, use rev_line_ix */ /* only if revise_word command */ if ^rw_cmd then prev_line_ix (prevx) = line_ix; else prev_line_ix (prevx) = rev_line_ix; end; end; if msf then do; if rw_cmd then do; if temp_len ^= 0 then do; /* write out line to temp work file */ call iox_$put_chars (outputp, temp_ptr, temp_len, code); if code ^= 0 then call err_exit; if last < input_len /* copy end of input line */ then call iox_$put_chars (outputp, addr (input_vec (last+1)), input_len-last, code); end; else call iox_$put_chars (outputp, line_ptr, input_len, code); if code ^= 0 then call err_exit; end; call iox_$get_line (inputp, line_ptr, max_line_len, input_len, code); end; else do; line_ix = line_ix + line_len + 1; if rw_cmd & long_opt then do; rev_line_len = line_len + line_diff; /* compute length of revised line */ rev_line_ix = rev_line_ix + rev_line_len +1; /* compute index of next revised line */ line_diff = 0; end; end; end; %page; end_of_data: /* For revise_words, if there are any chars left after the last revision, move them to the temp seg. Then copy the whole temp seg into the original input seg (which becomes the output seg). */ if rw_cmd then do; if msf then do; if changed_lines then do; code = 0; do while (code = 0); /* copy rest of input file */ call iox_$get_line (inputp, line_ptr, max_line_len, input_len, code); if code = 0 | code = error_table_$short_record then call iox_$put_chars (outputp, line_ptr, input_len, code); end; if code ^= error_table_$end_of_info then call err_exit; call iox_$close (inputp, code); /* close input file */ call close_file (outputp); outputp = null; call copy_temp_file (dname, ename, get_wdir_ (), input_ename); call iox_$open (inputp, 1, "0"b, code); /* open input file for reading */ if code ^= 0 then call err_exit; end; else call close_file (outputp); /* don't need temp work file anymore */ end; else if last > 0 then do; n = input_len - last; if n > 0 then do; substr (temp_cs, temp_len+1, n) = substr (input_cs, last+1, n); temp_len = temp_len + n; end; output_ptr = input_ptr; substr (output_ptr -> temp_cs, 1, temp_len) = substr (temp_cs, 1, temp_len); input_len, output_len = temp_len; end; end; if cwl_cmd then do; /* if create_wordlist entry */ if ^brief_opt then call ioa_ ("total number of words = ^d", output_words); /* print word count */ if ^no_sort_opt then do; /* if nosort option not requested */ if msf then call copy_keyed_file; else do; call alphabetize_strings_ (sort_data_ptr, output_words); /* alphabetize the words */ call copy_sorted_words; /* copy sorted words to output seg */ end; if ^brief_opt then call ioa_ ("number of unique words = ^d", output_words); /* print unique word count */ end; end; else do; if msf then do; current_record = 1; call iox_$position (inputp, -1, 0, code); /* BOF */ end; do wordx = 1 to n_words; /* print results for locate_words or revise_words */ if count_opt then call ioa_ ("^d match^[es^] for ^a", num_matches (wordx), (num_matches (wordx) ^= 1), match_word); else if rw_cmd & ^long_opt then do; if num_matches (wordx) = 0 then call ioa_ ("No revisions for ^a", match_word); else if ^brief_opt then call ioa_ ("^d revision^[s^] for ^a", num_matches (wordx), (num_matches (wordx) ^= 1), match_word); end; else if lw_cmd & ^long_opt then do; if num_matches (wordx) = 0 then call ioa_ ("^20a NONE", match_word); else do; line_data_count (wordx) = num_matches (wordx); do i = 1 by 20 to 2*num_matches (wordx); call ioa_ ("^[^20a^;^20x^s^]^vs^10(^d^x^s^)", i = 1, match_word, i-1, line_data_kludge); end; end; end; else call print_long; /* print lines of text */ end; end; if (cwl_cmd | (rw_cmd & last > 0)) & ^msf then do; substr (output_cs, output_len+1, 4 - mod (output_len, 4)) = ""; /* set to NUL */ call terminate_file_ (output_ptr, 9*output_len, TERM_FILE_TRUNC_BC, code); /* truncate output seg */ if code ^= 0 then call err_exit; end; finish: call cleaner; exit: return; err_exit: /* moan and return */ proc; call com_err_ (code, whoami, "^a", pathname_ (input_dname, input_ename)); goto finish; end err_exit; %page; next_arg: proc; /* fetches next command arg */ argno = argno + 1; if argno > n_args then goto noarg; call cu_$arg_ptr (argno, ap, al, code); end next_arg; next_arg_num: proc (num); /* fetches next arg, converts to fixed bin */ dcl num fixed bin (24); call next_arg; num = cv_dec_check_ (arg, code); end next_arg_num; %page; validate_word: proc (word); dcl word char (*); /* checks validity of words supplied as arguments to commands a word must not contain delimiters or surrounding punctuation and must not be underlined */ if search (word, delims) ^= 0 /* word contains delimiters */ then do; bad_word: call com_err_ (0, whoami, """^a"" is not a word.", word); invalid_sw = "1"b; /* the word is invalid */ return; end; strip_ptr = addr (word); strip_ix = 1; strip_len = length (word); call strip_punc; /* strip surrounding punctuation from argument word */ if word_ix > 1 | word_len < strip_len /* some punctuation was removed */ then goto bad_word; call check_ul; /* check word for underlining */ if ul_sw then goto bad_word; end validate_word; %page; strip_punc: proc; /* removes surrounding punctuation from a string the input string is given by substr(strip_cs, strip_ix, strip_len) the output string is given by substr(strip_cs, word_ix, word_len) */ dcl n fixed bin (24); n = verify (substr (strip_cs, strip_ix, strip_len), "([{""") -1; /* check for leading punctuation including PAD (177) */ if n = -1 then goto no_strip; /* if all punctuation, do not strip */ word_ix = strip_ix + n; word_len = strip_len - n; n = verify (reverse (substr (strip_cs, word_ix, word_len)), ")]}""!,.:;?")-1; /* check for trailing punctuation */ if n = -1 then do; /* if all punctuation, do not strip */ no_strip: word_ix = strip_ix; word_len = strip_len; return; end; word_len = word_len - n; if word_len >= 2 then do; /* enough room for underlining */ if strip_ix < word_ix then if substr (strip_cs, word_ix, 2) = "_" then do; /* do not strip underlined leading punctuation */ word_ix = word_ix -1; word_len = word_len + 1; end; if word_ix + word_len < strip_ix + strip_len then if substr (strip_cs, word_ix + word_len -2, 2) = "_" then word_len = word_len +1; /* do not strip underlined trailing punctuation */ end; end strip_punc; %page; check_ul: proc; /* checks word for continuous underlining de-underlined string is assembled in ul_cs underline without adjacent backspace -> space the input word is given by substr(strip_cs, word_ix, word_len) */ dcl (i, j) fixed bin; dcl end_word_ix fixed bin; ul_sw = "0"b; /* assume word is not underlined */ if index (substr (strip_cs, word_ix, word_len), "") ^= 0 then do; /* word contains backspaces, check for underlining */ i = word_ix; end_word_ix = word_ix + word_len - 1; do j = 1 by 1 while (i <= end_word_ix); /* scan token */ if i+2 > end_word_ix then goto check_single_ul; if substr (strip_cs, i, 2) = "_" then do; substr (ul_cs, j, 1) = substr (strip_cs, i+2, 1); i = i + 3; end; else if substr (strip_cs, i+1, 2) = "_" then do; substr (ul_cs, j, 1) = substr (strip_cs, i, 1); i = i +3; end; else check_single_ul: if substr (strip_cs, i, 1) = "_" then do; substr (ul_cs, j, 1) = " "; i = i + 1; end; else return; /* not standard underlined string */ end; ul_sw = "1"b; /* yup, that was an underlined string */ ul_len = j - 1; /* remember length of de-underlined string */ end; end check_ul; %page; output_word: proc; /* Move the word specified to an output file. If MSF input, then if sorting the word goes to a keyed vfile_, else put in stream output file. If ^MSF, then if sorting, word ptr and length goes to sort_data array, else put in output seg with NL appended. Since we're eliminating white space from the input file and words are delimited by at least 1 white space character, if the input is not an MSF, the output cannot be. Words containing no letters are excluded from the wordlist unless -no_exclude specified. */ dcl 1 aki, 2 flags aligned, 3 input_key bit (1) unaligned init ("1"b), 3 input_desc bit (1) unaligned init ("1"b), 3 mbz bit (34) unaligned init ("0"b), 2 descrip fixed bin (35) init (0), 2 key_len fixed bin, 2 key char (256); if ^no_exclude_opt then if search (substr (strip_cs, word_ix, word_len), letters) = 0 then return; output_words = output_words + 1; if msf then if no_sort_opt then do; call iox_$put_chars (outputp, addr (strip_vec (word_ix)), (word_len), code); if code ^= 0 then call err_exit; call iox_$put_chars (outputp, addr (NL), length (NL), code); if code ^= 0 then call err_exit; end; else do; aki.key_len = min (256, word_len); aki.key = substr (strip_cs, word_ix, word_len); call iox_$control (sortp, "add_key", addr (aki), code); if code ^= 0 then if code = error_table_$key_duplication then ; /* allowable */ else call err_exit; end; else if no_sort_opt then do; substr (output_cs, output_len + 1, word_len) = substr (strip_cs, word_ix, word_len); output_len = output_len + word_len; substr (output_cs, output_len + 1, 1) = NL; output_len = output_len + 1; end; else do; if output_words > hbound (sort_data, 1) then do; call com_err_ (0, whoami, "Number of words exceeds sorting limit of ^d.", hbound (sort_data, 1)); goto finish; end; sort_data (output_words).wordp = addr (strip_vec (word_ix)); sort_data (output_words).wordl = word_len; end; return; end output_word; %page; test_word: proc; /* tests if current word matches any of the match words if a match is found, the action taken depends on whether locate_words or revise_words was called for locate_words, the line number and line index of the current word is saved for revise_words, the uncopied portion of the input string preceding the current word is copied to the temp seg if "-long" was specified, the line number and line index of the revised word is saved */ dcl cc fixed bin (24); dcl i fixed bin; /* Since the match_word array is sorted, we only have to search until we find the first word in the array that is greater than or equal to the current word. */ do wordx = 1 to n_words while (match_word < substr (strip_cs, word_ix, word_len)); end; if wordx <= n_words then if match_word = substr (strip_cs, word_ix, word_len) then do; num_matches (wordx) = num_matches (wordx) + 1; /* we found a match, increment match count */ if count_opt then return; if rw_cmd then do; /* move chars before current word to temp seg and revise word */ if ul_sw then do; /* word was de-underlined */ word_ix = ul_ix + ul_spaces + 3* (word_ix-1-ul_spaces); /* get index of original word */ word_len = 3 * word_len; /* get length of original word */ end; word_ix = word_ix + line_ix -1; cc = word_ix -last -1; /* compute number of unmoved chars before word_ix */ substr (temp_cs, temp_len+1, cc) = substr (input_cs, last+1, cc); /* move 'em */ last = last + cc + word_len; /* recompute last char moved */ temp_len = temp_len + cc; /* number of chars in temp seg */ changed_lines = "1"b; if ^ul_sw then do; substr (temp_cs, temp_len+1, length (rev_word)) = rev_word; /* drop in the revision */ temp_len = temp_len + length (rev_word); end; else do i = 1 to length (rev_word); /* underline the revision canonically */ if substr (rev_word, i, 1) < "_" then do; substr (temp_cs, temp_len +1, 1) = substr (rev_word, i, 1); temp_len = temp_len +1; substr (temp_cs, temp_len+1, 2) = "_"; temp_len = temp_len + 2; end; else do; substr (temp_cs, temp_len +1, 2) = "_"; temp_len = temp_len +2; substr (temp_cs, temp_len +1, 1) = substr (rev_word, i, 1); temp_len = temp_len +1; end; end; if long_opt then do; /* compute difference between original and revised line lengths */ line_diff = line_diff + length (rev_word) - word_len; goto save_line_number; end; end; else do; save_line_number: if mod (num_matches (wordx), line_data_incr) = 1 then do; /* allocate more space for line data */ old_count = line_data_count (wordx); if old_count > 0 then old_ptr = line_data_ptr (wordx); line_data_count (wordx) = old_count + line_data_incr; allocate line_data in (system_area); if old_count > 0 then do; line_data_ptr (wordx) -> line_data_mover = line_data_mover; free line_data_mover in (system_area); end; end; line_num (num_matches (wordx)) = line; /* remember line number */ if long_opt then if msf /* don't need line_index for MSFs */ then line_index (num_matches (wordx)) = 0; else do; /* remember line index */ if lines = 0 then if lw_cmd then i = line_ix; else i = rev_line_ix; else i = prev_line_ix (mod (prevx + 1, lines)); /* use oldest line in circular buffer */ line_index (num_matches (wordx)) = i; end; end; end; end test_word; %page; print_long: proc; /* prints output for -long option */ dcl (i, j, k) fixed bin (21); dcl last_line_printed fixed bin (21); dcl j_contains_match bit(1); dcl NL_index fixed bin (21); if n_words ^= 1 then if lw_cmd then call ioa_ ("^2/^a^/", match_word); else call ioa_ ("^2/^a^/", rev_word); if num_matches (wordx) = 0 then do; call ioa_ ("^-NONE"); return; end; last_line_printed = 0; do i = 1 to num_matches (wordx); /* print line containing each match */ if i > 1 then if line_num (i) = line_num (i-1) then goto next_line_num; /* don't print same line twice */ line = line_num (i); line_ix = line_index (i); do j = max (line - lines, 1) to line + lines; /* print surrounding lines */ if ^msf then if line_ix > input_len then goto next_line_num; if i < num_matches (wordx) then if (j = line_num (i+1)) & (j ^= line) then goto next_line_num; /* don't print line for next match yet */ if msf then do; if j ^= current_record then do; /* find record with relative positioning */ call iox_$position (inputp, 0, j - current_record, code); if code ^= 0 & code ^= error_table_$short_record then call err_exit; end; call iox_$get_line (inputp, line_ptr, max_line_len, line_len, code); if code ^= 0 then if code = error_table_$end_of_info then goto next_line_num; else call err_exit; current_record = j + 1; /* reading advanced by 1 record */ NL_index = index (input_line, NL); /* look for NL */ if NL_index ^= 0 then line_len = NL_index - 1; /* we have one, bump back 1 char so ioa_ doesn't print 2 NLs */ end; else do; line_ptr = addr (input_vec (line_ix)); line_len = index (substr (input_cs, line_ix), NL) -1; if line_len = -1 then line_len = input_len - line_ix + 1; end; if j > last_line_printed then do; do k = i to num_matches (wordx); if line_num (k) = j then do; j_contains_match = "1"b; k = num_matches (wordx); end; else j_contains_match = "0"b; end; call ioa_ ("^6d ^[*^; ^] ^a", j, ((lines > 0) & ((j = line) | (j_contains_match = "1"b))), input_line); last_line_printed = j; end; line_ix = line_ix + line_len + 1; end; next_line_num: end; end print_long; %page; copy_keyed_file: proc; dcl 1 gki, 2 flags aligned like gk_header.flags, 2 descrip fixed bin (35) aligned, 2 key_len fixed bin, 2 key char (256); unspec (gki) = "0"b; dname = sort_dir; ename = sort_name; call iox_$position (sortp, -1, 0, code); /* to BOF */ if code ^= 0 then call err_exit; code, output_words = 0; do while (code = 0); call iox_$control (sortp, "get_key", addr (gki), code); if code = 0 then do; output_words = output_words + 1; call iox_$put_chars (outputp, addr (gki.key), (gki.key_len), code); if code ^= 0 then call err_exit; call iox_$put_chars (outputp, addr (NL), length (NL), code); if code ^= 0 then call err_exit; call iox_$position (sortp, 0, 1, code); if code = 0 then call iox_$control (sortp, "get_key", addr (gki), code); end; end; if code = error_table_$end_of_info | code = error_table_$no_key | code = error_table_$no_record then ; /* allowable errors */ else call err_exit; return; end copy_keyed_file; %page; copy_sorted_words: proc; /* copies sorted words from temp seg to output seg eliminates duplications */ dcl i fixed bin (24); dcl unique_words fixed bin (24); dcl (wordp, last_wordp) ptr; dcl (wordl, last_wordl) fixed bin (24); dcl sort_string char (wordl) based (wordp); dcl last_sort_string char (last_wordl) based (last_wordp); unique_words = 0; last_wordl = 0; do i = 1 to output_words; wordp = sort_data (i).wordp; wordl = sort_data (i).wordl; if wordl = last_wordl then if sort_string = last_sort_string then goto next_word; unique_words = unique_words + 1; last_wordl = wordl; last_wordp = wordp; substr (output_cs, output_len + 1, wordl) = sort_string; output_len = output_len + wordl; substr (output_cs, output_len + 1, 1) = NL; output_len = output_len + 1; next_word: end; output_words = unique_words; end copy_sorted_words; %page; cleaner: proc; /* cleanup handler */ if plip ^= null then do; free prev_line_ix in (system_area); plip = null; end; if ldpp ^= null then do; do wordx = 1 to n_words; if line_data_count (wordx) > 0 then free line_data in (system_area); end; free line_data_ptr in (system_area); free line_data_count in (system_area); ldpp, ldcp = null; end; if nmp ^= null then do; free num_matches in (system_area); nmp = null; end; if mpp ^= null then do; free match_ptr in (system_area); mpp = null; end; if mlp ^= null then do; free match_len in (system_area); mlp = null; end; if rpp ^= null then do; free rev_ptr in (system_area); rpp = null; end; if rlp ^= null then do; free rev_len in (system_area); rlp = null; end; if temp_ptr_array (1) ^= null then call release_temp_segments_ (whoami, temp_ptr_array, code); if msf then do; call close_file (inputp); call close_file (outputp); if ^no_sort_opt & cwl_cmd then do; call close_file (sortp); call delete_$path (sort_dir, sort_name, "101111"b, whoami, code); if code ^= 0 then call com_err_ (code, whoami, "Deleting ^a.", pathname_ (sort_dir, sort_name)); end; end; else do; /* terminate input output segs */ if input_ptr = output_ptr then input_ptr = null; do input_ptr = input_ptr, output_ptr; if input_ptr ^= null then call terminate_file_ (input_ptr, 0, TERM_FILE_TERM, (0)); end; end; return; end cleaner; %page; copy_temp_file: proc (input_dir, input_name, output_dir, output_name); /* Copy the contents of the input file to the output file. This is only used in MSF mode. */ dcl (input_dir, output_dir) char (*) parameter; dcl (input_name, output_name) char (*) parameter; dcl buffer char (1024); dcl 1 co like copy_options; dcl copy_ entry (ptr); co.version = COPY_OPTIONS_VERSION_1; co.caller_name = whoami; co.source_dir = input_dir; co.source_name = input_name; co.target_dir = output_dir; co.target_name = output_name; unspec (co.flags) = "0"b; co.flags.delete = "1"b; /* delete source when done */ co.flags.force = "1"b; /* try to force access if needed */ unspec (co.copy_items) = "0"b; co.copy_items.update = "1"b; call copy_ (addr(co)); /* copy work file to input file */ if co.target_err_switch then call err_exit; /* errors reported by sub_err_ */ return; end copy_temp_file; %page; open_file: proc (dir, ent, iocbp, mode); dcl (dir, ent) char (*) parameter; dcl iocbp ptr parameter; dcl mode fixed bin parameter; dcl atd char (256) varying; dcl switchname char (32) varying; dname = dir; if dname = "" then dname = temp_dir; ename = ent; if ename = "" then ename = unique_chars_ ("0"b) || "." || whoami; atd = "vfile_ " || rtrim (dname); atd = atd || ">"; atd = atd || rtrim (ename); switchname = unique_chars_ (""b) || "."; switchname = switchname || whoami; call iox_$attach_name ((switchname), iocbp, (atd), null, code); if code ^= 0 then call err_exit; call iox_$open (iocbp, mode, "0"b, code); if code ^= 0 then call err_exit; return; end open_file; close_file: proc (iocbp); dcl iocbp ptr parameter; if iocbp ^= null then do; call iox_$close (iocbp, (0)); call iox_$detach_iocb (iocbp, (0)); call iox_$destroy_iocb (iocbp, (0)); end; return; end close_file; %page; %include copy_options; %include copy_flags; %include ak_info; %include access_mode_values; %include terminate_file; %include iox_modes; end create_wordlist;  find_dict_word_.pl1 02/16/88 1448.4r w 02/16/88 1411.9 108522 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ find_dict_word_: proc (pm_word, pm_control, pm_word_found, pm_descrip, pm_dict_path, pm_err_p, pm_code); /* This procedure finds a specified word in the sequence of dictionaries defined by the "dict" search list. */ /* Coded 10/17/77 by J. Stern */ /* Modified 07/07/81 by PWB to allow option of whether or not a bad dict in search list will cause processing to halt, and provide a mechanism to report those errors. */ /* Parameters */ dcl pm_word char (*); dcl pm_control bit (36) aligned; dcl pm_word_found char (256); dcl pm_descrip bit (36) aligned; dcl pm_dict_path char (168); dcl pm_err_p ptr; /* input -> null = abort if invalid dict found */ dcl pm_code fixed bin (35); /* Automatic */ dcl aborting bit (1); dcl ndict fixed bin; dcl dictx fixed bin; dcl prev_level fixed bin; dcl forget_sw bit (1) aligned; dcl dict_iocbps_p ptr; dcl good_dicts_p ptr; dcl switch char (32); dcl atd char (256); dcl word char (256) varying; dcl info_ptr ptr; dcl 1 fdw_control aligned, 2 exact_match bit (1) unal, 2 mbz bit (35) unal; dcl 1 get_key_info aligned, 2 flags like gk_header.flags, 2 descrip bit (36) aligned, 2 key_len fixed bin, 2 key char (256); /* Based */ dcl current_sl_index fixed bin (71) based (sl_info.change_index_p); dcl system_area area based (system_area_p); dcl dict_iocbps (ndict) ptr based (dict_iocbps_p); dcl good_dicts (ndict) bit (1) unal based (good_dicts_p); dcl 1 bad_dicts aligned based (pm_err_p), 2 n fixed bin, 2 entry (0 refer (bad_dicts.n)), 3 ecode fixed bin (35), 3 path char (168) unal; /* Static */ dcl system_area_p ptr int static init (null); dcl level fixed bin int static init (0); dcl have_dictionaries bit (1) aligned int static init ("0"b); dcl static_sl_info_p ptr int static; dcl static_dict_iocbps_p ptr int static; dcl static_good_dicts_p ptr int static init (null); dcl keyed_sequential_input fixed bin int static options (constant) init (8); dcl capital_letters char (26) int static options (constant) init ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); dcl small_letters char (26) int static options (constant) init ("abcdefghijklmnopqrstuvwxyz"); dcl error_table_$no_record fixed bin (35) ext static; dcl error_table_$no_key fixed bin (35) ext static; dcl error_table_$id_not_found fixed bin (35) ext static; dcl error_table_$no_search_list fixed bin (35) ext static; dcl error_table_$fatal_error fixed bin(35) ext static; dcl error_table_$recoverable_error fixed bin(35) ext static; dcl search_list_defaults_$dict ext static; /* Conditions */ dcl cleanup condition; /* Builtins */ dcl (null, rtrim, unspec, verify, search, translate, length, bit, bin, addr, substr, string) builtin; /* Entries */ dcl get_system_free_area_ entry (ptr); dcl search_paths_$get entry (char (*), bit (36), char (*), ptr, ptr, fixed bin, ptr, fixed bin (35)); dcl unique_chars_ entry (bit (*)) returns (char (15)); dcl iox_$attach_name entry (char (*), ptr, char (*), entry, fixed bin (35)); dcl iox_$open entry (ptr, fixed bin, bit (1) aligned, fixed bin (35)); dcl iox_$close entry (ptr, fixed bin (35)); dcl iox_$detach_iocb entry (ptr, fixed bin (35)); dcl iox_$control entry (ptr, char (*), ptr, fixed bin (35)); dcl sub_err_ entry options (variable); /* include files */ %include sl_info; %include ak_info; /* initialize */ pm_code = 0; pm_dict_path = ""; aborting = (pm_err_p = null()); if ^aborting then bad_dicts.n = 0; if system_area_p = null then call get_system_free_area_ (system_area_p); forget_sw = "0"b; prev_level = level; on cleanup call cleaner; level = level + 1; /* open dictionaries from search list if not already open */ if ^have_dictionaries then do; if prev_level > 0 then go to cant_do; sl_info_p, dict_iocbps_p = null; forget_sw = "1"b; call get_dictionaries; forget_sw = "0"b; end; else do; sl_info_p = static_sl_info_p; ndict = sl_info.num_paths; dict_iocbps_p = static_dict_iocbps_p; good_dicts_p = static_good_dicts_p; do dictx = 1 to ndict; if ^(good_dicts (dictx)) /* if dict was flagged as bad */ then do; /* in last invocation */ forget_sw = "1"b; call retry_bad_dict; /* then see if it works now */ forget_sw = "0"b; end; end; end; /* reopen dictionaries if search list has changed */ if current_sl_index ^= sl_info.change_index then do; if prev_level > 0 then go to cant_do; if ^aborting then bad_dicts.n = 0; forget_sw = "1"b; call forget_dictionaries; call get_dictionaries; forget_sw = "0"b; end; /* scan the dictionaries in order for the specified word */ if length (rtrim (pm_word)) > 256 /* max word size = 256 */ then go to not_found; word = substr (pm_word, 1, length (rtrim (pm_word))); unspec (fdw_control) = pm_control; get_key_info.flags.input_key = "1"b; get_key_info.input_desc = "0"b; get_key_info.desc_code = 0; get_key_info.rel_type = 0; get_key_info.head_size = 256; get_key_info.reset_pos = "0"b; get_key_info.pad = ""b; get_key_info.version = gk_info_version_0; do dictx = 1 to ndict; pm_dict_path = sl_info.pathname (dictx); if word_found () then go to finish; end; pm_dict_path = ""; not_found: pm_code = error_table_$id_not_found; finish: if pm_code = 0 & ^aborting then if bad_dicts.n ^= 0 then pm_code = error_table_$recoverable_error; call cleaner; return; cant_do: call sub_err_ (0, "find_dict_word_", "s", null, (0), "Cannot proceed without harm to prior activation. Please restart or release level ^d.", prev_level); go to cant_do; /* should never get here, but just in case */ cleaner: proc; /* cleanup procedure */ level = prev_level; if forget_sw then call forget_dictionaries; end cleaner; /* This procedure opens the dictionaries defined in the "dict" search list. */ get_dictionaries: proc; dcl i fixed bin; call search_paths_$get ("dict", "111111"b, "", null, system_area_p, sl_info_version_1, sl_info_p, pm_code); if pm_code ^= 0 then go to finish; ndict = sl_info.num_paths; allocate dict_iocbps in (system_area); allocate good_dicts in (system_area); dict_iocbps (*) = null; good_dicts (*) = "0"b; do i = 1 to ndict; pm_dict_path = sl_info.pathname (i); switch = unique_chars_ (""b); /* use unique I/O switch name */ atd = "vfile_ " || rtrim (sl_info.pathname (i)) || " -share"; /* build attach description */ call iox_$attach_name (switch, dict_iocbps (i), atd, find_dict_word_, pm_code); if pm_code ^= 0 then if aborting /* abort if that's what he wants */ then goto finish; else call log_bad_dict (i); /* or just record the bad one */ else do; call iox_$open (dict_iocbps (i), keyed_sequential_input, "0"b, pm_code); if pm_code ^= 0 then if aborting /* same here */ then goto finish; else do; call log_bad_dict (i); /* and here */ call iox_$detach_iocb (dict_iocbps (i), pm_code); end; else good_dicts (i) = "1"b; /* everybody's happy */ end; end; if (string (good_dicts) = "0"b) /* he told us not to abort */ then do; /* but ALL the dictionaries */ pm_code = error_table_$fatal_error; /* are bad */ goto finish; /* so abort anyway */ end; pm_dict_path = ""; static_sl_info_p = sl_info_p; static_dict_iocbps_p = dict_iocbps_p; static_good_dicts_p = good_dicts_p; have_dictionaries = "1"b; end get_dictionaries; /* This procedure closes any previously opened dictionaries */ forget_dictionaries: proc; dcl i fixed bin; dcl code fixed bin (35); have_dictionaries = "0"b; if dict_iocbps_p ^= null then do; do i = 1 to ndict; if dict_iocbps (i) ^= null then do; call iox_$close (dict_iocbps (i), code); call iox_$detach_iocb (dict_iocbps (i), code); dict_iocbps (i) = null; end; end; free dict_iocbps in (system_area); dict_iocbps_p = null; free good_dicts in (system_area); good_dicts_p = null; end; if sl_info_p ^= null then do; free sl_info in (system_area); sl_info_p = null; end; end forget_dictionaries; /* This procedure attempts to open a dictionary that was previously flagged as bad (probably non-existent). */ retry_bad_dict: proc; pm_dict_path = sl_info.pathname (dictx); switch = unique_chars_ (""b); /* use unique I/O switch name */ atd = "vfile_ " || rtrim (sl_info.pathname (dictx)) || " -share"; /* build attach description */ call iox_$attach_name (switch, dict_iocbps (dictx), atd, find_dict_word_, pm_code); if pm_code = 0 then do; call iox_$open (dict_iocbps (dictx), keyed_sequential_input, "0"b, pm_code); if pm_code = 0 then good_dicts (dictx) = "1"b; else do; if aborting then goto finish; call log_bad_dict (dictx); call iox_$detach_iocb (dict_iocbps (dictx), pm_code); end; end; else if aborting then goto finish; else call log_bad_dict (dictx); pm_dict_path = ""; end retry_bad_dict; /* This procedure puts the error code and associated pathname for a bad dictionary in the structure bad_dicts so that the calling procedure can report the errors. */ log_bad_dict: proc (which); dcl which fixed bin parameter; bad_dicts.n = bad_dicts.n + 1; bad_dicts.entry.ecode (bad_dicts.n) = pm_code; bad_dicts.entry.path (bad_dicts.n) = sl_info.pathname (which); pm_code = 0; end log_bad_dict; /* This procedure finds the specified word in the current dictionary. If the word does not exist and the exact_match option was not specified, the word is checked for standard capitalization. If standard capitalization is found, then the dictionary is consulted again for decapitalized forms of the same word. */ word_found: proc returns (bit (1) aligned); if ^(good_dicts (dictx)) /* ignore bad dictionary */ then return ("0"b); get_key_info.key = word; if known_word () then return ("1"b); if fdw_control.exact_match then return ("0"b); if verify (word, capital_letters) = 0 then do; if length (word) > 1 then do; substr (get_key_info.key, 2) = translate (substr (word, 2), small_letters, capital_letters); if known_word () then return ("1"b); end; check_no_cap: get_key_info.key = translate (word, small_letters, capital_letters); if known_word () then return ("1"b); end; else if length (word) > 1 then if search (substr (word, 1, 1), capital_letters) = 1 & verify (substr (word, 2), small_letters) = 0 then go to check_no_cap; return ("0"b); end word_found; /* This procedure determines whether or not a specified word is "known", i.e., whether or not the word is defined in the current dictionary. */ known_word: proc returns (bit (1) aligned); get_key_info.key_len = 256; call iox_$control (dict_iocbps (dictx), "get_key", addr (get_key_info), pm_code); if pm_code ^= 0 then if pm_code = error_table_$no_record | pm_code = error_table_$no_key then return ("0"b); else go to finish; pm_word_found = get_key_info.key; pm_descrip = get_key_info.descrip; return ("1"b); end known_word; end find_dict_word_;  hyphenate_word_.pl1 11/18/82 1707.6rew 11/18/82 1629.2 39924 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ hyphenate_word_: proc (pm_word, pm_space, pm_hpoint, pm_code); /* This procedure finds the rightmost hyphenation point within a specified word that fits within a specified number of spaces. */ /* Coded 10/19/77 by J. Stern */ /* Modified 3/5/80 by E. Wallman to incorporate changes in J. Stern's */ /* private version that never got into the >unb product. */ /* Modified 7/10/81 by P. Benjamin to reflect change in find_dict_word_ calling sequence. */ /* Parameters */ dcl pm_word char (*); /* the word to be hyphenated (Input) */ dcl pm_space fixed bin; /* the space available up to and including the hyphen (Input) */ dcl pm_hpoint fixed bin; /* the hyphenation point (Output) */ dcl pm_code fixed bin (35); /* an error code (Output) */ /* Automatic */ dcl nargs fixed bin; dcl space fixed bin; dcl i fixed bin; dcl code fixed bin (35); dcl word_found char (256); dcl dict_path char (168); dcl word char (256); dcl word_len fixed bin; dcl (leader, trailer) fixed bin; dcl 1 descriptor aligned, 2 hpoints bit (32) unal, 2 pad bit (4) unal; /* Based */ dcl based_descrip bit (36) aligned based (addr (descriptor)); /* Static */ dcl error_table_$id_not_found fixed bin (35) ext; /* Builtins */ dcl (length, substr, addr, index, reverse, min, dim, verify, null) builtin; /* Entries */ dcl find_dict_word_ entry (char (*), bit (36) aligned, char (256), bit (36) aligned, char (168), ptr, fixed bin (35)); dcl cu_$arg_count entry (fixed bin); call cu_$arg_count (nargs); /* see how many args */ if nargs = 4 /* fourth arg is optional */ then pm_code = 0; pm_hpoint = 0; leader, trailer = 0; /* do punctuation stripping */ leader = verify (pm_word, "([{""") -1; if leader = -1 then return; trailer = verify (reverse (pm_word), " )]}""!,.;:?") -1; if trailer = -1 then return; word_len = length (pm_word) - leader - trailer; if word_len > 256 then return; word = substr (pm_word, leader+1, word_len); space = pm_space - leader; if space < 2 | space > length (pm_word) then return; space = min (space, word_len); /* first_try = "1"b; */ retry: call find_dict_word_ (word, ""b, word_found, based_descrip, dict_path, null, code); if code ^= 0 /* | based_descrip = ""b */ then do; /* The code following involves parts-of-speech processing that was rejected for the >unb product. It is preserved here for posterity. */ /* dcl first_try bit (1) aligned; /*dcl new_suffix (6) char (1) varying int static options (constant) init ("y", "o", "", "y", "", ""); /*dcl (si, sl) fixed bin; /*dcl suffix (6) char (3) varying int static options (constant) init ("ies", "oes", "s", "ied", "ed", "ing"); /*dcl suffix_syllable (6) bit (1) int static options (constant) init ((5) (1) "0"b, "1"b); /* if first_try /* then do si = 1 to dim (suffix, 1); /* see if we recognize a suffix */ /* sl = length (suffix (si)); /* if substr (word, word_len-sl+1, sl) = suffix (si) /* then do; /* first_try = "0"b; /* substr (word, word_len-sl+1, sl) = new_suffix (si); /* word_len = word_len -sl + length (new_suffix (si)); /* go to retry; /* end; /* end; */ if nargs = 4 then if code ^= error_table_$id_not_found then pm_code = code; return; end; /* if ^first_try /* then if suffix_syllable (si) /* then if word_len <= 32 /* then substr (descriptor.hpoints, word_len, 1) = "1"b; */ space = min (33, space); i = index (reverse (substr (descriptor.hpoints, 1, space-1)), "1"b); if i ^= 0 then do; i = space - i; if i < word_len then if substr (word, i+1, 1) = "-" then if nargs = 4 then i = i + 1; else return; /* runoff can't handle this */ pm_hpoint = i + leader; end; end hyphenate_word_;  print_wordlist.pl1 12/17/85 1304.8rew 12/16/85 1652.5 175824 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * *********************************************************** */ /****^ HISTORY COMMENTS: 1) change(85-09-13,Spitzer), approve(85-09-13,MCR6618), audit(85-10-30,Blair), install(85-12-16,MR12.0-1001): Allow to read/write MSFs. END HISTORY COMMENTS */ print_wordlist: pwl: proc; /* Coded 11/14/77 by J. Stern */ /* Modified 10/06/83 by Charlie Spitzer. make -of use equal names. phx14967 make empty wordlist not print error. phx13055 */ /* Automatic */ dcl component fixed bin; dcl ring_brackets (3) fixed bin (6); dcl max_seg_size fixed bin (24); dcl msf bit (1) aligned; dcl type fixed bin (2); dcl (seg_output, got_pname, first_time) bit (1) aligned init ("0"b); dcl atd char (256) varying; dcl argno fixed bin; dcl ap ptr; dcl (input_ptr, output_ptr) ptr init (null); dcl nargs fixed bin; dcl al fixed bin; dcl (fcb_ptr, temp_ptr) ptr; dcl isaved fixed bin; dcl (cols, rows) fixed bin (21); dcl max_cols fixed bin; dcl last_col_rows fixed bin; dcl code fixed bin (35); dcl (dname, of_dname) char (168); dcl (ename, of_ename) char (32); dcl bc fixed bin (24); dcl (c, r, i) fixed bin (21); dcl (input_len, output_len) fixed bin (21); dcl word_ptr ptr; dcl (word_len, real_len) fixed bin (21); dcl (nwords, words_per_page) fixed bin (21); dcl (end_of_col, ntabs, nspaces, line_position) fixed bin (21); dcl col_width fixed bin (21); dcl (page_len, vert_margin, input_idx) fixed bin (21); dcl (system_area_ptr, words_ptr) ptr; dcl (first_word_row, word_index) fixed bin; /* Based */ dcl arg char (al) based (ap); dcl input_cs char (input_len) based (input_ptr); dcl output_cs char (output_len) based (temp_ptr); dcl word char (word_len) based (word_ptr); dcl words (words_per_page) char (col_width * 3) based (words_ptr); /* holds words (possibly underlined) from file */ dcl system_area area based (system_area_ptr); /* Conditions */ dcl cleanup condition; /* Static */ dcl BS char (1) int static options (constant) init (""); dcl NL char (1) int static options (constant) init (" "); dcl HT char (1) int static options (constant) init (" "); dcl NP char (1) int static options (constant) init (" "); dcl whoami char (32) int static options (constant) init ("print_wordlist"); dcl (error_table_$badopt, error_table_$dirseg, error_table_$wrong_no_of_args, error_table_$noarg, error_table_$long_record, error_table_$short_record, error_table_$end_of_info) ext fixed bin (35); dcl iox_$user_output ext ptr; dcl sys_info$max_seg_size fixed bin(35) ext static; /* Builtins */ dcl (addr, copy, divide, hbound, index, length, max, mod, null, rtrim, search, substr) builtin; /* Entries */ dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr ext entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl com_err_ ext entry options (variable); dcl get_system_free_area_ entry() returns(ptr); dcl get_equal_name_ entry (char(*), char(*), char(32), fixed bin(35)); dcl expand_pathname_$add_suffix ext entry (char (*), char (*), char (*), char (*), fixed bin (35)); dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); dcl iox_$put_chars entry (ptr, ptr, fixed bin (21), fixed bin (35)); dcl iox_$attach_name entry (char(*), ptr, char(*), ptr, fixed bin(35)); dcl iox_$open entry (ptr, fixed bin, bit(1) aligned, fixed bin(35)); dcl iox_$close entry (ptr, fixed bin(35)); dcl iox_$detach_iocb entry (ptr, fixed bin(35)); dcl iox_$destroy_iocb entry (ptr, fixed bin(35)); dcl iox_$get_line entry (ptr, ptr, fixed bin(21), fixed bin(21), fixed bin(35)); dcl unique_chars_ entry (bit(*)) returns(char(15)); dcl cv_dec_check_ ext entry (char (*), fixed bin (35)) returns (fixed bin); dcl get_line_length_$switch entry (ptr, fixed bin (35)) returns (fixed bin); dcl get_temp_segment_ entry (char(*), ptr, fixed bin(35)); dcl release_temp_segment_ entry (char(*), ptr, fixed bin(35)); dcl hcs_$make_seg entry (char(*), char(*), char(*), fixed bin(5), ptr, fixed bin(35)); dcl hcs_$status_minf entry (char(*), char(*), fixed bin(1), fixed bin(2), fixed bin(24), fixed bin(35)); dcl initiate_file_ entry (char(*), char(*), bit(*), ptr, fixed bin(24), fixed bin(35)); dcl terminate_file_ entry (ptr, fixed bin(24), bit(*), fixed bin(35)); dcl pathname_ entry (char(*), char(*)) returns(char(168)); dcl make_msf_ entry (char(*), char(*), (3) fixed bin(6), fixed bin(35)); dcl unmake_msf_ entry (char(*), char(*), bit(1), (3) fixed bin(6), fixed bin(35)); dcl msf_manager_$open entry (char(*), char(*), ptr, fixed bin(35)); dcl msf_manager_$close entry (ptr); dcl msf_manager_$get_ptr entry (ptr, fixed bin, bit(1), ptr, fixed bin(24), fixed bin(35)); /* examine arguments */ call cu_$arg_count (nargs); if nargs = 0 then do; noarg: code = error_table_$noarg; usage: call com_err_ (code, whoami, "^/Usage: print_wordlist path {-columns N} {-page_length N} {-vertical_margin N} {-output_file path}"); return; end; cols, page_len, vert_margin = -1; col_width = 20; do argno = 1 to nargs; call cu_$arg_ptr (argno, ap, al, code); if index (arg, "-") ^= 1 then do; /* not an option, must be pathname */ if got_pname then do; /* already have pathname => error */ code = error_table_$wrong_no_of_args; go to usage; end; call expand_pathname_$add_suffix (arg, "wl", dname, ename, code); if code ^= 0 then do; bad_path: call com_err_ (code, whoami, arg); return; end; got_pname = "1"b; end; else if arg = "-cols" | arg = "-columns" then do; call next_arg_num (cols); if code ^= 0 | cols < 1 then do; call com_err_ (0, whoami, "Invalid column count. ^a", arg); return; end; end; else if arg = "-cw" | arg = "-column_width" then do; call next_arg_num (col_width); if code ^= 0 | col_width < 2 then do; call com_err_ (0, whoami, "Invalid column width. ^a", arg); return; end; end; else if arg = "-pl" | arg = "-page_length" then do; call next_arg_num (page_len); if code ^= 0 | page_len < 1 then do; call com_err_ (0, whoami, "Invalid page length. ^a", arg); return; end; end; else if arg = "-vm" | arg = "-vertical_margin" then do; call next_arg_num (vert_margin); if code ^= 0 | vert_margin < 0 then do; call com_err_ (0, whoami, "Invalid vertical margin. ^a", arg); return; end; end; else if arg = "-of" | arg = "-output_file" then do; call next_arg; call expand_pathname_ (arg, of_dname, of_ename, code); if code ^= 0 then go to bad_path; if search (rtrim (of_ename), "%=") ^= 0 then do; call get_equal_name_ (ename, (of_ename), of_ename, code); if code ^= 0 then go to bad_path; end; seg_output = "1"b; end; else do; call com_err_ (error_table_$badopt, whoami, arg); return; end; end; if ^got_pname /* no pathname given */ then go to noarg; if page_len = -1 then if seg_output then page_len = 60; else page_len = 66; if vert_margin = -1 then if seg_output then vert_margin = 0; else vert_margin = 3; rows = page_len - 2 * vert_margin; if rows < 1 then do; call com_err_ (0, whoami, "Page length of ^d too small for vertical margin of ^d.", page_len, vert_margin); return; end; if seg_output then if cols = -1 then cols = max (divide (136, col_width, 17, 0), 1); /* set default cols for seg output */ else; else do; /* not seg output, check line length */ i = get_line_length_$switch (iox_$user_output, code); max_cols = max (divide (i, col_width, 17, 0), 1); if code = 0 then if cols > max_cols then do; call com_err_ (0, whoami, "Line length too small for specified number of columns."); return; end; if cols = -1 then cols = max_cols; /* set default for user_output */ end; /* open input segment */ fcb_ptr, temp_ptr, input_ptr, output_ptr, words_ptr = null; system_area_ptr = get_system_free_area_ (); component = 0; on cleanup call cleaner; call hcs_$status_minf (dname, ename, 1, type, bc, code); if code ^= 0 then call input_seg_error; if type = 2 then if bc = 0 then do; code = error_table_$dirseg; call input_seg_error; end; else msf = "1"b; else msf = "0"b; if msf then do; atd = "vfile_ " || rtrim (dname); atd = atd || ">"; atd = atd || ename; call iox_$attach_name (unique_chars_ (""b)||".pwl", input_ptr, (atd), null, code); if code ^= 0 then call input_seg_error; call iox_$open (input_ptr, 1, "0"b, code); /* open for input */ if code ^= 0 then call input_seg_error; if seg_output then do; /* make output seg */ atd = "vfile_ " || rtrim (of_dname); atd = atd || ">"; atd = atd || of_ename; call iox_$attach_name (unique_chars_ (""b)||".pwl", output_ptr, (atd), null, code); if code ^= 0 then call output_seg_error; call iox_$open (output_ptr, 2, "0"b, code); /* open for output */ if code ^= 0 then call output_seg_error; end; else output_ptr = null; end; else do; call initiate_file_ (dname, ename, R_ACCESS, input_ptr, bc, code); if input_ptr = null then call input_seg_error; input_len = divide (bc+8, 9, 24, 0); /* get character count */ input_idx = 1; /* character index */ if seg_output then do; call hcs_$make_seg (of_dname, of_ename, "", RW_ACCESS_BIN, output_ptr, code); if output_ptr = null then if code ^= error_table_$dirseg then call output_seg_error; else do; call hcs_$status_minf (of_dname, of_ename, 1, type, bc, code); if code ^= 0 then call output_seg_error; if type = 2 then if bc = 0 then do; code = error_table_$dirseg; call output_seg_error; end; /* make a SSF from the MSF, but don't save any contents. */ call unmake_msf_ (of_dname, of_ename, "0"b, ring_brackets, code); if code ^= 0 then call output_seg_error; call initiate_file_ (of_dname, of_ename, RW_ACCESS, output_ptr, bc, code); if code ^= 0 then call output_seg_error; end; if output_ptr = input_ptr then do; call com_err_ (0, whoami, "Input and output files are the same. ^a and ^a", pathname_ (dname, ename), pathname_ (of_dname, of_ename)); goto error; end; temp_ptr = output_ptr; /* build output segment directly in segment, not temp seg. */ end; end; if temp_ptr = null then do; call get_temp_segment_ (whoami, temp_ptr, code); if code ^= 0 then do; call com_err_ (code, whoami, "Cannot get temporary segment."); go to error; end; end; if output_ptr = null then output_ptr = iox_$user_output; /* writing to terminal */ output_len = 0; /* now build the output segment one page at a time */ first_time = "1"b; words_per_page = rows * cols; allocate words in (system_area) set (words_ptr); max_seg_size = sys_info$max_seg_size * 4; do while ("1"b); call fill_word_array (nwords); if nwords = 0 then if first_time then do; call com_err_ (0, whoami, "Wordlist empty. ^a", pathname_ (dname, ename)); goto error; end; else goto EOF; /* end of file */ else first_time = "0"b; if nwords < cols then do; cols = nwords; rows = 1; end; word_index, first_word_row = 1; call output (copy (NL, vert_margin), vert_margin); if rows * cols > nwords then rows = divide (nwords + cols -1, cols, 17, 0); /* minimize length of last page */ last_col_rows = rows - (rows * cols - nwords); do r = 1 to rows; if r > 1 then call output (NL, 1); if r = last_col_rows + 1 then cols = cols - 1; do c = 1 to cols; if first_word_row > rows then goto EOP; word_ptr = addr (words (word_index)); word_len = length (rtrim (words (word_index))); word_index = word_index + rows; if word_index > nwords then word_index, first_word_row = first_word_row + 1; i = index (word, BS); /* check for backspace */ if i ^= 0 then do; isaved = col_width - 2; real_len = i - 2; do i = i + 1 to word_len while (real_len <= col_width-1); if substr (word, i, 1) = BS then real_len = real_len - 1; else do; real_len = real_len + 1; if real_len = col_width - 2 then isaved = i; end; end; if real_len > col_width - 1 then word_len = isaved; end; else do; /* no backspaces */ real_len = word_len; if word_len > col_width - 1 then word_len = col_width - 2; end; call output (word, word_len); if real_len > col_width - 1 then do; real_len = col_width - 1; call output ("*", 1); end; if c < cols then do; end_of_col = c * col_width; line_position = end_of_col - col_width + real_len; ntabs = divide (end_of_col, 10, 17, 0) - divide (line_position, 10, 17, 0); if ntabs > 0 then do; call output (copy (HT, ntabs), ntabs); line_position = line_position - mod (line_position, 10) + 10 * ntabs; end; nspaces = end_of_col - line_position; if nspaces > 0 then call output (copy ("", nspaces), nspaces); end; end; /* do cols */ next_row: /* end of line */ end; /* do rows */ EOP: if seg_output then if vert_margin = 0 then call output (NP, length (NP)); else call output (copy (NL, vert_margin - length (NP))||NP, vert_margin); else do; call output (copy (NL, vert_margin+1), vert_margin+1); call iox_$put_chars (output_ptr, temp_ptr, output_len, code); if code ^= 0 then call com_err_ (code, whoami, "Attempting to write on user_output switch."); output_len = 0; /* start at beginning of segment again */ end; end; /* do forever */ EOF: /* come here on end of input file */ if output_len > 0 then if msf then do; call iox_$put_chars (output_ptr, temp_ptr, output_len, code); if code ^= 0 then call com_err_ (code, whoami, "Attempting to write on user_output switch."); end; else do; call terminate_file_ (output_ptr, output_len * 9, TERM_FILE_TRUNC_BC_TERM, code); if code ^= 0 then call com_err_ (code, whoami, "^a", pathname_ (dname, ename)); end; error: call cleaner; return; input_seg_error: proc; input_seg: call com_err_ (code, whoami, "^a", pathname_ (dname, ename)); go to error; output_seg_error: entry; dname = of_dname; ename = of_ename; go to input_seg; end input_seg_error; cleaner: proc; /* cleanup handler */ if output_ptr = iox_$user_output | output_ptr = temp_ptr then output_ptr = null; if temp_ptr ^= null then if ^msf & seg_output then ; else call release_temp_segment_ (whoami, temp_ptr, (0)); do input_ptr = input_ptr, output_ptr; if input_ptr ^= null then if msf then do; call iox_$close (input_ptr, (0)); call iox_$detach_iocb (input_ptr, (0)); call iox_$destroy_iocb (input_ptr, (0)); end; else call terminate_file_ (input_ptr, 0, TERM_FILE_TERM, (0)); end; if fcb_ptr ^= null then call msf_manager_$close (fcb_ptr); if words_ptr ^= null then free words in (system_area); return; end cleaner; next_arg: proc; /* gets next argument */ argno = argno + 1; if argno > nargs then go to noarg; call cu_$arg_ptr (argno, ap, al, code); end next_arg; next_arg_num: proc (num); /* gets next argument, converts to fixed bin */ dcl num fixed bin (21); call next_arg; num = cv_dec_check_ (arg, code); end next_arg_num; fill_word_array: proc (cnt); dcl cnt fixed bin (21); dcl nread fixed bin (21); cnt = 1; do while (cnt ^> hbound (words, 1)); if msf then do; call iox_$get_line (input_ptr, addr (words (cnt)), length (words (cnt)), nread, code); if code ^= 0 then if code = error_table_$end_of_info then do; END_OF_INPUT: cnt = cnt - 1; return; end; else if code = error_table_$long_record | code = error_table_$short_record then ; /* ok to get this one */ else call input_seg_error; else if nread = 1 then goto read_next_word; /* blank line */ else substr (words (cnt), nread) = ""; /* take out NL + leftover junk */ end; else do; if input_idx > input_len then goto END_OF_INPUT; word_len = index (substr (input_cs, input_idx), NL) -1; if word_len = 0 then do; input_idx = input_idx + 1; goto read_next_word; /* blank line */ end; if word_len = -1 then word_len = input_len - input_idx + 1; /* final newline missing */ words (cnt) = substr (input_cs, input_idx, word_len); input_idx = input_idx + word_len + 1; /* bump character index over this word */ end; cnt = cnt + 1; read_next_word: end; cnt = cnt - 1; return; end fill_word_array; %page; output: proc (str, len) recursive; dcl str char (*) parameter; /* string to output */ dcl len fixed bin (21) parameter; /* how long it is */ dcl chars_that_fit fixed bin (21); if seg_output then if msf then do; call iox_$put_chars (output_ptr, addr (str), len, code); if code ^= 0 then call output_seg_error; return; end; else if output_len + len + 1 > max_seg_size then do; /* output segment grows to an MSF */ /* Fill end of segment with whatever fits from the input string */ chars_that_fit = max_seg_size - output_len; substr (output_cs, output_len + 1, chars_that_fit) = str; if component = 0 then do; /* Terminate the output file, make it into an MSF, then open using msf_manager_. Continue to use pointer I/O on each component which has to be more efficient than using vfile_. */ call terminate_file_ (output_ptr, max_seg_size * 9, TERM_FILE_BC | TERM_FILE_TERM, code); if code ^= 0 then call output_seg_error; call make_msf_ (of_dname, of_ename, ring_brackets, code); if code ^= 0 then call output_seg_error; call msf_manager_$open (of_dname, of_ename, fcb_ptr, code); if code ^= 0 then call output_seg_error; call msf_manager_$get_ptr (fcb_ptr, 1, "1"b, output_ptr, bc, code); if code ^= 0 then call output_seg_error; component = 1; temp_ptr = output_ptr; end; else do; call terminate_file_ (output_ptr, max_seg_size * 9, TERM_FILE_BC | TERM_FILE_TERM, code); if code ^= 0 then call output_seg_error; call msf_manager_$get_ptr (fcb_ptr, component+1, "1"b, output_ptr, bc, code); if code ^= 0 then call output_seg_error; component = component + 1; temp_ptr = output_ptr; end; output_len = 0; /* empty output file */ /* Put rest of input string at the head of the output buffer. Since the string passed might not be len chars long, pad with spaces if the difference is negative. */ if len > chars_that_fit then call output (substr (str, chars_that_fit + 1), len - chars_that_fit); return; end; substr (output_cs, output_len + 1, len) = str; output_len = output_len + len; return; end output; %page; %include access_mode_values; %include terminate_file; end print_wordlist;  sort_strings_.pl1 11/18/82 1707.6rew 11/18/82 1629.3 35487 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ sort_strings_: proc (pm_Ap, pm_count); /* Algorithm 347 AN EFFICIENT ALGORITHM FOR SORTING WITH MINIMAL STORAGE Richard C. Singleton CACM 12, Number 3, March 1969, pp. 185-7 Converted to Multics PL/I by Paul A. Green - April 6, 1974 Modified to sort adjustable character strings instead of fixed binary numbers by Jerry Stern - May 30, 1974 Modified 10/19/77 by J. Stern to add $indirect entry */ /* Parameters */ dcl pm_Ap ptr; /* ptr to array of string descriptors */ dcl pm_count fixed bin (24); /* number of strings to sort */ dcl pm_Ip ptr; /* ptr to array of "indirect" data */ /* Automatic */ dcl ind_sw bit (1) aligned; dcl (Ap, Ip) ptr; dcl (first, last, median, low, high) fixed bin (24); dcl depth fixed bin; dcl 1 stack (0:20) aligned, 2 first fixed bin (24), 2 last fixed bin (24); dcl 1 A_temp aligned like A_entry; dcl I_temp fixed bin (71); /* Based */ dcl cstring char (262144) based; dcl 1 A_entry aligned based, 2 p ptr unal, 2 l fixed bin; dcl 1 A (pm_count) aligned based (Ap) like A_entry; dcl I (pm_count) fixed bin (71) based (Ip); /* Builtins */ dcl (divide, substr) builtin; ind_sw = "0"b; go to join; indirect: entry (pm_Ap, pm_count, pm_Ip); ind_sw = "1"b; Ip = pm_Ip; join: Ap = pm_Ap; depth = 0; first = 1; last = pm_count; go to L4; L1: median = divide (first + last, 2, 24, 0); low = first; high = last; if substr (A (first).p -> cstring, 1, A (first).l) > substr (A (median).p -> cstring, 1, A (median).l) then call swap (first, median); if substr (A (last).p -> cstring, 1, A (last).l) < substr (A (median).p -> cstring, 1, A (median).l) then do; call swap (last, median); if substr (A (first).p -> cstring, 1, A (first).l) > substr (A (median).p -> cstring, 1, A (median).l) then call swap (first, median); end; A_temp = A (median); L2: do high = high -1 by -1 while (substr (A (high).p -> cstring, 1, A (high).l) > substr (A_temp.p -> cstring, 1, A_temp.l)); end; do low = low +1 by 1 while (substr (A (low).p -> cstring, 1, A (low).l) < substr (A_temp.p -> cstring, 1, A_temp.l)); end; if low <= high then do; call swap (high, low); go to L2; end; if (high - first) > (last - low) then do; stack.first (depth) = first; stack.last (depth) = high; first = low; end; else do; stack.first (depth) = low; stack.last (depth) = last; last = high; end; depth = depth +1; L4: if (last - first) > 10 then go to L1; if first = 1 then if first < last then go to L1; do first = first +1 to last; A_temp = A (first); if ind_sw then I_temp = I (first); do low = first -1 by -1 while (substr (A (low).p -> cstring, 1, A (low).l) > substr (A_temp.p -> cstring, 1, A_temp.l)); A (low +1) = A (low); if ind_sw then I (low +1) = I (low); end; A (low +1) = A_temp; if ind_sw then I (low +1) = I_temp; end; depth = depth -1; if depth >= 0 then do; first = stack.first (depth); last = stack.last (depth); go to L4; end; return; swap: proc (i, j); dcl (i, j) fixed bin (24); dcl 1 A_swap aligned like A_entry; dcl I_swap fixed bin (71); A_swap = A (i); A (i) = A (j); A (j) = A_swap; if ind_sw then do; I_swap = I (i); I (i) = I (j); I (j) = I_swap; end; end swap; end sort_strings_;  trim_wordlist.pl1 02/16/88 1448.4rew 02/16/88 1406.4 181071 /****^ *********************************************************** * * * Copyright, (C) Honeywell Bull Inc., 1988 * * * * Copyright, (C) Honeywell Information Systems Inc., 1981 * * * *********************************************************** */ /****^ HISTORY COMMENTS: 1) change(85-09-13,Spitzer), approve(85-09-13,MCR6618), audit(85-10-30,Blair), install(85-12-16,MR12.0-1001): Allow to read/write MSFs. 2) change(88-01-01,Gilcrease), approve(88-02-05,MCR7834), audit(88-02-05,Blair), install(88-02-16,MR12.2-1023): Fix trim error when first letter cap, and contains '. END HISTORY COMMENTS */ trim_wordlist: twl: proc; /* The trim_wordlist command removes from a specified wordlist all words found in a specified sequence of dictionaries. The dictionaries are consulted in order. If the "notrim" attribute is enabled for a word found in a dictionary, the word is not deleted and subsequent dictionaries in the sequence, if any, are not consulted for that word. */ /* Coded 9/28/77 by J. Stern */ /* Modified 7/7/81 by P. Benjamin to fix bug where bad dict in search list stops processing */ /* Automatic */ dcl msf bit (1) aligned; dcl (nargs, argno) fixed bin; dcl ap ptr; dcl al fixed bin; dcl code fixed bin (35); dcl system_area_ptr ptr; dcl ndict fixed bin; dcl temp_ndict fixed bin; dcl (brief, exact_match, have_wl_path) bit (1) aligned; dcl (temp_dir, dname) char (168); dcl (temp_name, ename) char (32); dcl temp_ptr ptr; dcl type fixed bin (2); dcl bc fixed bin (24); dcl wl_ptr ptr; dcl (wl_len, wl_ix) fixed bin (21); dcl switch char (32); dcl atd char (256) varying; dcl dictx fixed bin; dcl (nwords, saved_nwords, original_nwords) fixed bin (21); dcl eof bit (1) aligned; dcl wordx fixed bin (21); dcl word_ptr ptr; dcl word_len fixed bin (21); dcl notrim bit (1) aligned; dcl new_wl_len fixed bin (21); dcl dip ptr; dcl 1 get_key_info, 2 flags like gk_header.flags, 2 descriptor, 3 hpoints bit (32) unal, 3 notrim bit (1) unal, 3 pad bit (3) unal, 2 key_len fixed bin, 2 key char (256); /* Based */ dcl arg char (al) based (ap); dcl system_area area based (system_area_ptr); dcl dict_iocbps (ndict) ptr based (dip); dcl wl_cs char (wl_len) based (wl_ptr); dcl wl_vec (wl_len) char (1) unal based (wl_ptr); dcl word char (word_len) based (word_ptr); dcl 1 trim_data (nwords) aligned based (temp_ptr), 2 wordp ptr unal, 2 notrim bit (1) unal, 2 pad bit (10) unal, 2 wordl fixed bin (24) unal; /* Static */ dcl error_table_$dirseg fixed bin(35) ext static; dcl error_table_$short_record fixed bin(35) ext static; dcl error_table_$end_of_info fixed bin(35) ext static; dcl error_table_$fatal_error fixed bin (35) ext; dcl error_table_$noarg fixed bin (35) ext; dcl error_table_$zero_length_seg fixed bin (35) ext; dcl error_table_$badopt fixed bin (35) ext; dcl error_table_$no_record fixed bin (35) ext; dcl error_table_$no_key fixed bin (35) ext; dcl whoami char (13) int static options (constant) init ("trim_wordlist"); dcl capital_letters char (26) int static options (constant) init ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); dcl small_letters char (26) int static options (constant) init ("abcdefghijklmnopqrstuvwxyz"); dcl NL char (1) int static options (constant) init (" "); /* Conditions */ dcl cleanup condition; /* Builtins */ dcl (substr, divide, null, rtrim, index, addr, verify, translate, search, mod, length, unspec) builtin; /* Entries */ dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl com_err_ entry options (variable); dcl get_system_free_area_ entry (ptr); dcl get_pdir_ entry() returns(char(168)); dcl expand_pathname_$add_suffix entry (char (*), char (*), char (*), char (*), fixed bin (35)); dcl absolute_pathname_ entry (char(*), char(*), fixed bin(35)); dcl absolute_pathname_$add_suffix entry (char (*), char (*), char (*), fixed bin (35)); dcl initiate_file_ entry (char(*), char(*), bit(*), ptr, fixed bin(24), fixed bin(35)); dcl (get_temp_segment_, release_temp_segment_) entry (char (*), ptr, fixed bin (35)); dcl hcs_$status_minf entry (char(*), char(*), fixed bin(1), fixed bin(2), fixed bin(24), fixed bin(35)); dcl unique_chars_ entry (bit (*)) returns (char (15)); dcl pathname_ entry (char(*), char(*)) returns(char(168)); dcl iox_$attach_name entry (char(*), ptr, char(*), ptr, fixed bin(35)); dcl iox_$open entry (ptr, fixed bin, bit (1) aligned, fixed bin (35)); dcl iox_$control entry (ptr, char (*), ptr, fixed bin (35)); dcl iox_$close entry (ptr, fixed bin (35)); dcl iox_$detach_iocb entry (ptr, fixed bin (35)); dcl iox_$destroy_iocb entry (ptr, fixed bin(35)); dcl iox_$put_chars entry (ptr, ptr, fixed bin(21), fixed bin(35)); dcl iox_$get_line entry (ptr, ptr, fixed bin(21), fixed bin(21), fixed bin(35)); dcl delete_$path entry (char(*), char(*), bit(36) aligned, char(*), fixed bin(35)); dcl ioa_ entry options (variable); dcl terminate_file_ entry (ptr, fixed bin(24), bit(*), fixed bin(35)); dcl search_paths_$get entry (char (*), bit (36), char (*), ptr, ptr, fixed bin, ptr, fixed bin (35)); dcl copy_ entry (ptr); wl_ptr, temp_ptr, dip, sl_info_p = null; /* initialize ptrs */ /* find out how many args we have */ call cu_$arg_count (nargs); if nargs < 1 then do; noarg: call com_err_ (error_table_$noarg, whoami, "^/Usage: trim_wordlist wl_path {dict_paths} {-brief} {-exact_match}"); go to finish; end; on cleanup call cleaner; /* allocate space for dictionary pathnames */ sl_info_num_paths = nargs - 1; /* upper limit on number of dict paths */ call get_system_free_area_ (system_area_ptr); allocate sl_info in (system_area); /* examine arguments */ ndict = 0; brief, exact_match, have_wl_path = "0"b; temp_dir = get_pdir_ (); do argno = 1 to nargs; call cu_$arg_ptr (argno, ap, al, code); if index (arg, "-") ^= 1 /* not a control arg */ then if ^have_wl_path /* don't have wordlist pathname yet */ then do; call expand_pathname_$add_suffix (arg, "wl", dname, ename, code); if code ^= 0 then do; call com_err_ (code, whoami, arg); go to finish; end; have_wl_path = "1"b; /* remember we have the wordlist pathname */ end; else do; /* must be a dictionary pathname */ ndict = ndict + 1; call absolute_pathname_$add_suffix (arg, "dict", sl_info.pathname (ndict), code); if code ^= 0 then do; call com_err_ (code, whoami, ar