home *** CD-ROM | disk | FTP | other *** search
- ########################################################################
- #
- # Name: itlib.icn
- #
- # Title: Icon termlib-type tools
- #
- # Author: Richard L. Goerwitz
- #
- # Version: 1.23
- #
- #########################################################################
- #
- # I place this and future versions of itlib in the public domain - RLG
- #
- #########################################################################
- #
- # The following library represents a series of rough functional
- # equivalents to the standard Unix low-level termcap routines. They
- # are not meant as exact termlib clones. Nor are they enhanced to
- # take care of magic cookie terminals, terminals that use \D in their
- # termcap entries, or, in short, anything I felt would not affect my
- # normal, day-to-day work with ANSI and vt100 terminals.
- #
- # Requires: A unix platform & co-expressions. There is an MS-DOS
- # version, itlibdos.icn.
- #
- # setname(term)
- # Use only if you wish to initialize itermlib for a terminal
- # other than what your current environment specifies. "Term" is the
- # name of the termcap entry to use. Normally this initialization is
- # done automatically, and need not concern the user.
- #
- # getval(id)
- # Works something like tgetnum, tgetflag, and tgetstr. In the
- # spirit of Icon, all three have been collapsed into one routine.
- # Integer valued caps are returned as integers, strings as strings,
- # and flags as records (if a flag is set, then type(flag) will return
- # "true"). Absence of a given capability is signalled by procedure
- # failure.
- #
- # igoto(cm,destcol,destline) - NB: default 1 offset (*not* zero)!
- # Analogous to tgoto. "Cm" is the cursor movement command for
- # the current terminal, as obtained via getval("cm"). Igoto()
- # returns a string which, when output via iputs, will cause the
- # cursor to move to column "destcol" and line "destline." Column and
- # line are always calculated using a *one* offset. This is far more
- # Iconish than the normal zero offset used by tgoto. If you want to
- # go to the first square on your screen, then include in your program
- # "iputs(igoto(getval("cm"),1,1))."
- #
- # iputs(cp,affcnt)
- # Equivalent to tputs. "Cp" is a string obtained via getval(),
- # or, in the case of "cm," via igoto(getval("cm"),x,y). Affcnt is a
- # count of affected lines. It is only relevant for terminals which
- # specify proportional (starred) delays in their termcap entries.
- #
- # Bugs: I have not tested these routines on terminals that require
- # padding. These routines WILL NOT WORK if your machines stty com-
- # mand has no -g option (tisk, tisk). This includes NeXT worksta-
- # tions, and some others that I haven't had time to pinpoint.
- #
- ##########################################################################
- #
- # Requires: UNIX, co-expressions
- #
- # See also: iscreen.icn (a set of companion utilities)
- #
- ##########################################################################
-
-
- global tc_table, tty_speed
- record true()
-
-
- procedure check_features()
-
- local in_params, line
- # global tty_speed
-
- initial {
- find("unix",map(&features)) |
- er("check_features","unix system required",1)
- find("o-expres",&features) |
- er("check_features","co-expressions not implemented - &$#!",1)
- system("/bin/stty tabs") |
- er("check_features","can't set tabs option",1)
- }
-
- # clumsy, clumsy, clumsy, and probably won't work on all systems
- tty_speed := getspeed()
- return "term characteristics reset; features check out"
-
- end
-
-
-
- procedure setname(name)
-
- # Sets current terminal type to "name" and builds a new termcap
- # capability database (residing in tc_table). Fails if unable to
- # find a termcap entry for terminal type "name." If you want it
- # to terminate with an error message under these circumstances,
- # comment out "| fail" below, and uncomment the er() line.
-
- #tc_table is global
-
- check_features()
-
- tc_table := table()
- tc_table := maketc_table(getentry(name)) | fail
- # er("setname","no termcap entry found for "||name,3)
- return "successfully reset for terminal " || name
-
- end
-
-
-
- procedure getname()
-
- # Getname() first checks to be sure we're running under Unix, and,
- # if so, tries to figure out what the current terminal type is,
- # checking successively the value of the environment variable
- # TERM, and then the output of "tset -". Terminates with an error
- # message if the terminal type cannot be ascertained.
-
- local term, tset_output
-
- check_features()
-
- if not (term := getenv("TERM")) then {
- tset_output := open("/bin/tset -","pr") |
- er("getname","can't find tset command",1)
- term := !tset_output
- close(tset_output)
- }
- return \term |
- er("getname","can't seem to determine your terminal type",1)
-
- end
-
-
-
- procedure er(func,msg,errnum)
-
- # short error processing utility
- write(&errout,func,": ",msg)
- exit(errnum)
-
- end
-
-
-
- procedure getentry(name, termcap_string)
-
- # "Name" designates the current terminal type. Getentry() scans
- # the current environment for the variable TERMCAP. If the
- # TERMCAP string represents a termcap entry for a terminal of type
- # "name," then getentry() returns the TERMCAP string. Otherwise,
- # getentry() will check to see if TERMCAP is a file name. If so,
- # getentry() will scan that file for an entry corresponding to
- # "name." If the TERMCAP string does not designate a filename,
- # getentry() will scan /etc/termcap for the correct entry.
- # Whatever the input file, if an entry for terminal "name" is
- # found, getentry() returns that entry. Otherwise, getentry()
- # fails.
-
- local f, getline, line, nm, ent1, ent2
-
- # You can force getentry() to use a specific termcap file by cal-
- # ling it with a second argument - the name of the termcap file
- # to use instead of the regular one, or the one specified in the
- # termcap environment variable.
- /termcap_string := getenv("TERMCAP")
-
- if \termcap_string ? (not match("/"), pos(0) | tab(find("|")+1), =name)
- then return termcap_string
- else {
-
- # The logic here probably isn't clear. The idea is to try to use
- # the termcap environment variable successively as 1) a termcap en-
- # try and then 2) as a termcap file. If neither works, 3) go to
- # the /etc/termcap file. The else clause here does 2 and, if ne-
- # cessary, 3. The "\termcap_string ? (not match..." expression
- # handles 1.
-
- if find("/",\termcap_string)
- then f := open(termcap_string)
- /f := open("/etc/termcap") |
- er("getentry","I can't access your /etc/termcap file",1)
-
- getline := create read_file(f)
-
- while line := @getline do {
- if line ? (pos(1) | tab(find("|")+1), =name, any(':|')) then {
- entry := ""
- while (\line | @getline) ? {
- if entry ||:= 1(tab(find(":")+1), pos(0))
- then {
- close(f)
- # if entry ends in tc= then add in the named tc entry
- entry ?:= tab(find("tc=")) ||
- # recursively fetch the new termcap entry
- (move(3), getentry(tab(find(":"))) ?
- # remove the name field from the new entry
- (tab(find(":")+1), tab(0)))
- return entry
- }
- else {
- \line := &null # must precede the next line
- entry ||:= trim(trim(tab(0),'\\'),':')
- }
- }
- }
- }
- }
-
- close(f)
- er("getentry","can't find and/or process your termcap entry",3)
-
- end
-
-
-
- procedure read_file(f)
-
- # Suspends all non #-initial lines in the file f.
- # Removes leading tabs and spaces from lines before suspending
- # them.
-
- local line
-
- \f | er("read_tcap_file","no valid termcap file found",3)
- while line := read(f) do {
- match("#",line) & next
- line ?:= (tab(many('\t ')) | &null, tab(0))
- suspend line
- }
-
- fail
-
- end
-
-
-
- procedure maketc_table(entry)
-
- # Maketc_table(s) (where s is a valid termcap entry for some
- # terminal-type): Returns a table in which the keys are termcap
- # capability designators, and the values are the entries in
- # "entry" for those designators.
-
- local k, v
-
- /entry & er("maketc_table","no entry given",8)
- if entry[-1] ~== ":" then entry ||:= ":"
-
- /tc_table := table()
-
- entry ? {
-
- tab(find(":")+1) # tab past initial (name) field
-
- while tab((find(":")+1) \ 1) ? {
- &subject == "" & next
- if k := 1(move(2), ="=")
- then tc_table[k] := Decode(tab(find(":")))
- else if k := 1(move(2), ="#")
- then tc_table[k] := integer(tab(find(":")))
- else if k := 1(tab(find(":")), pos(-1))
- then tc_table[k] := true()
- else er("maketc_table", "your termcap file has a bad entry",3)
- }
- }
-
- return tc_table
-
- end
-
-
-
- procedure getval(id)
-
- /tc_table := maketc_table(getentry(getname())) |
- er("getval","can't make a table for your terminal",4)
-
- return \tc_table[id] | fail
- # er("getval","the current terminal doesn't support "||id,7)
-