xref: /freebsd/contrib/less/input.c (revision 7374caaaed222af059fc66cb7fade7074ab391f4)
1a5f0fb15SPaul Saab /*
27374caaaSXin LI  * Copyright (C) 1984-2008  Mark Nudelman
3a5f0fb15SPaul Saab  *
4a5f0fb15SPaul Saab  * You may distribute under the terms of either the GNU General Public
5a5f0fb15SPaul Saab  * License or the Less License, as specified in the README file.
6a5f0fb15SPaul Saab  *
7a5f0fb15SPaul Saab  * For more information about less, or for information on how to
8a5f0fb15SPaul Saab  * contact the author, see the README file.
9a5f0fb15SPaul Saab  */
10a5f0fb15SPaul Saab 
11a5f0fb15SPaul Saab 
12a5f0fb15SPaul Saab /*
13a5f0fb15SPaul Saab  * High level routines dealing with getting lines of input
14a5f0fb15SPaul Saab  * from the file being viewed.
15a5f0fb15SPaul Saab  *
16a5f0fb15SPaul Saab  * When we speak of "lines" here, we mean PRINTABLE lines;
17a5f0fb15SPaul Saab  * lines processed with respect to the screen width.
18a5f0fb15SPaul Saab  * We use the term "raw line" to refer to lines simply
19a5f0fb15SPaul Saab  * delimited by newlines; not processed with respect to screen width.
20a5f0fb15SPaul Saab  */
21a5f0fb15SPaul Saab 
22a5f0fb15SPaul Saab #include "less.h"
23a5f0fb15SPaul Saab 
24a5f0fb15SPaul Saab extern int squeeze;
25a5f0fb15SPaul Saab extern int chopline;
268ed69c6fSPaul Saab extern int hshift;
27a5f0fb15SPaul Saab extern int quit_if_one_screen;
28a5f0fb15SPaul Saab extern int sigs;
29a5f0fb15SPaul Saab extern int ignore_eoi;
306dcb072bSXin LI extern int status_col;
31a5f0fb15SPaul Saab extern POSITION start_attnpos;
32a5f0fb15SPaul Saab extern POSITION end_attnpos;
33a5f0fb15SPaul Saab #if HILITE_SEARCH
34a5f0fb15SPaul Saab extern int hilite_search;
35a5f0fb15SPaul Saab extern int size_linebuf;
36a5f0fb15SPaul Saab #endif
37a5f0fb15SPaul Saab 
38a5f0fb15SPaul Saab /*
39a5f0fb15SPaul Saab  * Get the next line.
40a5f0fb15SPaul Saab  * A "current" position is passed and a "new" position is returned.
41a5f0fb15SPaul Saab  * The current position is the position of the first character of
42a5f0fb15SPaul Saab  * a line.  The new position is the position of the first character
43a5f0fb15SPaul Saab  * of the NEXT line.  The line obtained is the line starting at curr_pos.
44a5f0fb15SPaul Saab  */
45a5f0fb15SPaul Saab 	public POSITION
46a5f0fb15SPaul Saab forw_line(curr_pos)
47a5f0fb15SPaul Saab 	POSITION curr_pos;
48a5f0fb15SPaul Saab {
496dcb072bSXin LI 	POSITION base_pos;
50a5f0fb15SPaul Saab 	POSITION new_pos;
51a5f0fb15SPaul Saab 	register int c;
52a5f0fb15SPaul Saab 	int blankline;
53a5f0fb15SPaul Saab 	int endline;
546dcb072bSXin LI 	int backchars;
55a5f0fb15SPaul Saab 
567374caaaSXin LI get_forw_line:
57a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION)
58a5f0fb15SPaul Saab 	{
59a5f0fb15SPaul Saab 		null_line();
60a5f0fb15SPaul Saab 		return (NULL_POSITION);
61a5f0fb15SPaul Saab 	}
62a5f0fb15SPaul Saab #if HILITE_SEARCH
637374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
64a5f0fb15SPaul Saab 		/*
65a5f0fb15SPaul Saab 		 * If we are ignoring EOI (command F), only prepare
66a5f0fb15SPaul Saab 		 * one line ahead, to avoid getting stuck waiting for
67a5f0fb15SPaul Saab 		 * slow data without displaying the data we already have.
68a5f0fb15SPaul Saab 		 * If we're not ignoring EOI, we *could* do the same, but
69a5f0fb15SPaul Saab 		 * for efficiency we prepare several lines ahead at once.
70a5f0fb15SPaul Saab 		 */
71a5f0fb15SPaul Saab 		prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
72a5f0fb15SPaul Saab 				ignore_eoi ? 1 : -1);
73a5f0fb15SPaul Saab #endif
74a5f0fb15SPaul Saab 	if (ch_seek(curr_pos))
75a5f0fb15SPaul Saab 	{
76a5f0fb15SPaul Saab 		null_line();
77a5f0fb15SPaul Saab 		return (NULL_POSITION);
78a5f0fb15SPaul Saab 	}
79a5f0fb15SPaul Saab 
807374caaaSXin LI 	/*
817374caaaSXin LI 	 * Step back to the beginning of the line.
827374caaaSXin LI 	 */
836dcb072bSXin LI 	base_pos = curr_pos;
846dcb072bSXin LI 	for (;;)
856dcb072bSXin LI 	{
866dcb072bSXin LI 		if (ABORT_SIGS())
876dcb072bSXin LI 		{
886dcb072bSXin LI 			null_line();
896dcb072bSXin LI 			return (NULL_POSITION);
906dcb072bSXin LI 		}
916dcb072bSXin LI 		c = ch_back_get();
926dcb072bSXin LI 		if (c == EOI)
936dcb072bSXin LI 			break;
946dcb072bSXin LI 		if (c == '\n')
956dcb072bSXin LI 		{
966dcb072bSXin LI 			(void) ch_forw_get();
976dcb072bSXin LI 			break;
986dcb072bSXin LI 		}
996dcb072bSXin LI 		--base_pos;
1006dcb072bSXin LI 	}
1016dcb072bSXin LI 
1027374caaaSXin LI 	/*
1037374caaaSXin LI 	 * Read forward again to the position we should start at.
1047374caaaSXin LI 	 */
105a5f0fb15SPaul Saab  	prewind();
1066dcb072bSXin LI 	plinenum(base_pos);
1076dcb072bSXin LI 	(void) ch_seek(base_pos);
1087374caaaSXin LI 	new_pos = base_pos;
1097374caaaSXin LI 	while (new_pos < curr_pos)
1106dcb072bSXin LI 	{
1116dcb072bSXin LI 		if (ABORT_SIGS())
1126dcb072bSXin LI 		{
1136dcb072bSXin LI 			null_line();
1146dcb072bSXin LI 			return (NULL_POSITION);
1156dcb072bSXin LI 		}
1166dcb072bSXin LI 		c = ch_forw_get();
1177374caaaSXin LI 		backchars = pappend(c, new_pos);
1187374caaaSXin LI 		new_pos++;
1196dcb072bSXin LI 		if (backchars > 0)
1206dcb072bSXin LI 		{
1216dcb072bSXin LI 			pshift_all();
1227374caaaSXin LI 			new_pos -= backchars;
1236dcb072bSXin LI 			while (--backchars >= 0)
1246dcb072bSXin LI 				(void) ch_back_get();
1256dcb072bSXin LI 		}
1266dcb072bSXin LI 	}
1276dcb072bSXin LI 	(void) pflushmbc();
1286dcb072bSXin LI 	pshift_all();
129a5f0fb15SPaul Saab 
1307374caaaSXin LI 	/*
1317374caaaSXin LI 	 * Read the first character to display.
1327374caaaSXin LI 	 */
133a5f0fb15SPaul Saab 	c = ch_forw_get();
134a5f0fb15SPaul Saab 	if (c == EOI)
135a5f0fb15SPaul Saab 	{
136a5f0fb15SPaul Saab 		null_line();
137a5f0fb15SPaul Saab 		return (NULL_POSITION);
138a5f0fb15SPaul Saab 	}
139a5f0fb15SPaul Saab 	blankline = (c == '\n' || c == '\r');
140a5f0fb15SPaul Saab 
1417374caaaSXin LI 	/*
1427374caaaSXin LI 	 * Read each character in the line and append to the line buffer.
1437374caaaSXin LI 	 */
144a5f0fb15SPaul Saab 	for (;;)
145a5f0fb15SPaul Saab 	{
146a5f0fb15SPaul Saab 		if (ABORT_SIGS())
147a5f0fb15SPaul Saab 		{
148a5f0fb15SPaul Saab 			null_line();
149a5f0fb15SPaul Saab 			return (NULL_POSITION);
150a5f0fb15SPaul Saab 		}
151a5f0fb15SPaul Saab 		if (c == '\n' || c == EOI)
152a5f0fb15SPaul Saab 		{
153a5f0fb15SPaul Saab 			/*
154a5f0fb15SPaul Saab 			 * End of the line.
155a5f0fb15SPaul Saab 			 */
1566dcb072bSXin LI 			backchars = pflushmbc();
157a5f0fb15SPaul Saab 			new_pos = ch_tell();
1586dcb072bSXin LI 			if (backchars > 0 && !chopline && hshift == 0)
1596dcb072bSXin LI 			{
1606dcb072bSXin LI 				new_pos -= backchars + 1;
1616dcb072bSXin LI 				endline = FALSE;
1626dcb072bSXin LI 			} else
163a5f0fb15SPaul Saab 				endline = TRUE;
164a5f0fb15SPaul Saab 			break;
165a5f0fb15SPaul Saab 		}
1666dcb072bSXin LI 		if (c != '\r')
1676dcb072bSXin LI 			blankline = 0;
168a5f0fb15SPaul Saab 
169a5f0fb15SPaul Saab 		/*
170a5f0fb15SPaul Saab 		 * Append the char to the line and get the next char.
171a5f0fb15SPaul Saab 		 */
1726dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
1736dcb072bSXin LI 		if (backchars > 0)
174a5f0fb15SPaul Saab 		{
175a5f0fb15SPaul Saab 			/*
176a5f0fb15SPaul Saab 			 * The char won't fit in the line; the line
177a5f0fb15SPaul Saab 			 * is too long to print in the screen width.
178a5f0fb15SPaul Saab 			 * End the line here.
179a5f0fb15SPaul Saab 			 */
1808ed69c6fSPaul Saab 			if (chopline || hshift > 0)
181a5f0fb15SPaul Saab 			{
182a5f0fb15SPaul Saab 				do
183a5f0fb15SPaul Saab 				{
184a5f0fb15SPaul Saab 					c = ch_forw_get();
185a5f0fb15SPaul Saab 				} while (c != '\n' && c != EOI);
186a5f0fb15SPaul Saab 				new_pos = ch_tell();
187a5f0fb15SPaul Saab 				endline = TRUE;
188a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
189a5f0fb15SPaul Saab 			} else
190a5f0fb15SPaul Saab 			{
1916dcb072bSXin LI 				new_pos = ch_tell() - backchars;
192a5f0fb15SPaul Saab 				endline = FALSE;
193a5f0fb15SPaul Saab 			}
194a5f0fb15SPaul Saab 			break;
195a5f0fb15SPaul Saab 		}
196a5f0fb15SPaul Saab 		c = ch_forw_get();
197a5f0fb15SPaul Saab 	}
1987374caaaSXin LI 
1997374caaaSXin LI 	pdone(endline, c);
2007374caaaSXin LI 
2017374caaaSXin LI #if HILITE_SEARCH
2027374caaaSXin LI 	if (is_filtered(base_pos))
2037374caaaSXin LI 	{
2047374caaaSXin LI 		/*
2057374caaaSXin LI 		 * We don't want to display this line.
2067374caaaSXin LI 		 * Get the next line.
2077374caaaSXin LI 		 */
2087374caaaSXin LI 		curr_pos = new_pos;
2097374caaaSXin LI 		goto get_forw_line;
2107374caaaSXin LI 	}
2117374caaaSXin LI 
2127374caaaSXin LI 	if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL))
2137374caaaSXin LI 		set_status_col('*');
2147374caaaSXin LI #endif
215a5f0fb15SPaul Saab 
216a5f0fb15SPaul Saab 	if (squeeze && blankline)
217a5f0fb15SPaul Saab 	{
218a5f0fb15SPaul Saab 		/*
219a5f0fb15SPaul Saab 		 * This line is blank.
220a5f0fb15SPaul Saab 		 * Skip down to the last contiguous blank line
221a5f0fb15SPaul Saab 		 * and pretend it is the one which we are returning.
222a5f0fb15SPaul Saab 		 */
223a5f0fb15SPaul Saab 		while ((c = ch_forw_get()) == '\n' || c == '\r')
224a5f0fb15SPaul Saab 			if (ABORT_SIGS())
225a5f0fb15SPaul Saab 			{
226a5f0fb15SPaul Saab 				null_line();
227a5f0fb15SPaul Saab 				return (NULL_POSITION);
228a5f0fb15SPaul Saab 			}
229a5f0fb15SPaul Saab 		if (c != EOI)
230a5f0fb15SPaul Saab 			(void) ch_back_get();
231a5f0fb15SPaul Saab 		new_pos = ch_tell();
232a5f0fb15SPaul Saab 	}
233a5f0fb15SPaul Saab 
234a5f0fb15SPaul Saab 	return (new_pos);
235a5f0fb15SPaul Saab }
236a5f0fb15SPaul Saab 
237a5f0fb15SPaul Saab /*
238a5f0fb15SPaul Saab  * Get the previous line.
239a5f0fb15SPaul Saab  * A "current" position is passed and a "new" position is returned.
240a5f0fb15SPaul Saab  * The current position is the position of the first character of
241a5f0fb15SPaul Saab  * a line.  The new position is the position of the first character
242a5f0fb15SPaul Saab  * of the PREVIOUS line.  The line obtained is the one starting at new_pos.
243a5f0fb15SPaul Saab  */
244a5f0fb15SPaul Saab 	public POSITION
245a5f0fb15SPaul Saab back_line(curr_pos)
246a5f0fb15SPaul Saab 	POSITION curr_pos;
247a5f0fb15SPaul Saab {
2487374caaaSXin LI 	POSITION new_pos, begin_new_pos, base_pos;
249a5f0fb15SPaul Saab 	int c;
250a5f0fb15SPaul Saab 	int endline;
2516dcb072bSXin LI 	int backchars;
252a5f0fb15SPaul Saab 
2537374caaaSXin LI get_back_line:
254a5f0fb15SPaul Saab 	if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
255a5f0fb15SPaul Saab 	{
256a5f0fb15SPaul Saab 		null_line();
257a5f0fb15SPaul Saab 		return (NULL_POSITION);
258a5f0fb15SPaul Saab 	}
259a5f0fb15SPaul Saab #if HILITE_SEARCH
2607374caaaSXin LI 	if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
261a5f0fb15SPaul Saab 		prep_hilite((curr_pos < 3*size_linebuf) ?
262a5f0fb15SPaul Saab 				0 : curr_pos - 3*size_linebuf, curr_pos, -1);
263a5f0fb15SPaul Saab #endif
264a5f0fb15SPaul Saab 	if (ch_seek(curr_pos-1))
265a5f0fb15SPaul Saab 	{
266a5f0fb15SPaul Saab 		null_line();
267a5f0fb15SPaul Saab 		return (NULL_POSITION);
268a5f0fb15SPaul Saab 	}
269a5f0fb15SPaul Saab 
270a5f0fb15SPaul Saab 	if (squeeze)
271a5f0fb15SPaul Saab 	{
272a5f0fb15SPaul Saab 		/*
273a5f0fb15SPaul Saab 		 * Find out if the "current" line was blank.
274a5f0fb15SPaul Saab 		 */
275a5f0fb15SPaul Saab 		(void) ch_forw_get();    /* Skip the newline */
276a5f0fb15SPaul Saab 		c = ch_forw_get();       /* First char of "current" line */
277a5f0fb15SPaul Saab 		(void) ch_back_get();    /* Restore our position */
278a5f0fb15SPaul Saab 		(void) ch_back_get();
279a5f0fb15SPaul Saab 
280a5f0fb15SPaul Saab 		if (c == '\n' || c == '\r')
281a5f0fb15SPaul Saab 		{
282a5f0fb15SPaul Saab 			/*
283a5f0fb15SPaul Saab 			 * The "current" line was blank.
284a5f0fb15SPaul Saab 			 * Skip over any preceding blank lines,
285a5f0fb15SPaul Saab 			 * since we skipped them in forw_line().
286a5f0fb15SPaul Saab 			 */
287a5f0fb15SPaul Saab 			while ((c = ch_back_get()) == '\n' || c == '\r')
288a5f0fb15SPaul Saab 				if (ABORT_SIGS())
289a5f0fb15SPaul Saab 				{
290a5f0fb15SPaul Saab 					null_line();
291a5f0fb15SPaul Saab 					return (NULL_POSITION);
292a5f0fb15SPaul Saab 				}
293a5f0fb15SPaul Saab 			if (c == EOI)
294a5f0fb15SPaul Saab 			{
295a5f0fb15SPaul Saab 				null_line();
296a5f0fb15SPaul Saab 				return (NULL_POSITION);
297a5f0fb15SPaul Saab 			}
298a5f0fb15SPaul Saab 			(void) ch_forw_get();
299a5f0fb15SPaul Saab 		}
300a5f0fb15SPaul Saab 	}
301a5f0fb15SPaul Saab 
302a5f0fb15SPaul Saab 	/*
303a5f0fb15SPaul Saab 	 * Scan backwards until we hit the beginning of the line.
304a5f0fb15SPaul Saab 	 */
305a5f0fb15SPaul Saab 	for (;;)
306a5f0fb15SPaul Saab 	{
307a5f0fb15SPaul Saab 		if (ABORT_SIGS())
308a5f0fb15SPaul Saab 		{
309a5f0fb15SPaul Saab 			null_line();
310a5f0fb15SPaul Saab 			return (NULL_POSITION);
311a5f0fb15SPaul Saab 		}
312a5f0fb15SPaul Saab 		c = ch_back_get();
313a5f0fb15SPaul Saab 		if (c == '\n')
314a5f0fb15SPaul Saab 		{
315a5f0fb15SPaul Saab 			/*
316a5f0fb15SPaul Saab 			 * This is the newline ending the previous line.
317a5f0fb15SPaul Saab 			 * We have hit the beginning of the line.
318a5f0fb15SPaul Saab 			 */
3197374caaaSXin LI 			base_pos = ch_tell() + 1;
320a5f0fb15SPaul Saab 			break;
321a5f0fb15SPaul Saab 		}
322a5f0fb15SPaul Saab 		if (c == EOI)
323a5f0fb15SPaul Saab 		{
324a5f0fb15SPaul Saab 			/*
325a5f0fb15SPaul Saab 			 * We have hit the beginning of the file.
326a5f0fb15SPaul Saab 			 * This must be the first line in the file.
327a5f0fb15SPaul Saab 			 * This must, of course, be the beginning of the line.
328a5f0fb15SPaul Saab 			 */
3297374caaaSXin LI 			base_pos = ch_tell();
330a5f0fb15SPaul Saab 			break;
331a5f0fb15SPaul Saab 		}
332a5f0fb15SPaul Saab 	}
333a5f0fb15SPaul Saab 
334a5f0fb15SPaul Saab 	/*
335a5f0fb15SPaul Saab 	 * Now scan forwards from the beginning of this line.
336a5f0fb15SPaul Saab 	 * We keep discarding "printable lines" (based on screen width)
337a5f0fb15SPaul Saab 	 * until we reach the curr_pos.
338a5f0fb15SPaul Saab 	 *
339a5f0fb15SPaul Saab 	 * {{ This algorithm is pretty inefficient if the lines
340a5f0fb15SPaul Saab 	 *    are much longer than the screen width,
341a5f0fb15SPaul Saab 	 *    but I don't know of any better way. }}
342a5f0fb15SPaul Saab 	 */
3437374caaaSXin LI 	new_pos = base_pos;
344a5f0fb15SPaul Saab 	if (ch_seek(new_pos))
345a5f0fb15SPaul Saab 	{
346a5f0fb15SPaul Saab 		null_line();
347a5f0fb15SPaul Saab 		return (NULL_POSITION);
348a5f0fb15SPaul Saab 	}
349a5f0fb15SPaul Saab 	endline = FALSE;
350a5f0fb15SPaul Saab 	prewind();
351a5f0fb15SPaul Saab 	plinenum(new_pos);
3526dcb072bSXin LI     loop:
3536dcb072bSXin LI 	begin_new_pos = new_pos;
354a5f0fb15SPaul Saab 	(void) ch_seek(new_pos);
355a5f0fb15SPaul Saab 
356a5f0fb15SPaul Saab 	do
357a5f0fb15SPaul Saab 	{
358a5f0fb15SPaul Saab 		c = ch_forw_get();
359a5f0fb15SPaul Saab 		if (c == EOI || ABORT_SIGS())
360a5f0fb15SPaul Saab 		{
361a5f0fb15SPaul Saab 			null_line();
362a5f0fb15SPaul Saab 			return (NULL_POSITION);
363a5f0fb15SPaul Saab 		}
364a5f0fb15SPaul Saab 		new_pos++;
365a5f0fb15SPaul Saab 		if (c == '\n')
366a5f0fb15SPaul Saab 		{
3676dcb072bSXin LI 			backchars = pflushmbc();
3686dcb072bSXin LI 			if (backchars > 0 && !chopline && hshift == 0)
3696dcb072bSXin LI 			{
3706dcb072bSXin LI 				backchars++;
3716dcb072bSXin LI 				goto shift;
3726dcb072bSXin LI 			}
373a5f0fb15SPaul Saab 			endline = TRUE;
374a5f0fb15SPaul Saab 			break;
375a5f0fb15SPaul Saab 		}
3766dcb072bSXin LI 		backchars = pappend(c, ch_tell()-1);
3776dcb072bSXin LI 		if (backchars > 0)
378a5f0fb15SPaul Saab 		{
379a5f0fb15SPaul Saab 			/*
380a5f0fb15SPaul Saab 			 * Got a full printable line, but we haven't
381a5f0fb15SPaul Saab 			 * reached our curr_pos yet.  Discard the line
382a5f0fb15SPaul Saab 			 * and start a new one.
383a5f0fb15SPaul Saab 			 */
3848ed69c6fSPaul Saab 			if (chopline || hshift > 0)
385a5f0fb15SPaul Saab 			{
386a5f0fb15SPaul Saab 				endline = TRUE;
387a5f0fb15SPaul Saab 				quit_if_one_screen = FALSE;
388a5f0fb15SPaul Saab 				break;
389a5f0fb15SPaul Saab 			}
3906dcb072bSXin LI 		shift:
3916dcb072bSXin LI 			pshift_all();
3926dcb072bSXin LI 			while (backchars-- > 0)
3936dcb072bSXin LI 			{
394a5f0fb15SPaul Saab 				(void) ch_back_get();
395a5f0fb15SPaul Saab 				new_pos--;
3966dcb072bSXin LI 			}
397a5f0fb15SPaul Saab 			goto loop;
398a5f0fb15SPaul Saab 		}
399a5f0fb15SPaul Saab 	} while (new_pos < curr_pos);
400a5f0fb15SPaul Saab 
4017374caaaSXin LI 	pdone(endline, ch_forw_get());
4027374caaaSXin LI 
4037374caaaSXin LI #if HILITE_SEARCH
4047374caaaSXin LI 	if (is_filtered(base_pos))
4057374caaaSXin LI 	{
4067374caaaSXin LI 		/*
4077374caaaSXin LI 		 * We don't want to display this line.
4087374caaaSXin LI 		 * Get the previous line.
4097374caaaSXin LI 		 */
4107374caaaSXin LI 		curr_pos = begin_new_pos;
4117374caaaSXin LI 		goto get_back_line;
4127374caaaSXin LI 	}
4137374caaaSXin LI 
4147374caaaSXin LI 	if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL))
4157374caaaSXin LI 		set_status_col('*');
4167374caaaSXin LI #endif
417a5f0fb15SPaul Saab 
418a5f0fb15SPaul Saab 	return (begin_new_pos);
419a5f0fb15SPaul Saab }
420a5f0fb15SPaul Saab 
421a5f0fb15SPaul Saab /*
422a5f0fb15SPaul Saab  * Set attnpos.
423a5f0fb15SPaul Saab  */
424a5f0fb15SPaul Saab 	public void
425a5f0fb15SPaul Saab set_attnpos(pos)
426a5f0fb15SPaul Saab 	POSITION pos;
427a5f0fb15SPaul Saab {
428a5f0fb15SPaul Saab 	int c;
429a5f0fb15SPaul Saab 
430a5f0fb15SPaul Saab 	if (pos != NULL_POSITION)
431a5f0fb15SPaul Saab 	{
432a5f0fb15SPaul Saab 		if (ch_seek(pos))
433a5f0fb15SPaul Saab 			return;
434a5f0fb15SPaul Saab 		for (;;)
435a5f0fb15SPaul Saab 		{
436a5f0fb15SPaul Saab 			c = ch_forw_get();
437a5f0fb15SPaul Saab 			if (c == EOI)
438a5f0fb15SPaul Saab 				return;
439a5f0fb15SPaul Saab 			if (c != '\n' && c != '\r')
440a5f0fb15SPaul Saab 				break;
441a5f0fb15SPaul Saab 			pos++;
442a5f0fb15SPaul Saab 		}
443a5f0fb15SPaul Saab 	}
444a5f0fb15SPaul Saab 	start_attnpos = pos;
445a5f0fb15SPaul Saab 	for (;;)
446a5f0fb15SPaul Saab 	{
447a5f0fb15SPaul Saab 		c = ch_forw_get();
448a5f0fb15SPaul Saab 		pos++;
449a5f0fb15SPaul Saab 		if (c == EOI || c == '\n' || c == '\r')
450a5f0fb15SPaul Saab 			break;
451a5f0fb15SPaul Saab 	}
452a5f0fb15SPaul Saab 	end_attnpos = pos;
453a5f0fb15SPaul Saab }
454