home *** CD-ROM | disk | FTP | other *** search
- /*
- ** ed.c
- **
- ** Ed, Version 1.51, Copyright (c) 1992-94 SoftCircuits
- ** Redistributed by permission.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <pictor.h>
- #include "ed.h"
-
- char hlp_file[] = "ED.HLP";
- static int mainloop = TRUE;
-
- /*
- ** displays an out-of-memory error message
- ** since messagebox creates a window using static memory,
- ** there is no danger that messagebox will fail due to lack of memery
- */
- void outofmemory(void)
- {
- messagebox("Out of memory","Error",MB_OK,&msgcolors);
-
- } /* outofmemory */
-
- /*
- ** expands the given line to accommodate the specified
- ** number of characters at the specified column
- */
- int expand_line(LINE **line,int col,int count)
- {
- LINE *new;
-
- /* resize buffer */
- new = realloc(*line,sizeof(LINE) + (*line)->len + count);
-
- if(new == NULL) { /* out of memory */
- outofmemory();
- return(FALSE);
- }
-
- /* shift characters to make room */
- memmove(new->text + col + count,new->text + col,new->len - col);
- new->len += count;
-
- /* if realloc() moved the buffer, update any */
- /* pointers that pointed to the old buffer */
- if(new != *line) {
- if(head == *line) head = new;
- if(tail == *line) tail = new;
- if(top_line == *line) top_line = new;
-
- if(new->prev) new->prev->next = new;
- if(new->next) new->next->prev = new;
-
- *line = new;
- }
-
- return(TRUE);
-
- } /* expand_line */
-
- /*
- ** shrinks the given line at the given column count bytes
- ** there is no return value since this function assumes realloc
- ** will succeed (since we are making the block smaller)
- */
- void shrink_line(LINE **line,int col,int count)
- {
- LINE *new;
-
- /* don't delete more characters than are in the line */
- if(count > (*line)->len)
- count = (*line)->len;
-
- /* shift characters */
- memmove((*line)->text + col,(*line)->text + col + count,
- (*line)->len - (col + count));
-
- /* resize buffer */
- new = realloc(*line,sizeof(LINE) + (*line)->len - count);
- new->len -= count;
-
- /* if realloc() moved the buffer, update any */
- /* pointers that pointed to the old buffer */
- if(new != *line) {
- if(head == *line) head = new;
- if(tail == *line) tail = new;
- if(top_line == *line) top_line = new;
-
- if(new->prev) new->prev->next = new;
- if(new->next) new->next->prev = new;
-
- *line = new;
- }
-
- } /* shrink_line */
-
- /*
- ** splits the current line at the current position
- ** into two separate lines
- */
- void split_line()
- {
- LINE *new;
-
- /* allocate new line */
- new = malloc(sizeof(LINE) + (curr_line->len - line_ndx));
- if(new == NULL) { /* out of memory */
- outofmemory();
- return;
- }
-
- add_to_list(new,curr_line);
-
- /* copy split portion of line to new line */
- new->len = (curr_line->len - line_ndx);
- memmove(new->text,curr_line->text + line_ndx,new->len);
-
- /* resize original line */
- shrink_line(&curr_line,line_ndx,new->len);
-
- /* move to start of new line */
- _down();
- line_ndx = 0;
-
- modified = TRUE;
- update_state = UPDATE_REPAINT;
- update_cursor(TRUE);
-
- } /* split_line */
-
- /*
- ** appends the next line to the current line
- */
- void join_line()
- {
- int i;
-
- /* if there is a next line */
- if(curr_line->next != NULL) {
-
- i = curr_line->len;
-
- /* make room for combined line */
- if(!expand_line(&curr_line,curr_line->len,curr_line->next->len))
- return; /* out of memory */
-
- /* append next line to current line */
- memmove(curr_line->text + i,curr_line->next->text,
- curr_line->next->len);
-
- /* delete next line */
- remove_from_list(curr_line->next);
-
- modified = TRUE;
- update_state = UPDATE_REPAINT;
- update_cursor(TRUE);
- }
-
- } /* join_line */
-
- /*
- ** deletes the current line
- */
- void delete_line()
- {
- /* don't remove last line from list */
- if(curr_line->next == NULL) {
- if(curr_line->len > 0) {
- shrink_line(&curr_line,0,curr_line->len);
- }
- }
- else {
- curr_line = curr_line->next;
- remove_from_list(curr_line->prev);
- }
- line_ndx = 0;
- modified = TRUE;
- update_state = UPDATE_REPAINT;
- update_cursor(TRUE);
-
- } /* delete_line */
-
- /*
- ** deletes the character at the current position
- */
- void delete_char()
- {
- /* if anything at cursor to delete */
- if(line_ndx < curr_line->len) {
- shrink_line(&curr_line,line_ndx,1);
-
- /* show modified line */
- show_line(curr_line,(file_row - top_row) + edit_top);
- modified = TRUE;
- update_cursor(TRUE);
- }
- else join_line(); /* delete line break */
-
- } /* delete_char */
-
- /*
- ** deletes the character left of the current position
- */
- void backspace_char()
- {
- if(line_ndx > 0 || curr_line->prev != NULL) {
- _left();
- delete_char();
- }
- } /* backspace_char */
-
- /*
- ** inserts a character at the current file position
- */
- void insert_char(char c)
- {
- /* expand line if insert mode or at line end */
- if(line_ndx >= curr_line->len || insert_mode) {
- if(!expand_line(&curr_line,line_ndx,1))
- return; /* error */
- }
-
- /* put character into buffer */
- curr_line->text[line_ndx] = c;
-
- /* show modified line */
- show_line(curr_line,(file_row - top_row) + edit_top);
-
- line_ndx++;
- modified = TRUE;
- update_cursor(TRUE);
-
- } /* insert_char */
-
- /*
- ** displays command line syntax and terminates
- ** with errorlevel 1
- */
- void show_usage()
- {
- printf("%s\n\n",copyright);
-
- printf("Usage:\tED <filename> [/b] [/s]\n");
- printf("\t/b Black and white (disables color on color systems)\n");
- printf("\t/s Snow check (write only during video retrace)\n");
-
- exit(1);
-
- } /* show_usage */
-
- /*
- ** causes the main loop to terminate by setting mainloop = FALSE
- */
- void terminate(void)
- {
- helpsetcontext(hlp_exit);
- mainloop = !save_modified();
-
- } /* terminate */
-
- /*
- ** here's main()
- */
- int main(int argc,char *argv[])
- {
- int i,key,blkwht = FALSE,snwchk = FALSE;
- char *fname = NULL;
-
- /* read command line arguments */
- for(i = 1;i < argc;i++) {
- switch(argv[i][0]) {
- case '/':
- case '-':
- switch(tolower(argv[i][1])) {
- case 'b':
- blkwht = TRUE;
- break;
- case 's':
- snwchk = TRUE;
- break;
- default:
- show_usage();
- }
- break;
- default:
- if(fname == NULL)
- fname = strupr(argv[i]);
- else
- show_usage();
- }
- }
- initvideo(); /* initialize library */
- getvconfig(&vcfg);
-
- if(snwchk)
- snowcheckoff();
-
- if(vcfg.colorsupport && !blkwht) {
- edit_color = foreback(BOLD|CYAN,BLUE);
- status_color = foreback(BLACK,CYAN);
- msgcolors.normal = foreback(BLACK,WHITE);
- msgcolors.boldnormal = foreback(BOLD|WHITE,WHITE);
- msgcolors.select = foreback(WHITE,BLACK);
- msgcolors.boldselect = foreback(BOLD|WHITE,BLACK);
- mnucolors.normal = foreback(BLACK,CYAN);
- mnucolors.boldnormal = foreback(BOLD|WHITE,CYAN);
- mnucolors.select = foreback(BOLD|CYAN,BLUE);
- mnucolors.boldselect = foreback(BOLD|WHITE,BLUE);
- _PL_shadowcolor = foreback(BOLD|BLACK,BLACK);
- }
- edit_top = 2; edit_bottom = vcfg.rows - 1;
- edit_left = 1; edit_right = vcfg.columns;
-
- vcolor(edit_color); cls();
- showmenu(mainmenu,&mnucolors,FALSE);
- initstatus(vcfg.rows,status_color);
- hookints(&msgcolors);
- helpopen(hlp_file,&msgcolors,&msgcolors);
- installclock(1,vcfg.columns - 7,mnucolors.normal);
-
- if(fname == NULL)
- new_file(fname);
- else
- load_file(fname);
-
- while(mainloop) {
-
- key = runmenu(mainmenu,&mnucolors,&mnucolors);
-
- switch(key) {
- case 0x00: /* key processed by runmenu() */
- break;
- case LEFT_KEY: /* cursor left */
- cursor_left();
- break;
- case RIGHT_KEY: /* cursor right */
- cursor_right();
- break;
- case HOME_KEY: /* start of line */
- line_ndx = 0;
- update_cursor(TRUE);
- break;
- case END_KEY: /* end of line */
- line_ndx = curr_line->len;
- update_cursor(TRUE);
- break;
- case UP_KEY: /* cursor up */
- cursor_up();
- break;
- case DOWN_KEY: /* cursor down */
- cursor_down();
- break;
- case PGUP_KEY: /* page up */
- page_up();
- break;
- case PGDN_KEY: /* page down */
- page_down();
- break;
- case CTRL_PGUP: /* start of file */
- case CTRL_HOME:
- file_home();
- break;
- case CTRL_PGDN: /* end of file */
- case CTRL_END:
- file_end();
- break;
- case DELETE_KEY: /* delete */
- delete_char();
- break;
- case BACKSPACE_KEY: /* backspace */
- backspace_char();
- break;
- case CTRL_Y: /* delete line */
- delete_line();
- break;
- case ENTER_KEY: /* create new line */
- split_line();
- break;
- case INSERT_KEY: /* toggle insert */
- insert_mode = !(insert_mode);
- show_status();
- break;
- case F1_KEY:
- helprun(hlp_general);
- break;
- case CTRL_F1: /* help index */
- help_index();
- break;
- case F2_KEY: /* save file */
- filesave();
- break;
- case CTRL_F2: /* save file as */
- filesaveas();
- break;
- case F3_KEY:
- repeatsearch(); /* repeat last find */
- break;
- case F4_KEY: /* find */
- search();
- break;
- case F9_KEY: /* print */
- fileprint();
- break;
- case F10_KEY: /* exit */
- terminate();
- break;
- default:
- key &= 0xFF;
- if(isprint(key) || key == '\t')
- insert_char((char)key);
- else
- beep();
- }
- }
- removeclock();
-
- /* restore screen */
- vcolor(foreback(WHITE,BLACK));
- cls();
-
- return(0);
-
- } /* main */
-