:Info: ted_support.gi: 11/19/82 ted_support.gi Ted can invoke external requests. These requests be either standard system routines or user supplied. In this way a user is able to add specialized editing requests to ted. Syntax: [.,.] |xyz rest-of-line Function: A request like this will cause ted to try to execute ted_xyz_$ted_xyz_. Syntax: help |xyz An external request may also have info available for the ted help request. The info is in standard help file format. The help file must be named ted_xyz_.info. The ted help request uses the info search rules, but for this instance adds the name of the directory where ted_xyz_ is found (via system search rules). Global processing: A mechanism is available whereby the writer of a function may get a global type of action (g or v) without having to bother with figuring out how to do all of the details which are neces- sary. The ted_support structure contains a pair of entry variables for this purpose. The syntax of a global function is one of two forms: |function /expression/additional-info/ rest-of-line |function /expression/ rest-of-line call proc_expr (ted_support_p, msg, code); This procedure is called when a global expression needs to be processed. A globally executing function could be written to always use the remembered expression, but it usually is not. proc_expr takes the first non-blank character to be the delimiter, scan and compiles the expression, and leaves the second delimiter as the cur- rent character. If it returns with a zero return code, everything is ready to process any additional info which the function may require. call do_global (worker, mode, ted_support_p, msg, code); This procedure does all the global overhead. "worker" is an inter- nal procedure which actually does the function to be performed. It will be called once for each line in the addressed range which matches the criteria. When it is called, inp.sb points to the first character of the line to be processed and inp.se points to the NL of this line. These two values may not be modified. "mode" is either a "g" or "v" to indicate which kind of operation is needed. The last 3 args are the same ones which the function itself was called with. Regular expression processing: Regular expressions may be utilized with 2 and maybe 3 easy steps. The steps are 1) initialization of an expression area, 2) compilation of an expression, and 3) searching with an expression. call tedsrch_$init_exp (addr (someplace), size (someplace)); This entry would not usually be used. This exists for the condition where a function wishes to make use of regular expressions without impacting ted's remembered expression. The 2 args are where the hold area is and how long it is. call tedsrch_$compile (ex_p,ex_l,re_p,lmod,rmod,msg,code); This compiles a regular expression into its internal form. Usually an expression is compiled once and then used for searching many times. "ex_p" points to first character of the expression to be compiled. "ex_l" is the number of characters in the expression. "re_p" points to the area to hold the compiled expression. ted's area may be used by referencing ted_support.reg_exp_p. "lmod" is "1"b for line mode, ""b for string mode. "rmod" is "1"b for regular expression mode, ""b for literal mode. The last 2 args are the last 2 function paramters. call tedsrch_$search (re_p,cb_p,sb,se,mb,me,me2,msg,code); This searches for an expression in a string within a buffer. Searching may be done in the input string but not the output string since it is not a buffer. "re_p" points to the area containing the compiled expression. "cb_p" points to the control block associated with the input data. "sb" is the offset in the buffer string where the search is to begin. "se" is the offset where it is to end. "mb" is the offset of where a match began. "me" is the offset of where a match ended. "me2" is the last character used to find the match (sometimes higher than "me"). The last 2 args are the last 2 function paramters. List of standard support functions: [.] |ax append LINES after addressed line (after Speedtype expansion) [.,.] |cx change addressed lines, replacing with LINES (after Speedtype expan- sion) [.] |ix insert LINES before addressed line (after Speedtype expansion) [.,.] |comment add comments to addressed lines. [.,.] |tabin convert spaces to HTs where possible. [.,.] |gtabout `RE`C,n,n...` (global |tabout) convert pseudo-tab C to spaces on all lines which match the expression RE. [.,.] |vtabout `RE`C,n,n...` (exclusive |tabout) convert pseudo-tab C to spaces on all lines which do not match the expression RE. [.,.] |tabout `C,n,n...` convert pseudo-tab C to spaces using tabstops defined by n,n,... [.,.] |fiad `STR`L,R{,I` Fill the addressed data and adjust to make an even right margin. [.,.] |fina `STR`L,R{,I` Fill the addressed data without adjusting. [.,.] |dumpl dump (long) addressed string in octal and ASCII 20 across (needs 110 print positions) [.,.] |dumps dump (short) addressed string in octal and ASCII 10 across (needs 65 print positions) [.,.] |dumpvs dump (very-short) addressed string in octal and ASCII 5 across (needs 39 print positions) [.,.] |dump dump addressed string in octal and ASCII using long, short, or very-short depending on current linelength Action taken: It is assumed that external requests are likely to fit in the same mold and certain actions are taken to ease the bur- den on them. A request may work in some other fashion if it wishes, however. Processing is done from an input string to an output seg- ment. The input string is all of the data in the buffer with the addressed portion indicated. The request may do whatever it wishes to the output segment. It may not modify the input string in any way, and may not count on the string being in the same location if called again in the same buffer. These actions are performed by ted: 1) Copy all of the input string which precedes the address range into the output buffer. 2) Call the routine. The call is done this way: dcl ted_xyz_ entry (ptr, char (168)var, fixed bin (35)); call ted_xyz_ (addr (ted_support), msg, code); 3) Copy input string following the address range to the output buffer. The end-of-address location may be updated by the routine to end-of-string if it has already taken care of this task. 4) Make this output string be the buffer contents. 5) Set the current location if specified. Options: The return code may specify that step 4 is to be omitted, that 4 & 5 are to be omitted (no change), or that an error has occurred. The "rest-of-line" is passed to the request with the assumption that everything which follows is information for the request. The request may then 1) Do nothing. A new line will be read for execution. 2) Set the next location just after any data utilized by the request. In this case, execution will continue on the rest of the line. 3) Supply a new value and length for the data in the request line and set the next location back to 1. In this case, execution will com- mence with the line supplied by the request. Example: A request to convert vowels to uppercase, both regular and globally. ted_uppercase_: proc (ted_support_p, msg, code); /* This routine converts all vowels to uppercase in the range addressed. */ /* It also can do this action globally (g | v). */ /* It does not allow any request to follow in the same line. */ /* Usage: {.,.} |uppercase {ignored} */ mode = " "; goto common; ted_guppercase_: entry (ted_support_p, msg, code); /* Usage: {.,.} |guppercase /regexp/ {ignored} */ mode = "g"; goto common; ted_vuppercase_: entry (ted_support_p, msg, code); /* Usage: {.,.} |vuppercase /regexp/ {ignored} */ mode = "v"; common: if (ted_support_version_2 ^= ted_support.version) then do; /* check for proper version */ code = error_table_$unimplemented_version; return; /* can't handle this one. */ end; if (inp.de = 0) then do; /* must be some data to work on */ msg = "Buffer Empty."; /* supply the message text */ code = tederror_table_$Error_Msg;/* say that a message is present */ end; else do; if (mode = " ") then call worker; else do; call proc_expr (ted_support_p, msg, code); if (code ^= 0) then return; call do_global (worker, mode, ted_support_p, msg, code); end; current = out.de; /* and say that "." is there */ code = tederror_table_$Copy_Set; /* tell ted to finish up */ end; worker: proc; i = inp.se - inp.sb + 1; /* calc how much to process */ substr (ostr, out.de+1, i) = translate (substr (istr, inp.sb, i), "AEIOU", "aeiou"); /* translate that much */ out.de = out.de + i; /* update the output length */ end worker; dcl (msg char (168)var, code fixed bin (35)) parm; dcl mode char (1); dcl i fixed bin (24); %include ted_support; end ted_uppercase_; Example: a request to renumber a range of a buffer. ted_renumber_: proc (ted_support_p, msg, code); /* This routine renumbers the addressed portion of the buffer. It takes 1 or */ /* 2 arguments within a delimited string. The 1st argument is the beginning */ /* number; the 2nd argument specifies the increment to use (assumes 10). */ /* Whatever follows the argument string will be left for further ted */ /* execution. */ /* --- This is not robust code. It does not include exhaustive error */ /* --- checking. It is intended only to show how to use the interface */ /* --- stucture's various data. */ /* Usage: {1,$} |renumber /from,incr/ */ dcl msg char (168)var, /* error message text (OUT) */ code fixed bin (35); /* error code (OUT) */ if (ted_support_version_2 ^= ted_support.version) then do; /* make sure its correct version */ code = error_table_$unimplemented_version; return; /* can't handle this */ end; if (inp.de = 0) then do; /* must be some data to process */ msg = "Buffer Empty."; code = tederror_table_$Error_Msg; return; end; /**** 1) Parse the arg list */ req.nc = req.cc; /* move back to current location */ delim = rchr (req.nc); /* save the delimiter char */ if (delim = " ") | (delim = NL) then do; code = tederror_table_$No_Delim1; return; end; req.nc = req.nc + 1; /* skip over it */ i = verify (substr (rstr, req.nc), "0123456789") -1; ln = fixed (substr (rstr, req.nc, i)); /* get starting line number */ req.nc = req.nc + i; /* skip over part used up */ if (rchr (req.nc) = ",") then do; /* 2nd arg is present */ req.nc = req.nc + 1; /* skip over the comma */ i = verify (substr (rstr, req.nc), "0123456789") -1; incr = fixed (substr (rstr, req.nc, i)); /* get increment */ req.nc = req.nc + i; /* skip over part used up */ end; else incr = 10; /* supply the default */ if (rchr (req.nc) ^= delim) then do; msg = "Only 2 args allowed"; code = tederror_table_$Error_Msg; return; end; req.nc = req.nc + 1; /* leave "next" for continued */ /* execution of request line data */ /**** 2) see if default address needed */ if addr_ct = 0 then do; inp.sb = 1; /* the default is 1,$ */ inp.se = inp.de; out.de = 0; /* forget anything already done here */ end; /**** 3) do all lines in address range */ do while (inp.sb <= inp.se); i = verify (substr (istr, inp.sb), "0123456789") -1; inp.sb = inp.sb + i; /* strip any existing line number */ pic5 = ln; /* get display form of line number */ substr (ostr, out.de+1, 5) = pic5; out.de = out.de + 5; /* place new number in output */ i = index (substr (istr, inp.sb), NL); /* find line length */ substr (ostr, out.de+1, i) = substr (istr, inp.sb, i); out.de = out.de + i; /* add in the line of data */ inp.sb = inp.sb + i; /* account for user-up input data */ ln = ln + incr; /* move on to next number value */ end; /**** 4) tell ted its AOK */ code = tederror_table_$Copy_Set; dcl i fixed bin (24); dcl delim char (1); /* arg list delimiter */ dcl ln fixed bin; /* line number value */ dcl incr fixed bin; /* line number increment */ dcl pic5 pic "99999"; /* display form of line number */ dcl NL char (1) int static options (constant) init (" "); %include ted_support; end ted_renumber_; :Info: ted_ax_: ted_cx_: ted_ix_: 12/05/78 Speedtype input mode [.] |ax append LINES after addressed line [.,.] |cx change addressed lines, replacing with LINES [.] |ix insert LINES before addressed line LINES are read from user_input. speedtype expansion is done on each line. End of input signal is \F. Requests on line after this request are executed after end of input is signalled. :Info: ted_comment_: 08/03/82 Add comments [.,.] |comment add comments to addressed lines. Each non-blank line is typed out without a NL. Then, whatever you type is added to the end of the line. However, the last two characters can be one of these control sequences: \d delete the displayed line \F \f end of input (no data inserted) \i insert next line typed, then examine for \a. \a append next line typed, then examine for another \a. :Info: ted_tabin_: 08/03/82 Process in HTs [.,.] |tabin convert spaces to HTs where possible. Also, trailing white space is removed from all lines. :Info: ted_tabout_: ted_gtabout_: ted_vtabout_: 11/03/82 Process out pseudo-tabs [.,.] |gtabout `RE`C,n,n...` (global |tabout) convert pseudo-tab C to spaces on all lines which match the expression RE. [.,.] |vtabout `RE`C,n,n...` (exclusive |tabout) convert pseudo-tab C to spaces on all lines which do not match the expression RE. [.,.] |tabout `C,n,n...` convert pseudo-tab C to spaces using tabstops defined by n,n,... Tabstop specifications are of this form: n - set text left nL - set text left nC - set text centered nR - set text right "n" represents the column where the character following the tab character is to be placed. It must be in the range 1 thru 200. When the left or center options are selected, they apply to the text leading up to the tabstop. The location of each tabstop in turn is remembered. Then when a left/center is called for, the data since the last tabstop is involved. The number of spaces needed is calcu- lated; then if centering, half of this number is placed before the data and the rest after. Otherwise all the spaces are placed before the data. :Info: ted_dump_: ted_dumpl_: ted_dumps_: ted_dumpvs_: 08/03/82 Octal/alpha dumping [.,.] |dumpl dump (long) addressed string in octal and ASCII 20 across (needs 110 print positions) [.,.] |dumps dump (short) addressed string in octal and ASCII 10 across (needs 65 print positions) [.,.] |dumpvs dump (very-short) addressed string in octal and ASCII 5 across (needs 39 print positions) [.,.] |dump dump addressed string in octal and ASCII using long, short, or very-short depending on current linelength :Info: ted_fiad_: ted_fina_: 11/03/82 Fill and adjust/no-adjust [.,.] |fiad `STR`L,R{,I` Fill the addressed data and adjust to make an even right margin. [.,.] |fina `STR`L,R{,I` Fill the addressed data without adjusting. STR is a string (NOT regular expression) and may be null. If non-null, each line which begins with that string will be left as-is during the filling process. The line will remain in place, that is, filling does not span the line. L is the left margin value, R is the right margin value, and I is the optional indent value. If I is not present, the value of L is assumed. The indent value is applied to all "first" lines. The most obvious "first" line is the line where processing begins. Emp- ty lines will always remain as empty lines. Each text line after an empty line is also considered to be a "first". Thus a series of paragraphs may be filled in a consistent manner. Three paragraph forms are available depending on the relationship of L and I: L=I LI xxxx xxx xxxxx xxxx xxxx xxxx xxxx xxxx xxxx ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved