| home | contents | previous | next page | send comment | send link | add bookmark |

IDE_MENU.CPP

menu functions

/*-------------------------------------------------------------------*
     Menu processor

     File:     ide_menu.cpp

     Module:   editor

     by:  Stephen R. Schmitt
 *-------------------------------------------------------------------*/

#include "ide_data.h"

/*-------------------------------------------------------------------*
    Data Section
 *-------------------------------------------------------------------*/

/*
 *   external declarations
 */
       /* in ide_main.c */
extern line *First_line, *Last_line, *Text_line;
extern struct edit Select_begin, Select_end;
extern bool Select_text;
extern bool Insert;
extern bool Run_editor;
extern int Text_line_num;
extern int Lin;
extern int Col;
extern int Top;
extern int Bottom;
extern int Right;
extern int Left;
extern int Tab_size;
extern int Msg_lin;
extern int Msg_col;
extern int Last_line_num;
extern bool Insert;
extern char *Screen_buffer;
extern char *Dos_screen;
extern int Dos_lin, Dos_col;

/*
 *   global declarations
 */
FILE *Program;                                      // edit file
char File_name[FILE_NAME_LENGTH];                   // edit file name
bool File_changed;                                  // edit file status
char Find_string[MAX_STRING_LENGTH];                // pattern to find

/*-------------------------------------------------------------------*
    Code Section
 *-------------------------------------------------------------------*/

/*
 *   "single_box_window" creates a window with a single box frame
 *
 *   returns:  nothing
 */
void single_box_window(int left,                    // left position
                       int top,                     // top position
                       int right,                   // right position
                       int bottom,                  // bottom position
                       int background,              // color number
                       int foreground)              // color number
{
    register int i;

    window(left, top, right, bottom);
    textattr(background*16 + foreground);
    clrscr();

    gotoxy(2, 1);
    putch(218);                                     // left, top corner
    for (i = 3; i < right - left; i++)
        putch(196);                                 // horizontal
    putch(191);                                     // right, top corner

    for (i = 2; i < bottom - top + 1; i++)
    {
        gotoxy(2, i);
        putch(179);                                 // left vertical
        gotoxy(right - left, i);
        putch(179);                                 // right vertical
    }

    gotoxy(2, bottom - top + 1);
    putch(192);                                     // left, bottom corner
    for (i = 3; i < right - left; i++)
        putch(196);                                 // horizontal
    putch(217);                                     // right, bottom corner
}

/*
 *   "double_box_window" create window with a double box frame
 *
 *   returns:  nothing
 */
void double_box_window(int left,                    // left position
                       int top,                     // top position
                       int right,                   // right position
                       int bottom,                  // bottom position
                       int background,              // color number
                       int foreground)              // color number
{
    register int i;

    window(left, top, right, bottom);
    textattr(background*16 + foreground);
    clrscr();

    gotoxy(2, 1);
    putch(201);                                     // left, top corner
    for (i = 3; i < right - left; i++)
        putch(205);                                 // horizontal
    putch(187);                                     // right, top corner

    for (i = 2; i < bottom - top + 1; i++)
    {
        gotoxy(2, i);
        putch(186);                                 // left vertical
        gotoxy(right - left, i);
        putch(186);                                 // right vertical
    }

    gotoxy(2, bottom - top + 1);
    putch(200);                                     // left, bottom corner
    for (i = 3; i < right - left; i++)
        putch(205);                                 // horizontal
    putch(188);                                     // right, bottom corner
}

/*
 *   "menu_init" puts menu items in a window
 *
 *   returns:  the current item number
 */
int menu_init(int items,                            // number of choices
              char *choice[])                       // list of choices
{
    int i;

    // write menu
    for (i = 0; i < items; i++)
    {
        gotoxy(4, i + 3);
        cprintf("%s", choice[i]);
    }

    // initialize
    i = 0;
    textcolor(WHITE);
    gotoxy(4, i + 3);
    cprintf("%s", choice[i]);

    return i;
}

/*
 *   "menu_item" selects the next menu choice
 *
 *   returns:  the new item number
 */
int menu_item(char key,                             // key input
              int i,                                // current item
              int items,                            // number of choices
              char *choice[])                       // list of choices
{
    switch (key)
    {
    case 72: /* up arrow */
        textcolor(BLACK);                           // reset current choice
        gotoxy(4, i + 3);
        cprintf("%s", choice[i]);
        i--;                                        // set new choice
        if (i < 0)                                  // at top?
            i = items - 1;                          // last item number
        textcolor(WHITE);
        gotoxy(4, i + 3);
        cprintf("%s", choice[i]);
        break;

    case 80: /* down arrow */
        textcolor(BLACK);                           // reset current choice
        gotoxy(4, i + 3);
        cprintf("%s", choice[i]);
        i++;                                        // set new choice
        if (i > (items - 1))                        // at bottom?
            i = 0;                                  // first item number
        textcolor(WHITE);
        gotoxy(4, i + 3);
        cprintf("%s", choice[i]);
        break;

    default:
        break;
    }

    return i;
}

/*
 *   "string_input" creates a window for for string entry and
 *   gets a string
 *
 *   returns:  true on Enter key, or false on Esc key
 */
bool string_input(int col, int lin,                 // window origin
                  int length,                       // length of string
                  char *string)                     // the string to get
{
    int i;
    scancode key;
    bool valid = false;

    // open string edit window
    textattr(BLACK*16 + WHITE);
    gotoxy(col, lin);
    for (i = 0; i < length; i++)
        putch(' ');

    memset(string, '\0', length);                   // init string

    // enter file name from keyboard
    i = 0;
    gotoxy(col + i + 1, lin);
    do
    {
        key.ch = get_key();

        if (key.c[0] == 13) /* Enter key */
        {
            valid = true;
            break;
        }
        else if (key.c[0] == 8 && i > 0) /* Backspace key */
        {
            i--;
            string[i] = NULL;
            gotoxy(col + i + 1, lin);
            putch(' ');
            gotoxy(col + i + 1, lin);
        }
        else if (isprint(key.c[0]))
        {
            // add new character to string
            string[i] = key.c[0];
            putch(key.c[0]);
            i++;
        }
    }
    while (key.c[0] != 27); /* Esc key */

    return valid;
}

/*
 *   "restore_edit_window"  restores original editing window saved
 *   in Screen_buffer on call to pull down menu function
 *
 *   returns:  nothing
 */
void restore_edit_window()
{
    window(1, 1, 80, 25);
    textattr(BLACK*16 + WHITE);
    clrscr();

    if (Insert == true)
        _setcursortype(_NORMALCURSOR);
    else
        _setcursortype(_SOLIDCURSOR);

    puttext(1, 1, 80, 25, Screen_buffer);
    gotoxy(Col, Lin);
}

/*
 *   "error_message" displays an error message
 *
 *   returns:  nothing
 */
void error_message(char *msg)
{
    int length = strlen(msg);
    assert(length <= 28);                           // display space
    int c = (28 - length)/2;                        // for centering

    // create a message window
    double_box_window(24, 20, 57, 22, RED, WHITE);
    gotoxy(4, 2);
    while (c > 0)
    {
        putch(' ');
        c--;
    }
    cputs(msg);
}

/*-------------------------------------------------------------------*
    File processes
 *-------------------------------------------------------------------*/

/*
 *   "files" selects an option for file handling
 *
 *   returns:  nothing
 */
void files()
{
    union scancode key;
    int items = 6;
    char *choice[] = {" Load     ",
                      " New      ",
                      " Save     ",
                      " Write to ",
                      " OS shell ",
                      " Quit     "};

    gettext(1, 1, 80, 25, Screen_buffer);

    // create window with height of 4 + number of choices
    _setcursortype(_NOCURSOR);
    single_box_window(30, 5, 46, 14, LIGHTGRAY, BLACK);
    gotoxy(6, 1);
    cputs(" files ");

    int i = menu_init(items, choice);

    do // process keys
    {
        key.ch = get_key();
        if (key.c[0] == 0)  /* Function key */
        {
            i = menu_item(key.c[1], i, items, choice);
        }
        else if (key.c[0] == 13)  /* Enter key */
        {
            bool ok = true;
            switch (i)
            {
            case 0:
                if (File_changed == true)
                    ok = file_warning();
                if (ok)
                {
                    file_load();
                    File_changed = false;
                }
                break;

            case 1:
                if (File_changed == true)
                    ok = file_warning();
                if (ok)
                {
                    file_new();
                    File_changed = false;
                }
                break;

            case 2:
                file_save();
                File_changed = false;
                break;

            case 3:
                file_write();
                File_changed = true;
                break;

            case 4:
                file_shell();
                break;

            case 5:
                if (File_changed == true)
                    ok = file_warning();
                if (ok)
                    Run_editor = false;
                break;

            default:
                assert(0);
                break;
            }
            if (ok)
                goto files_exit;
            else
                goto files_restore;
        }
    }
    while (key.c[0] != 27); /* Esc key */

files_restore:
    restore_edit_window();

files_exit:
    return;
}

/*
 *   "sortstr" selects a value based on result of string comparison
 *
 *   returns:  result of comparison
 */
int sortstr(const void *a,                          // ptr to first string
            const void *b)                          // ptr to second string
{
    return strcmp((char *) a, (char *) b);
}

/*
 *   "file_load" selects a file from disk storage to load
 *
 *   returns:  nothing
 */
void file_load()
{
    struct ffblk file;                              // file access data
    char findfile[FILE_NAME_LENGTH];                // buffer for filenames
    char filelist[80][16];                          // list of files
    int col, lin;

    // create a window
    double_box_window(1, 2, 80, 25, LIGHTGRAY, BLACK);
    gotoxy(26, 1);
    cputs(" enter name of file to load: ");

    // find and print list of files in current directory
    textcolor(BLACK);
    int done = findfirst("*.t", &file, 0);
    if (!done)
    {
        int j = 0;
        for (col = 0; col < 5; col++)
        {
            for (lin = 0; lin < 16; lin++)
            {
                strcpy(filelist[j], file.ff_name);
                j++;
                done = findnext(&file);
                if (done)
                    break;
            }
            if (done)
                break;
        }
        qsort((void *)filelist, j, sizeof(filelist[0]), sortstr);
        int i = 0;
        for (col = 0; col < 5; col++)
        {
            for (lin = 0; lin < 16; lin++)
            {
                gotoxy(14*col + 6, lin + 6);
                cprintf("%s", filelist[i]);
                i++;
                if (i == j)
                    break;
            }
            if (i == j)
                break;
        }
    }

    // get file name and load
    _setcursortype(_NORMALCURSOR);
    bool ok = string_input(8, 3, FILE_NAME_LENGTH, findfile);
    while (ok)
    {
        Program = fopen(findfile, "r+");
        if (Program == NULL)
        {
            gotoxy(8, 4);
            textattr(LIGHTGRAY*16 + RED);
            cputs("Cannot Find This File, Re-enter!");
            get_key();
            gotoxy(8, 4);
            cputs("                                ");
            ok = string_input(8, 3, FILE_NAME_LENGTH, findfile);
        }
        else                                        // load it
        {
            file_new();
            strcpy(File_name, findfile);
            file_load_process();                    // new edit window
            goto file_load_exit;
        }
    }

    restore_edit_window();                          // to original

file_load_exit:
    return;
}

/*
 *   "file_load_process" loads a file from disk storage
 *
 *   returns:  nothing
 */
void file_load_process()
{
    int i = 0;                                      // first char number
    Last_line_num = 1;
    char ch = fgetc(Program);                       // get first character

    while (ch != EOF)
    {
        if ((ch == '\n') || (i > MAX_LINE_LENGTH - 1))
        {
            // null terminate current line and add a
            // new line of text after current text line
            Text_line->string[i] = NULL;
            i = 0;                                  // reset char number

            ch = fgetc(Program);                    // check for end of file
            if (ch != EOF)
            {
                ungetc(ch, Program);                // put back character

                line *new_line = new line;          // allocate a new line

                if (new_line == NULL)
                {
                    error_message("System is out of memory!");
                    get_key();
                    fclose(Program);
                    file_new();
                    goto file_load_process_exit;
                }
                else
                {
                    Text_line->next = new_line;
                    new_line->prev = Text_line;
                    new_line->next = Last_line;
                    Last_line->prev = new_line;

                    Text_line = new_line;
                    memset(Text_line->string, '\0', MAX_LINE_LENGTH);

                    Last_line_num++;
                }
            }
        }
        else                                        // update current line
        {
            // replace tabs with standard DOS tab of 8 spaces
            if (ch == '\t')
            {
                for (int j = 0; j < 8; j++)
                {
                    Text_line->string[i] = ' ';
                    i++;
                }
            }
            else
            {
                Text_line->string[i] = ch;
                i++;
            }
        }

        ch = fgetc(Program);                        // get next character
    }
    fclose(Program);

    // write file on the screen
    first_text_line();
    write_screen(Text_line, Text_line_num);

    // set editing parameters
    first_text_line();
    Insert = true;
    Lin = Top;
    Col = Left;
    gotoxy(Col, Lin);

file_load_process_exit:
    return;
}

/*
 *   "file_new" deletes current file and initializes text editing
 *   screen
 *
 *   returns:  nothing
 */
void file_new()
{
    // remove existing file if any
    strcpy(File_name, "UN_NAMED.T");                // clears old name

    if (First_line != NULL)
    {
        line *this_line = First_line;

        while ((this_line != Last_line)&&           // do not free last line
               (this_line != NULL     ))            // do not free null ptr
        {
            line *next_line = this_line->next;

            if (this_line == First_line)            // just delete string
                memset(this_line->string, '\0', MAX_LINE_LENGTH);
            else                                    // free text line
            {
                assert(this_line != NULL);
                delete this_line;
            }

            this_line = next_line;
        }
    }

    // initialize text line data structure
    if (First_line == NULL)
    {
        First_line = new line;
        memset(First_line->string, '\0', MAX_LINE_LENGTH);
    }
    if (Last_line == NULL)
    {
        Last_line = new line;
        memset(Last_line->string, '\0', MAX_LINE_LENGTH);
    }

    // initialize linked list pointers
    First_line->prev = NULL;
    First_line->next = Last_line;
    Last_line->prev = First_line;
    Last_line->next = NULL;

    // set editing parameters
    first_text_line();
    Last_line_num = 1;
    Insert = true;
    Lin = Top;
    Col = Left;
    Select_begin.line_ptr = NULL;
    Select_begin.line_num = 0;
    Select_begin.char_num = 0;
    Select_end.line_ptr = NULL;
    Select_end.line_num = 0;
    Select_end.char_num = 0;
    Select_text = false;

    // open text window
    window(1, 1, 80, 25);
    textattr(BLACK*16 + WHITE);
    clrscr();
    _setcursortype(_NORMALCURSOR);
    Insert = true;
}

/*
 *   "file_save" opens a file and saves the current edit text
 *
 *   returns:  nothing
 */
void file_save()
{
    char command[FILE_NAME_LENGTH * 2 + 8];
    char backup_file[FILE_NAME_LENGTH];
    struct ffblk file;

    // if an old file exists, convert it into a backup file
    int found = findfirst(File_name, &file, 0);
    if (found == 0)
    {
        strcpy(backup_file, File_name);
        char *str_ptr = strchr(backup_file, '.');
        strcpy(str_ptr, ".BAK");
        strcpy(command, "copy ");
        strcat(command, File_name);
        strcat(command, " ");
        strcat(command, backup_file);
        system(command);
    }

    restore_edit_window();

    // open the file
    Program = fopen(File_name, "wt+");
    if (Program == NULL)
    {
        textcolor(YELLOW);
        gotoxy(Msg_col, Msg_lin);
        cputs("FAILURE! ");
    }
    else                                            // save the text
    {
        textcolor(YELLOW);
        gotoxy(Msg_col, Msg_lin);
        cputs("saving... ");

        line *save = First_line;
        while (save != Last_line)
        {
            int i = 0;
            while (save->string[i] != NULL)
            {
                putc(save->string[i], Program);
                i++;
            }
            putc('\n', Program);
            save = save->next;
        }
        fclose(Program);
    }
    delay(1000);
    textcolor(LIGHTGRAY);
    gotoxy(Msg_col, Msg_lin);
    cputs("F10 Help  ");
}

/*
 *   "file_write" changes name of current file in editing buffer
 *
 *   returns:  nothing
 */
void file_write()
{
    char file[FILE_NAME_LENGTH];                    // buffer for filenames

    // create a window
    double_box_window(1, 2, 80, 6, LIGHTGRAY, BLACK);
    gotoxy(22, 1);
    cputs(" enter new file name to write to: ");

    // get new file name
    _setcursortype(_NORMALCURSOR);
    bool ok = string_input(8, 3, FILE_NAME_LENGTH, file);
    if (ok)
        strcpy(File_name, file);

    restore_edit_window();
    return;
}

/*
 *   "file_shell" transfers control to the operating system
 *
 *   returns:  nothing
 */
void file_shell()
{
    char str[] = "use EXIT command to return to the Editor .. \n";

    _setcursortype(_NORMALCURSOR);
    window(1, 1, 80, 25);
    puttext(1, 1, 80, 25, Dos_screen);
    gotoxy(Dos_col, Dos_lin);

    puts(str);
    system("command");

    Dos_col = wherex();                             // user screen data
    Dos_lin = wherey();
    gettext(1, 1, 80, 25, Dos_screen);

    restore_edit_window();                          // to original
}

/*
 *   "file_warning" alerts the user that the edit file was changed.
 *   If either the 'y' key or the 'Y' key is pressed, the edit file
 *   is saved.
 *
 *   returns:  nothing
 */
bool file_warning()
{
    union scancode key;                             // keyboard input
    bool ok;

    error_message("Save current file(y|n)?");

    while (1)
    {
        key.ch = get_key();

        if ((key.c[0] == 'y') || (key.c[0] == 'Y'))
        {
            file_save();
            ok = true;
            break;
        }
        else if ((key.c[0] == 'n') || (key.c[0] == 'N'))
        {
            ok = true;
            break;
        }
        else if (key.c[0] == 27) /* Esc */
        {
            ok = false;
            break;
        }
    }
    return ok;
}

/*-------------------------------------------------------------------*
    Production processes
 *-------------------------------------------------------------------*/

/*
 *   "production" selects an option for production of programs
 *
 *   returns:  nothing
 */
void production()
{
    union scancode key;
    int items = 4;
    char *choice[] = {" Search   ",
                      " Errors   ",
                      " Debugger ",
                      " Run      "};

    gettext(1, 1, 80, 25, Screen_buffer);

    // create window
    _setcursortype(_NOCURSOR);
    single_box_window(30, 5, 46, 12, LIGHTGRAY, BLACK);
    gotoxy(4, 1);
    cputs(" function: ");

    int i = menu_init(items, choice);

    do  // process keys
    {
        key.ch = get_key();
        if (key.c[0] == 0)  /* Function key */
        {
            i = menu_item(key.c[1], i, items, choice);
        }
        else if (key.c[0] == 13)  /* Enter key */
        {
            switch (i)
            {
            case 0:
                find();
                break;

            case 1:
                show_error();
                break;

            case 2:
                run(1);
                break;

            case 3:
                run(0);
                break;

            default:
                assert(0);
                break;
            }
            goto production_exit;
        }
    }
    while (key.c[0] != 27);  /* Esc key */

    restore_edit_window();

production_exit:
    return;
}

/*
 *   "run" saves the source file and calls interpreter
 *
 *   returns:  nothing
 */
void run(int option)                                // 0 = run, 1 = debug
{
    int result = -1;
    char file[FILE_NAME_LENGTH];

    strcpy(file, File_name);
    file_save();                                    // save "File_name"
    file_new();
    File_changed = false;

    _setcursortype(_NORMALCURSOR);
    window(1, 1, 80, 25);
    puttext(1, 1, 80, 25, Dos_screen);              // restore dos screen
    gotoxy(Dos_col, Dos_lin);

    if (option == 0)
        result = spawnlp(P_WAIT, "ti.exe", "ti.exe", file, NULL);
    else if (option == 1)
        result = spawnlp(P_WAIT, "ti.exe", "ti.exe", file, "debug", NULL);

    Dos_col = wherex();                             // user screen data
    Dos_lin = wherey();
    gettext(1, 1, 80, 25, Dos_screen);

    // create a message window
    strcpy(File_name, file);
    Program = fopen(file, "r+");
    file_load_process();                            // new edit window
    cursor_position();
    gettext(1, 1, 80, 25, Screen_buffer);

    _setcursortype(_NOCURSOR);
    if (result == -1)                               // failure!
        error_message("Interpreter failure");
    else if (result > 0)                            // compile errors!
    {
        double_box_window(24, 20, 57, 22, RED, WHITE);
        gotoxy(4, 2);
        cprintf("     Total Errors = %2d    ", result);
    }
    else                                            // success!
    {
        double_box_window(24, 20, 57, 22, GREEN, WHITE);
        gotoxy(4, 2);
        cputs("         Success!         ");
    }

    get_key();                                      // wait for keypress
    restore_edit_window();
}

/*
 *   "show_error" highlights each line in the source which contains
 *   an error and displays an error message.
 *
 *   returns:  nothing
 */
void show_error()
{
    char *flag, temp[80];
    char err_msg_file[FILE_NAME_LENGTH];
    struct message syntax[MAX_ERRORS];
    int i, error_count, top_line;
    union scancode key;
    bool ok;

    restore_edit_window();
    error_count = 0;

    // convert source file name into error message file name
    // then open error file with this name
    strcpy(err_msg_file, File_name);
    char *str_ptr = strchr(err_msg_file, '.');
    strcpy(str_ptr, ".ERR");

    FILE *error_file = fopen(err_msg_file, "r");
    if (error_file != NULL)
    {
        // transfer error messages from file
        // note: format must agree with "compile_error" format
        //       in interpreter program
        for (i = 0; i < MAX_ERRORS; i++)
        {
            flag = fgets(temp, 80, error_file);
            if (flag == NULL)
                break;                              // at end of file

            str_ptr = strtok(temp, " ");
            strcpy(syntax[i].fil, temp);

            str_ptr = strtok(NULL, " ");
            error_count = atoi(str_ptr);

            str_ptr = strtok(NULL, " ");
            syntax[i].lin = atoi(str_ptr);

            str_ptr = strtok(NULL, " ");
            syntax[i].col = atoi(str_ptr);

            str_ptr = strtok(NULL, "\n");
            strcpy(syntax[i].msg, str_ptr);
        }

        fclose(error_file);
    }

    if (error_count == 0)
    {
        gettext(1, 1, 80, 25, Screen_buffer);

        gotoxy(1, 25);
        clreol();
        _setcursortype(_NOCURSOR);
        textattr(GREEN*16 + WHITE);
        clreol();
        cputs("  No Errors!");

        get_key();
        restore_edit_window();
    }
    else                                            // display error messages
    {
        for (i = 0; i < error_count; i++)
        {
            // get source file
            if (strcmp(File_name, syntax[i].fil))
            {
                if (File_changed == true)
                    ok = file_warning();
                if (ok)
                {
                    file_new();
                    strcpy(File_name, syntax[i].fil);
                    Program = fopen(File_name, "r+");
                    file_load_process();
                    File_changed = false;
                }
                else
                    goto show_error_exit;
            }

            // set text line to top of screen, nine lines above error
            top_line = syntax[i].lin - 9;
            if (top_line <= 1)
                first_text_line();
            else
            {
                 if (top_line < Text_line_num)
                 {
                    while (top_line != Text_line_num)
                        decr_text_line();
                 }
                 else
                 {
                    while (top_line != Text_line_num)
                        incr_text_line();
                 }
            }

            // re-write the text screen and
            // set editor to error line and column
            write_screen(Text_line, Text_line_num);
            gettext(1, 1, 80, 25, Screen_buffer);

            Col = syntax[i].col;
            Lin = Top;
            while (syntax[i].lin != Text_line_num)
            {
                incr_text_line();
                Lin++;
            }

            // display message and point to error
            cursor_position();
            gotoxy(1, 25);
            textattr(GREEN*16 + WHITE);
            clreol();
            cprintf(" error %d: %s", i + 1, syntax[i].msg);

            gotoxy(1, Lin);
            textattr(LIGHTGRAY*16 + BLACK);
            clreol();
            write_line(Text_line, Text_line_num, Lin);
            textattr(BLACK*16 + WHITE);
            cursor_position();

            key.ch = get_key();
            if (key.c[0] == 27) /* Esc key */
                break;
        }

        // restore screen without shift from last error display
show_error_exit:
        restore_edit_window();
    }
}

/*
 *   "find" locates a string in the editing buffer
 *
 *   returns:  nothing
 */
void find()
{
    char string[MAX_STRING_LENGTH];                 // buffer for filenames

    // create a window
    double_box_window(1, 2, 80, 6, LIGHTGRAY, BLACK);
    gotoxy(28, 1);
    cputs(" enter string to find: ");

    // get string to find
    _setcursortype(_NORMALCURSOR);
    bool ok = string_input(8, 3, MAX_STRING_LENGTH, string);
    if (ok)
    {
        restore_edit_window();                      // to original

        // find the string
        strcpy(Find_string, string);
        search();
    }
    else
        restore_edit_window();                      // to original

    return;
}

/*
 *  "search" locates a string in the edit file and points to it
 *  with the cursor; or displays a "not found" message.
 *
 *  returns:  nothing
 */
void search()
{
    int i, j;
    bool found = false;

    int text_col = Col - 1;
    line *text = Text_line;
    int text_num = Text_line_num;

    int find_len = strlen(Find_string);
    if (find_len == 0)
        goto search_exit;

    while (text != NULL)
    {
        int text_len = strlen(text->string);

        for (i = text_col, j = 0; i < text_len && j < find_len; i++, j++)
        {
            if (text->string[i] != Find_string[j])
            {
                i -= j;
                j = -1;
            }
        }

        if (j == find_len)
        {
            found = true;
            text_col = i;
            break;
        }
        else
        {
            text = text->next;
            text_num++;
            text_col = 0;
        }
    }

    if (found)
    {
        int top = text_num - 9;
        if (top <= 1)
            first_text_line();
        else
        {
            if (top < Text_line_num)
            {
                while (top != Text_line_num)
                    decr_text_line();
            }
            else
            {
                while (top != Text_line_num)
                    incr_text_line();
            }
        }

        write_screen(Text_line, Text_line_num);

        Col = text_col;
        Lin = Top;
        while (text_num != Text_line_num)
        {
            incr_text_line();
            Lin++;
        }
        cursor_position();
    }
    else
    {
        gettext(1, 1, 80, 25, Screen_buffer);

        gotoxy(1, 25);
        textattr(GREEN*16 + WHITE);
        _setcursortype(_NOCURSOR);
        clreol();
        cprintf("  String not found");

        get_key();
        restore_edit_window();
    }

search_exit:
    return;
}

/*-------------------------------------------------------------------*
    Help processes
 *-------------------------------------------------------------------*/

/*
 *   "help" selects a help information window
 *
 *   returns:  nothing
 */
void help()
{
    union scancode key;
    int items = 5;
    char *choice[] = {" Language ",
                      " Keyboard ",
                      " Ctrl + K ",
                      " Fx keys  ",
                      " About    "};

    gettext(1, 1, 80, 25, Screen_buffer);

    // create window
    _setcursortype(_NOCURSOR);
    single_box_window(30, 5, 46, 13, LIGHTGRAY, BLACK);
    gotoxy(6, 1);
    cputs(" help ");

    int i = menu_init(items, choice);

    do                                              // process keys
    {
        key.ch = get_key();
        if (key.c[0] == 0) /* Function key */
        {
            i = menu_item(key.c[1], i, items, choice);
        }
        else if (key.c[0] == 13)  /* Enter key */
        {
            switch (i)
            {
            case 0:
                language();
                break;

            case 1:
                keyboard();
                break;

            case 2:
                control_keys();
                break;

            case 3:
                function_keys();
                break;

            case 4:
                about();
                break;

            default:
                assert(0);
                break;
            }
            goto help_exit;
        }
    }
    while (key.c[0] != 27);  /* Esc key */

    restore_edit_window();

help_exit:
    return;
}

/*
 *   "keyboard" shows the available keyboard commands
 *
 *   returns:  nothing
 */
void keyboard()
{
    char *kbrd_msg[] = {
        "Esc        - return to edit screen from a window",
        "Enter      - breaks current line and starts new line",
        "Backspace  - deletes character to left of cursor",
        "Tab        - inserts spaces up to next tab stop",
        "Shift+Tab  - deletes characters back to last tab stop",
        "Insert     - toggles between insert and overwrite mode",
        "Delete     - deletes character at cursor location",
        "Home       - moves cursor to beginning of line",
        "End        - moves cursor to end of line",
        "arrow keys - move cursor in direction of arrow",
        "Page Up    - moves cursor upward by 20 lines",
        "Page Down  - moves cursor downward by 20 lines" };

    // create window
    double_box_window(11, 5, 70, 20, LIGHTGRAY, BLACK);
    _setcursortype(_NOCURSOR);
    gotoxy(25, 1);
    cputs(" keyboard: ");

    // write text
    for (int i = 0; i < 12; i++)
    {
        gotoxy(4, 3 + i);
        cputs(kbrd_msg[i]);
    }

    // wait for any key then return
    get_key();
    restore_edit_window();
}

/*
 *   "control_keys" shows the available Ctrl+key commands
 *
 *   returns:  nothing
 */
void control_keys()
{
    char *ctrl_msg[] = {
        "Ctrl+Prnt Scrn - prints screen -> SCREEN.TXT",
        "Ctrl+Page Up   - moves cursor to beginning of text",
        "Ctrl+Page Down - moves cursor to end of text",
        "Ctrl+B         - set Beginning of selected text",
        "Ctrl+C         - Copy text -> CLIP.TXT",
        "Ctrl+D         - Delete text",
        "Ctrl+E         - set End of selected text",
        "Ctrl+P         - Paste text <- CLIP.TXT",
        "Ctrl+R         - cleaR selected text markers",
        "Ctrl+T         - cuT out text -> CLIP.TXT",
        "Ctrl+V         - moVe text to cursor location",
        "Ctrl+Y         - Yank current text line"};

    // create window
    double_box_window(11, 5, 69, 20, LIGHTGRAY, BLACK);
    _setcursortype(_NOCURSOR);
    gotoxy(23, 1);
    cputs(" Ctrl+key: ");

    // write text
    for (int i = 0; i < 12; i++)
    {
        gotoxy(4, 3 + i);
        cputs(ctrl_msg[i]);
    }

    // wait for any key then return
    get_key();
    restore_edit_window();
}

/*
 *   "function_keys" shows the available function key commands
 *
 *   returns:  nothing
 */
void function_keys()
{
    char *func_msg[] = {
        "F1      - displays file processing menu",
        "F2      - saves the current program to disk",
        "F3      - displays production function menu",
        "F4      - repeats the last search",
        "F10     - displays the help menu"};

    // create window
    double_box_window(11, 5, 69, 13, LIGHTGRAY, BLACK);
    _setcursortype(_NOCURSOR);
    gotoxy(23, 1);
    cputs(" Fx keys: ");

    // write text
    for (int i = 0; i < 5; i++)
    {
        gotoxy(4, 3 + i);
        cputs(func_msg[i]);
    }

    // wait for any key then return
    get_key();
    restore_edit_window();
}

/*
 *   "language" shows T language elements
 *
 *   returns:  nothing
 */
void language()
{
    int result;

    result = spawnlp(P_WAIT, "th.exe", "th.exe", "nosave", NULL);

    if (result == -1)                               // failure!
    {
        error_message("TH.EXE missing!");
        get_key();                                  // wait for keypress
    }

    restore_edit_window();
}

/*
 *   "about" displays an information window
 *
 *   returns:  nothing
 */
void about()
{
    char *func_msg[] = {
        "T Interpreter, ver 1.1",
        "",
        "Created by:",
        "",
        "  Stephen R. Schmitt"};

    // create window
    double_box_window(26, 5, 54, 17, LIGHTGRAY, BLACK);
    _setcursortype(_NOCURSOR);
    gotoxy(12, 1);
    cputs(" About ");

    // write text
    for (int i = 0; i < 6; i++)
    {
        gotoxy(4, 3 + i);
        cputs(func_msg[i]);
    }

    // wait for any key then return
    get_key();
    restore_edit_window();
}

| home | contents | previous | next page | send comment | send link | add bookmark |

Copyright © 2004, Stephen R. Schmitt