static void draw_window (size_t topline, Window wp) { size_t i, o; Region r; int highlight = calculate_highlight_region (wp, &r); /* Find the first line to display on the first screen line. */ for (o = buffer_start_of_line (get_window_bp (wp), window_o (wp)), i = get_window_topdelta (wp); i > 0 && o > 0; assert ((o = buffer_prev_line (get_window_bp (wp), o)) != SIZE_MAX), --i) ; /* Draw the window lines. */ size_t cur_tab_width = tab_width (get_window_bp (wp)); for (i = topline; i < get_window_eheight (wp) + topline; ++i) { /* Clear the line. */ term_move (i, 0); term_clrtoeol (); /* If at the end of the buffer, don't write any text. */ if (o == SIZE_MAX) continue; draw_line (i, get_window_start_column (wp), wp, o, r, highlight, cur_tab_width); if (get_window_start_column (wp) > 0) { term_move (i, 0); term_addstr("$"); } o = buffer_next_line (get_window_bp (wp), o); } set_window_all_displayed (wp, o >= get_buffer_size (get_window_bp (wp))); /* Draw the status line only if there is available space after the buffer text space. */ if (get_window_fheight (wp) - get_window_eheight (wp) > 0) draw_status_line (topline + get_window_eheight (wp), wp); }
int Reader::buffer_next() { assert(states.size() == 1); assert(buff_written == 0); if (input->eof()) return 0; int seq_start = 0; while (true) { int start_offset = buff_written; if (buffer_next_line() < 0) { return -1; } // buff could change due to reallocation so we need to calculate it // after reading a line. const int line_start = start_offset; const char* line = buff + start_offset; assert(states.size() > 0); auto state = states.top(); //std::cerr << state << " " << line << std::endl; switch (state) { case OUT: if (strncmp(line, "{RED", 4) == 0) { states.push(IN); next_type_ = READ; } else if (strncmp(line, "{OVL", 4) == 0) { states.push(IN); next_type_ = OVERLAP; } else if (strncmp(line, "{UNV", 4) == 0) { states.push(IN); next_type_ = UNIVERSAL; } else if (strncmp(line, "{LIB", 4) == 0) { states.push(IN); next_type_ = LIBRARY; } else if (strncmp(line, "{FRG", 4) == 0) { states.push(IN); next_type_ = FRAGMENT; } else { std::cerr << line_num << ":" << line << std::endl; assert(false); } buff_marks.push_back(BufferMark(ObjectDef, line_start, buff_written)); break; case IN: if (line[0] == '}') { buff_marks.push_back(BufferMark(ObjectEnd, line_start, buff_written)); states.pop(); } else if (strncmp(line, "seq:", 4) == 0) { states.push(IN_STR); seq_start = line_start; } else if (strncmp(line, "qlt:", 4) == 0) { states.push(IN_STR); seq_start = line_start; } else if (strncmp(line, "com:", 4) == 0) { states.push(IN_STR); seq_start = line_start; } else if (strncmp(line, "{DST", 4) == 0) { buff_marks.push_back(BufferMark(ObjectDef, line_start, buff_written)); states.push(IN); } else { buff_marks.push_back(BufferMark(AttrDef, line_start, buff_written)); } break; case IN_STR: if (line[0] == '.') { // we do not want to include the '.' at the end buff_marks.push_back(BufferMark(AttrDef, seq_start, buff_written - 1)); states.pop(); } break; default: assert(false); } if (states.size() == 1) { //cerr << "FILL " << buff << endl; return buff_written; } } return -1; }