REF SYSUTIL John Gibson Apr 1994 COPYRIGHT University of Sussex 1994. All Rights Reserved. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<< UNIX UTILITY PROCEDURES >>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< These procedures perform miscellaneous functions within the system, including interfacing to Unix facilities not directly concerned with input/output (for which see REF * SYSIO). Some of these are direct interfaces to Unix system calls, etc, while others are in form that can be made compatible across all Poplog implementations. See also REF * ASYNC for procedures concerned with Unix signal handling. CONTENTS - (Use <ENTER> g to access required sections) 1 Username and Environment Variable Processing 2 Filename Processing 3 Directory Manipulation 4 Unix Processes 5 Running Shell Commands 6 Termcap Interface ----------------------------------------------- 1 Username and Environment Variable Processing ----------------------------------------------- sysgetpasswdentry(user_id) -> entry [procedure] sysgetpasswdentry(user_id, spec) -> entry This procedure accesses information about a given user from the password file '/etc/passwd' (see passwd(5) and getpwent(3) in the Unix Programmers Manual). user_id is either a user login name (a string), or a user identification (an integer); in all cases, false is returned if the specified user cannot be found. Without a second spec argument, the procedure returns a (new) standard full vector containing the broken-down fields from the password entry line, subscripted thus: 1 Name (login name, contains no upper case) (string). 2 Encrypted password (string). 3 User's identification (integer). 4 User's group identification (integer). 5 This is called 'pw_quota' (always 0 at present). 6 This is called 'pw_comment' (always an empty string). 7 User's real name, office, phone extension etc (string). 8 Initial working directory (string). 9 Program to use as login shell (string). If specified, the spec argument selects variations on this, as follows: If spec is standard full vector of length >= 2, then that is used instead of creating a new one (for as many of the fields as it will hold), and is again returned as the result. If on the other hand spec is a vector of length 1, containing an integer from 1 - 9, then only the field selected by that integer is returned. Finally, spec may be true, in which case the whole of the password entry line is returned as a string (this doesn't include fields 5 and 6, which aren't actually in the password file). sysgetusername(user_id) -> name_string [procedure] Uses sysgetpasswdentry to select field 7 (user's real name) for the user specified by user_id, and then returns the leading substring of this upto the first comma (or the whole string otherwise), which is assumed to be the real name part. systranslate(string) -> trans_string [procedure] systranslate(string, flags) -> trans_string trans_string -> systranslate(string) trans_string -> systranslate(string, flags) Provides or updates a translation of the string string, either as a user login name to login directory, or an environment variable name to its value, as follows: ¤ If the first character of string is `~` (tilde) then the remaining substring of string is taken to be a user login name. The user's login directory is returned as a string (using sysgetpasswdentry, see above), or false if the user is non-existent. An empty user name (i.e. string = ~ ) is interpreted as the current user (and returns systranslate('HOME')). A first character of ~ is not allowed with the updater. ¤ Otherwise, the whole string string (or string excluding the first character if this is $ (dollar)) is interpreted as an environment variable name. The strings in the list popenvlist are searched, and if one is found of the form 'string=trans_string' then the substring trans_string is returned, otherwise false. For the updater, any existing entry in popenvlist for string is first removed; if trans_string is false, no further action is taken, otherwise a new entry of the form 'string=trans_string' is added to popenvlist. For compatibility with the VMS version, this procedure allows an optional integer flags argument (which is ignored). popenvlist -> list [variable] list -> popenvlist Holds a list of the environment variable strings passed to the Poplog system on startup, i.e. a list of strings of the form 'name=value' where name is a variable name and value its value. systranslate uses this to translate an environment variable to its value (see above). popusername -> string [protected variable] This variable is initialised on Poplog startup to be the string got from systranslate('USER') (or systranslate('LOGNAME') in System V), i.e. the name of the current user. ---------------------- 2 Filename Processing ---------------------- sysfileok(filename) -> trans_filename [procedure] sysfileok(filename, true) -> (trans_filename, dsk_sub, dir_sub, nam_sub, ext_sub, ver_sub) This procedure is called by most procedures in Poplog which take a filename argument; it performs translations on filenames, and (in the second form of the call with extra argument true), returns a parse of the result. The translations performed on the (string/word) filename are as follows: First, if the filename filename begins with the character ~ or the character $, then the substring from the that character upto the next character before a / (or to the end of the name if there isn't one), is replaced by systranslate on that substring (thus environment variables and user names can be used at the beginning of filenames). E.g. sysfileok('~johng/ref') => ** /cog/johng/ref sysfileok('$popautolib/nl.p') => ** /poplog/pop/lib/auto/nl.p Second, sysfileok truncates filenames longer than pop_max_filename_len characters (see below). This is done in such a way that any file 'extension' or trailing hyphens on a 'back' file name are preserved, e.g. sysfileok('$popautolib/cleargensymproperty.p-') => ** /poplog/pop/lib/auto/cleargensym.p- When a 2nd argument of true is supplied, sysfileok returns 5 integers in addition to the translated filename. These are the starting subscripts within trans_filename of its last 5 fields (the first field starting at subscript 1), where the 6 fields are: Num Subscr Field --- ------ ----- 1 1 Host machine (part to ! before first /) 2 dsk_sub Disk (in Unix, always empty) 3 dir_sub Directory (upto and including last /) 4 nam_sub Name (part after last / and before last dot) 5 ext_sub Extension (part after and including last dot) 6 ver_sub Version (zero or more trailing hyphens) Where a field is empty, the subscript for that field equals the subscript for the next field, or datalength(trans_filename)+1 for the last (the version). Thus the length of any field is its subscript subtracted from the next, or from datalength(trans_filename)+1 for the version. E.g substring(ext_sub, ver_sub-ext_sub, trans_filename) will extract the extension, whereas datalength(trans_filename)+1 -> END_SUB; substring(nam_sub, END_SUB-nam_sub, trans_filename) will extract the name, extension and version. pop_max_filename_len -> int [protected variable] int -> pop_max_filename_len System variable. Holds the maximum length of a filename. The procedure sysfileok uses it to ensure that filenames are within the permissible length, truncating where necessary. sys_fname(filename) -> parse_vec [procedure] sys_fname(filename, n) -> field_n sys_fname(filename, n, m) -> fields_n_to_m This procedure provides a convenient interface to the parsing of filename fields performed by sysfileok. It creates (and caches in an internal temporary property), a 6-element vector parse_vec holding the results of sysfileok(filename,true), i.e. consvector(sysfileok(filename,true), 6) -> parse_vec; parse_vec -> temp_prop(filename); Repeated calls of sys_fname with the same (==) filename argument will then reuse a stored parse_vec for that name if possible (the property is of type "tmpclr", so all entries are cleared by garbage collections). The first form of the call, with only a filename argument, just returns parse_vec. In the second and third forms, one or two integer field numbers n, m in the range 1 - 6 may be specified to extract either the n-th field, or fields n to m inclusive, from the translated filename. (In the latter case n must be less than or equal to m; n = m is the same as n alone). For example, sys_fname(filename, 4) = name sys_fname(filename, 4,5) = name and extension (Note that since sys_fname uses substring to extract fields, it's guaranteed that nullstring is returned for an empty field). sys_fname_path (filename) -> path [procedure] sys_fname_nam (filename) -> nam [procedure] sys_fname_name (filename) -> name [procedure] sys_fname_namev(filename) -> namev [procedure] sys_fname_extn (filename) -> extn [procedure] Closures of sys_fname for useful fields or field ranges, as follows: Pdr Num Fields --- --- ------ path 1,3 host + disk + dir nam 4 name name 4,5 name + extension namev 4,6 name + extension + version extn 5 extension (N.B. Because the location of a file in VMS is described by fields 1 to 3, it is essential to use sys_fname_path for the 'directory' of a file, not field 3 alone, if you want to write portable Poplog programs. In Unix, the disk field is always empty, and only special-purpose programs will expect to have to deal with filenames containing a non-empty host field.) dir dir_>< filename1 -> filename2 [operator 4] Concatenates a directory path dir onto a filename filename1. Both arguments may be either a word or a string; the result filename2 is their concatenation (using sys_><), with a / added in between if dir doesn't already end with one and filename1 doesn't already start with one. E.g. '$popautolib' dir_>< 'sort.p' => ** $popautolib/sort.p 'foo/baz' dir_>< nullstring => ** foo/baz/ nullstring dir_>< 'foo/baz' => ** foo/baz Note that if filename1 is empty, then the result will always end with a /, EXCEPT when dir is empty also. sys_file_match(file_spec, def_spec, fvec, flags) [procedure] -> filename_rep This procedure can be used to find all file names that match a given file specification file_spec. It returns a file name repeater, i.e. a procedure which each time it is called produces the next actual file name matching file_spec, or <termin> if there are no more. The arguments are as follows: file_spec This is the file specification string. It is first run through sysfileok, which means that an initial $environment-var is translated, as is an initial ~username. It can then contain normal shell-type wildcard characters as follows: * match 0 or more characters; ? match any single character; [abcA-Z] match any of a,b,c or A-Z, etc; [^abcA-Z] match any character but a,b,c or A-Z, etc; {patt1,patt2,...} match any of patt1, patt2, ... (each patt may contain wildcards). Note that as usual, `.` at the beginning of a name part must be matched explicitly. (However, {?,.} or {*,.*} may be used instead of ? or * to get around this.) In addition, there are two other special wildcards: The first is concerned with the Poplog convention of naming 'back' files by appending 1 or more trailing hyphens (see pop_file_versions in REF * SYSIO): this is `#`, which matches the start position of 0 or more trailing `-` characters on the end of a file name. (Thus for example, '*#' would match only file names with no trailing hyphens, whereas '*#-*' would match names with at least one trailing hyphen.) The other special wildcard is '...' for a directory name, which means match all sub-directories recursively, e.g. '/foo/.../baz/*.p' would match all '*.p' files in any directories called 'baz' anywhere in the tree from /foo downwards. def_spec The file specification file_spec is considered to have 3 parts, namely path, name and version (the last being a # character plus anything following it); if present, the corresponding parts of the default specification string def_spec are then used to fill in the missing parts of file_spec. For example, if file_spec was '*.ph' (having only the name part), and def_spec was $usepop/.../*.p# (having all three parts), then the actual specification used would be '$usepop/.../*.ph#' fvec A standard full vector or false. If fvec is a vector, then a * sys_file_stat is performed on each file name generated, using fvec as the vector in which to store the status information. In this case the repeater returned by sys_file_match produces two results, the file name and the status information, like this: filename_rep() -> (stat, filename); There is a complication in the case where filename is a symbolic link. If the "follow symbolic links" bit of the flags argument to sys_file_match (see below) is set, then the data in stat refers to the file pointed to by the symbolic link. If the "follow symbolic links" flag is not set, however, then stat is status information about the link itself. If fvec is false then only the file name is returned, i.e filename_rep() -> filename; (unless the "strip" bit of the flags argument is set -- see below). flags An integer argument, in which bits 0 - 1 have the following meanings: Bit Meaning --- ------- 0 If set, strip directory pathnames 1 If set, follow symbolic links when calling sys_file_stat (see above) The flags argument may also be a boolean. true is equivalent to 2:01 ("strip" set), and false is equivalent to 2:00 ("strip" not set). The significance of bit 1 ("follow symbolic links") is discussed above in the section on the fvec parameter. If the "strip" bit (bit 0) is set, the directory part of each file name is stripped and only returned in between the stream of file names, whenever the directory path changes. When this happens, the repeater returns false for the file name and a second result for the path. Thus when "strip" is set, the repeater should be used as follows: until (filename_rep() ->> filename) == termin do if filename then <process file name> -> stat (if fvec a vector) else -> path; <process directory path> endif enduntil; Note that unless path is empty, it will always end with /. If however the "strip" bit is not set, the file names returned by the repeater are the full file names, with the directory path included in each. sys_match_filename() [procedure] sys_matchin_dir() [procedure] System procedures used by sys_file_match. sys_search_unix_path(name, unix_path) -> filename [procedure] Searches the $PATH-style directory list unix_path for a file called name, returning the full pathname if found, and false otherwise. For example, under SunOS, with a conventional value of $PATH: sys_search_unix_path('lpr',systranslate('PATH')) => ** /usr/ucb/lpr systmpfile(dir, prefix, suffix) -> filename [procedure] Generates a new unique file name in the given directory dir. If dir is false, the default temporary directory given by the environment variable $TMPDIR is used, or '/tmp' if that is undefined. If dir is an empty string, the current directory is used. prefix should be a string which identifies the program which needs the temporary file, and suffix should be the extension required. Example: systmpfile('/foo', 'load', '.o') => ** /foo/load6x21564.o sysobjectfile(filename) -> object_filename [procedure] sysobjectfile(filename, want_archive) -> archive_filename Generates and returns an object file name (or library archive file name if want_archive is supplied and true) based on the given source file name. The file name that is generated includes information about the type of machine and operating system currently being used, and will be of the form: <source file name> _ <machine type> . <suffix> The <machine type> part of the name is generated from the contents of sys_machine_type. The <suffix> is normally '.o' (or '.a' if an archive file name is being generated) but will be '.so' on SPARC machines running Solaris 2.x, and '.sl' on HP 9000 machines running HP-UX 9.x. For example, on a Sun 4 running SunOS 4.x: sysobjectfile('test.c') => ** test_sun3.o sysobjectfile('libtest', true) => ** libtest_sun3.a but on a Sun 4 running Solaris 2.x sysobjectfile('test.c') => ** test_sun4r5.so ------------------------- 3 Directory Manipulation ------------------------- current_directory -> string [variable] string -> current_directory This (active) variable holds the current directory as a string: assigning to it changes the current Unix directory of the process. On assignment, an empty string is replaced by the string got from systranslate('HOME') popdirectory -> string [protected variable] This variable is initialised on Poplog startup to be the string got from systranslate('HOME') i.e. the current user's home directory. sysfilemode(filename) -> int [procedure] int -> sysfilemode(filename) Returns or sets the protection value on a file filename. sysisdirectory(filename) -> bool [procedure] Returns true if filename is a directory, false otherwise. An empty string is equivalent to '.'. syslink(old_filename, new_filename) -> bool [procedure] syslink(old_filename, new_filename, follow_symlinks) -> bool Creates a hard link named new_filename to the file named old_filename, where old_filename and new_filename are both strings. The optional follow_symlinks argument specifies whether symbolic links should be recursively deferenced. The most general value is an integer, in which bit 0 = 1 means dereference symbolic links on old_filename, and bit 1 = 1 means dereference them on new_filename. A boolean may also be supplied, true being the same as 1 (deref old_filename only), amd false being the same as 0 (the default if follow_symlinks is omitted). (Note that it is an error if new_filename exists, unless follow_symlinks specifies bit 1 = 1 and the name is a symbolic link pointing to a nonexistent file.) If the call fails merely because old_filename doesn't exist then false is returned, but any other failure produces a mishap. true is returned if the link was successfully created. syssymlink(old_filename, new_filename) -> bool [procedure] syssymlink(old_filename, new_filename, follow_symlinks) -> bool As for syslink, but creates a symbolic link instead of a hard one (note that in this case false can never be returned because it isn't necessary for old_filename to exist for the symbolic link to be created). In Unix systems that don't support Berkeley symbolic links this procedure just mishaps. sysunlink(filename) -> bool [procedure] sysunlink(filename, follow_symlinks) -> bool Unlinks the directory entry for the file named filename, where filename is a string. If the optional boolean follow_symlinks argument is true, and filename is a symbolic link, then the link is first recursively dereferenced; if false (the default when omitted), this is not done. If the call fails merely because filename doesn't exist then false is returned, but any other failure produces a mishap. true is returned if filename was successfully unlinked. sysdelete(filename) -> bool [procedure] sysdelete(filename, follow_symlinks) -> bool Deletes the file with filename string filename, returning true if successful, false if the file doesn't exist. This procedure is essentially the opposite of syscreate, which in particular means it 'moves forward' any back file versions of filename that exist. (See pop_file_versions in REF * SYSIO.) Unless the optional third argument follow_symlinks is specified, and false, sysdelete will follow symbolic links, i.e. given a symbolic link as argument it will delete the file pointed to by the link, not the link itself. sys_file_copy(filename1, filename2) [procedure] Copies the file named filename1 (which must exist) to a file named filename2. Note that this procedure uses syscreate to create the new file, and thus maintains back versions of filename2 according to pop_file_versions. sys_file_move(old_filename, new_filename) [procedure] sys_file_move(old_filename, new_filename, follow_symlinks) Renames the file named old_filename (which must exist) as new_filename, except that it COPIES the file (deleting the old one) when either (a) new_filename refers to a different file system from old_filename (in which case a new hard link isn't possible), or (b) new_filename exists already and has more than 1 link (thus it preserves links to new_filename). Note that, whether it renames or copies, back versions of new_filename are maintained according to pop_file_versions. The optional follow_symlinks argument specifies whether symbolic links should be recursively deferenced. The most general value is an integer, in which bit 0 = 1 means dereference symbolic links on old_filename, and bit 1 = 1 means dereference them on new_filename. A boolean may also be supplied, true being the same as 1 (deref old_filename only), amd false being the same as 0 (the default if follow_symlinks is omitted). sys_dir_size(dir) -> n_kbytes [procedure] Returns the number of kilobytes occupied by dir and all the files and sub-directories within dir. Files which have multiple links are only counted once. sys_dir_size is similar to the shell command UNIX * du ----------------- 4 Unix Processes ----------------- sys_fork(will_do_wait) -> pid [procedure] sys_fork(will_do_wait, ast_p) -> pid Forks the current Poplog process, producing a new child process which is an exact copy of the current one. In the parent, the call of sys_fork returns with the child pid; in the child it returns false. will_do_wait is a boolean argument which indicates whether you will (at some later point) call sys_wait to wait for the child process to terminate: true = yes, false = no. (If will_do_wait is true and you do not call sys_wait, you will leave a 'zombie' process record in Poplog's internal process list; on the other hand, if the argument is false and you do call sys_wait, a mishap will result. Note that Poplog does an automatic Unix waitpid system call for every child process when it dies, regardless of the value of will_do_wait. Thus you do not have to sys_wait for a child merely to avoid creating a Unix zombie.) ast_p is an optional asychronous trap procedure. If supplied, it will be executed asychronously when the child process terminates, with the child pid and exit status as arguments, i.e. ast_p(pid, status) (See Asynchronous Trap Procedures in REF * ASYNC for full details of the ast_p argument, which may also be a pair whose front is the procedure.) Executing sys_fork causes the process specific destroy property sys_process_destroy_action to be cleared in the child process (see REF * PROPS for details). See also popdevin, popdevout and popdeverr in REF * SYSIO for details on reassigning standard I/O. sys_vfork(will_do_wait) -> pid [procedure] sys_vfork(will_do_wait, ast_p) -> pid Forks the current Poplog process, producing a new child process which 'borrows' the address space of the current one until a sysexit or sysexecute is performed; until this happens, only the open files of the two processes are different. sys_vfork is therefore used ONLY in the situation where the purpose of forking is to immediately sysexecute another image in the child, possibly after redirecting the standard input and/or output etc (and is quicker than sys_fork because Unix doesn't have to copy the whole Poplog process). Using it in any other way will crash the system -- in particular, the procedure that calls sys_vfork must not exit when running as the child (this is the same limitation placed on the use of the vfork system call in C). In the parent, the call of sys_vfork returns with the child pid; in the child it returns false. The arguments to sys_vfork are the same as for sys_fork. (Note, however, that when Poplog is running inside a vfork'ed child, the arguments to a another sys_fork or sys_vfork are ignored. This is because the vfork'ed process is not expected to do anything but exit after the second fork.) sys_wait(pid_or_list_or_false) -> (pid, status) [procedure] Waits for the termination of child process(es) created by sys_fork or sys_vfork with will_do_wait argument true. The Process IDentification number and exit status of a dead child are returned. The argument may be ¤ a child process pid, meaning wait for that child; ¤ a list of child process pids, meaning wait for the first of those children to die; ¤ false, meaning wait for any child process created by sys_fork or sys_vfork (this option is provided for compatibility with the old version of sys_wait, and should not generally be used). Each call of sys_wait returns the pid and (integer) status of the first specified child to die, waiting for this to happen if necessary (with syshibernate). A mishap will result if there are no child processes corresponding to the argument, or none that have not already been waited for. A mishap also results if you attempt to wait for a process created with a false will_do_wait argument. Note that if sys_wait is abnormally exited while inside syshibernate (e.g. by a mishap or Ctrl-C), the process or list of processes given by pid will have their will_do_wait flags unset. Those process(es) cannot then be waited for again. You may wish to locally define interrupt to be identfn before calling sys_wait. sysexecute(file, arg_list, env_list) [procedure] sysexecute(file, arg_list, env_list, dev_list) Does a UNIX * execve (or * execvp) system call, i.e. runs the executable file in place of the current Poplog image, passing it the strings in arg_list as arguments, and the strings in env_list as environment variables. file may be either a filename string directly, or one inside a reference (i.e. consref(string)); in the latter case, execvp is used instead of execve (meaning that for a relative pathname, the PATH environment variable is searched for the file). The list arg_list should begin with the zero-th argument (i.e, that usually used for the name of the program). If env_list is false then it is replaced by the current value of popenvlist (see above). All files opened by Poplog have the Unix 'close on execute' flag set automatically. This means that on a sysexecute all files will be closed, except that by default, sysexecute unsets the flag for the three standard devices popdevin, popdevout and popdeverr. To keep other files open, dev_list is an optional (non-empty) list of devices whose associated file descriptors are to be left open across the execve system call; the flag is cleared for each device in this list. poppid -> int [protected variable] Contains the Process IDentification number of the current Poplog process. ------------------------- 5 Running Shell Commands ------------------------- sysobey(string) [procedure] sysobey(string, shell) sysobey(file, arg_list) In the first two forms, obeys the string string as a shell or cshell command (by forking a child process). The integer shell is an ASCII character code controlling which shell is used, as follows: `$` /bin/sh `%` /bin/csh `!` the value of systranslate('SHELL') If shell is absent, /bin/sh is assumed. In the third form it forks a child, calls * sysexecute on the executable file with argument strings arg_list, and then calls * sys_wait for the child. In all cases, the exit status of the child process is saved in pop_status. sysobeylist(command_list) [procedure] Given a list of commands strings command_list, runs sysobey(string, `!`) on each string in the list. pop_status -> int [variable] int -> pop_status This variable is set to the (integer) exit status of child processes run by sysobey. pipein(file, arg_list, want_rep) -> dev_or_char_rep [procedure] Forks a child process, and then calls * sysexecute on the executable file with argument strings arg_list. The standard output of the child is made the output side of a pipe; the input side of this is returned in the parent process as either a device (want_rep false) or character repeater procedure (want_rep true). See HELP * PIPEUTILS pipeout(char_source, file, arg_list, wait) [procedure] Forks a child process, and then calls * sysexecute on the executable file with argument strings arg_list. The standard input of the child is made the input side of a pipe, and the data got from char_source is written to the output side. char_source may be either ¤ A character repeater directly, or a valid argument for discin to produce one (in which case it is replaced by discin(char_source)). The character repeater is then called until it returns <termin>, each character being written to the pipe. ¤ A reference containing a procedure p (i.e. consref(p)) which takes an output device as argument. In this case, p is simply applied to the output pipe device, i.e. p(dev), and should write the data directly to it. If the boolean wait argument is true, pipeout waits for the child to finish before returning; otherwise, it returns immediately. (Note that in the latter case, it also does a second fork to prevent the creation of a zombie process.) For more information on pipes see HELP * PIPEUTILS -------------------- 6 Termcap Interface -------------------- termcap_getentry(term) -> bool [procedure] Reads the termcap entry for the terminal type named by the string or word term. The result is true if the entry was read successfully and false otherwise. The entry is read into a static area, so only one entry can be active at a time. termcap_name -> string [active variable] The name of the currently active termcap entry (a string), or false if none. Assigning to this variable has the effect of calling termcap_getentry to read the named termcap entry; a mishap occurs unless the call returns true. termcap_getflag(cap) -> bool [procedure] termcap_getnum(cap) -> int [procedure] termcap_getstring(cap) -> string [procedure] Get the value of the capability cap from the currently active termcap entry. cap should be a two-character string or word: 'am', 'li', 'cm' etc. All three procedures return false if the capability is unsupported or unrecognised or if there is no currently active termcap entry. termcap_compile(string, n, delay) -> p [procedure] termcap_compile(string, n, delay, out_p) -> p Compiles a termcap string into a procedure, decoding any delay specifications and parameter escapes. string is the string to be compiled, normally the result of a previous call to termcap_getstring. n is the integer number of parameters expected by the string, typically zero, but could be (say) 2 for the 'cm' (cursor motion) capability. delay determines how delay specifications are to be treated. It can take three possible values: Value Meaning ----- ------- false all delays are ignored; integer constant delays are decoded correctly, but variable delays are multiplied once-and-for-all by the given value and thereafter treated as constant; true full treatment of delays. An extra integer argument is added to the result procedure, being the number of lines affected by the operation; this is ignored by strings involving constant delays, but is used as a multiplier for variable delays. The result procedure p has the form procedure(ARG-1, ..., ARG-n, AFFCNT); .... endprocedure where ARG-1, ..., ARG-n are the n parameters expected by the string and AFFCNT is the number of lines affected by the operation: this will be present only when delay is true. p outputs all literal characters from the original string, together with those arguments selected by parameter escapes. Delays are implemented by outputting a sufficient number of pad characters, the exact number depending on the output speed of the terminal as determined at the time the termcap entry was read. out_p is an optional output procedure to be used by p. It may be an actual procedure or a procedure variable name; the default is "rawcharout". As a special case, the argument n may be given as false to indicate that string is not parameterised. In this case termcap_compile will try to return a string rather than a procedure, the string being a copy of string but with any delay specifications replaced by the appropriate number of pad characters. The result will still be a procedure however if delay is true and string does require variable amounts of padding. Note that compilation of a procedure result makes use of VM code planting instructions, so termcap_compile should not be called generally unless inside a call of sysCOMPILE. For details see REF * VMCODE +-+ C.unix/ref/sysutil +-+ Copyright University of Sussex 1994. All rights reserved.