1a5f0fb15SPaul Saab /* 2*95270f73SXin LI * Copyright (C) 1984-2022 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 * 796e55cc7SXin LI * For more information, see the README file. 8a5f0fb15SPaul Saab */ 9a5f0fb15SPaul Saab 10a5f0fb15SPaul Saab /* 11a5f0fb15SPaul Saab * High level routines dealing with getting lines of input 12a5f0fb15SPaul Saab * from the file being viewed. 13a5f0fb15SPaul Saab * 14a5f0fb15SPaul Saab * When we speak of "lines" here, we mean PRINTABLE lines; 15a5f0fb15SPaul Saab * lines processed with respect to the screen width. 16a5f0fb15SPaul Saab * We use the term "raw line" to refer to lines simply 17a5f0fb15SPaul Saab * delimited by newlines; not processed with respect to screen width. 18a5f0fb15SPaul Saab */ 19a5f0fb15SPaul Saab 20a5f0fb15SPaul Saab #include "less.h" 21a5f0fb15SPaul Saab 22a5f0fb15SPaul Saab extern int squeeze; 238ed69c6fSPaul Saab extern int hshift; 24a5f0fb15SPaul Saab extern int quit_if_one_screen; 25a5f0fb15SPaul Saab extern int sigs; 26a5f0fb15SPaul Saab extern int ignore_eoi; 276dcb072bSXin LI extern int status_col; 28a5f0fb15SPaul Saab extern POSITION start_attnpos; 29a5f0fb15SPaul Saab extern POSITION end_attnpos; 30a5f0fb15SPaul Saab #if HILITE_SEARCH 31a5f0fb15SPaul Saab extern int hilite_search; 32a5f0fb15SPaul Saab extern int size_linebuf; 332235c7feSXin LI extern int show_attn; 34a5f0fb15SPaul Saab #endif 35a5f0fb15SPaul Saab 36a5f0fb15SPaul Saab /* 37a5f0fb15SPaul Saab * Get the next line. 38a5f0fb15SPaul Saab * A "current" position is passed and a "new" position is returned. 39a5f0fb15SPaul Saab * The current position is the position of the first character of 40a5f0fb15SPaul Saab * a line. The new position is the position of the first character 41a5f0fb15SPaul Saab * of the NEXT line. The line obtained is the line starting at curr_pos. 42a5f0fb15SPaul Saab */ 43a5f0fb15SPaul Saab public POSITION 44*95270f73SXin LI forw_line_seg(curr_pos, skipeol, rscroll, nochop) 45f6b74a7dSXin LI POSITION curr_pos; 46*95270f73SXin LI int skipeol; 47*95270f73SXin LI int rscroll; 48*95270f73SXin LI int nochop; 49a5f0fb15SPaul Saab { 506dcb072bSXin LI POSITION base_pos; 51a5f0fb15SPaul Saab POSITION new_pos; 521ea31627SRobert Watson int c; 53a5f0fb15SPaul Saab int blankline; 54a5f0fb15SPaul Saab int endline; 55b2ea2440SXin LI int chopped; 566dcb072bSXin LI int backchars; 57a5f0fb15SPaul Saab 587374caaaSXin LI get_forw_line: 59a5f0fb15SPaul Saab if (curr_pos == NULL_POSITION) 60a5f0fb15SPaul Saab { 61a5f0fb15SPaul Saab null_line(); 62a5f0fb15SPaul Saab return (NULL_POSITION); 63a5f0fb15SPaul Saab } 64a5f0fb15SPaul Saab #if HILITE_SEARCH 657374caaaSXin LI if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) 66a15691bfSXin LI { 67a5f0fb15SPaul Saab /* 68a5f0fb15SPaul Saab * If we are ignoring EOI (command F), only prepare 69a5f0fb15SPaul Saab * one line ahead, to avoid getting stuck waiting for 70a5f0fb15SPaul Saab * slow data without displaying the data we already have. 71a5f0fb15SPaul Saab * If we're not ignoring EOI, we *could* do the same, but 72a5f0fb15SPaul Saab * for efficiency we prepare several lines ahead at once. 73a5f0fb15SPaul Saab */ 74a5f0fb15SPaul Saab prep_hilite(curr_pos, curr_pos + 3*size_linebuf, 75a5f0fb15SPaul Saab ignore_eoi ? 1 : -1); 76a15691bfSXin LI curr_pos = next_unfiltered(curr_pos); 77a15691bfSXin LI } 78a5f0fb15SPaul Saab #endif 79a5f0fb15SPaul Saab if (ch_seek(curr_pos)) 80a5f0fb15SPaul Saab { 81a5f0fb15SPaul Saab null_line(); 82a5f0fb15SPaul Saab return (NULL_POSITION); 83a5f0fb15SPaul Saab } 84a5f0fb15SPaul Saab 857374caaaSXin LI /* 867374caaaSXin LI * Step back to the beginning of the line. 877374caaaSXin LI */ 886dcb072bSXin LI base_pos = curr_pos; 896dcb072bSXin LI for (;;) 906dcb072bSXin LI { 916dcb072bSXin LI if (ABORT_SIGS()) 926dcb072bSXin LI { 936dcb072bSXin LI null_line(); 946dcb072bSXin LI return (NULL_POSITION); 956dcb072bSXin LI } 966dcb072bSXin LI c = ch_back_get(); 976dcb072bSXin LI if (c == EOI) 986dcb072bSXin LI break; 996dcb072bSXin LI if (c == '\n') 1006dcb072bSXin LI { 1016dcb072bSXin LI (void) ch_forw_get(); 1026dcb072bSXin LI break; 1036dcb072bSXin LI } 1046dcb072bSXin LI --base_pos; 1056dcb072bSXin LI } 1066dcb072bSXin LI 1077374caaaSXin LI /* 1087374caaaSXin LI * Read forward again to the position we should start at. 1097374caaaSXin LI */ 110a5f0fb15SPaul Saab prewind(); 1112235c7feSXin LI plinestart(base_pos); 1126dcb072bSXin LI (void) ch_seek(base_pos); 1137374caaaSXin LI new_pos = base_pos; 1147374caaaSXin LI while (new_pos < curr_pos) 1156dcb072bSXin LI { 1166dcb072bSXin LI if (ABORT_SIGS()) 1176dcb072bSXin LI { 1186dcb072bSXin LI null_line(); 1196dcb072bSXin LI return (NULL_POSITION); 1206dcb072bSXin LI } 1216dcb072bSXin LI c = ch_forw_get(); 1227374caaaSXin LI backchars = pappend(c, new_pos); 1237374caaaSXin LI new_pos++; 1246dcb072bSXin LI if (backchars > 0) 1256dcb072bSXin LI { 1266dcb072bSXin LI pshift_all(); 1277374caaaSXin LI new_pos -= backchars; 1286dcb072bSXin LI while (--backchars >= 0) 1296dcb072bSXin LI (void) ch_back_get(); 1306dcb072bSXin LI } 1316dcb072bSXin LI } 1326dcb072bSXin LI (void) pflushmbc(); 1336dcb072bSXin LI pshift_all(); 134a5f0fb15SPaul Saab 1357374caaaSXin LI /* 1367374caaaSXin LI * Read the first character to display. 1377374caaaSXin LI */ 138a5f0fb15SPaul Saab c = ch_forw_get(); 139a5f0fb15SPaul Saab if (c == EOI) 140a5f0fb15SPaul Saab { 141a5f0fb15SPaul Saab null_line(); 142a5f0fb15SPaul Saab return (NULL_POSITION); 143a5f0fb15SPaul Saab } 144a5f0fb15SPaul Saab blankline = (c == '\n' || c == '\r'); 145a5f0fb15SPaul Saab 1467374caaaSXin LI /* 1477374caaaSXin LI * Read each character in the line and append to the line buffer. 1487374caaaSXin LI */ 149b2ea2440SXin LI chopped = FALSE; 150a5f0fb15SPaul Saab for (;;) 151a5f0fb15SPaul Saab { 152a5f0fb15SPaul Saab if (ABORT_SIGS()) 153a5f0fb15SPaul Saab { 154a5f0fb15SPaul Saab null_line(); 155a5f0fb15SPaul Saab return (NULL_POSITION); 156a5f0fb15SPaul Saab } 157a5f0fb15SPaul Saab if (c == '\n' || c == EOI) 158a5f0fb15SPaul Saab { 159a5f0fb15SPaul Saab /* 160a5f0fb15SPaul Saab * End of the line. 161a5f0fb15SPaul Saab */ 1626dcb072bSXin LI backchars = pflushmbc(); 163a5f0fb15SPaul Saab new_pos = ch_tell(); 164*95270f73SXin LI if (backchars > 0 && (nochop || !chop_line()) && hshift == 0) 1656dcb072bSXin LI { 1666dcb072bSXin LI new_pos -= backchars + 1; 1676dcb072bSXin LI endline = FALSE; 1686dcb072bSXin LI } else 169a5f0fb15SPaul Saab endline = TRUE; 170a5f0fb15SPaul Saab break; 171a5f0fb15SPaul Saab } 1726dcb072bSXin LI if (c != '\r') 1736dcb072bSXin LI blankline = 0; 174a5f0fb15SPaul Saab 175a5f0fb15SPaul Saab /* 176a5f0fb15SPaul Saab * Append the char to the line and get the next char. 177a5f0fb15SPaul Saab */ 1786dcb072bSXin LI backchars = pappend(c, ch_tell()-1); 1796dcb072bSXin LI if (backchars > 0) 180a5f0fb15SPaul Saab { 181a5f0fb15SPaul Saab /* 182a5f0fb15SPaul Saab * The char won't fit in the line; the line 183a5f0fb15SPaul Saab * is too long to print in the screen width. 184a5f0fb15SPaul Saab * End the line here. 185a5f0fb15SPaul Saab */ 186*95270f73SXin LI if (skipeol) 187a5f0fb15SPaul Saab { 1882235c7feSXin LI /* Read to end of line. */ 189a5f0fb15SPaul Saab do 190a5f0fb15SPaul Saab { 19133096f16SXin LI if (ABORT_SIGS()) 19233096f16SXin LI { 19333096f16SXin LI null_line(); 19433096f16SXin LI return (NULL_POSITION); 19533096f16SXin LI } 196a5f0fb15SPaul Saab c = ch_forw_get(); 197a5f0fb15SPaul Saab } while (c != '\n' && c != EOI); 198a5f0fb15SPaul Saab new_pos = ch_tell(); 199a5f0fb15SPaul Saab endline = TRUE; 200a5f0fb15SPaul Saab quit_if_one_screen = FALSE; 201b2ea2440SXin LI chopped = TRUE; 202a5f0fb15SPaul Saab } else 203a5f0fb15SPaul Saab { 2046dcb072bSXin LI new_pos = ch_tell() - backchars; 205a5f0fb15SPaul Saab endline = FALSE; 206a5f0fb15SPaul Saab } 207a5f0fb15SPaul Saab break; 208a5f0fb15SPaul Saab } 209a5f0fb15SPaul Saab c = ch_forw_get(); 210a5f0fb15SPaul Saab } 2117374caaaSXin LI 2122235c7feSXin LI #if HILITE_SEARCH 2132235c7feSXin LI if (blankline && show_attn) 2142235c7feSXin LI { 2152235c7feSXin LI /* Add spurious space to carry possible attn hilite. */ 2162235c7feSXin LI pappend(' ', ch_tell()-1); 2172235c7feSXin LI } 2182235c7feSXin LI #endif 219*95270f73SXin LI pdone(endline, rscroll && chopped, 1); 2207374caaaSXin LI 2217374caaaSXin LI #if HILITE_SEARCH 2227374caaaSXin LI if (is_filtered(base_pos)) 2237374caaaSXin LI { 2247374caaaSXin LI /* 2257374caaaSXin LI * We don't want to display this line. 2267374caaaSXin LI * Get the next line. 2277374caaaSXin LI */ 2287374caaaSXin LI curr_pos = new_pos; 2297374caaaSXin LI goto get_forw_line; 2307374caaaSXin LI } 2317374caaaSXin LI 2322235c7feSXin LI if (status_col) 2332235c7feSXin LI { 2342235c7feSXin LI int attr = is_hilited_attr(base_pos, ch_tell()-1, 1, NULL); 2352235c7feSXin LI if (attr) 2362235c7feSXin LI set_status_col('*', attr); 2372235c7feSXin LI } 2387374caaaSXin LI #endif 239a5f0fb15SPaul Saab 240a5f0fb15SPaul Saab if (squeeze && blankline) 241a5f0fb15SPaul Saab { 242a5f0fb15SPaul Saab /* 243a5f0fb15SPaul Saab * This line is blank. 244a5f0fb15SPaul Saab * Skip down to the last contiguous blank line 245a5f0fb15SPaul Saab * and pretend it is the one which we are returning. 246a5f0fb15SPaul Saab */ 247a5f0fb15SPaul Saab while ((c = ch_forw_get()) == '\n' || c == '\r') 248a5f0fb15SPaul Saab if (ABORT_SIGS()) 249a5f0fb15SPaul Saab { 250a5f0fb15SPaul Saab null_line(); 251a5f0fb15SPaul Saab return (NULL_POSITION); 252a5f0fb15SPaul Saab } 253a5f0fb15SPaul Saab if (c != EOI) 254a5f0fb15SPaul Saab (void) ch_back_get(); 255a5f0fb15SPaul Saab new_pos = ch_tell(); 256a5f0fb15SPaul Saab } 257a5f0fb15SPaul Saab 258a5f0fb15SPaul Saab return (new_pos); 259a5f0fb15SPaul Saab } 260a5f0fb15SPaul Saab 2612235c7feSXin LI public POSITION 2622235c7feSXin LI forw_line(curr_pos) 2632235c7feSXin LI POSITION curr_pos; 2642235c7feSXin LI { 265*95270f73SXin LI 266*95270f73SXin LI return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE); 2672235c7feSXin LI } 2682235c7feSXin LI 269a5f0fb15SPaul Saab /* 270a5f0fb15SPaul Saab * Get the previous line. 271a5f0fb15SPaul Saab * A "current" position is passed and a "new" position is returned. 272a5f0fb15SPaul Saab * The current position is the position of the first character of 273a5f0fb15SPaul Saab * a line. The new position is the position of the first character 274a5f0fb15SPaul Saab * of the PREVIOUS line. The line obtained is the one starting at new_pos. 275a5f0fb15SPaul Saab */ 276a5f0fb15SPaul Saab public POSITION 277f6b74a7dSXin LI back_line(curr_pos) 278f6b74a7dSXin LI POSITION curr_pos; 279a5f0fb15SPaul Saab { 2807374caaaSXin LI POSITION new_pos, begin_new_pos, base_pos; 281a5f0fb15SPaul Saab int c; 282a5f0fb15SPaul Saab int endline; 283b2ea2440SXin LI int chopped; 2846dcb072bSXin LI int backchars; 285a5f0fb15SPaul Saab 2867374caaaSXin LI get_back_line: 287a5f0fb15SPaul Saab if (curr_pos == NULL_POSITION || curr_pos <= ch_zero()) 288a5f0fb15SPaul Saab { 289a5f0fb15SPaul Saab null_line(); 290a5f0fb15SPaul Saab return (NULL_POSITION); 291a5f0fb15SPaul Saab } 292a5f0fb15SPaul Saab #if HILITE_SEARCH 2937374caaaSXin LI if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) 294a5f0fb15SPaul Saab prep_hilite((curr_pos < 3*size_linebuf) ? 295a5f0fb15SPaul Saab 0 : curr_pos - 3*size_linebuf, curr_pos, -1); 296a5f0fb15SPaul Saab #endif 297a5f0fb15SPaul Saab if (ch_seek(curr_pos-1)) 298a5f0fb15SPaul Saab { 299a5f0fb15SPaul Saab null_line(); 300a5f0fb15SPaul Saab return (NULL_POSITION); 301a5f0fb15SPaul Saab } 302a5f0fb15SPaul Saab 303a5f0fb15SPaul Saab if (squeeze) 304a5f0fb15SPaul Saab { 305a5f0fb15SPaul Saab /* 306a5f0fb15SPaul Saab * Find out if the "current" line was blank. 307a5f0fb15SPaul Saab */ 308a5f0fb15SPaul Saab (void) ch_forw_get(); /* Skip the newline */ 309a5f0fb15SPaul Saab c = ch_forw_get(); /* First char of "current" line */ 310a5f0fb15SPaul Saab (void) ch_back_get(); /* Restore our position */ 311a5f0fb15SPaul Saab (void) ch_back_get(); 312a5f0fb15SPaul Saab 313a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 314a5f0fb15SPaul Saab { 315a5f0fb15SPaul Saab /* 316a5f0fb15SPaul Saab * The "current" line was blank. 317a5f0fb15SPaul Saab * Skip over any preceding blank lines, 318a5f0fb15SPaul Saab * since we skipped them in forw_line(). 319a5f0fb15SPaul Saab */ 320a5f0fb15SPaul Saab while ((c = ch_back_get()) == '\n' || c == '\r') 321a5f0fb15SPaul Saab if (ABORT_SIGS()) 322a5f0fb15SPaul Saab { 323a5f0fb15SPaul Saab null_line(); 324a5f0fb15SPaul Saab return (NULL_POSITION); 325a5f0fb15SPaul Saab } 326a5f0fb15SPaul Saab if (c == EOI) 327a5f0fb15SPaul Saab { 328a5f0fb15SPaul Saab null_line(); 329a5f0fb15SPaul Saab return (NULL_POSITION); 330a5f0fb15SPaul Saab } 331a5f0fb15SPaul Saab (void) ch_forw_get(); 332a5f0fb15SPaul Saab } 333a5f0fb15SPaul Saab } 334a5f0fb15SPaul Saab 335a5f0fb15SPaul Saab /* 336a5f0fb15SPaul Saab * Scan backwards until we hit the beginning of the line. 337a5f0fb15SPaul Saab */ 338a5f0fb15SPaul Saab for (;;) 339a5f0fb15SPaul Saab { 340a5f0fb15SPaul Saab if (ABORT_SIGS()) 341a5f0fb15SPaul Saab { 342a5f0fb15SPaul Saab null_line(); 343a5f0fb15SPaul Saab return (NULL_POSITION); 344a5f0fb15SPaul Saab } 345a5f0fb15SPaul Saab c = ch_back_get(); 346a5f0fb15SPaul Saab if (c == '\n') 347a5f0fb15SPaul Saab { 348a5f0fb15SPaul Saab /* 349a5f0fb15SPaul Saab * This is the newline ending the previous line. 350a5f0fb15SPaul Saab * We have hit the beginning of the line. 351a5f0fb15SPaul Saab */ 3527374caaaSXin LI base_pos = ch_tell() + 1; 353a5f0fb15SPaul Saab break; 354a5f0fb15SPaul Saab } 355a5f0fb15SPaul Saab if (c == EOI) 356a5f0fb15SPaul Saab { 357a5f0fb15SPaul Saab /* 358a5f0fb15SPaul Saab * We have hit the beginning of the file. 359a5f0fb15SPaul Saab * This must be the first line in the file. 360a5f0fb15SPaul Saab * This must, of course, be the beginning of the line. 361a5f0fb15SPaul Saab */ 3627374caaaSXin LI base_pos = ch_tell(); 363a5f0fb15SPaul Saab break; 364a5f0fb15SPaul Saab } 365a5f0fb15SPaul Saab } 366a5f0fb15SPaul Saab 367a5f0fb15SPaul Saab /* 368a5f0fb15SPaul Saab * Now scan forwards from the beginning of this line. 369a5f0fb15SPaul Saab * We keep discarding "printable lines" (based on screen width) 370a5f0fb15SPaul Saab * until we reach the curr_pos. 371a5f0fb15SPaul Saab * 372a5f0fb15SPaul Saab * {{ This algorithm is pretty inefficient if the lines 373a5f0fb15SPaul Saab * are much longer than the screen width, 374a5f0fb15SPaul Saab * but I don't know of any better way. }} 375a5f0fb15SPaul Saab */ 3767374caaaSXin LI new_pos = base_pos; 377a5f0fb15SPaul Saab if (ch_seek(new_pos)) 378a5f0fb15SPaul Saab { 379a5f0fb15SPaul Saab null_line(); 380a5f0fb15SPaul Saab return (NULL_POSITION); 381a5f0fb15SPaul Saab } 382a5f0fb15SPaul Saab endline = FALSE; 383a5f0fb15SPaul Saab prewind(); 3842235c7feSXin LI plinestart(new_pos); 3856dcb072bSXin LI loop: 3866dcb072bSXin LI begin_new_pos = new_pos; 387a5f0fb15SPaul Saab (void) ch_seek(new_pos); 388b2ea2440SXin LI chopped = FALSE; 389a5f0fb15SPaul Saab 390a5f0fb15SPaul Saab do 391a5f0fb15SPaul Saab { 392a5f0fb15SPaul Saab c = ch_forw_get(); 393a5f0fb15SPaul Saab if (c == EOI || ABORT_SIGS()) 394a5f0fb15SPaul Saab { 395a5f0fb15SPaul Saab null_line(); 396a5f0fb15SPaul Saab return (NULL_POSITION); 397a5f0fb15SPaul Saab } 398a5f0fb15SPaul Saab new_pos++; 399a5f0fb15SPaul Saab if (c == '\n') 400a5f0fb15SPaul Saab { 4016dcb072bSXin LI backchars = pflushmbc(); 402*95270f73SXin LI if (backchars > 0 && !chop_line() && hshift == 0) 4036dcb072bSXin LI { 4046dcb072bSXin LI backchars++; 4056dcb072bSXin LI goto shift; 4066dcb072bSXin LI } 407a5f0fb15SPaul Saab endline = TRUE; 408a5f0fb15SPaul Saab break; 409a5f0fb15SPaul Saab } 4106dcb072bSXin LI backchars = pappend(c, ch_tell()-1); 4116dcb072bSXin LI if (backchars > 0) 412a5f0fb15SPaul Saab { 413a5f0fb15SPaul Saab /* 414a5f0fb15SPaul Saab * Got a full printable line, but we haven't 415a5f0fb15SPaul Saab * reached our curr_pos yet. Discard the line 416a5f0fb15SPaul Saab * and start a new one. 417a5f0fb15SPaul Saab */ 418*95270f73SXin LI if (chop_line() || hshift > 0) 419a5f0fb15SPaul Saab { 420a5f0fb15SPaul Saab endline = TRUE; 421b2ea2440SXin LI chopped = TRUE; 422a5f0fb15SPaul Saab quit_if_one_screen = FALSE; 423a5f0fb15SPaul Saab break; 424a5f0fb15SPaul Saab } 4256dcb072bSXin LI shift: 4266dcb072bSXin LI pshift_all(); 4276dcb072bSXin LI while (backchars-- > 0) 4286dcb072bSXin LI { 429a5f0fb15SPaul Saab (void) ch_back_get(); 430a5f0fb15SPaul Saab new_pos--; 4316dcb072bSXin LI } 432a5f0fb15SPaul Saab goto loop; 433a5f0fb15SPaul Saab } 434a5f0fb15SPaul Saab } while (new_pos < curr_pos); 435a5f0fb15SPaul Saab 436b2ea2440SXin LI pdone(endline, chopped, 0); 4377374caaaSXin LI 4387374caaaSXin LI #if HILITE_SEARCH 4397374caaaSXin LI if (is_filtered(base_pos)) 4407374caaaSXin LI { 4417374caaaSXin LI /* 4427374caaaSXin LI * We don't want to display this line. 4437374caaaSXin LI * Get the previous line. 4447374caaaSXin LI */ 4457374caaaSXin LI curr_pos = begin_new_pos; 4467374caaaSXin LI goto get_back_line; 4477374caaaSXin LI } 4487374caaaSXin LI 4492235c7feSXin LI if (status_col && curr_pos > 0) 4502235c7feSXin LI { 4512235c7feSXin LI int attr = is_hilited_attr(base_pos, curr_pos-1, 1, NULL); 4522235c7feSXin LI if (attr) 4532235c7feSXin LI set_status_col('*', attr); 4542235c7feSXin LI } 4557374caaaSXin LI #endif 456a5f0fb15SPaul Saab 457a5f0fb15SPaul Saab return (begin_new_pos); 458a5f0fb15SPaul Saab } 459a5f0fb15SPaul Saab 460a5f0fb15SPaul Saab /* 461a5f0fb15SPaul Saab * Set attnpos. 462a5f0fb15SPaul Saab */ 463a5f0fb15SPaul Saab public void 464f6b74a7dSXin LI set_attnpos(pos) 465f6b74a7dSXin LI POSITION pos; 466a5f0fb15SPaul Saab { 467a5f0fb15SPaul Saab int c; 468a5f0fb15SPaul Saab 469a5f0fb15SPaul Saab if (pos != NULL_POSITION) 470a5f0fb15SPaul Saab { 471a5f0fb15SPaul Saab if (ch_seek(pos)) 472a5f0fb15SPaul Saab return; 473a5f0fb15SPaul Saab for (;;) 474a5f0fb15SPaul Saab { 475a5f0fb15SPaul Saab c = ch_forw_get(); 476a5f0fb15SPaul Saab if (c == EOI) 477a5f0fb15SPaul Saab break; 478a15691bfSXin LI if (c == '\n' || c == '\r') 479a15691bfSXin LI { 480a15691bfSXin LI (void) ch_back_get(); 481a15691bfSXin LI break; 482a15691bfSXin LI } 483a5f0fb15SPaul Saab pos++; 484a5f0fb15SPaul Saab } 485a15691bfSXin LI end_attnpos = pos; 486a15691bfSXin LI for (;;) 487a15691bfSXin LI { 488a15691bfSXin LI c = ch_back_get(); 489a15691bfSXin LI if (c == EOI || c == '\n' || c == '\r') 490a15691bfSXin LI break; 491a15691bfSXin LI pos--; 492a15691bfSXin LI } 493a5f0fb15SPaul Saab } 494a5f0fb15SPaul Saab start_attnpos = pos; 495a5f0fb15SPaul Saab } 496