editor

/*----------------*/
/* screen editer */
/*----------------*/
#include < stdio.h >
#include < string.h >
#include < stdlib.h >
#include < ctype.h >
#include < jctype.h >
#include < jctype.h >
#include < jstring.h >
#include < malloc.h >
#include < dos.h >
/*----------------*/
#define COLOR(n, a) printf("\x1b[%d;%dm", n, a)
#define BLACK   30
#define RED     31
#define GREEN   32
#define YELLOW  33
#define BLUE    34
#define MAGENTA 35
#define CYAN    36
#define WHITE   37
#define NORMAL  0
#define UNDERLINE   4
#define BLINK   5
#define REVERSE 7

#define UP  0x0b
#define DOWN    0x0a
#define ESC 0x1b
#define RETURN 0x0d

#define COLOR_OFF 0
#define COLOR_ON 1

#define LEN 1000

#define LOCATE(x, y) printf("\x1b[%d;%dH", y + 1, x + 1)
#define CURSOLE(f)  printf("\x1b[>5%c", f ? '1' : 'h')

union REGS ingres;
union REGS outregs;

struct list
{
    unsigned char *data;
    struct list *back;
    struct list *front;
} *head,
*page_head,
*now,
*new,
*new_start, *new_end,
*appoint_start, *appoint_end,
*paste_start, *paste_end;

int paste_flag;

long paste_start_no;

int xp, yp,
len,
width,
scrol,
tab,
color,
char drive;

int cx, cy;
int len_min = 8;
width_min = 20;
int drive_set_flag = 0;

static char filename[80];
static char *workfile[4]
= { "A:WORKO", "A:WORK1", "A:WORK2", "A:WORK3"};

FILE *fp0, *fp1, *fp2, *fp3;
/*----------------*/
void initial_process(void);
void ending_process(void);
void commandline_set(char **p, int n);
void parameter_value_check(void);
void load_process(int flag);
void waku_displat(int x, int y, int len, int width, int color, int zokusei);
void title_display(void);
void file_read(void);
void new_file_make(void);
void new_creat(void);
void hensyu(void);
void rollup_syori(void);
void rolldown_syori(void);
void left_key_syori(void);
void right_key_syori(void);
void up_key_syori(void);
void down_key_syori(void);
void bs_key_syori(void);
int ins_key_syori(int ins_flag);
int insert_syori(unsigned char m, struct list *p, int n);
void over_write_syori(unsigned char *p, int n);
void line_feed_syori(struct list *p, int n);
void buffer_memory_set(unsigned char *buffer, unsigned char *p, int n);
int menu_select(void);
void save_process(void);
void backward_page_check(struct list *p);
void forward_page_renketu(struct list *p);
void backward_page_load(void);
void forward_page_load(void);
void backward_page_save(void);
void forward_page_save(void);
void backward_page_memory_check(void);
void forward_page_memory_check(void);
int paste_locate(void);
void paste_set(void);
void cut_process(void);
void buffer_clear(unsigned char *p, int n);
void jump_process(void);
void hyouji(struct list *p, int s, int sw);
void vram_text_disp(unsigned char *p, int x, int y, int len, int color_sw);
void vram_color_set(unsigned char color_value, int x, int y, int len);
int input(unsigned char buffer[], int x, int y, int len);
int moji_check(unsigned char *buffer, int n);
int inkey(void);
void keybuffer_clear(void);
int scan_esc(void);
int scan_ins(void);
int scan_del(void);
int scan_bs(void);
int scan_rollup(void);
int scan_rolldown(void);
int scan_up(void);
int scan_down(void);
int scan_left(void);
int scan_right(void);
void cursole_blink(int sw)
/*----------------*/
/* main */
/*----------------*/
void main(int argc, char *argv[])
{
    initial_process();
    
    commandline_set(&argv[1], argc - 1);
    
    waku_display(xp - 1, yp - 1, len + 2, width + 2, WHITE, NORMAL);
    
    load_process(0);
    
    if (*filename != '\0')
    {
        hyouji(head, 0, COLOR_ON);
        henshu();
    }
    ending_process();
}
/*----------------*/
/* initial setting */
/*----------------*/
void initial_process(void)
{
    xp = 1; yp = 1; len = 20; width = 78; scroll = 1; tab = 4; color = 7;
    drive = ' A';
    head = paste_start = paste_end = NULL;
    paste_flag = 0;
}
/*----------------*/
/* ending process */
/*----------------*/
void ending_process(void)
{
    unlink(workfile[0]);
    unlink(workfile[1]);
    unlink(workfile[2]);
    unlink(workfile[3]);
    LOCATE(0, yp + len);
    COLOR(WHITE, NORMAL);
    CURSOLE(1);
}
/*----------------*/
/* comandline set */
/*----------------*/
void commandline_set(char **p, int n)
{
    int i;
    
    for(i = 0; i < n; i++)
    {
        if(**p == ' -')
        {
            *(*p + 1) = toupper(*(*p + 1));
            switch (*(*p + 1))
            {
                case 'X' : xp = atoi(*p + 2);
                    break;
                case 'Y' : yp = atoi(*p + 2);
                    break;
                case 'L' : len = atoi(*p + 2);
                    break;
                case 'W' : width = atoi(*p + 2);
                    break;
                case 'S' : scroll = atoi(*p + 2);
                    break;
                case 'T' : tab = atoi(*p + 2);
                    break;
                case 'C' : color = atoi(*p + 2);
                    break;
                case 'D' : drive = atoi(*p + 2);
                    drive = toupper(drive);
                    break;
                default : break;
            }
        }
        else
            strcpy(filename, *p);
        
        p++;
    }
    parameter_value_check();
}
/*----------------*/
/* parameter check */
/*----------------*/
void parameter_value_check(void)
{
    if(xp < 1)
        xp = 1;
    else if(xp > 79 - width_min)
        xp = 79 - width_min;
    
    if(yp < 1)
        yp = 1;
    else if(yp > 23 - len_min)
        yp = 23 - len_min;
    
    if (len < len_min)
        len = len_min;
    if (yp + len > 23)
        len = 23 - yp;
    
    if (width < width_min)
        width = width_min;
    if (xp + width > 79)
        width = 79 - xp;
    
    if (color < 1)
        color = 1;
    else if (color > 7)
        color = 7;
    color = color * 32 + 1;
    
    if (drive_set_flag == 0)
    {
        if (drive >= 'A' && drive <= 'Z')
        {
            *workfile[0] = drive;
            fp0 = fopen(workfile[0], "w");
            *workfile[0] = *workfile[1];
            if (fp0 != NULL)
            {
                *workfile[0] = drive;
                *workfile[1] = drive;
                *workfile[2] = drive;
                *workfile[3] = drive;
            }
            fcloseall();
        }
    }
    drive_set_flag = 1;
}
/*----------------*/
/* load transaction flag 0: start 1: edit */
/*----------------*/
void load_process(int flag)
{
    static char buffer[80], * work[10];
    int i, n, p, sw, set_flag;
    struct list *wp;
    
    sw = 0;
    
    while (*filename == '\0' || flag == 1)
    {
        LOCATE(xp, yp); COLOR(WHITE, REVERSE); printf(" -> ");
        sw = input (buffer, xp + 4, yp, width - 4);
        
        if (sw == RETURN && buffer[0] != '\0')
        {
            set_flag = n = 0;
            p = strlen(buffer);
            for(i = 0; i < p; i++)
            {
                if(set_flag == 0 && buffer[i] != ' ')
                {
                    work[n++] = buffer + i;
                    set_flag = 1;
                }
                else if (set_flag == 1 && buffer[i] == ' ')
                {
                    buffer[i] = '\0';
                    if (n == 10)
                        break;
                    set_flag = 0;
                }
            }
            hyouji(page_head, 0, COLOR_ON);
            
            commandline_set(&work[0], n);
            
            waku_display(xp - 1, yp - 1, len + 2, width + 2, WHITE, NORMAL);
            
            flag = 2;
        }
        else if(sw == ESC)
        {
            flag = 2;
            break;
        }
    }
    CURSOLE(0);
    LOCATE(xp + width / 2 - strlen(filename) / 2 - 2, yp -1);
    COLOR(WHITE, REVERSE); printf("[ %s ]", filename);
    
    if (flag== 0 || sw == RETURN)
    {
        fp1 = fopen(workfile[1], "w+b");
        fp2 = fopen(workfile[2], "w+b");
        fcloseall();
        
        wp = head;
        while (wp != NULL)
        {
            free(wp->data);
            free(wp);
            wp = wp->front;
        }
        
        title_display();
        
        file_read();
        
        page_head = now = head;
        cx = cy = 0;
    }
    CURSOLE(1);
}
/*----------------*/
/* title display */
/*----------------*/
void tile_display(void)
{
    int hxp, hyp;
    
    hxp = xp + width / 2 - 10;
    hyp = yp + len / 2- 2;
    COLOR(CYAN, REVERSE);
    LOCATE(hxp, hyp); printf("  Screen Editor   "); hyp++;
    COLOR(WHITE, REVERSE);
    LOCATE(hxp, hyp); printf(" By Editor maker. "); hyp += 3;
    COLOR(WHITE, BLINK);
    LOCATE(hxp, hyp); printf(" Now reading !!!");
}
/*----------------*/
/* display frame */
/*----------------*/
void waku_display(int x, int y, int len, int width, int color, int zokusei)
{
    int i;
    char space[80];
    
    cURSOLE(0);
    for(i = 0; i < width - 2; i++)
        space[i] = ' ';
    space[i] = '\0';
    
    COLOR(color, zokusei);
    LOCATE(x, y); printf(" -");
    LOCATE(x+width-1, y); printf("-");
    LOCATE(x, y+len-1); printf("-");
    LOCATE(x+width-1, y+len-1); printf("-");
    for(i = x+1; i <= x+width-2; i++)
    {
        LOCATE(i, y); printf("--");
        LOCATE(i, y+len-1); printf("--");
    }
    for (i = y+1; i <= y+len-2; i++)
    {
        LOCATE(x, i);
        printf(" | %s |", space);
    }
    CURSOLe(1);
}
/*----------------*/
/* data lead */
/*----------------*/
void file_read(void)
{
    int c, i, n;
    long rc;
    unsigned char m;
    struct list *backward;
    
    fp1 = fopen(filename, "r");
    fp2 = fopen(workfile[2], "w+b");
    
    if(fp1 != NULL)
    {
        head = NULL;
        rc = 0;
        n = width;
        while((c = getc(fp1)) != EOF)
        {
            m = (unsigned char)c;
            
            if(n == width || iskanji(m) != 0 && n == width -1)
            {
                rc++;
                if(rc <= LEN)
                {
                    new_creat();
                    
                    if(head == NULL)
                    {
                        head = new;
                        new->back = NULL;
                    }
                    else
                    {
                        backward->front = new;
                        new->back = backward;
                    }
                    backward = new;
                    n = 0;
                }
                else
                {
                    if (rc == LEN +1)
                    {
                        new->front = NULL;
                        new_creat();
                    }
                    else
                    {
                        fwirte(new->data, width, 1, fp2);
                        for(i = 0; i < width; i++)
                            *(new->data + i) = '\0';
                    }
                    n = 0;
                }
            }
            
            *(new->data + n++) = m;
            if (iskanji(m) != 0)
            {
                c = getc(fpl);
                m = (unsigned char)c;
                *(new->data + n++) = m;
            }
            else if (m == '\t')
            {
                while(n % tab != 0 && n < width)
                    n++;
            }
            else if(m == '\n')
                n = width;
        }
        new->front = NULL;
        
        if (rc > LEN && n > 0)
        {
            fwrite(new->data, width, 1, fp2);
            free(new->data);
            free(new);
        }
        
        if (head == NULL)
            new_file_make();
    }
    else
        new_file_make();
    
    fcloseall();
}
/*----------------*/
/* make a new file */
/*----------------*/
void new_file_make(void)
{
    new_creat();
    *(new->data) = '\n';
    head = new;
}
/*----------------*/
/* hold new area */
/*----------------*/
void new_creat(void)
{
    int i;
    
    new = (struct list *)malloc(sizeof(struct list));
    new->data = malloc(width);
    
    for(i = 0; i < width; i++)
        *(new->data + i) = '\0';
    new->back = new->front = NULL;
}
/*----------------*/
/* edit */
/*----------------*/
void hensyu(void)
{
    int ins_flag, edit_flag;
    int c, i, hcx, mlen, left_key;
    unsigned char m;
    struct list *backward;
    
    CURSOLE(1);
    page_head = now = head;
    cx = cy = 0;
    ins_flag = edit_flag = 1;
    
    do{
        hcx = cx;
        
        LOCATE(xp + cx, yp + cy);
        
        while ()
    }
}
/*----------------*/
/* search */
/*----------------*/
void search_process(void)
{
    int c, i, k, flag;
    char string[80], buffer[160];
    struct list *backward, *forward;
    
    COLOR(WHITE, REVERSE);
    LOCATE(xp, yp); printf(" -> ");
    
    if ((c = input(string, xp + 4, yp, width -3)) != ESC)
    {
        k = strlen(string);
        cy = 0;
        do {
            if ( c == RETURN || c == DOWN)
            {
                do {
                    forward_page_check();
                    
                    for (i = 0; i < width; i++)
                        buffer[i] = *(now->data + i);
                    if (now->front != NULL)
                        for(i = 0; i < k -1; i++)
                            buffer[i + width] = *((now->front)->data + i);
                    else
                        for (i = 0; i < k - 1; i++)
                            buffer[i + width] = '\0';
                    
                    flag = 0;
                    for(i = cx; i < width && flag == 0; i++)
                        if (strncmp(buffer + i, string, k) == 0)
                        {
                            cx = i;
                            flag = 1;
                        }
                    if (flag == 0)
                    {
                        page_head = backward = now;
                        now = now->front;
                        cx = 0;
                    }
                } while (flag == 0 && now != NULL);
                if (flag == 0)
                    now = backward;
            }
            else if ( c == UP)
            {
                do {
                    backward_page_check();
                    
                    for (i = 0; i < width; i++)
                        buffer[i] = *(now->data + i);
                    if(now->front != NULL)
                        for(i = 0; i < k - 1; i++)
                            buffer[i + width] = *((now->front)->data +i);
                    else
                        for (i = 0; i < k - 1; i++)
                            buffer[i + width] = '\0';
                    flag = 0;
                    for(i = cx; i >= 0 && flag == 0; i--)
                        if(strncmp(buffer + i, string, k) == 0)
                        {
                            cx = i;
                            flag = 1;
                        }
                    if(flag == 0)
                    {
                        page_head = forward = now;
                        now = now->back;
                        cx = width - 1;
                    }
                } while (flag == 0 && now != NULL);
                if (flag == 0)
                    now = forward;
            }
            page_head = now;
            hyouji(page_head, 0, COLOR_ON);
            
            if (flag == 1)
            {
                if (cx + k <= width)
                    vram_color_set(0xc5, xp + cx, yp, k);
                else
                {
                    vram_color_set(0xc5, xp + cx, yp, width - cx);
                    vram_color_set(0xc5, xp, yp + 1, k - (width - cx));
                }
            }
            else
                cx = 0;
            LOCATE(xp + cx, yp + cy);
            c = getch();
            
            if (c == RETURN || c == DOWN)
            {
                cx = cx + k;
                if (cx >= width && now->front != NULL)
                {
                    now = now->front;
                    cx = 0;
                }
            }
            else if(c == UP)
            {
                cx--;
                if (cx < 0 && now->back != NULL)
                {
                    now = now->back;
                    cx = width - 1;
                }
            }
        } while (c  != ESC);
    }
}
/*----------------*/
/* search */
/*----------------*/
void hyouji(struct list *p, int s, int sw)
{
    static char space[80];
    int n;
    
    for(n = s; n < len; n++)
    {
        if (p != NULL)
        {
            vram_text_disp(p->data, xp, yp+n, width, sw);
            p = p->front;
        }
        else
            vram_text_disp(space, xp, yp+n, width, sw);
    }
}
/*----------------*/
/* VRAM text display */
/*----------------*/
void vram_text_disp(unsigned char *p, int x, int y, int len, int color_sw)
{
    unsigned short w;
    char far *vram_t = (char far *)0xa0000000L;
    char far *vram_a = (char far *)0xa2000000L;
    int n = 0;
    
    vram_t += x * 2 + y * 160;
    vram_a += x * 2 + y * 160;
    while (n < len)
    {
        if (*p != '\0')
        {
            if (iskanji(*p) && iskanji2(*(p+1)))
            {
                w = (*p << 8) + *(p + 1);
                w = jmstojis(w);
                w -= 0x2000;
                
                *vram_t++ = (char)(w >> 8);
                *vram_t++ = (char)(w & 0x00ff);
                if (color_sw == 1)
                {
                    *vram_a++ = color;
                    vram_a++
                }
                
                *vram_t++ = (char)((w >> 8) + 0x80);
                *vram_t++ = (char)(w & 0x00ff);
                if (color_sw == 1)
                {
                    *vram_a++ = color;
                    vram_a++;
                }
                p += 2;
                n += 2;
            }
            else
            {
                if (*p == '\t')
                {
                    *vram_t++ = ' ';
                    if (color_sw == 1)
                    {
                        *vram_a++ = color;
                        vram_a++;
                    }
                    p++;
                }
                else if (*p == '\n')
                {
                    *vram_t++ = 0x1f;
                    if (color_sw == 1)
                    {
                        if (color != 0xc1)
                            *vram_a++ = 0xc1;
                        else
                            *vram_a++ = 0xe1;
                        vram_a++;
                    }
                    p++;
                }
                else
                {
                    *vram_t++ = *p++;
                    if (color_sw == 1)
                    {
                        *vram_a++ = color;
                        vram_a++
                    }
                }
                *vram_t++ = 0;
                n++;
            }
        }
        else
        {
            *vram_t++ = ' ';
            *vram_t++ = 0;
            if (color_sw == 1)
            {
                *vram_a++ = color;
                vram_a++;
            }
            *p++;
            n++;
        }
    }
}
void vram_color_set(unsigned char color_value, int x, int y, int len)
{
    char far *vram = (char far *)0xa200000L;
    int c = 0;
}