1a5f0fb15SPaul Saab /* 2f6b74a7dSXin LI * Copyright (C) 1984-2017 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; 23a5f0fb15SPaul Saab extern int chopline; 248ed69c6fSPaul Saab extern int hshift; 25a5f0fb15SPaul Saab extern int quit_if_one_screen; 26a5f0fb15SPaul Saab extern int sigs; 27a5f0fb15SPaul Saab extern int ignore_eoi; 286dcb072bSXin LI extern int status_col; 29a5f0fb15SPaul Saab extern POSITION start_attnpos; 30a5f0fb15SPaul Saab extern POSITION end_attnpos; 31a5f0fb15SPaul Saab #if HILITE_SEARCH 32a5f0fb15SPaul Saab extern int hilite_search; 33a5f0fb15SPaul Saab extern int size_linebuf; 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 44f6b74a7dSXin LI forw_line(curr_pos) 45f6b74a7dSXin LI POSITION curr_pos; 46a5f0fb15SPaul Saab { 476dcb072bSXin LI POSITION base_pos; 48a5f0fb15SPaul Saab POSITION new_pos; 491ea31627SRobert Watson int c; 50a5f0fb15SPaul Saab int blankline; 51a5f0fb15SPaul Saab int endline; 52*b2ea2440SXin LI int chopped; 536dcb072bSXin LI int backchars; 54a5f0fb15SPaul Saab 557374caaaSXin LI get_forw_line: 56a5f0fb15SPaul Saab if (curr_pos == NULL_POSITION) 57a5f0fb15SPaul Saab { 58a5f0fb15SPaul Saab null_line(); 59a5f0fb15SPaul Saab return (NULL_POSITION); 60a5f0fb15SPaul Saab } 61a5f0fb15SPaul Saab #if HILITE_SEARCH 627374caaaSXin LI if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) 63a15691bfSXin LI { 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); 73a15691bfSXin LI curr_pos = next_unfiltered(curr_pos); 74a15691bfSXin LI } 75a5f0fb15SPaul Saab #endif 76a5f0fb15SPaul Saab if (ch_seek(curr_pos)) 77a5f0fb15SPaul Saab { 78a5f0fb15SPaul Saab null_line(); 79a5f0fb15SPaul Saab return (NULL_POSITION); 80a5f0fb15SPaul Saab } 81a5f0fb15SPaul Saab 827374caaaSXin LI /* 837374caaaSXin LI * Step back to the beginning of the line. 847374caaaSXin LI */ 856dcb072bSXin LI base_pos = curr_pos; 866dcb072bSXin LI for (;;) 876dcb072bSXin LI { 886dcb072bSXin LI if (ABORT_SIGS()) 896dcb072bSXin LI { 906dcb072bSXin LI null_line(); 916dcb072bSXin LI return (NULL_POSITION); 926dcb072bSXin LI } 936dcb072bSXin LI c = ch_back_get(); 946dcb072bSXin LI if (c == EOI) 956dcb072bSXin LI break; 966dcb072bSXin LI if (c == '\n') 976dcb072bSXin LI { 986dcb072bSXin LI (void) ch_forw_get(); 996dcb072bSXin LI break; 1006dcb072bSXin LI } 1016dcb072bSXin LI --base_pos; 1026dcb072bSXin LI } 1036dcb072bSXin LI 1047374caaaSXin LI /* 1057374caaaSXin LI * Read forward again to the position we should start at. 1067374caaaSXin LI */ 107a5f0fb15SPaul Saab prewind(); 1086dcb072bSXin LI plinenum(base_pos); 1096dcb072bSXin LI (void) ch_seek(base_pos); 1107374caaaSXin LI new_pos = base_pos; 1117374caaaSXin LI while (new_pos < curr_pos) 1126dcb072bSXin LI { 1136dcb072bSXin LI if (ABORT_SIGS()) 1146dcb072bSXin LI { 1156dcb072bSXin LI null_line(); 1166dcb072bSXin LI return (NULL_POSITION); 1176dcb072bSXin LI } 1186dcb072bSXin LI c = ch_forw_get(); 1197374caaaSXin LI backchars = pappend(c, new_pos); 1207374caaaSXin LI new_pos++; 1216dcb072bSXin LI if (backchars > 0) 1226dcb072bSXin LI { 1236dcb072bSXin LI pshift_all(); 1247374caaaSXin LI new_pos -= backchars; 1256dcb072bSXin LI while (--backchars >= 0) 1266dcb072bSXin LI (void) ch_back_get(); 1276dcb072bSXin LI } 1286dcb072bSXin LI } 1296dcb072bSXin LI (void) pflushmbc(); 1306dcb072bSXin LI pshift_all(); 131a5f0fb15SPaul Saab 1327374caaaSXin LI /* 1337374caaaSXin LI * Read the first character to display. 1347374caaaSXin LI */ 135a5f0fb15SPaul Saab c = ch_forw_get(); 136a5f0fb15SPaul Saab if (c == EOI) 137a5f0fb15SPaul Saab { 138a5f0fb15SPaul Saab null_line(); 139a5f0fb15SPaul Saab return (NULL_POSITION); 140a5f0fb15SPaul Saab } 141a5f0fb15SPaul Saab blankline = (c == '\n' || c == '\r'); 142a5f0fb15SPaul Saab 1437374caaaSXin LI /* 1447374caaaSXin LI * Read each character in the line and append to the line buffer. 1457374caaaSXin LI */ 146*b2ea2440SXin LI chopped = FALSE; 147a5f0fb15SPaul Saab for (;;) 148a5f0fb15SPaul Saab { 149a5f0fb15SPaul Saab if (ABORT_SIGS()) 150a5f0fb15SPaul Saab { 151a5f0fb15SPaul Saab null_line(); 152a5f0fb15SPaul Saab return (NULL_POSITION); 153a5f0fb15SPaul Saab } 154a5f0fb15SPaul Saab if (c == '\n' || c == EOI) 155a5f0fb15SPaul Saab { 156a5f0fb15SPaul Saab /* 157a5f0fb15SPaul Saab * End of the line. 158a5f0fb15SPaul Saab */ 1596dcb072bSXin LI backchars = pflushmbc(); 160a5f0fb15SPaul Saab new_pos = ch_tell(); 1616dcb072bSXin LI if (backchars > 0 && !chopline && hshift == 0) 1626dcb072bSXin LI { 1636dcb072bSXin LI new_pos -= backchars + 1; 1646dcb072bSXin LI endline = FALSE; 1656dcb072bSXin LI } else 166a5f0fb15SPaul Saab endline = TRUE; 167a5f0fb15SPaul Saab break; 168a5f0fb15SPaul Saab } 1696dcb072bSXin LI if (c != '\r') 1706dcb072bSXin LI blankline = 0; 171a5f0fb15SPaul Saab 172a5f0fb15SPaul Saab /* 173a5f0fb15SPaul Saab * Append the char to the line and get the next char. 174a5f0fb15SPaul Saab */ 1756dcb072bSXin LI backchars = pappend(c, ch_tell()-1); 1766dcb072bSXin LI if (backchars > 0) 177a5f0fb15SPaul Saab { 178a5f0fb15SPaul Saab /* 179a5f0fb15SPaul Saab * The char won't fit in the line; the line 180a5f0fb15SPaul Saab * is too long to print in the screen width. 181a5f0fb15SPaul Saab * End the line here. 182a5f0fb15SPaul Saab */ 1838ed69c6fSPaul Saab if (chopline || hshift > 0) 184a5f0fb15SPaul Saab { 185a5f0fb15SPaul Saab do 186a5f0fb15SPaul Saab { 18733096f16SXin LI if (ABORT_SIGS()) 18833096f16SXin LI { 18933096f16SXin LI null_line(); 19033096f16SXin LI return (NULL_POSITION); 19133096f16SXin LI } 192a5f0fb15SPaul Saab c = ch_forw_get(); 193a5f0fb15SPaul Saab } while (c != '\n' && c != EOI); 194a5f0fb15SPaul Saab new_pos = ch_tell(); 195a5f0fb15SPaul Saab endline = TRUE; 196a5f0fb15SPaul Saab quit_if_one_screen = FALSE; 197*b2ea2440SXin LI chopped = TRUE; 198a5f0fb15SPaul Saab } else 199a5f0fb15SPaul Saab { 2006dcb072bSXin LI new_pos = ch_tell() - backchars; 201a5f0fb15SPaul Saab endline = FALSE; 202a5f0fb15SPaul Saab } 203a5f0fb15SPaul Saab break; 204a5f0fb15SPaul Saab } 205a5f0fb15SPaul Saab c = ch_forw_get(); 206a5f0fb15SPaul Saab } 2077374caaaSXin LI 208*b2ea2440SXin LI pdone(endline, chopped, 1); 2097374caaaSXin LI 2107374caaaSXin LI #if HILITE_SEARCH 2117374caaaSXin LI if (is_filtered(base_pos)) 2127374caaaSXin LI { 2137374caaaSXin LI /* 2147374caaaSXin LI * We don't want to display this line. 2157374caaaSXin LI * Get the next line. 2167374caaaSXin LI */ 2177374caaaSXin LI curr_pos = new_pos; 2187374caaaSXin LI goto get_forw_line; 2197374caaaSXin LI } 2207374caaaSXin LI 2217374caaaSXin LI if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL)) 2227374caaaSXin LI set_status_col('*'); 2237374caaaSXin LI #endif 224a5f0fb15SPaul Saab 225a5f0fb15SPaul Saab if (squeeze && blankline) 226a5f0fb15SPaul Saab { 227a5f0fb15SPaul Saab /* 228a5f0fb15SPaul Saab * This line is blank. 229a5f0fb15SPaul Saab * Skip down to the last contiguous blank line 230a5f0fb15SPaul Saab * and pretend it is the one which we are returning. 231a5f0fb15SPaul Saab */ 232a5f0fb15SPaul Saab while ((c = ch_forw_get()) == '\n' || c == '\r') 233a5f0fb15SPaul Saab if (ABORT_SIGS()) 234a5f0fb15SPaul Saab { 235a5f0fb15SPaul Saab null_line(); 236a5f0fb15SPaul Saab return (NULL_POSITION); 237a5f0fb15SPaul Saab } 238a5f0fb15SPaul Saab if (c != EOI) 239a5f0fb15SPaul Saab (void) ch_back_get(); 240a5f0fb15SPaul Saab new_pos = ch_tell(); 241a5f0fb15SPaul Saab } 242a5f0fb15SPaul Saab 243a5f0fb15SPaul Saab return (new_pos); 244a5f0fb15SPaul Saab } 245a5f0fb15SPaul Saab 246a5f0fb15SPaul Saab /* 247a5f0fb15SPaul Saab * Get the previous line. 248a5f0fb15SPaul Saab * A "current" position is passed and a "new" position is returned. 249a5f0fb15SPaul Saab * The current position is the position of the first character of 250a5f0fb15SPaul Saab * a line. The new position is the position of the first character 251a5f0fb15SPaul Saab * of the PREVIOUS line. The line obtained is the one starting at new_pos. 252a5f0fb15SPaul Saab */ 253a5f0fb15SPaul Saab public POSITION 254f6b74a7dSXin LI back_line(curr_pos) 255f6b74a7dSXin LI POSITION curr_pos; 256a5f0fb15SPaul Saab { 2577374caaaSXin LI POSITION new_pos, begin_new_pos, base_pos; 258a5f0fb15SPaul Saab int c; 259a5f0fb15SPaul Saab int endline; 260*b2ea2440SXin LI int chopped; 2616dcb072bSXin LI int backchars; 262a5f0fb15SPaul Saab 2637374caaaSXin LI get_back_line: 264a5f0fb15SPaul Saab if (curr_pos == NULL_POSITION || curr_pos <= ch_zero()) 265a5f0fb15SPaul Saab { 266a5f0fb15SPaul Saab null_line(); 267a5f0fb15SPaul Saab return (NULL_POSITION); 268a5f0fb15SPaul Saab } 269a5f0fb15SPaul Saab #if HILITE_SEARCH 2707374caaaSXin LI if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) 271a5f0fb15SPaul Saab prep_hilite((curr_pos < 3*size_linebuf) ? 272a5f0fb15SPaul Saab 0 : curr_pos - 3*size_linebuf, curr_pos, -1); 273a5f0fb15SPaul Saab #endif 274a5f0fb15SPaul Saab if (ch_seek(curr_pos-1)) 275a5f0fb15SPaul Saab { 276a5f0fb15SPaul Saab null_line(); 277a5f0fb15SPaul Saab return (NULL_POSITION); 278a5f0fb15SPaul Saab } 279a5f0fb15SPaul Saab 280a5f0fb15SPaul Saab if (squeeze) 281a5f0fb15SPaul Saab { 282a5f0fb15SPaul Saab /* 283a5f0fb15SPaul Saab * Find out if the "current" line was blank. 284a5f0fb15SPaul Saab */ 285a5f0fb15SPaul Saab (void) ch_forw_get(); /* Skip the newline */ 286a5f0fb15SPaul Saab c = ch_forw_get(); /* First char of "current" line */ 287a5f0fb15SPaul Saab (void) ch_back_get(); /* Restore our position */ 288a5f0fb15SPaul Saab (void) ch_back_get(); 289a5f0fb15SPaul Saab 290a5f0fb15SPaul Saab if (c == '\n' || c == '\r') 291a5f0fb15SPaul Saab { 292a5f0fb15SPaul Saab /* 293a5f0fb15SPaul Saab * The "current" line was blank. 294a5f0fb15SPaul Saab * Skip over any preceding blank lines, 295a5f0fb15SPaul Saab * since we skipped them in forw_line(). 296a5f0fb15SPaul Saab */ 297a5f0fb15SPaul Saab while ((c = ch_back_get()) == '\n' || c == '\r') 298a5f0fb15SPaul Saab if (ABORT_SIGS()) 299a5f0fb15SPaul Saab { 300a5f0fb15SPaul Saab null_line(); 301a5f0fb15SPaul Saab return (NULL_POSITION); 302a5f0fb15SPaul Saab } 303a5f0fb15SPaul Saab if (c == EOI) 304a5f0fb15SPaul Saab { 305a5f0fb15SPaul Saab null_line(); 306a5f0fb15SPaul Saab return (NULL_POSITION); 307a5f0fb15SPaul Saab } 308a5f0fb15SPaul Saab (void) ch_forw_get(); 309a5f0fb15SPaul Saab } 310a5f0fb15SPaul Saab } 311a5f0fb15SPaul Saab 312a5f0fb15SPaul Saab /* 313a5f0fb15SPaul Saab * Scan backwards until we hit the beginning of the line. 314a5f0fb15SPaul Saab */ 315a5f0fb15SPaul Saab for (;;) 316a5f0fb15SPaul Saab { 317a5f0fb15SPaul Saab if (ABORT_SIGS()) 318a5f0fb15SPaul Saab { 319a5f0fb15SPaul Saab null_line(); 320a5f0fb15SPaul Saab return (NULL_POSITION); 321a5f0fb15SPaul Saab } 322a5f0fb15SPaul Saab c = ch_back_get(); 323a5f0fb15SPaul Saab if (c == '\n') 324a5f0fb15SPaul Saab { 325a5f0fb15SPaul Saab /* 326a5f0fb15SPaul Saab * This is the newline ending the previous line. 327a5f0fb15SPaul Saab * We have hit the beginning of the line. 328a5f0fb15SPaul Saab */ 3297374caaaSXin LI base_pos = ch_tell() + 1; 330a5f0fb15SPaul Saab break; 331a5f0fb15SPaul Saab } 332a5f0fb15SPaul Saab if (c == EOI) 333a5f0fb15SPaul Saab { 334a5f0fb15SPaul Saab /* 335a5f0fb15SPaul Saab * We have hit the beginning of the file. 336a5f0fb15SPaul Saab * This must be the first line in the file. 337a5f0fb15SPaul Saab * This must, of course, be the beginning of the line. 338a5f0fb15SPaul Saab */ 3397374caaaSXin LI base_pos = ch_tell(); 340a5f0fb15SPaul Saab break; 341a5f0fb15SPaul Saab } 342a5f0fb15SPaul Saab } 343a5f0fb15SPaul Saab 344a5f0fb15SPaul Saab /* 345a5f0fb15SPaul Saab * Now scan forwards from the beginning of this line. 346a5f0fb15SPaul Saab * We keep discarding "printable lines" (based on screen width) 347a5f0fb15SPaul Saab * until we reach the curr_pos. 348a5f0fb15SPaul Saab * 349a5f0fb15SPaul Saab * {{ This algorithm is pretty inefficient if the lines 350a5f0fb15SPaul Saab * are much longer than the screen width, 351a5f0fb15SPaul Saab * but I don't know of any better way. }} 352a5f0fb15SPaul Saab */ 3537374caaaSXin LI new_pos = base_pos; 354a5f0fb15SPaul Saab if (ch_seek(new_pos)) 355a5f0fb15SPaul Saab { 356a5f0fb15SPaul Saab null_line(); 357a5f0fb15SPaul Saab return (NULL_POSITION); 358a5f0fb15SPaul Saab } 359a5f0fb15SPaul Saab endline = FALSE; 360a5f0fb15SPaul Saab prewind(); 361a5f0fb15SPaul Saab plinenum(new_pos); 3626dcb072bSXin LI loop: 3636dcb072bSXin LI begin_new_pos = new_pos; 364a5f0fb15SPaul Saab (void) ch_seek(new_pos); 365*b2ea2440SXin LI chopped = FALSE; 366a5f0fb15SPaul Saab 367a5f0fb15SPaul Saab do 368a5f0fb15SPaul Saab { 369a5f0fb15SPaul Saab c = ch_forw_get(); 370a5f0fb15SPaul Saab if (c == EOI || ABORT_SIGS()) 371a5f0fb15SPaul Saab { 372a5f0fb15SPaul Saab null_line(); 373a5f0fb15SPaul Saab return (NULL_POSITION); 374a5f0fb15SPaul Saab } 375a5f0fb15SPaul Saab new_pos++; 376a5f0fb15SPaul Saab if (c == '\n') 377a5f0fb15SPaul Saab { 3786dcb072bSXin LI backchars = pflushmbc(); 3796dcb072bSXin LI if (backchars > 0 && !chopline && hshift == 0) 3806dcb072bSXin LI { 3816dcb072bSXin LI backchars++; 3826dcb072bSXin LI goto shift; 3836dcb072bSXin LI } 384a5f0fb15SPaul Saab endline = TRUE; 385a5f0fb15SPaul Saab break; 386a5f0fb15SPaul Saab } 3876dcb072bSXin LI backchars = pappend(c, ch_tell()-1); 3886dcb072bSXin LI if (backchars > 0) 389a5f0fb15SPaul Saab { 390a5f0fb15SPaul Saab /* 391a5f0fb15SPaul Saab * Got a full printable line, but we haven't 392a5f0fb15SPaul Saab * reached our curr_pos yet. Discard the line 393a5f0fb15SPaul Saab * and start a new one. 394a5f0fb15SPaul Saab */ 3958ed69c6fSPaul Saab if (chopline || hshift > 0) 396a5f0fb15SPaul Saab { 397a5f0fb15SPaul Saab endline = TRUE; 398*b2ea2440SXin LI chopped = TRUE; 399a5f0fb15SPaul Saab quit_if_one_screen = FALSE; 400a5f0fb15SPaul Saab break; 401a5f0fb15SPaul Saab } 4026dcb072bSXin LI shift: 4036dcb072bSXin LI pshift_all(); 4046dcb072bSXin LI while (backchars-- > 0) 4056dcb072bSXin LI { 406a5f0fb15SPaul Saab (void) ch_back_get(); 407a5f0fb15SPaul Saab new_pos--; 4086dcb072bSXin LI } 409a5f0fb15SPaul Saab goto loop; 410a5f0fb15SPaul Saab } 411a5f0fb15SPaul Saab } while (new_pos < curr_pos); 412a5f0fb15SPaul Saab 413*b2ea2440SXin LI pdone(endline, chopped, 0); 4147374caaaSXin LI 4157374caaaSXin LI #if HILITE_SEARCH 4167374caaaSXin LI if (is_filtered(base_pos)) 4177374caaaSXin LI { 4187374caaaSXin LI /* 4197374caaaSXin LI * We don't want to display this line. 4207374caaaSXin LI * Get the previous line. 4217374caaaSXin LI */ 4227374caaaSXin LI curr_pos = begin_new_pos; 4237374caaaSXin LI goto get_back_line; 4247374caaaSXin LI } 4257374caaaSXin LI 42696e55cc7SXin LI if (status_col && curr_pos > 0 && is_hilited(base_pos, curr_pos-1, 1, NULL)) 4277374caaaSXin LI set_status_col('*'); 4287374caaaSXin LI #endif 429a5f0fb15SPaul Saab 430a5f0fb15SPaul Saab return (begin_new_pos); 431a5f0fb15SPaul Saab } 432a5f0fb15SPaul Saab 433a5f0fb15SPaul Saab /* 434a5f0fb15SPaul Saab * Set attnpos. 435a5f0fb15SPaul Saab */ 436a5f0fb15SPaul Saab public void 437f6b74a7dSXin LI set_attnpos(pos) 438f6b74a7dSXin LI POSITION pos; 439a5f0fb15SPaul Saab { 440a5f0fb15SPaul Saab int c; 441a5f0fb15SPaul Saab 442a5f0fb15SPaul Saab if (pos != NULL_POSITION) 443a5f0fb15SPaul Saab { 444a5f0fb15SPaul Saab if (ch_seek(pos)) 445a5f0fb15SPaul Saab return; 446a5f0fb15SPaul Saab for (;;) 447a5f0fb15SPaul Saab { 448a5f0fb15SPaul Saab c = ch_forw_get(); 449a5f0fb15SPaul Saab if (c == EOI) 450a5f0fb15SPaul Saab break; 451a15691bfSXin LI if (c == '\n' || c == '\r') 452a15691bfSXin LI { 453a15691bfSXin LI (void) ch_back_get(); 454a15691bfSXin LI break; 455a15691bfSXin LI } 456a5f0fb15SPaul Saab pos++; 457a5f0fb15SPaul Saab } 458a15691bfSXin LI end_attnpos = pos; 459a15691bfSXin LI for (;;) 460a15691bfSXin LI { 461a15691bfSXin LI c = ch_back_get(); 462a15691bfSXin LI if (c == EOI || c == '\n' || c == '\r') 463a15691bfSXin LI break; 464a15691bfSXin LI pos--; 465a15691bfSXin LI } 466a5f0fb15SPaul Saab } 467a5f0fb15SPaul Saab start_attnpos = pos; 468a5f0fb15SPaul Saab } 469