#include <stdlib.h>
#include "openaxiom-c-macros.h"
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include "edible.h"
#define HFT 0
#define SUN 1
#define DEC 2
#define control_to_alpha(x) (x + ('A' - 0x01))
#define alpha_to_control(x) (x - ('A' - 0x01))
int termId;
QueStruct *ring = NULL;
QueStruct *current = NULL;
int ring_size = 0;
int MAXRING = 64;
int prev_check = 10;
int curr_pntr;
int num_pntr;
int num_proc;
int had_tab;
int had_tab_last;
extern char buff[1024];
extern int buff_flag[1024];
int buff_pntr;
#include "edin.h"
#include "prt.h"
#include "wct.h"
#include "cursor.h"
#include "fnct_key.h"
void
init_reader(void)
{
char *termVal;
buff[50] = '\0';
init_flag(buff_flag, MAXLINE);
buff_pntr = curr_pntr = 0;
had_tab = 0;
had_tab_last = 0;
termVal = (char *) getenv("TERM");
if (!strcmp("sun", termVal))
termId = SUN;
else if (!strcmp("xterm", termVal) || !strncmp("vt", termVal, 2))
termId = DEC;
else if (!strcmp("hft", termVal) || !strncmp("aixterm", termVal, 7))
termId = HFT;
}
void
do_reading(void)
{
int ttt_read;
int done_completely;
done_completely = 0;
num_proc = 0;
while (num_proc < num_read) {
if(in_buff[num_proc]== _ERASE) {
back_over_current_char();
num_proc++;
}
else {
switch (in_buff[num_proc]) {
case _EOLN:
case _CR:
send_line_to_child();
if (!PTY)
myputchar('\n');
break;
case _DEL:
delete_current_char();
break;
case _CNTRL_W:
move_back_word();
num_proc++;
break;
case _TAB:
had_tab = 1;
num_proc++;
if (had_tab_last)
rescan_wct();
else
find_wct();
break;
case _BELL:
insert_buff_nonprinting(1);
putchar(_BELL);
fflush(stdout);
break;
case _ESC:
while (!(num_read - num_proc > 2)) {
ttt_read = read(0,
in_buff + num_read,
2 - (num_read - num_proc) + 1);
if (ttt_read > 0)
num_read = num_read + ttt_read;
}
if (in_buff[num_proc + 1] == _LBRACK) {
switch (in_buff[num_proc + 2]) {
case _A:
prev_buff();
curr_pntr = buff_pntr;
num_proc = num_proc + 3;
break;
case _B:
next_buff();
curr_pntr = buff_pntr;
num_proc = num_proc + 3;
break;
case _C:
move_ahead();
num_proc = num_proc + 3;
break;
case _D:
move_back();
num_proc = num_proc + 3;
break;
case _P:
delete_current_char();
break;
case _H:
case 0:
move_home();
num_proc += 3;
break;
case _M:
case _Z:
insert_buff_nonprinting(3);
done_completely = 1;
num_proc += 3;
break;
case _x:
num_proc = num_read;
break;
case _1:
case _2:
case _0:
while (!(num_read - num_proc > 3)) {
ttt_read = read(0,
in_buff + num_read,
3 - (num_read - num_proc) + 1);
if (ttt_read > 0)
num_read = num_read + ttt_read;
}
if (in_buff[num_proc + 3] == _twiddle) {
switch (in_buff[num_proc + 2]) {
case _2:
flip(INS_MODE);
if (INS_MODE)
Cursor_shape(5);
else
Cursor_shape(2);
reprint(curr_pntr);
num_proc += 4;
break;
default:
insert_buff_nonprinting(1);
break;
}
break;
}
while (!(num_read - num_proc > 4)) {
ttt_read = read(0,
in_buff + num_read,
4 - (num_read - num_proc) + 1);
if (ttt_read > 0)
num_read = num_read + ttt_read;
}
if (in_buff[num_proc + 4] == _twiddle) {
insert_buff_nonprinting(1);
break;
}
while (!(num_read - num_proc > 5)) {
ttt_read = read(0,
in_buff + num_read,
5 - (num_read - num_proc) + 1);
if (ttt_read > 0)
num_read = num_read + ttt_read;
}
if (insert_toggle(&in_buff[num_proc + 3])) {
flip(INS_MODE);
if (INS_MODE)
Cursor_shape(5);
else
Cursor_shape(2);
reprint(curr_pntr);
num_proc = num_proc + 6;
break;
}
else if (cntrl_end(&in_buff[num_proc + 3])) {
num_proc = num_proc + 6;
delete_to_end_of_line();
break;
}
else if (back_word(&in_buff[num_proc + 3])) {
move_back_word();
num_proc += 6;
break;
}
else if (fore_word(&in_buff[num_proc + 3])) {
move_fore_word();
num_proc += 6;
break;
}
else if (end_key(&in_buff[num_proc + 3])) {
move_end();
num_proc += 6;
break;
}
switch (in_buff[num_proc + 5]) {
case _q:
{
char num[3];
int key;
num[0] = in_buff[num_proc + 3];
num[1] = in_buff[num_proc + 4];
num[2] = '\0';
key = atoi(num);
if (key > 0 && key < 13) {
if (function_key[key].str != NULL) {
handle_function_key(key, contNum);
done_completely = 1;
}
else {
insert_buff_nonprinting(6);
done_completely = 1;
}
}
else {
insert_buff_nonprinting(6);
done_completely = 1;
}
break;
}
case _z:
{
char num[3];
int key;
num[0] = in_buff[num_proc + 3];
num[1] = in_buff[num_proc + 4];
num[2] = '\0';
key = atoi(num) - 23;
if (key > 0 && key < 13) {
if (function_key[key].str != NULL) {
handle_function_key(key, contNum);
done_completely = 1;
}
else {
insert_buff_nonprinting(6);
done_completely = 1;
}
}
else if (atoi(num) == 14) {
move_home();
num_proc += 6;
done_completely = 1;
}
else if (atoi(num) == 20) {
move_end();
num_proc += 6;
done_completely = 1;
}
else if (atoi(num) == 47) {
flip(INS_MODE);
if (INS_MODE)
Cursor_shape(5);
else
Cursor_shape(2);
reprint(curr_pntr);
num_proc = num_proc + 6;
done_completely = 1;
}
else {
insert_buff_nonprinting(6);
done_completely = 1;
}
break;
}
default:
insert_buff_nonprinting(1);
break;
}
default:
if (!done_completely)
insert_buff_nonprinting(1);
break;
}
}
else {
insert_buff_nonprinting(1);
}
break;
case _BKSPC:
back_over_current_char();
num_proc++;
break;
default:
if (in_buff[num_proc] == _KILL) {
delete_line();
num_proc++;
}
else {
if ((in_buff[num_proc] == _INTR) || (in_buff[num_proc] == _QUIT)) {
write(contNum, &in_buff[num_proc], num_read - num_proc);
if (!PTY)
write(contNum, "\n", 1);
num_proc++;
}
else {
if (in_buff[num_proc] == _EOF) {
insert_buff_nonprinting(1);
if (!PTY)
write(contNum, "\n", 1);
num_proc++;
}
else {
if (in_buff[num_proc] == _EOL) {
send_line_to_child();
if (!PTY)
write(contNum, "\n", 1);
}
else {
if (in_buff[num_proc] == _ERASE) {
back_over_current_char();
num_proc++;
}
else {
if (control_char(in_buff[num_proc]))
insert_buff_nonprinting(1);
else
insert_buff_printing(1);
}
}
}
}
}
break;
}
}
if (had_tab) {
had_tab_last = 1;
had_tab = 0;
}
else
had_tab_last = 0;
}
}
void
send_line_to_child(void)
{
static char converted_buffer[MAXLINE];
int converted_num;
back_it_up(curr_pntr);
if (buff_pntr)
insert_queue();
buff[buff_pntr] = in_buff[num_proc];
buff_flag[buff_pntr++] = 1;
buff[buff_pntr] = '\0';
buff_flag[buff_pntr] = -1;
converted_num =
convert_buffer(converted_buffer, buff, buff_flag, buff_pntr);
write(contNum, converted_buffer, converted_num);
init_flag(buff_flag, buff_pntr);
init_buff(buff, buff_pntr);
buff_pntr = curr_pntr = 0;
current = NULL;
num_proc++;
return;
}
int
convert_buffer(char *target, char *source,int * source_flag, int num)
{
int i, j;
for (i = 0, j = 0; i < num; i++, j++) {
switch (source[i]) {
case _CARROT:
if (source_flag[i] == 1) {
target[j] = source[i];
}
else {
if (source[i + 1] == _LBRACK) {
target[j] = _ESC;
i++;
}
else if (source[i + 1] >= 'A' && source[i + 1] <= 'Z') {
target[j] = alpha_to_control(source[i + 1]);
i++;
}
}
break;
case '?':
default:
target[j] = source[i];
}
}
return j;
}
void
insert_buff_printing(int amount)
{
int count;
if ((buff_pntr + amount) > 1023) {
putchar(_BELL);
fflush(stdout);
num_proc += amount;
}
else {
if (INS_MODE) {
forwardcopy(&buff[curr_pntr + amount],
&buff[curr_pntr],
buff_pntr - curr_pntr);
forwardflag_cpy(&buff_flag[curr_pntr + amount],
&buff_flag[curr_pntr],
buff_pntr - curr_pntr);
for (count = 0; count < amount; count++) {
buff[curr_pntr + count] = in_buff[num_proc + count];
buff_flag[curr_pntr + count] = 1;
}
ins_print(curr_pntr, amount);
buff_pntr = buff_pntr + amount;
}
else {
for (count = 0; count < amount; count++) {
if (buff_flag[curr_pntr + count] == 2) {
myputchar(buff[curr_pntr + count]);
curr_pntr += count + 1;
delete_current_char();
num_proc -= 3;
curr_pntr -= count + 1;
myputchar(_BKSPC);
}
buff[curr_pntr + count] = in_buff[num_proc + count];
buff_flag[curr_pntr + count] = 1;
}
myputchar(in_buff[num_proc]);
if (curr_pntr == buff_pntr)
buff_pntr++;
}
num_proc = num_proc + amount;
curr_pntr = curr_pntr + amount;
fflush(stdout);
}
return;
}
void
insert_buff_nonprinting(int amount)
{
int count;
if ((buff_pntr + amount) > 1023) {
myputchar(_BELL);
fflush(stdout);
num_proc += amount;
}
else {
if (INS_MODE) {
forwardcopy(&buff[curr_pntr + amount + 1],
&buff[curr_pntr],
buff_pntr - curr_pntr);
forwardflag_cpy(&buff_flag[curr_pntr + amount + 1],
&buff_flag[curr_pntr],
buff_pntr - curr_pntr);
switch (in_buff[num_proc]) {
case _ESC:
buff[curr_pntr] = _CARROT;
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = _LBRACK;
buff_flag[curr_pntr + 1] = 0;
break;
default:
if (control_char(in_buff[num_proc])) {
buff[curr_pntr] = _CARROT;
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]);
buff_flag[curr_pntr + 1] = 0;
}
else {
buff[curr_pntr] = '?';
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = in_buff[num_proc];
buff_flag[curr_pntr] = 0;
break;
}
}
for (count = 1; count < amount; count++) {
buff[curr_pntr + count + 1] = in_buff[num_proc + count];
buff_flag[curr_pntr + count + 1] = 1;
}
ins_print(curr_pntr, amount + 1);
buff_pntr = buff_pntr + amount + 1;
}
else {
switch (in_buff[num_proc]) {
case _ESC:
buff[curr_pntr] = _CARROT;
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = _LBRACK;
buff_flag[curr_pntr + 1] = 0;
break;
default:
if (control_char(in_buff[num_proc])) {
buff[curr_pntr] = _CARROT;
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = control_to_alpha(in_buff[num_proc]);
buff_flag[curr_pntr + 1] = 0;
}
else {
buff[curr_pntr] = '?';
buff_flag[curr_pntr] = 2;
buff[curr_pntr + 1] = in_buff[num_proc];
buff_flag[curr_pntr] = 0;
break;
}
}
for (count = 1; count < amount; count++) {
if (buff_flag[curr_pntr + count] == 2) {
curr_pntr += count + 1;
delete_current_char();
num_proc -= 3;
curr_pntr -= count + 1;
}
buff[curr_pntr + count + 1] = in_buff[num_proc + count];
buff_flag[curr_pntr + count + 1] = 1;
}
printbuff(curr_pntr, amount + 1);
}
num_proc = num_proc + amount;
curr_pntr = curr_pntr + amount + 1;
if (curr_pntr > buff_pntr)
buff_pntr = curr_pntr;
}
return;
}
void
prev_buff(void)
{
if (ring == NULL)
return;
clear_buff();
init_buff(buff, buff_pntr);
init_flag(buff_flag, buff_pntr);
if (current == NULL) {
if (ring == NULL)
return;
current = ring;
}
else
current = current->prev;
strcpy(buff, current->buff);
flagcpy(buff_flag, current->flags);
fflush(stdout);
printbuff(0, strlen(buff));
curr_pntr = buff_pntr = strlen(buff);
fflush(stdout);
return ;
}
void
next_buff(void)
{
if (ring == NULL)
return;
clear_buff();
init_buff(buff, buff_pntr);
init_flag(buff_flag, buff_pntr);
if (current == NULL) {
if (ring == NULL)
return;
current = ring->next;
}
else
current = current->next;
strcpy(buff, current->buff);
flagcpy(buff_flag, current->flags);
fflush(stdout);
printbuff(0, strlen(buff));
curr_pntr = buff_pntr = strlen(buff);
fflush(stdout);
return ;
}
void
forwardcopy(char *buff1,char * buff2,int num)
{
int count;
for (count = num; count >= 0; count--)
buff1[count] = buff2[count];
}
void
forwardflag_cpy(int *buff1,int * buff2,int num)
{
int count;
for (count = num; count >= 0; count--)
buff1[count] = buff2[count];
}
void
flagcpy(int *s,int *t)
{
while (*t >= 0)
*s++ = *t++;
*s = *t;
}
void
flagncpy(int *s,int *t,int n)
{
while (n-- > 0)
*s++ = *t++;
}
void
insert_queue(void)
{
QueStruct *trace;
QueStruct *new_q;
int c;
if (!ECHOIT)
return;
if (ring != NULL && !strcmp(buff, ring->buff))
return;
for (c = 0, trace = ring; trace != NULL && c < (prev_check - 1);
c++, trace = trace->prev) {
if (!strcmp(buff, trace->buff)) {
trace->next->prev = trace->prev;
trace->prev->next = trace->next;
trace->prev = ring;
trace->next = ring->next;
ring->next = trace;
trace->next->prev = trace;
ring = trace;
return;
}
}
if (ring_size < MAXRING) {
new_q = (QueStruct *) malloc(sizeof(struct que_struct));
if (new_q == NULL) {
fprintf(stderr, "Malloc Error: Ran out of memory\n");
exit(-1);
}
if (ring_size == 0) {
ring = new_q;
ring->prev = ring->next = new_q;
}
else {
new_q->next = ring->next;
new_q->prev = ring;
ring->next = new_q;
new_q->next->prev = new_q;
ring = new_q;
}
ring_size++;
}
else
ring = ring->next;
init_flag(ring->flags, MAXLINE);
init_buff(ring->buff, MAXLINE);
strcpy(ring->buff, buff);
flagncpy(ring->flags, buff_flag, buff_pntr);
(ring->buff)[buff_pntr] = '\0';
(ring->flags)[buff_pntr] = -1;
}
void
init_flag(int *flags, int num)
{
int i;
for (i = 0; i < num; i++)
flags[i] = -1;
}
void
init_buff(char *flags, int num)
{
int i;
for (i = 0; i < num; i++)
flags[i] = '\0';
}
void
send_function_to_child(void)
{
back_it_up(curr_pntr);
if (buff_pntr)
insert_queue();
buff[buff_pntr] = _EOLN;
buff_flag[buff_pntr++] = 1;
buff[buff_pntr] = '\0';
buff_flag[buff_pntr] = 0;
write(contNum, buff, buff_pntr);
init_flag(buff_flag, buff_pntr);
init_buff(buff, buff_pntr);
buff_pntr = curr_pntr = 0;
current = NULL;
num_proc++;
return;
}
void
send_buff_to_child(int chann)
{
if (buff_pntr > 0)
write(chann, buff, buff_pntr);
num_proc += 6;
init_flag(buff_flag, buff_pntr);
init_buff(buff, buff_pntr);
buff_pntr = curr_pntr = 0;
current = NULL;
return;
}