#include <sys/queue.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
RSIZE countfword(void);
int grabword(char **);
int
backword(int f, int n)
{
if (n < 0)
return (forwword(f | FFRAND, -n));
if (backchar(FFRAND, 1) == FALSE)
return (FALSE);
while (n--) {
while (inword() == FALSE) {
if (backchar(FFRAND, 1) == FALSE)
return (TRUE);
}
while (inword() != FALSE) {
if (backchar(FFRAND, 1) == FALSE)
return (TRUE);
}
}
return (forwchar(FFRAND, 1));
}
int
forwword(int f, int n)
{
if (n < 0)
return (backword(f | FFRAND, -n));
while (n--) {
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
while (inword() != FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
}
return (TRUE);
}
int
transposeword(int f, int n)
{
struct line *tmp1_w_dotp = NULL;
struct line *tmp2_w_dotp = NULL;
int tmp2_w_doto = 0;
int tmp1_w_dotline = 0;
int tmp2_w_dotline = 0;
int tmp1_w_doto;
int i;
int ret, s;
int newline;
int leave = 0;
int tmp_len;
char *word1 = NULL;
char *word2 = NULL;
char *chr;
if (n == 0)
return (TRUE);
n = 1;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
undo_boundary_enable(FFRAND, 0);
(void)backword(FFRAND, 1);
ret = grabword(&word1);
if (ret == ABORT) {
ewprintf("No word to the left to tranpose.");
return (FALSE);
}
if (ret < 0) {
dobeep();
ewprintf("Error copying word: %s", strerror(ret));
free(word1);
return (FALSE);
}
while (n-- > 0) {
i = 0;
newline = 0;
tmp1_w_doto = curwp->w_doto;
tmp1_w_dotline = curwp->w_dotline;
tmp1_w_dotp = curwp->w_dotp;
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE) {
leave = 1;
if (tmp1_w_dotline < curwp->w_dotline)
curwp->w_dotline--;
ewprintf("Don't have two things to transpose");
break;
}
if (curwp->w_doto == 0) {
newline = 1;
i = 0;
} else if (newline)
i++;
}
if (leave) {
tmp2_w_doto = tmp1_w_doto;
tmp2_w_dotline = tmp1_w_dotline;
tmp2_w_dotp = tmp1_w_dotp;
break;
}
tmp2_w_doto = curwp->w_doto;
tmp2_w_dotline = curwp->w_dotline;
tmp2_w_dotp = curwp->w_dotp;
ret = grabword(&word2);
if (ret < 0 || ret == ABORT) {
dobeep();
ewprintf("Error copying word: %s", strerror(ret));
free(word1);
return (FALSE);
}
tmp_len = strlen(word2);
tmp2_w_doto += tmp_len;
curwp->w_doto = tmp1_w_doto;
curwp->w_dotline = tmp1_w_dotline;
curwp->w_dotp = tmp1_w_dotp;
for (chr = word2; *chr != '\0'; ++chr)
linsert(1, *chr);
if (newline)
tmp2_w_doto = i;
curwp->w_doto = tmp2_w_doto;
curwp->w_dotline = tmp2_w_dotline;
curwp->w_dotp = tmp2_w_dotp;
free(word2);
word2 = NULL;
}
curwp->w_doto = tmp2_w_doto;
curwp->w_dotline = tmp2_w_dotline;
curwp->w_dotp = tmp2_w_dotp;
for (chr = word1; *chr != '\0'; ++chr)
linsert(1, *chr);
if (leave)
(void)backword(FFRAND, 1);
free(word1);
free(word2);
undo_boundary_enable(FFRAND, 1);
return (TRUE);
}
int
grabword(char **word)
{
size_t len = 0, cap = 0;
char *t;
while (inword() == TRUE) {
if (cap == 0 || len == cap - 1) {
t = recallocarray(*word, cap, cap + 8, 1);
if (t == NULL) {
free(*word);
*word = NULL;
return (errno);
}
cap += 8;
*word = t;
}
(*word)[len++] = lgetc(curwp->w_dotp, curwp->w_doto);
(void)forwdel(FFRAND, 1);
}
if (*word == NULL)
return (ABORT);
return (TRUE);
}
int
upperword(int f, int n)
{
int c, s;
RSIZE size;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
if (n < 0)
return (FALSE);
while (n--) {
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
size = countfword();
undo_add_change(curwp->w_dotp, curwp->w_doto, size);
while (inword() != FALSE) {
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (ISLOWER(c) != FALSE) {
c = TOUPPER(c);
lputc(curwp->w_dotp, curwp->w_doto, c);
lchange(WFFULL);
}
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
}
return (TRUE);
}
int
lowerword(int f, int n)
{
int c, s;
RSIZE size;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
if (n < 0)
return (FALSE);
while (n--) {
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
size = countfword();
undo_add_change(curwp->w_dotp, curwp->w_doto, size);
while (inword() != FALSE) {
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (ISUPPER(c) != FALSE) {
c = TOLOWER(c);
lputc(curwp->w_dotp, curwp->w_doto, c);
lchange(WFFULL);
}
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
}
return (TRUE);
}
int
capword(int f, int n)
{
int c, s;
RSIZE size;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
if (n < 0)
return (FALSE);
while (n--) {
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
size = countfword();
undo_add_change(curwp->w_dotp, curwp->w_doto, size);
if (inword() != FALSE) {
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (ISLOWER(c) != FALSE) {
c = TOUPPER(c);
lputc(curwp->w_dotp, curwp->w_doto, c);
lchange(WFFULL);
}
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
while (inword() != FALSE) {
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (ISUPPER(c) != FALSE) {
c = TOLOWER(c);
lputc(curwp->w_dotp, curwp->w_doto, c);
lchange(WFFULL);
}
if (forwchar(FFRAND, 1) == FALSE)
return (TRUE);
}
}
}
return (TRUE);
}
RSIZE
countfword()
{
RSIZE size;
struct line *dotp;
int doto;
dotp = curwp->w_dotp;
doto = curwp->w_doto;
size = 0;
while (inword() != FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
goto out;
++size;
}
out:
curwp->w_dotp = dotp;
curwp->w_doto = doto;
return (size);
}
int
delfword(int f, int n)
{
RSIZE size;
struct line *dotp;
int doto;
int s;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
if (n < 0)
return (FALSE);
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
dotp = curwp->w_dotp;
doto = curwp->w_doto;
size = 0;
while (n--) {
while (inword() == FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
goto out;
++size;
}
while (inword() != FALSE) {
if (forwchar(FFRAND, 1) == FALSE)
goto out;
++size;
}
}
out:
curwp->w_dotp = dotp;
curwp->w_doto = doto;
return (ldelete(size, KFORW));
}
int
delbword(int f, int n)
{
RSIZE size;
int s;
if ((s = checkdirty(curbp)) != TRUE)
return (s);
if (curbp->b_flag & BFREADONLY) {
dobeep();
ewprintf("Buffer is read-only");
return (FALSE);
}
if (n < 0)
return (FALSE);
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
if (backchar(FFRAND, 1) == FALSE)
return (TRUE);
size = 1;
while (n--) {
while (inword() == FALSE) {
if (backchar(FFRAND, 1) == FALSE)
goto out;
++size;
}
while (inword() != FALSE) {
if (backchar(FFRAND, 1) == FALSE)
goto out;
++size;
}
}
if (forwchar(FFRAND, 1) == FALSE)
return (FALSE);
--size;
out:
return (ldelete(size, KBACK));
}
int
inword(void)
{
return (curwp->w_doto != llength(curwp->w_dotp) &&
ISWORD(curwp->w_dotp->l_text[curwp->w_doto]));
}