/* (c) Marietta Systems, Inc. 1987 * All rights reserved */ #include "mtest.h" /* * * Program to demonstrate use of ascii files * A simple text editor * */ unsigned maxsize = 20000; unsigned maxrecs = 253; void delline(int*, int, int); void editfile(char*, int*, int*); int getfile(char*, char*, int*, int*); void insline(int*, int, int); void linedisp(char*, int*, int, int); void putfile(int, char*, char*, int*, int); void scrndisp(char*, int*, int, int*, int); void show_nbr(int, int); /* * * Function to obtain file and read it in * */ int getfile(fname, text, lineptr, len) char *fname, *text; int *lineptr; int *len;{ long rec_nbr; int z, slen, fh, ret; byte out[20], *ptr; /* setup */ strcpy(fname, "textfile.dat"); top_spot(1); for (z = 0 ; z < 8 ; KEYMATCH[z++] = 0); /* blank out function keys */ disp_err("",1); /* display new function key settings */ for (z = 0, slen = 0 ; z < maxrecs; z++, slen += 79) {lineptr[z] = slen; text[slen] = 0;}/* initialize out line ptr */ /* */ for(;;){ display("Text file to edit - ", 19, 1, low); if (accept(fname, left, alt_reverse, 51, 0) && INCHAR == QUIT) goodbye(0); if ((fh = fileopen(fname, ascii, readonly)) < 0) {disp_err("File name or access error",1); continue;} disp_err(fname, 1); if (!fh) if (!disp_qry("File not found, Create")) continue; else {*len = 0; ptr = fname; for (z = 0 ; z < strlen(fname) && fname[z] != '.' ; z++) if (fname[z] == '\\') ptr = &fname[z+1]; display(ptr, 1, 50, reverse); return 0;} display((byte*)FN[fh].fname, 1, 50, reverse); fileseek(fh, -1L); /* position to end of file */ if (FN[fh].location >= (long)maxsize) {disp_err("File is too big for editor", 1); fileclos(fh); continue;} fileinit(fh, 0, 81, 0L); /* Max record width is set to 80 */ *len = 0; text[0] = 0; if (!fh) return 0; /* new text file */ /* read in the text and set up line pointers */ rec_nbr = 0L; if (fileread(fh, firstrec, &rec_nbr) <= 0) goodbye(10); ptr = text; display ("Loading text file ", 21, 1, high); for (; rec_nbr < (long)maxrecs;){ slen = strlen(FN[fh].record); FN[fh].record[slen-1] = 0; /* replace the '\n' with 0 */ strncpy(ptr, FN[fh].record, 78); ptr = &ptr[79]; if ((ret = fileread(fh, nextrec, &rec_nbr)) < 0) goodbye(11); if (!ret) {*len = (int)rec_nbr - 2; fileclos(fh); return fh;} /* EOF */ if (!(rec_nbr & 0X3F)) /* print rec_nbr every 48 */ {sprintf(out, "%lu", rec_nbr); display(out, 21, 20, reverse);} } disp_err("File contains too many records", (int)rec_nbr); fileclos(fh); continue; } /* end of main for loop */ } /* end of function getedit*/ /* * * Function editfile * */ void editfile(text, lineptr, len) char *text; int *lineptr; int *len;{ int h, top = 0, x = 1, bottom; /* setup */ display("\030 \031 Ctrl+Home Ctrl+End PgUp PgDn", 1, 2, low); if (mk_wndw(TOP_LINE+2, 1, SCRN_LEN - 1, 80, " 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75") < 0) goodbye(20); KEYMATCH[0] = 0XA38; /* PgDn, Crs-up, Crs-rt, Tab, Shift-Tab */ KEYMATCH[1] = 0X10C; /* PgUp, Crs-dn, Crs-lt */ KEYMATCH[4] = 0X3000; /* F5, F6 */ KEYMATCH[7] = 0X1400; /* Ctrl+end, Ctrl+home */ KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[5] = KEYMATCH[6] = 0; disp_err("",1); /* force display of control keys */ h = WINDOW[W_NUM].H - 1; /* lines in screen */ scrndisp(text, lineptr, top, &bottom, *len); /* initial display */ A_TRACK = 0; INCHAR = ENTER; x = 0; /* main for loop */ for (;;){ switch((int)INCHAR){ case CRS_LT: case SFT_TAB: A_TRACK = 78 - 1; case CRS_UP: if (!(--x)) if (!top) {x = 1; A_TRACK = 0;} /* at TOF */ else {scroll(-1, 0); linedisp(text, lineptr, --top, (x = 1)); if (top + h <= bottom) bottom--;} break; case ENTER: case CRS_RT: case TAB: A_TRACK = 0; case CRS_DN: if ((++x) > h) if (bottom >= *len) {x = h; A_TRACK = 78 - 1;} else {scroll(1, 0); top++; linedisp(text, lineptr, ++bottom, (x = h));} if (INCHAR != ENTER) {if (top + x > *len) {x--; A_TRACK = 78 - 1;} break;} if (top + x <= bottom) break; case INSERT: if (*len == maxrecs) break; insline(lineptr, top + x, *len); scroll(-1, x - 1); A_TRACK = 0; text[lineptr[top + x - 1]] = 0; *len += 1; break; case DELETE: if (!*len) break; delline(lineptr, top + x, *len); scroll(1, x - 1); if (*len > bottom) linedisp(text, lineptr, bottom, h); else {bottom--; if (x > bottom - top) x--;} *len -= 1; break; case PGUP: top -= h; if (top < 0) top = 0; scrndisp(text, lineptr, top, &bottom, *len); break; case PGDN: if (bottom >= *len) break; top += h; scrndisp(text, lineptr, top, &bottom, *len); if (x > bottom - top) x = bottom - top; break; case CTL_HOME: top = 0; x = 1; scrndisp(text, lineptr, top, &bottom, *len); break; case CTL_END: top = *len - h; if (top < 0) top = 0; scrndisp(text, lineptr, top, &bottom, *len); x = bottom - top; break; case QUIT: if (disp_qry("Have you finished editing")) return; break; default: disp_err("Invalid function key", 1); break; } /* end switch */ set_crsr(x, 1); show_nbr(top + x, *len); if (accept(&text[lineptr[top+x-1]], as_typed, alt_reverse, 78, 0) < 0) goodbye(10); } /* end for loop */ } /* end function editfile */ /* * * Function to display a line on screen * */ void linedisp(text, lineptr, nbr, x) char *text; int *lineptr; int nbr, x;{ byte line[81]; justify(as_typed, line, &text[lineptr[nbr]], 78, 0); display(line, x, 1, ACC_DISP); } /* * * Function to re_display screen on edit * */ void scrndisp(text, lineptr, top, bottom, len) char *text; int *lineptr, top, *bottom, len;{ int h = WINDOW[W_NUM].H - 1, k, x; byte line[81]; *bottom = top + h ; if (*bottom >= len) *bottom = len; for (x = 1, k = top ; x <= h && k < *bottom ; x++, k++) linedisp(text, lineptr, k, x); if (x > h) return; memset(line, 32, 78); line[78] = 0; /* blank bottom of screen */ for (; x <= h ; display(line, x++, 1, ACC_DISP)); } /* end of function scrndisp */ /* * * Function to insert pointer in lineptr * */ void insline(lineptr, k, len) int *lineptr, k, len;{ int z = len - k, save = lineptr[len]; if (z <= 0) return; /* pointer already at EOT */ memcpy ((char*)&lineptr[k], (char*)&lineptr[k - 1], ++z * sizeof(int)); lineptr[k - 1] = save; } /* * * Function to delete pointer from lineptr * */ void delline(lineptr, k, len) int *lineptr, k, len;{ int z = len - k, save = lineptr[k - 1]; if (!z) return; /* pointer at EOT */ memcpy((char*)&lineptr[k - 1], (char*)&lineptr[k], ++z * sizeof(int)); lineptr[len] = save; } /* * * Function to show current record location on screen * */ void show_nbr(loc, len) int loc; int len;{ char text[16]; set_clr(99, low); /* use error status color */ sprintf(text, "%3u of %-3u", loc, len); scrn_map(text, TOP_LINE + 1, 69); /* hairy technique */ set_clr(98, low); /* reset color */ } /* * * Function to store new file to disc * */ void putfile(fh, fname, text, lineptr, len) char *fname, *text; int fh, *lineptr, len;{ long rec_nbr = 0L; int z; if (fh && fileback(fname) < 1) goodbye(30); fh = fileopen(fname, ascii, recreate); fileinit(fh, 0, 81, 0L); if (fh <= 0) goodbye(31); for (z = 0 ; z < len ; z++){ strcpy(FN[fh].record, &text[lineptr[z]]); /* copy to record area */ concat(FN[fh].record, 0); /* strip trailing spaces */ strcat(FN[fh].record, "\n"); /* Add the '\n' char */ if (filewrit(fh, &rec_nbr)) goodbye(32); if (!(rec_nbr & 0XF)) disp_msg("Writing to disc - record",(int)rec_nbr); } disp_msg("",0); fileclos(fh); rm_wndw(); } /* * * Main program * */ void main(){ int len = 0; int fh, *lineptr; char *text, fname[66]; /* setup */ clr_scrn("Text Editor"); text = malloc(maxsize); /* assign workarea */ lineptr = (int*) malloc(sizeof(int) * maxrecs); if (text == NULL || lineptr == NULL) goodbye(1); /* edit */ if ((fh = getfile(fname, text, lineptr, &len)) < 0) goodbye(2); editfile(text, lineptr, &len); putfile(fh, fname, text, lineptr, len); disp_err("ready for goodbye", 11); idleloop(18); goodbye(0); }