mirror of
https://github.com/vbatts/bvi.git
synced 2024-11-22 08:35:42 +00:00
40e8e886bc
3035255ca79e0464567d255baa5544f7794e2b7eb791dcc60cc339cf1aa01e28 bvi-1.4.1.src.tar.gz https://bvi.sourceforge.net/download.html
1038 lines
20 KiB
C
1038 lines
20 KiB
C
/* edit - the edit commands
|
|
*
|
|
* NOTE: Edit this file with tabstop=4 !
|
|
*
|
|
* 1999-04-19 V 1.1.2
|
|
* 1999-07-02 V 1.2.0 beta
|
|
* 1999-10-30 V 1.2.0 final
|
|
* 2000-05-14 V 1.3.0 alpha
|
|
* 2000-07-15 V 1.3.0 final
|
|
* 2001-12-07 V 1.3.1
|
|
* 2003-07-04 V 1.3.2
|
|
* 2006-04-05 V 1.3.3 alpha - binary representation
|
|
* 2014-09-30 V 1.4.0
|
|
* 2019-10-12 V 1.4.1
|
|
*
|
|
* Copyright 1996-2019 by Gerhard Buergmann
|
|
* gerhard@puon.at
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 3, or (at your option) any
|
|
* later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* See file COPYING for information on distribution conditions.
|
|
*/
|
|
|
|
#include "bvi.h"
|
|
#include "set.h"
|
|
|
|
extern long precount;
|
|
|
|
char contrd[][4] = {"NUL", " ^A", " ^B", " ^C", " ^D", " ^E", " ^F", "BEL",
|
|
" BS", "TAB", " NL", "HOM", "CLR", " CR", " ^N", " ^O",
|
|
" ^P", " ^Q", " ^R", " ^S", " ^T", " ^U", " ^V", " ^W",
|
|
" ^X", " ^Y", " ^Z", "ESC", " FS", " GS", " RS", " US",
|
|
"DEL" };
|
|
char contru[][4] = {"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
|
|
" BS", " HT", " NL", " VT", " NP", " CR", " SO", " SI",
|
|
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
|
|
"CAN", " EM", "SUB", "ESC", " FS", " GS", " RS", " US",
|
|
"DEL" };
|
|
char tmpbuf[10];
|
|
char linbuf[16384];
|
|
long hl_spat = 0;
|
|
|
|
static char getcbuff[BUFFER];
|
|
static char *getcnext = NULL;
|
|
|
|
|
|
/* mode: ('A') append
|
|
* ('R') replace one or more different characters
|
|
* ('r') replace 1 character
|
|
* ('i') insert characters
|
|
* ('a') insert after cursor
|
|
* a precount can be used
|
|
*
|
|
* for insert and append we misuse the undo buffer for the inserted
|
|
* characters (for "." command)
|
|
*/
|
|
off_t
|
|
edit(mode)
|
|
int mode;
|
|
{
|
|
int ch, ch1;
|
|
size_t len;
|
|
off_t count = 0L;
|
|
off_t buffer = BUFFER;
|
|
off_t psize;
|
|
|
|
if (!filesize && mode == 'i') {
|
|
mode = 'A';
|
|
}
|
|
if (mode != 'A' && mode != 'a') {
|
|
if (current - mem >= filesize) {
|
|
beep();
|
|
return 0L;
|
|
}
|
|
}
|
|
if (precount < 1) precount = 1;
|
|
len = strlen(rep_buf);
|
|
if (mode == 'r' && current + precount > maxpos) {
|
|
beep();
|
|
rep_buf[len] = '\0';
|
|
return 0L;
|
|
}
|
|
if (alloc_buf(buffer, &undo_buf) == 0L) {
|
|
rep_buf[len] = '\0';
|
|
return 0L;
|
|
}
|
|
switch(mode) {
|
|
case 'A': edits = U_APPEND;
|
|
break;
|
|
case 'R': edits = U_EDIT;
|
|
smsg("REPLACE MODE");
|
|
break;
|
|
case 'r': edits = U_EDIT;
|
|
smsg("REPLACE 1 CHAR");
|
|
break;
|
|
case 'a':
|
|
case 'i': edits = U_INSERT;
|
|
smsg("INSERT MODE");
|
|
break;
|
|
}
|
|
|
|
undo_start = current;
|
|
|
|
while((ch = vgetc()) != ESC) {
|
|
ch &= 0xff;
|
|
rep_buf[len++] = ch;
|
|
if (ch == '\t') {
|
|
toggle();
|
|
setcur();
|
|
continue;
|
|
}
|
|
if (ch == KEY_BACKSPACE
|
|
|| ch == ASCII_DEL
|
|
|| ch == BVICTRL('H')) {
|
|
if (count > 0) {
|
|
len--;
|
|
count--;
|
|
if (mode == 'A' || mode == 'a' || mode == 'i') {
|
|
filesize--;
|
|
maxpos--;
|
|
}
|
|
current--;
|
|
cur_back();
|
|
setcur();
|
|
} else beep();
|
|
continue;
|
|
}
|
|
if (loc == HEX) {
|
|
if (isxdigit(ch)) {
|
|
mvaddch(y, x + 1, ' ');
|
|
mvaddch(y, x, ch);
|
|
do {
|
|
ch1 = vgetc() & 0xff;
|
|
if (ch1 == ESC) {
|
|
mvaddch(y, x, ' ');
|
|
current--;
|
|
cur_back();
|
|
goto escape;
|
|
}
|
|
if (!isxdigit(ch1)) {
|
|
beep();
|
|
ch1 = -1;
|
|
}
|
|
} while (ch1 == -1);
|
|
rep_buf[len++] = ch1;
|
|
mvaddch(y, x + 1, ch1);
|
|
sprintf(tmpbuf, "%c%c", ch, ch1);
|
|
sscanf(tmpbuf, "%2x", &ch);
|
|
} else {
|
|
beep();
|
|
len--;
|
|
goto wrong;
|
|
}
|
|
} else { /*** ASCII - Bereich ***/
|
|
if (isprint(ch)) {
|
|
mvaddch(y, x, ch);
|
|
} else {
|
|
beep();
|
|
goto wrong;
|
|
}
|
|
}
|
|
curpos = current++;
|
|
if (mode == 'i' || mode == 'a') {
|
|
memmove(current, curpos, maxpos - curpos);
|
|
}
|
|
if (mode == 'A' || mode == 'i' || mode == 'a') {
|
|
maxpos++;
|
|
filesize++;
|
|
/* NEU
|
|
undo_buf[count++] = ch;
|
|
*/
|
|
count++;
|
|
} else {
|
|
undo_buf[count++] = *curpos;
|
|
}
|
|
if (count == buffer) {
|
|
buffer += BUFFER;
|
|
if (alloc_buf(buffer, &undo_buf) == 0L) {
|
|
rep_buf[len] = '\0';
|
|
return count;
|
|
}
|
|
}
|
|
|
|
*curpos = (char)ch;
|
|
cur_forw(0);
|
|
statpos();
|
|
if (mode == 'i' || mode == 'a') {
|
|
repaint();
|
|
} else {
|
|
lineout();
|
|
}
|
|
setcur();
|
|
|
|
if (filesize > memsize - 2L) {
|
|
if (enlarge(100L)) break;
|
|
}
|
|
|
|
if ((mode != 'A' && mode != 'a') && curpos == maxpos - 1) break;
|
|
if (mode == 'r') { break; }
|
|
wrong:
|
|
continue;
|
|
}
|
|
rep_buf[len++] = ESC;
|
|
rep_buf[len] = '\0';
|
|
if (!count) goto escape;
|
|
|
|
if (precount > 1) {
|
|
switch (mode) {
|
|
case 'i':
|
|
case 'a':
|
|
case 'A':
|
|
psize = count * (precount - 1);
|
|
if (filesize + psize > memsize - 2L) {
|
|
if (enlarge(psize + 100L)) return count;
|
|
}
|
|
if (psize + count > buffer) {
|
|
if (alloc_buf(psize + count, &undo_buf) == 0L)
|
|
return count;
|
|
}
|
|
|
|
if (mode == 'i' || mode == 'a') {
|
|
memmove(current + psize, current, maxpos - curpos);
|
|
}
|
|
|
|
/* NEU
|
|
undo_pos = undo_buf + count - 1L;
|
|
*/
|
|
while (--precount) {
|
|
/* NEU
|
|
memcpy(undo_pos + 1L, undo_pos - count + 1L, count);
|
|
undo_pos += count;
|
|
*/
|
|
memcpy(curpos + 1L, curpos - count + 1L, count);
|
|
curpos += count;
|
|
}
|
|
filesize += psize;
|
|
count += psize;
|
|
maxpos += psize;
|
|
undo_count += psize;
|
|
current = curpos + 1L;
|
|
setpage(current);
|
|
repaint();
|
|
break;
|
|
case 'R':
|
|
if (current + count * (precount - 1) > maxpos) break;
|
|
psize = count;
|
|
while (--precount) {
|
|
memcpy(undo_buf + psize, curpos + 1L, count);
|
|
psize += count;
|
|
memcpy(curpos + 1L, curpos - count + 1L, count);
|
|
curpos += count;
|
|
}
|
|
count = psize;
|
|
setpage(++curpos);
|
|
repaint();
|
|
break;
|
|
case 'r':
|
|
while (--precount) {
|
|
undo_buf[count++] = *(++curpos);
|
|
*curpos = (char)ch;
|
|
cur_forw(0);
|
|
statpos();
|
|
lineout();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
cur_back();
|
|
escape:
|
|
setcur();
|
|
smsg("");
|
|
return(count);
|
|
}
|
|
|
|
|
|
/* Do the f, F, t or T command
|
|
* If flag == 1 save the character in rep_buf
|
|
* else setpage()
|
|
*/
|
|
PTR
|
|
do_ft(ch, flag)
|
|
int ch, flag;
|
|
{
|
|
static int chi;
|
|
static int chp = 1;
|
|
int dir;
|
|
size_t n;
|
|
PTR ptr;
|
|
|
|
switch (ch) {
|
|
/*
|
|
case 1: beep();
|
|
return NULL; no previous command
|
|
case -1: if (chp == 'f' || chp == 't') dir = BACKWARD;
|
|
else dir = FORWARD;
|
|
break;
|
|
case 0: if (chp == 'f' || chp == 't') dir = FORWARD;
|
|
else dir = BACKWARD;
|
|
break;
|
|
*/
|
|
case -1: if (chp == 1) {
|
|
beep();
|
|
return NULL;
|
|
}
|
|
if (chp == 'f' || chp == 't') dir = BACKWARD;
|
|
else dir = FORWARD;
|
|
break;
|
|
case 0: if (chp == 1) {
|
|
beep();
|
|
return NULL;
|
|
}
|
|
if (chp == 'f' || chp == 't') dir = FORWARD;
|
|
else dir = BACKWARD;
|
|
break;
|
|
default: chp = ch;
|
|
if (chp == 'f' || chp == 't') dir = FORWARD;
|
|
else dir = BACKWARD;
|
|
chi = vgetc();
|
|
if (flag) {
|
|
n = strlen(rep_buf);
|
|
rep_buf[n++] = chi;
|
|
rep_buf[n] = '\0';
|
|
}
|
|
}
|
|
ptr = current;
|
|
do {
|
|
if (dir == FORWARD) {
|
|
do {
|
|
ptr++;
|
|
if (ptr > maxpos) break;
|
|
} while (*ptr != chi);
|
|
if (ptr > maxpos) break;
|
|
} else {
|
|
do {
|
|
ptr--;
|
|
if (ptr < mem) break;
|
|
} while (*ptr != chi);
|
|
if (ptr < mem) break;
|
|
}
|
|
} while (--precount > 0);
|
|
/*
|
|
if (*ptr == chi) {
|
|
*/
|
|
if (ptr >= mem && ptr <= maxpos) {
|
|
if (loc == HEX) toggle();
|
|
if (chp == 't') ptr--;
|
|
if (chp == 'T') ptr++;
|
|
if (!flag) {
|
|
setpage(ptr);
|
|
}
|
|
return(ptr);
|
|
}
|
|
beep();
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void
|
|
do_z(mode)
|
|
int mode;
|
|
{
|
|
switch (mode) {
|
|
case '.': while (y != maxy / 2) {
|
|
if (y > maxy / 2) {
|
|
pagepos += Anzahl;
|
|
y--;
|
|
} else {
|
|
if (pagepos == mem) break;
|
|
pagepos -= Anzahl;
|
|
y++;
|
|
}
|
|
}
|
|
break;
|
|
case '-': while (y < maxy - 1) {
|
|
if (pagepos == mem) break;
|
|
pagepos -= Anzahl;
|
|
y++;
|
|
}
|
|
break;
|
|
case '\0':
|
|
case '\n':
|
|
case '\r': while (y > 0) {
|
|
y--;
|
|
pagepos += Anzahl;
|
|
}
|
|
break;
|
|
default : beep();
|
|
break;
|
|
}
|
|
repaint();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
scrolldown(lns)
|
|
int lns;
|
|
{
|
|
while (lns--) {
|
|
if (maxpos >= (pagepos + Anzahl)) pagepos += Anzahl;
|
|
else { beep(); lns = 0; }
|
|
repaint();
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
scrollup(lns)
|
|
int lns;
|
|
{
|
|
while (lns--) {
|
|
if (mem <= (PTR)(pagepos - Anzahl)) pagepos -= Anzahl;
|
|
else { beep(); lns = 0; }
|
|
repaint();
|
|
refresh();
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
xpos()
|
|
{
|
|
if (loc == HEX) return((x - AnzAdd) / 3);
|
|
else return(x - AnzAdd - Anzahl3);
|
|
}
|
|
|
|
|
|
void
|
|
toggle()
|
|
{
|
|
if (loc == HEX) {
|
|
x = xpos() + AnzAdd + Anzahl3;
|
|
loc = ASCII;
|
|
} else {
|
|
x = xpos() * 3 + AnzAdd;
|
|
loc = HEX;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
setcur()
|
|
{
|
|
move(y, x);
|
|
refresh();
|
|
}
|
|
|
|
|
|
/************* display current position *************/
|
|
void
|
|
statpos()
|
|
{
|
|
char bin_val [9];
|
|
unsigned char Char1;
|
|
int i;
|
|
off_t bytepos;
|
|
char string[MAXCMD+1], str[6];
|
|
|
|
if (!P(P_MO)) return;
|
|
bytepos = current - mem;
|
|
if (bytepos >= filesize) {
|
|
// mvaddstr(maxy, status, " ");
|
|
move(maxy, status);
|
|
for (i = status; i < maxx; i++) addch(' ');
|
|
return;
|
|
}
|
|
Char1 = *(mem + bytepos);
|
|
|
|
for (i = 0; i < 8; ++i) {
|
|
if(Char1 & (1<<i)) {
|
|
bin_val[7-i] = '1';
|
|
} else {
|
|
bin_val[7-i] = '0';
|
|
}
|
|
}
|
|
bin_val[8] = '\0';
|
|
|
|
sprintf(string, "%08llX %s \\%03o 0x%02X %3d ",
|
|
(long long)(bytepos + P(P_OF)), bin_val, Char1, Char1, Char1);
|
|
attrset(A_BOLD);
|
|
status = maxx - 1 - statsize;
|
|
mvaddstr(maxy, status, string);
|
|
|
|
if (isprint(Char1)) {
|
|
sprintf(str, "'%c'", Char1);
|
|
addstr(str);
|
|
} else if (Char1 < 32) {
|
|
if (P(P_US)) strcpy(str, contru[Char1]);
|
|
else strcpy(str, contrd[Char1]);
|
|
addstr(str);
|
|
} else if (Char1 == 127) {
|
|
if (P(P_US)) strcpy(str, contru[32]);
|
|
else strcpy(str, contrd[32]);
|
|
addstr(str);
|
|
} else {
|
|
if (P(P_RE)) {
|
|
if ((Char1 & 128) && ((Char1 > 159) && (Char1 < 255))) {
|
|
addstr("'");
|
|
attrset(A_REVERSE);
|
|
sprintf(str, "%c", Char1 & 127);
|
|
addstr(str);
|
|
attrset(A_BOLD);
|
|
addstr("'");
|
|
} else {
|
|
addstr(" ");
|
|
}
|
|
} else {
|
|
addstr(" ");
|
|
}
|
|
}
|
|
attrset(A_NORMAL);
|
|
}
|
|
|
|
|
|
void
|
|
printline(mempos, scpos)
|
|
PTR mempos;
|
|
int scpos;
|
|
{
|
|
PTR hl_start = 0;
|
|
PTR hl_end = 0;
|
|
PTR f_start = 0;
|
|
PTR f_end = 0;
|
|
int print_pos = 0, mv_pos = 0;
|
|
unsigned char cur_ch;
|
|
|
|
if (mempos > maxpos) {
|
|
strcpy(linbuf, "~ ");
|
|
} else {
|
|
|
|
sprintf(linbuf, addr_form, (long long)(mempos - mem + P(P_OF)));
|
|
*string = '\0';
|
|
}
|
|
mvaddstr(scpos, mv_pos, linbuf);
|
|
mv_pos = AnzAdd;
|
|
*linbuf = '\0';
|
|
if (hl_spat) {
|
|
f_start = (mempos - Anzahl) < mem ? mem : (mempos - Anzahl);
|
|
f_end = mempos + (2 * Anzahl);
|
|
hl_start = fsearch_end(f_start, f_end, search_pat, &hl_end);
|
|
}
|
|
|
|
for (print_pos = 0; print_pos < Anzahl; print_pos++) {
|
|
if (hl_spat) {
|
|
while (hl_start != NULL) {
|
|
if (hl_start < mempos) {
|
|
if (hl_end < mempos) {
|
|
f_start = hl_start + 1;
|
|
hl_start = fsearch_end(f_start, f_end, search_pat, &hl_end);
|
|
} else {
|
|
attrset(A_STANDOUT); /* start out highlighted */
|
|
break;
|
|
}
|
|
} else if (hl_start >= mempos) {
|
|
break;
|
|
}
|
|
}
|
|
if (hl_start != NULL) {
|
|
if ((hl_start - mempos) == print_pos) {
|
|
mvaddstr(scpos, mv_pos, linbuf);
|
|
mv_pos = AnzAdd + (3 * print_pos);
|
|
*linbuf = '\0';
|
|
attrset(A_STANDOUT);
|
|
}
|
|
if ((hl_end - mempos) == print_pos) {
|
|
mvaddstr(scpos, mv_pos, linbuf);
|
|
*linbuf = '\0';
|
|
mv_pos = AnzAdd + (3 * print_pos);
|
|
f_start = hl_end;
|
|
hl_start = fsearch_end(f_start, f_end, search_pat, &hl_end);
|
|
if (f_start != hl_start) {
|
|
attrset(A_NORMAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (mempos + print_pos >= maxpos) {
|
|
sprintf(tmpbuf, " ");
|
|
cur_ch = ' ';
|
|
} else {
|
|
cur_ch = *(mempos + print_pos);
|
|
sprintf(tmpbuf, "%02X ", cur_ch);
|
|
}
|
|
strcat(linbuf, tmpbuf);
|
|
}
|
|
mvaddstr(scpos, mv_pos, linbuf);
|
|
attrset(A_NORMAL);
|
|
|
|
for (print_pos = 0; print_pos < Anzahl; print_pos++) {
|
|
if (mempos + print_pos < maxpos) {
|
|
cur_ch = *(mempos + print_pos);
|
|
if (isprint(cur_ch)) {
|
|
sprintf(string, "%c", cur_ch);
|
|
addstr(string);
|
|
} else {
|
|
if (P(P_RE)) {
|
|
if ((cur_ch & 128) && ((cur_ch > 159) && (cur_ch < 255))) {
|
|
attrset(A_REVERSE);
|
|
sprintf(string, "%c", cur_ch & 127);
|
|
addstr(string);
|
|
attrset(A_NORMAL);
|
|
} else {
|
|
addstr(".");
|
|
}
|
|
} else {
|
|
addstr(".");
|
|
}
|
|
}
|
|
} else {
|
|
addstr(" ");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* displays a line on screen
|
|
* at pagepos + line y
|
|
*/
|
|
int
|
|
lineout()
|
|
{
|
|
off_t Adresse;
|
|
|
|
Adresse = pagepos - mem + y * Anzahl;
|
|
printline(mem + Adresse, y);
|
|
move(y, x);
|
|
return(0);
|
|
}
|
|
|
|
|
|
void
|
|
new_screen()
|
|
{
|
|
screen = Anzahl * (maxy - 1);
|
|
clear();
|
|
repaint();
|
|
}
|
|
|
|
|
|
void
|
|
repaint() /***** redraw screen *********************/
|
|
{
|
|
int save_y;
|
|
|
|
save_y = y;
|
|
for (y = 0; y < maxy; y++) lineout();
|
|
y = save_y;
|
|
}
|
|
|
|
|
|
|
|
/******* display an arbitrary address on screen *******/
|
|
void
|
|
setpage(addr)
|
|
PTR addr;
|
|
{
|
|
if ((addr >= pagepos) && ((addr - pagepos) < screen)) {
|
|
y = (addr - pagepos) / Anzahl;
|
|
if (loc == HEX)
|
|
x = AnzAdd + ((addr - pagepos) - y * Anzahl) * 3;
|
|
else
|
|
x = AnzAdd + Anzahl3 + ((addr - pagepos) - y * Anzahl);
|
|
} else {
|
|
pagepos = (((addr - mem) / Anzahl) * Anzahl + mem)
|
|
- (Anzahl * (maxy / 2));
|
|
if (pagepos < mem) pagepos = mem;
|
|
y = (addr - pagepos) / Anzahl;
|
|
if (loc == HEX)
|
|
x = AnzAdd + ((addr - pagepos) - y * Anzahl) * 3;
|
|
else
|
|
x = AnzAdd + Anzahl3 + ((addr - pagepos) - y * Anzahl);
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
cur_forw(check)
|
|
int check;
|
|
{
|
|
if (check) {
|
|
if (current - mem >= filesize) {
|
|
beep();
|
|
return 1;
|
|
}
|
|
}
|
|
if (loc == ASCII) {
|
|
if (x < AnzAdd - 1 + Anzahl3 + Anzahl) {
|
|
x++ ;
|
|
return 0;
|
|
} else x = AnzAdd + Anzahl3;
|
|
} else {
|
|
if (x < 5 + Anzahl3) {
|
|
x += 3;
|
|
return 0;
|
|
} else x = AnzAdd;
|
|
}
|
|
statpos();
|
|
lineout();
|
|
if (y < maxy - 1) {
|
|
y++;
|
|
return 0;
|
|
} else {
|
|
if (pagepos < (PTR)(mem + filesize)) {
|
|
pagepos += Anzahl;
|
|
repaint();
|
|
return 0;
|
|
} else {
|
|
beep();
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
cur_back()
|
|
{
|
|
if (loc == ASCII) {
|
|
if (x > AnzAdd + Anzahl3) {
|
|
x-- ;
|
|
return 0;
|
|
} else {
|
|
x = AnzAdd - 1 + Anzahl3 + Anzahl;
|
|
}
|
|
} else {
|
|
if (x > AnzAdd + 2) {
|
|
x -= 3;
|
|
return 0;
|
|
} else {
|
|
if (current == mem) return 0;
|
|
x = AnzAdd + Anzahl3 - 3;
|
|
}
|
|
}
|
|
statpos();
|
|
lineout();
|
|
if (y > 0) {
|
|
y--;
|
|
return 0;
|
|
} else {
|
|
if (pagepos > mem) {
|
|
pagepos -= Anzahl;
|
|
repaint();
|
|
return 0;
|
|
} else {
|
|
beep();
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
fileinfo(fname)
|
|
char *fname;
|
|
{
|
|
off_t bytepos;
|
|
char fstatus[MAXCMD];
|
|
char *string;
|
|
|
|
if (fname) {
|
|
string = malloc((size_t)strlen(fname) + MAXCMD);
|
|
if (string == NULL) {
|
|
emsg("Out of memory");
|
|
return;
|
|
}
|
|
sprintf(string, "\"%s\" ", fname);
|
|
} else {
|
|
string = malloc(MAXCMD);
|
|
if (string == NULL) {
|
|
emsg("Out of memory");
|
|
return;
|
|
}
|
|
strcpy(string, "No file ");
|
|
}
|
|
if (filemode != NEW && filemode != REGULAR)
|
|
strcat(string, "[Not edited] ");
|
|
if (P(P_RO)) strcat(string, "[Read only] ");
|
|
if (edits) strcat(string, "[Modified] ");
|
|
if (filesize) {
|
|
bytepos = (pagepos + y * Anzahl + xpos()) - mem + 1L;
|
|
sprintf(fstatus, "byte %llu of %llu --%llu%%--",
|
|
(unsigned long long)bytepos,
|
|
(unsigned long long)filesize,
|
|
(unsigned long long)(bytepos * 100L / filesize));
|
|
strcat(string, fstatus);
|
|
} else {
|
|
strcat(string, " 0 bytes");
|
|
}
|
|
msg(string);
|
|
free(string);
|
|
}
|
|
|
|
|
|
/********** END ************/
|
|
void
|
|
quit()
|
|
{
|
|
move(maxy, 0);
|
|
endwin();
|
|
printf("\nbvi version %s %s\n", VERSION, copyright);
|
|
exit(0);
|
|
}
|
|
|
|
|
|
int
|
|
vgetc()
|
|
{
|
|
int nextc;
|
|
|
|
if (getcnext != NULL) {
|
|
nextc = *getcnext++;
|
|
if (*getcnext == '\0') {
|
|
*getcbuff = '\0';
|
|
getcnext = NULL;
|
|
}
|
|
return(nextc);
|
|
}
|
|
return getch();
|
|
}
|
|
|
|
|
|
void
|
|
stuffin(s)
|
|
char *s;
|
|
{
|
|
if (s == NULL) { /* clear the stuff buffer */
|
|
getcnext = NULL;
|
|
return;
|
|
}
|
|
if (getcnext == NULL) {
|
|
strcpy(getcbuff, s);
|
|
getcnext = getcbuff;
|
|
} else
|
|
strcat(getcbuff, s);
|
|
}
|
|
|
|
|
|
void
|
|
do_back(n, start)
|
|
off_t n;
|
|
PTR start;
|
|
{
|
|
if (start - n < mem) {
|
|
beep();
|
|
return;
|
|
}
|
|
if ((undo_count = alloc_buf(n, &undo_buf)) == 0L)
|
|
return;
|
|
yanked = alloc_buf(n, &yank_buf);
|
|
edits = U_BACK;
|
|
undo_start = start - n;
|
|
memcpy(undo_buf, start - undo_count, undo_count);
|
|
memcpy(yank_buf, start - undo_count, undo_count);
|
|
memmove(start - undo_count, start, maxpos - start);
|
|
filesize -= undo_count;
|
|
maxpos -= undo_count;
|
|
setpage(start - undo_count);
|
|
repaint();
|
|
}
|
|
|
|
|
|
int
|
|
do_delete(n, start)
|
|
off_t n;
|
|
PTR start;
|
|
{
|
|
if (n + start > maxpos) {
|
|
beep();
|
|
return 1;
|
|
}
|
|
if ((undo_count = alloc_buf(n, &undo_buf)) == 0L)
|
|
return 1;
|
|
yanked = alloc_buf(n, &yank_buf);
|
|
edits = U_DELETE;
|
|
undo_start = start;
|
|
memcpy(undo_buf, start, undo_count);
|
|
memcpy(yank_buf, start, undo_count);
|
|
memmove(start, start + undo_count, maxpos - (start + undo_count));
|
|
filesize -= undo_count;
|
|
maxpos -= undo_count;
|
|
if (start == maxpos && start > mem) {
|
|
start--;
|
|
cur_back();
|
|
}
|
|
setpage(start);
|
|
repaint();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* The :insert, :append and :change command
|
|
*/
|
|
void
|
|
do_ins_chg(start, arg, mode)
|
|
PTR start;
|
|
char *arg;
|
|
int mode;
|
|
{
|
|
int base;
|
|
off_t buffer = BUFFER;
|
|
off_t count = 0L;
|
|
size_t len;
|
|
long val;
|
|
char *tempbuf = NULL;
|
|
char *poi, *epoi;
|
|
|
|
if ((mode == U_EDIT) && (current - mem >= filesize)) {
|
|
beep();
|
|
return;
|
|
}
|
|
len = strlen(arg);
|
|
if (!strncmp("ascii", arg, len) && CMDLNG(5, 1)) {
|
|
base = 1;
|
|
} else if (!strncmp("binary", arg, len) && CMDLNG(6, 1)) {
|
|
base = 2;
|
|
} else if (!strncmp("octal", arg, len) && CMDLNG(5, 1)) {
|
|
base = 8;
|
|
} else if (!strncmp("decimal", arg, len) && CMDLNG(7, 1)) {
|
|
base = 10;
|
|
} else if (!strncmp("hexadecimal", arg, len) && CMDLNG(11, 1)) {
|
|
base = 16;
|
|
} else {
|
|
emsg("No such option");
|
|
return;
|
|
}
|
|
addch('\n');
|
|
if (getcmdstr(cmdstr, 0) == 1) {
|
|
repaint();
|
|
return;
|
|
}
|
|
if (alloc_buf(buffer, &tempbuf) == 0L) return;
|
|
while(strcmp(cmdstr, ".")) {
|
|
poi = cmdstr;
|
|
if (base == 1) { /* ASCII */
|
|
while (*poi != '\0') {
|
|
if (*poi == '\\') {
|
|
switch (*(++poi)) {
|
|
case 'n': val = '\n'; break;
|
|
case 'r': val = '\r'; break;
|
|
case 't': val = '\t'; break;
|
|
case '0': val = '\0'; break;
|
|
case '\\': val = '\\'; break;
|
|
default : val = '\\'; poi--;
|
|
}
|
|
poi++;
|
|
} else {
|
|
val = *poi++;
|
|
}
|
|
*(tempbuf + count++) = val;
|
|
}
|
|
} else {
|
|
while (isspace(cmdstr[strlen(cmdstr) - 1]))
|
|
cmdstr[strlen(cmdstr) - 1] = '\0';
|
|
while (*poi != '\0') {
|
|
val = strtol(poi, &epoi, base);
|
|
if (val > 255 || val < 0 || poi == epoi) {
|
|
repaint();
|
|
emsg("Invalid value");
|
|
goto mfree;
|
|
}
|
|
poi = epoi;
|
|
*(tempbuf + count++) = val;
|
|
}
|
|
}
|
|
addch('\n');
|
|
if (getcmdstr(cmdstr, 0) == 1) {
|
|
repaint();
|
|
goto mfree;
|
|
}
|
|
}
|
|
if (count == 0) {
|
|
repaint();
|
|
goto mfree;
|
|
}
|
|
switch (mode) {
|
|
case U_INSERT:
|
|
do_put(start, count, tempbuf);
|
|
break;
|
|
case U_EDIT:
|
|
do_over(start, count, tempbuf);
|
|
break;
|
|
case U_APPEND:
|
|
if ((undo_count = alloc_buf(count, &undo_buf)) == 0L) {
|
|
repaint();
|
|
goto mfree;
|
|
}
|
|
do_append((off_t)count, tempbuf);
|
|
memcpy(undo_buf, tempbuf, count);
|
|
repaint();
|
|
break;
|
|
}
|
|
mfree:
|
|
#if defined(__MSDOS__) && !defined(DJGPP)
|
|
farfree(tempbuf);
|
|
#else
|
|
free(tempbuf);
|
|
#endif
|
|
}
|
|
|
|
|
|
void
|
|
clear_marks()
|
|
{
|
|
int n;
|
|
|
|
for (n = 0; n < 26; markbuf[n++] = NULL);
|
|
undo_count = 0;
|
|
last_motion = mem;
|
|
}
|
|
|
|
|
|
void
|
|
do_mark(mark, addr)
|
|
int mark;
|
|
PTR addr;
|
|
{
|
|
if (mark < 'a' || mark > 'z' || current >= maxpos)
|
|
return;
|
|
markbuf[mark - 'a'] = addr;
|
|
}
|
|
|
|
|
|
void
|
|
movebyte()
|
|
{
|
|
emsg("Command disabled@- use ':set memmove' to enable ");
|
|
}
|