1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
include <syserr.h>
include <chars.h>
include "gty.h"
# GTY_INDEX_CAPS -- Prepare an index into the caplist string, stored in
# the tty descriptor. Each two character capability name maps into a unique
# integer code, called the capcode. We prepare a list of capcodes, keeping
# only the first such code encountered in the case of multiple entries.
# The offset of the capability in the caplist string is associated with each
# capcode. When these lists have been prepared, they are sorted to permit
# a binary search for capabilities at runtime.
procedure gty_index_caps (tty, t_capcode, t_capindex, ncaps)
pointer tty
int t_capcode[ARB], t_capindex[ARB]
int ncaps
pointer ip, caplist
int i, swap, capcode, temp
int gty_encode_capability()
pointer coerce()
errchk syserr
begin
caplist = coerce (tty + T_OFFCAP, TY_STRUCT, TY_CHAR)
ip = caplist
# Scan the caplist and prepare the capcode and capindex lists.
for (ncaps=0; ncaps <= MAX_CAPS; ) {
# Advance to the next capability field. Normal exit occurs
# when ':' is followed immediately by EOS.
while (Memc[ip] != ':' && Memc[ip] != EOS)
ip = ip + 1
if (Memc[ip+1] == EOS || Memc[ip] == EOS)
break
ip = ip + 1 # skip the ':'
capcode = gty_encode_capability (Memc[ip])
# Is the capcode already in the list? If not found, add it to
# the list.
for (i=1; i <= ncaps && t_capcode[i] != capcode; i=i+1)
;
if (i > ncaps) { # not found
ncaps = ncaps + 1
t_capcode[ncaps] = capcode
t_capindex[ncaps] = ip - caplist + 1
}
}
if (ncaps > MAX_CAPS)
call syserr (SYS_TTYOVFL)
# A simple interchange sort is sufficient here, even though it would
# not be hard to interface to qsort. The longest termcap entries are
# about 50 caps, and the time req'd to sort such a short list is
# negligible compared to the time spent searching the termcap file.
if (ncaps > 1)
repeat {
swap = 0
do i = 1, ncaps-1
if (t_capcode[i] > t_capcode[i+1]) {
temp = t_capcode[i]
t_capcode[i] = t_capcode[i+1]
t_capcode[i+1] = temp
temp = t_capindex[i]
t_capindex[i] = t_capindex[i+1]
t_capindex[i+1] = temp
swap = 1
}
} until (swap == 0)
end
# GTY_FIND_CAPABILITY -- Search the caplist for the named capability.
# If found, return the char pointer IP to the first char of the value field,
# and YES as the function value. If the first char in the capability string
# is '@', the capability "is not present".
int procedure gty_find_capability (tty, cap, ip)
pointer tty # tty descriptor
char cap[ARB] # two character name of capability
pointer ip # pointer to capability string
int capcode, capnum
int gty_binsearch(), gty_encode_capability()
pointer coerce()
errchk syserr
begin
if (tty == NULL)
call syserr (SYS_TTYINVDES)
capcode = gty_encode_capability (cap)
capnum = gty_binsearch (capcode, T_CAPCODE(tty), T_NCAPS(tty))
if (capnum > 0) {
# Add 2 to skip the two capname chars.
ip = coerce (tty + T_OFFCAP, TY_STRUCT, TY_CHAR) +
T_CAPINDEX(tty+capnum-1) - 1 + 2
if (Memc[ip] != '@')
return (YES)
}
return (NO)
end
# GTY_BINSEARCH -- Perform a binary search of the capcode array for the
# indicated capability. Return the array index of the capability if found,
# else zero.
int procedure gty_binsearch (capcode, t_capcode, ncaps)
int capcode
int t_capcode[ARB], ncaps
int low, high, pos, ntrips
define err_ 91
begin
pos = 0
low = 1
high = ncaps
if (high < low)
goto err_
# Cut range of search in half until code is found, or until range
# vanishes (high - low <= 1). If neither high or low is the one,
# code is not found in the list.
do ntrips = 1, ncaps {
pos = (high - low) / 2 + low
if (t_capcode[low] == capcode)
return (low)
else if (t_capcode[high] == capcode)
return (high)
else if (pos == low) # (high-low)/2 == 0
return (0) # not found
else if (t_capcode[pos] < capcode)
low = pos
else
high = pos
}
# Search cannot fail to converge unless there is a bug in the software
# somewhere.
err_
call syserr (SYS_TTYBINSRCH)
end
# GTY_ENCODE_CAPABILITY -- Encode the two character capability string
# as a unique integer value.
int procedure gty_encode_capability (cap)
char cap[ARB]
begin
return (ENCODE(cap))
end
|