aboutsummaryrefslogtreecommitdiff
path: root/pkg/system/help/hinput.x
blob: c47716e8f45d6efb057163b697829cf6576530cb (plain) (blame)
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.

include	<ctype.h>
include	"help.h"

.help hinput
.nf __________________________________________________________________________
HINPUT -- Lroff line input procedure.  Called by Lroff to get lines of
input text.  Function varies slightly depending on the Help option.
If printing only single param or single section, our job is to eat all
input which is not part of the indicated section of the help block.
A parameter block begins with ".ls paramname" and ends with a matching
".le" or ".ih", if the text is formatted.  Similarly, the single section
begins with a ".ih" followed by the section name on the next line.
.endhelp ______________________________________________________________________

define	SEARCHING	1
define	IN_BLOCK	2
define	MAXPAT		10


# HINPUT -- Get next input line from the help block.

int procedure hinput (ctrl, lbuf)

pointer	ctrl
char	lbuf[ARB]

bool	formatted
int	fd, level, status, ip
int	getline(), strmatch(), gstrcpy(), stridxs()
int	h_findparam(), h_findsection()
errchk	getline, h_findparam, h_findsection
define	findsec_ 91

begin
	fd = H_IN(ctrl)

	# EOF flag is set after param block has been fully input,
	# but normally before the actual end of file.

	if (H_EOF(ctrl) == YES || H_QUIT(ctrl) == YES)
	    return (EOF)
	else if (H_RAWIN(ctrl) == YES || H_FILTER_INPUT(ctrl) == NO)
	    return (getline (fd, lbuf))

	# We get here only if special processing is required to
	# filter out all but a section of the help text.

	switch (H_STATE(ctrl)) {
	case BOF:
	    # Determine whether or not the help block is formatted.
	    # Read in first line but save it for later and return a
	    # dummy line to Lroff, telling it whether or not the help
	    # block is formatted.

	    repeat {
		if (getline (fd, lbuf) == EOF)
		    return (EOF)
		for (ip=1;  IS_WHITE(lbuf[ip]);  ip=ip+1)
		    ;
	    } until (lbuf[ip] != '\n')
	    call ungetline (fd, lbuf)

	    if (lbuf[1] == '.') {
		formatted = true
		status = gstrcpy (".in 4\n", lbuf, SZ_LINE)
	    } else {
		formatted = false
		status = gstrcpy (".nf\n", lbuf, SZ_LINE)
	    }
	    H_STATE(ctrl) = SEARCHING

	case SEARCHING:
	    status = getline (fd, lbuf)
	    if (H_PARNAME(ctrl) != EOS) {
		status = h_findparam (fd, lbuf, formatted, H_PARNAME(ctrl))
		level = 1
	    } else if (H_SECNAME(ctrl) != EOS)
findsec_	status = h_findsection (fd, lbuf, formatted, H_SECNAME(ctrl))
	    H_STATE(ctrl) = IN_BLOCK

	case IN_BLOCK:
	    # By the time we get here we are in the parameter or single
	    # section.
	    status = getline (fd, lbuf)

	    if (lbuf[1] == '.') {
		if (strmatch (lbuf, "^.{ih}") > 0) {
		    if (stridxs ("|", H_SECNAME(ctrl)) > 0)
			goto findsec_
		    status = EOF
		} else if (H_PARNAME(ctrl) != EOS) {
		    if (strmatch (lbuf, "^.{ls}") > 0)
			level = level + 1
		    else if (strmatch (lbuf, "^.{le}") > 0) {
			level = level - 1
			if (level == 0)
			    status = EOF
		    }
		}
	    }

	default:
	    call error (15, "hinput: unknown input state encountered")
	}

	return (status)
end


# H_FINDPARAM -- If text contains format directives, eat input lines until
# a ".ls" directive is found which contains the param name as a substring.
# If the text is not formatted, search for a line beginning with the pattern.
# We are called with the first line of the file in lbuf.

int procedure h_findparam (fd, lbuf, formatted, param)

int	fd
char	lbuf
bool	formatted
char	param[ARB]

bool	match_found
pointer	sp, pattern
int	getline(), strmatch(), strlen()
errchk	getline

begin
	call smark (sp)
	call salloc (pattern, SZ_FNAME, TY_CHAR)

	match_found = false

	if (formatted) {
	    call sprintf (Memc[pattern], SZ_FNAME, "{%s}")
		call pargstr (param)
	    repeat {
		if (strmatch (lbuf, "^.{ls}") > 0)
		    if (strmatch (lbuf, Memc[pattern]) > 0) {
			match_found = true
			break
		    }
	    } until (getline (fd, lbuf) == EOF)

	} else {
	    call sprintf (Memc[pattern], SZ_FNAME, "^#{%s}")
		call pargstr (param)
	    repeat {
		if (strmatch (lbuf, Memc[pattern]) > 0) {
		    match_found = true
		    break
		}
	    } until (getline (fd, lbuf) == EOF)
	}

	call sfree (sp)
	if (match_found)
	    return (strlen (lbuf))
	else
	    return (EOF)
end


# H_FINDSECTION -- If text contains format directives, eat input lines until
# a ".ih" directive is found for the named section.  If the text is not
# formatted, search for a line beginning with the section name.
# We are called with the first line of the file in lbuf.

int procedure h_findsection (fd, lbuf, formatted, sections)

int	fd			# input file
char	lbuf			# line buffer
bool	formatted		# is help block formatted
char	sections[ARB]		# list of sections "a|b|c"

bool	match_found
int	npat, ip
pointer	sp, patbuf, patoff[MAXPAT], op
bool	h_match()
int	getline(), strmatch(), gstrcpy()
errchk	getline

begin
	call smark (sp)
	call salloc (patbuf, SZ_LINE, TY_CHAR)

	# Process the list of sections into patbuf and patoff, i.e., into a
	# list of EOS delimited strings in the string buffer patbuf.  Each
	# section name or abbreviation is delimited by '|' (or).

	npat = 1
	op = patbuf
	patoff[1] = op

	for (ip=1;  sections[ip] != EOS;  ip=ip+1)
	    switch (sections[ip]) {
	    case '|':
		Memc[op] = EOS
		op = op + 1
		npat = min (MAXPAT, npat + 1)
		patoff[npat] = op
	    default:
		Memc[op] = sections[ip]
		op = op + 1
	    }
	Memc[op] = EOS

	match_found = false

	if (formatted) {
	    repeat {
		if (strmatch (lbuf, "^.{ih}") > 0)
		    if (getline (fd, lbuf) != EOF) {
			match_found = h_match (lbuf, patoff, npat)
			if (match_found)
			    break
		    }
	    } until (getline (fd, lbuf) == EOF)

	} else {
	    repeat {
		match_found = h_match (lbuf, patoff, npat)
		if (match_found)
		    break
	    } until (getline (fd, lbuf) == EOF)
	}


	# If only one section is to be printed, skip the section name, otherwise
	# pass the .ih secname on to the text formatter.

	call sfree (sp)
	if (match_found) {
	    if (npat == 1)
		return (getline (fd, lbuf))
	    else {
		call ungetline (fd, lbuf)
		return (gstrcpy (".ih\n", lbuf, SZ_LINE))
	    }
	} else
	    return (EOF)
end


# H_MATCH -- Match a set of patterns against a line of test, matching only
# at the beginning of line in either case.

bool procedure h_match (lbuf, patoff, npat)

char	lbuf[ARB]		# line of text
pointer	patoff[npat]		# pointers to pattern strings
int	npat			# number of patterns

int	pat
pointer	sp, pattern
int	strmatch()

begin
	call smark (sp)
	call salloc (pattern, SZ_FNAME, TY_CHAR)

	for (pat=1;  pat <= npat;  pat=pat+1) {
	    call sprintf (Memc[pattern], SZ_FNAME, "^{%s}")
		call pargstr (Memc[patoff[pat]])
	    if (strmatch (lbuf, Memc[pattern]) > 0) {
		call sfree (sp)
		return (true)
	    }
	}

	call sfree (sp)
	return (false)
end