QString LogData::doGetExpandedLineString( LineNumber line ) const { if ( line >= indexing_data_.getNbLines() ) { return ""; /* exception? */ } if ( keepFileClosed_ ) { reOpenFile(); } QByteArray rawString; { QMutexLocker locker( &fileMutex_ ); attached_file_->seek( ( line.get() == 0 ) ? 0 : indexing_data_.getPosForLine( line - 1_lcount).get() ); rawString = attached_file_->readLine(); if ( keepFileClosed_ ) { attached_file_->close(); } } auto string = untabify( codec_->toUnicode( rawString ) ); string.chop( 1 ); return string; }
std::vector<QString> LogData::doGetExpandedLines( LineNumber first_line, LinesCount number ) const { const auto last_line = first_line + number - 1_lcount; if ( number.get() == 0 ) { return std::vector<QString>(); } if ( last_line >= indexing_data_.getNbLines() ) { LOG(logWARNING) << "LogData::doGetExpandedLines Lines out of bound asked for"; return std::vector<QString>(); /* exception? */ } if ( keepFileClosed_ ) { reOpenFile(); } const auto first_byte = (first_line.get() == 0) ? 0 : indexing_data_.getPosForLine( first_line-1_lcount ).get(); const auto last_byte = indexing_data_.getPosForLine( last_line ).get(); QByteArray buffer; { QMutexLocker locker( &fileMutex_ ); attached_file_->seek( first_byte ); buffer = attached_file_->read( last_byte - first_byte ); if ( keepFileClosed_ ) { attached_file_->close(); } } std::vector<QString> list; list.reserve( number.get() ); qint64 beginning = 0; qint64 end = 0; std::unique_ptr<QTextDecoder> decoder {codec_->makeDecoder()}; EncodingParameters encodingParams{codec_}; for ( auto line = first_line; (line <= last_line); ++line ) { end = indexing_data_.getPosForLine( line ).get() - first_byte; list.emplace_back( untabify( decoder->toUnicode( buffer.data() + beginning, static_cast<LineLength::UnderlyingType>( end - beginning - encodingParams.lineFeedWidth ) ) ) ); beginning = end; } return list; }
void read_result(BUFFER *buf) { FILE *fp; int i, st, fds[2]; pid_t pipe_pid, pid; /* Clear buffer */ memset(buf, 0, sizeof(*buf)); if (pipe(fds) == -1) err(EX_OSERR, "pipe()"); if ((pipe_pid = vfork()) == -1) err(EX_OSERR, "vfork()"); else if (pipe_pid == 0) { close(fds[0]); if (fds[1] != STDOUT_FILENO) { dup2(fds[1], STDOUT_FILENO); close(fds[1]); } if (xflag) execvp(cmdv[0], cmdv); else execl(_PATH_BSHELL, _PATH_BSHELL, "-c", cmdstr, NULL); /* use warn(3) + _exit(2) not to call exit(3) */ warn("exec(%s)", cmdstr); _exit(EX_OSERR); /* NOTREACHED */ } if ((fp = fdopen(fds[0], "r")) == NULL) err(EX_OSERR, "fdopen()"); close(fds[1]); /* Read command output and convert tab to spaces * */ for (i = 0; i < MAXLINE && fgetws((*buf)[i], MAXCOLUMN, fp) != NULL; i++) untabify((*buf)[i], sizeof((*buf)[i])); fclose(fp); do { pid = waitpid(pipe_pid, &st, 0); } while (pid == -1 && errno == EINTR); /* Remember update time */ time(&lastupdate); }
QString LogData::doGetExpandedLineString( qint64 line ) const { if ( line >= indexing_data_.getNbLines() ) { return 0; /* exception? */ } fileMutex_.lock(); attached_file_->seek( (line == 0) ? 0 : indexing_data_.getPosForLine( line-1 ) ); QByteArray rawString = attached_file_->readLine(); fileMutex_.unlock(); QString string = untabify( codec_->toUnicode( rawString ) ); string.chop( 1 ); return string; }
QStringList LogData::doGetExpandedLines( qint64 first_line, int number ) const { QStringList list; const qint64 last_line = first_line + number - 1; if ( number == 0 ) { return QStringList(); } if ( last_line >= nbLines_ ) { LOG(logWARNING) << "LogData::doGetExpandedLines Lines out of bound asked for"; return QStringList(); /* exception? */ } dataMutex_.lock(); fileMutex_.lock(); file_->open( QIODevice::ReadOnly ); const qint64 first_byte = (first_line == 0) ? 0 : linePosition_[first_line-1]; const qint64 last_byte = linePosition_[last_line]; // LOG(logDEBUG) << "LogData::doGetExpandedLines first_byte:" << first_byte << " last_byte:" << last_byte; file_->seek( first_byte ); QByteArray blob = file_->read( last_byte - first_byte ); file_->close(); fileMutex_.unlock(); qint64 beginning = 0; qint64 end = 0; for ( qint64 line = first_line; (line <= last_line); line++ ) { end = linePosition_[line] - first_byte; // LOG(logDEBUG) << "Getting line " << line << " beginning " << beginning << " end " << end; QByteArray this_line = blob.mid( beginning, end - beginning - 1 ); // LOG(logDEBUG) << "Line is: " << QString( this_line ).toStdString(); list.append( untabify( this_line.constData() ) ); beginning = end; } dataMutex_.unlock(); return list; }
QString LogData::doGetExpandedLineString( qint64 line ) const { if ( line >= nbLines_ ) { return QString(); /* exception? */ } dataMutex_.lock(); fileMutex_.lock(); file_->open( QIODevice::ReadOnly ); file_->seek( (line == 0) ? 0 : linePosition_[line-1] ); QByteArray rawString = file_->readLine(); file_->close(); fileMutex_.unlock(); dataMutex_.unlock(); QString string = QString( untabify( rawString.constData() ) ); string.chop( 1 ); return string; }
QStringList LogData::doGetExpandedLines( qint64 first_line, int number ) const { QStringList list; const qint64 last_line = first_line + number - 1; if ( number == 0 ) { return QStringList(); } if ( last_line >= indexing_data_.getNbLines() ) { LOG(logWARNING) << "LogData::doGetExpandedLines Lines out of bound asked for"; return QStringList(); /* exception? */ } fileMutex_.lock(); const qint64 first_byte = (first_line == 0) ? 0 : indexing_data_.getPosForLine( first_line-1 ); const qint64 last_byte = indexing_data_.getPosForLine( last_line ); // LOG(logDEBUG) << "LogData::doGetExpandedLines first_byte:" << first_byte << " last_byte:" << last_byte; attached_file_->seek( first_byte ); QByteArray blob = attached_file_->read( last_byte - first_byte ); fileMutex_.unlock(); qint64 beginning = 0; qint64 end = 0; for ( qint64 line = first_line; (line <= last_line); line++ ) { end = indexing_data_.getPosForLine( line ) - first_byte; // LOG(logDEBUG) << "Getting line " << line << " beginning " << beginning << " end " << end; QByteArray this_line = blob.mid( beginning, end - beginning - 1 ); // LOG(logDEBUG) << "Line is: " << QString( this_line ).toStdString(); list.append( untabify( codec_->toUnicode( this_line ) ) ); beginning = end; } return list; }
/* Populates the sc->lines list with as many lines as possible. */ static void get_more_lines (sws_configuration *sc) { /* wrap anyway, if it's absurdly long. */ int wrap_pix = (wrap_p ? sc->line_pixel_width : 10000); int col = 0; int col_pix = 0; char *s = sc->buf; int target = sc->buf_size - sc->buf_tail - 2; /* Fill as much as we can into sc->buf. */ while (target > 0) { char c = textclient_getc (sc->tc); if (c <= 0) break; sc->buf[sc->buf_tail++] = c; sc->buf[sc->buf_tail] = 0; target--; } while (sc->total_lines < max_lines) { int cw; if (s >= sc->buf + sc->buf_tail) /* Reached end of buffer before end of line. Bail. */ return; cw = char_width (sc, *s); if (*s == '\r' || *s == '\n' || col_pix + cw >= wrap_pix) { int L = s - sc->buf; if (*s == '\r' || *s == '\n') { if (*s == '\r' && s[1] == '\n') /* swallow CRLF too */ *s++ = 0; *s++ = 0; } else { /* We wrapped -- try to back up to the previous word boundary. */ char *s2 = s; int n = 0; while (s2 > sc->buf && *s2 != ' ' && *s2 != '\t') s2--, n++; if (s2 > sc->buf) { s = s2; *s++ = 0; L = s - sc->buf; } } sc->lines[sc->total_lines] = (char *) malloc (L+1); memcpy (sc->lines[sc->total_lines], sc->buf, L); sc->lines[sc->total_lines][L] = 0; if (!textures_p) latin1_to_ascii (sc->lines[sc->total_lines]); { char *t = sc->lines[sc->total_lines]; char *ut = untabify (t); strip (ut, (alignment == 0), 1); /* if centering, strip leading whitespace too */ sc->lines[sc->total_lines] = ut; free (t); } sc->total_lines++; if (sc->buf_tail > (s - sc->buf)) { int i = sc->buf_tail - (s - sc->buf); memmove (sc->buf, s, i); sc->buf_tail = i; sc->buf[sc->buf_tail] = 0; } else { sc->buf_tail = 0; } sc->buf[sc->buf_tail] = 0; s = sc->buf; col = 0; col_pix = 0; } else { col++; col_pix += cw; if (*s == '\t') { int tab_pix = TAB_WIDTH * sc->char_width; col = TAB_WIDTH * ((col / TAB_WIDTH) + 1); col_pix = tab_pix * ((col / tab_pix) + 1); } s++; } } }
/* Returns a single line of text from the output buffer of the subprocess, taking into account wrapping, centering, etc. Returns 0 if no complete line is currently available. */ static char * get_one_line (fliptext_configuration *sc) { char *result = 0; int wrap_pix = sc->font_wrap_pixels; int col = 0; int col_pix = 0; char *s = sc->buf; int target = sc->buf_size - sc->buf_tail - 2; /* Fill as much as we can into sc->buf, but stop at newline. */ while (target > 0) { int c = textclient_getc (sc->tc); if (c <= 0) break; sc->buf[sc->buf_tail++] = (char) c; sc->buf[sc->buf_tail] = 0; target--; if (c == '\r' || c == '\n') break; } while (!result) { int cw; if (s >= sc->buf + sc->buf_tail) /* Reached end of buffer before end of line. Bail. */ return 0; cw = char_width (sc, *s); if (*s == '\r' || *s == '\n' || col_pix + cw >= wrap_pix) { int L = s - sc->buf; if (*s == '\r' || *s == '\n') { if (*s == '\r' && s[1] == '\n') /* swallow CRLF too */ *s++ = 0; *s++ = 0; } else { /* We wrapped -- try to back up to the previous word boundary. */ char *s2 = s; int n = 0; while (s2 > sc->buf && *s2 != ' ' && *s2 != '\t') s2--, n++; if (s2 > sc->buf) { s = s2; *s++ = 0; L = s - sc->buf; } } if (result) abort(); result = (char *) malloc (L+1); memcpy (result, sc->buf, L); result[L] = 0; { char *t = result; char *ut = untabify (t); strip (ut, (sc->alignment == 0), 1); /* if centering, strip leading whitespace too */ result = ut; free (t); } if (sc->buf_tail > (s - sc->buf)) { int i = sc->buf_tail - (s - sc->buf); memmove (sc->buf, s, i); sc->buf_tail = i; sc->buf[sc->buf_tail] = 0; } else { sc->buf_tail = 0; } sc->buf[sc->buf_tail] = 0; s = sc->buf; col = 0; col_pix = 0; } else { col++; col_pix += cw; if (*s == '\t') { int tab_pix = TAB_WIDTH * sc->char_width; col = TAB_WIDTH * ((col / TAB_WIDTH) + 1); col_pix = tab_pix * ((col / tab_pix) + 1); } s++; } } return result; }
int Editor::replace(int ibegin, int iend, WideString cstr, HistoryItem* mod, bool glue) { if (running || settings->mode) return iend; wchar_t const* str = cstr.c_str(); if (ibegin > iend) { int tmp = ibegin; ibegin = iend; iend = tmp; } POINT begin = toPoint(ibegin); POINT end = toPoint(iend); POINT oldEnd = end; if (mod) { mod->begin = ibegin; mod->end = ibegin + getlength(str); mod->text = substring(ibegin, iend); } else { HistoryItem h; h.begin = ibegin; h.end = ibegin + getlength(str); h.text = substring(ibegin, iend); h.glue = glue; bool push = true; if (historyPos < history.length()) history.resize(historyPos); else if (historyPos > 0 && h.text.empty() && h.end == h.begin + 1 && !h.glue) { HistoryItem& p = history[historyPos - 1]; if (p.text.empty() && h.begin == p.end) { push = false; p.end = h.end; } } if (push) { if (history.length() >= 256) { for (int i = 1; i < history.length(); i++) history[i - 1] = history[i]; history[history.length() - 1] = h; if (origHistory >= 0) origHistory--; } else history.push(h); } historyPos = history.length(); if (historyPos < origHistory) origHistory = -1; } if (begin.y == end.y) { Line ln = lines[begin.y]; lines.insert(begin.y + 1, ln); end.y = begin.y + 1; } lines[begin.y].text.resize(begin.x); int curLine = begin.y; int curPos = 0; while (str[curPos]) { if (str[curPos] == '\r' || str[curPos] == '\n') { if (curLine == begin.y) lines[curLine].text.append(str, curPos); else if (curLine < end.y) lines[curLine].text = WideString(str, curPos); else { Line& ln = lines.insert(curLine); ln.text = WideString(str, curPos); end.y++; } untabify(lines[curLine].text); if ((str[curPos + 1] == '\r' || str[curPos + 1] == '\n') && str[curPos] != str[curPos + 1]) curPos++; str = str + curPos + 1; curPos = 0; curLine++; } else curPos++; } if (curLine < end.y) { if (curLine == begin.y) lines[curLine].text += str; else lines[curLine].text = str; untabify(lines[curLine].text); int ex = lines[curLine].text.length(); lines[curLine].text += lines[end.y].text.substring(end.x); if (lines[end.y].breakpoint > 0) lines[curLine].breakpoint = 1; lines.remove(curLine + 1, end.y - curLine); end.y = curLine; end.x = ex; } else { lines[end.y].text.replace(0, end.x, str); end.x = wcslen(str); untabify(lines[end.y].text); } caret = selStart = fromPoint(end); updateCtx(begin.y, end.y); updateExtent(); updateCaret(); getParent()->notify(EN_MODIFIED, (uint32) this, 0); return caret; }