home *** CD-ROM | disk | FTP | other *** search
- _C PROGRAMMING COLUMN_
- by Al Stevens
-
- [LISTING 1]
-
- /* ------------ help.h -------------- */
-
- void load_help(char *);
- void display_help(void);
-
- extern char *help_window;
- #define set_help(s) help_window=s
-
-
- [LISTING 2]
-
- /* --------- help.c ----------- */
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <conio.h>
- #include "window.h"
- #include "menu.h"
- #include "entry.h"
- #include "help.h"
-
- #define MAXHELPS 25
-
- static struct helps {
- char hname [9];
- int h, w;
- long hptr;
- } hps [MAXHELPS+1];
-
- extern FIELD *fld;
- extern MENU *mn;
-
- static int hp = 0;
- static FILE *helpfp;
- static char hline [80];
- char *help_window;
-
- /* ----------- load the HELP! definition file ------------ */
- void load_help(char *hn)
- {
- extern void (*helpfunc)(void);
- extern int helpkey;
- char *cp;
-
- helpfunc = display_help;
- helpkey = F1;
- hp = 0;
- if ((helpfp = fopen(hn, "r")) == NULL)
- return;
- if ((fgets(hline, 80, helpfp)) == NULL)
- return;
- while (1) {
- if (hp == MAXHELPS)
- break;
- if (strncmp(hline, "<end>", 5) == 0)
- break;
- if (*hline != '<')
- continue;
- hps[hp].h = 2;
- hps[hp].w = 23;
- strncpy(hps[hp].hname, hline+1, 8);
- hps[hp].hname[8] = '\0';
- cp = strchr(hps[hp].hname, '>');
- if (cp)
- *cp = '\0';
- hps[hp].hptr = ftell(helpfp);
- if (fgets(hline, 80, helpfp) == NULL)
- strcpy(hline, "<end>");
- while (hline[0] != '<') {
- hps[hp].h++;
- hps[hp].w = max(hps[hp].w, strlen(hline)+2);
- if (fgets(hline, 80, helpfp) == NULL)
- strcpy(hline, "<end>");
- }
- hp++;
- }
- }
-
- /* ---------- display the current help window ----------- */
- void display_help()
- {
- int hx, hy, i, xx, yy, ch;
- extern int helpkey, hsel;
- char *save_help;
- static int inhelp = 0;
- extern struct wn wkw;
-
- if (inhelp)
- return;
- inhelp++;
- save_help = help_window;
- if (fld != NULL)
- help_window = fld->fhelp;
- else if (mn != NULL)
- help_window = (mn+hsel-1)->mshelp [wkw.wy-1];
- if (help_window != NULL) {
- for (ch = 0; ch < hp; ch++)
- if (strcmp(help_window, hps[ch].hname) == 0)
- break;
- if (ch < hp) {
- xx = wherex();
- yy = wherey();
- hidecursor();
- hx = ((80-hps[ch].w) / 2)+1;
- hy = ((25-hps[ch].h) / 2)+1;
- establish_window(hx, hy,
- hx+hps[ch].w-1, hy+hps[ch].h,
- HELPFG, HELPBG, TRUE);
- fseek(helpfp, hps[ch].hptr, 0);
- for (i = 0; i < hps[ch].h-2; i++) {
- gotoxy(2,2+i);
- fgets(hline, 80, helpfp);
- cprintf(hline);
- }
- gotoxy(2,2+i);
- cprintf(" [Any key to return]");
- hidecursor();
- getkey();
- delete_window();
- if (mn == NULL || fld != NULL) {
- textcolor(FIELDFG);
- textbackground(FIELDBG);
- gotoxy(xx, yy);
- }
- }
- }
- help_window = save_help;
- --inhelp;
- }
-
-
- [LISTING 3]
-
- <editor>
- TINY WORD PROCESSOR (TWP) COMMANDS
- -------Cursor Movement------ ---------Page Movement--------
- arrows = move text cursor Ctrl-Home = Beginning of File
- Ctrl-T = Top of Window Ctrl-End = End of File
- Ctrl-B = Bottom of Window PgUp = Previous Page
- Ctrl -> = Next Word PgDn = Next Page
- Ctrl <- = Previous Word
- Home = Beginning of Line ---------Editor Control-------
- End = End of Line Alt-A = Auto Paragraph Reform
- Shift-Tab = Back tab
-
- --------Block Controls------ ---------Edit Commands--------
- F2 = Form Paragraph Alt-Q or Esc = Done
- F5 = Mark Block Beginning Ins = Insert Mode
- F6 = Mark Block End Del = Delete Char
- F3 = Move Block <-- = Rubout
- F4 = Copy Block Ctrl-D = Delete Word
- F8 = Delete Block Alt-D = Delete Line
- F9 = Unmark Block F7 = Find
- Alt-F7 = Find again
- <load>
- Load a new file into TWP,
- replacing the existing file.
- <save>
- Save the file from the
- edit buffer.
- <merge>
- Merge a file into the
- edit buffer at the
- line where the cursor
- is pointed.
- <new>
- Clear the edit buffer
- and create a new file.
- <quit>
- Exit from TWP, returning to DOS
- <move>
- Move the block to the
- line where the cursor
- points. This is an
- insert move.
- <copy>
- Copy the block to the
- line where the cursor
- points. This is an
- insert copy.
- <delete>
- Delete the block closing
- the space it occupies.
- <hide>
- Turn off the block
- markers.
- <formpara>
- Form a paragraph.
- This makes a paragraph from
- a marked block, or, if no
- block is marked, to the next
- blank or indented line.
- <markbeg>
- Mark the beginning line
- of a block for move, copy,
- delete, or paragraph.
- <markend>
- Mark the ending line
- of a block for move, copy,
- delete, or paragraph.
- <find>
- Find a specified string
- in the edit buffer.
- Move the cursor to the
- location where the string
- was found.
- <findagn>
- Find the next occurrence
- of the string most recently
- specified.
- <auto>
- Turn on/off the automatic
- paragraph forming feature.
- <insert>
- Turn on/off the
- character insert mode.
- (insert/overstrike toggle)
- <filename>
- Enter the path and file name.
- The path is optional but must
- be fully qualified if entered.
- <findstr>
- Enter the string to be searched
- by the Find command.
- <end>
-
-
- [LISTING 4]
-
- /* --------- editshel.c ------------ */
- #include <stdio.h>
- #include <string.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <mem.h>
- #include <alloc.h>
- #include <ctype.h>
- #include "window.h"
- #include "menu.h"
- #include "entry.h"
- #include "editor.h"
- #include "help.h"
-
- int MAXLINES; /* maximum number of editor lines */
- #define EDITWIDTH 78 /* length of an editor line */
- #define BUFLEN (EDITWIDTH*MAXLINES)
-
- /* --------- alt keys returned by getkey() --------- */
- #define ALT_A 158
- #define ALT_L 166
- #define ALT_M 178
- #define ALT_N 177
-
- /* -------- configured advanced editor commands --------- */
- #define FIND F7
- #define FIND_AGAIN ALT_F7
- #define LOAD_FILE ALT_L
- #define SAVE_FILE ALT_S
- #define MERGE_FILE ALT_M
- #define NEW_FILE ALT_N
- #define EDITOR_MENU F10
- #define REFORM ALT_A
-
- /* ---------- editor menu tables --------- */
- static char *fselcs[] = {
- "Load [Alt-L]",
- "Save [Alt-S]",
- "Merge [Alt-M]",
- "New [Alt-N]",
- "Quit [Alt-Q]",
- NULL
- };
-
- static char *filehelp[] = {
- "load",
- "save",
- "merge",
- "new",
- "quit"
- };
-
- static char *eselcs[] = {
- "Move [F3]",
- "Copy [F4]",
- "Delete [F8]",
- "Hide [F9]",
- "Paragraph [F2]",
- "Mark Beg [F5]",
- "Mark End [F6]",
- "Find [F7]",
- "Find Again [Alt-F7]",
- NULL
- };
-
- static char *edithelp[] = {
- "move",
- "copy",
- "delete",
- "hide",
- "formpara",
- "markbeg",
- "markend",
- "find",
- "findagn",
- };
-
- static char *oselcs[] = {
- "Auto Paragraph Reformat [Alt-A]",
- "Insert [Ins]",
- NULL
- };
-
- static char *opthelp[] = {
- "auto",
- "insert"
- };
-
- void fileedit(char *);
- static int edit(int,int);
- static void editmenu(int);
- static int get_filename(char *, int);
- static int write_file(void);
- static int load_file(int,int);
- static int save_file(int,int);
- static int merge_file(int,int);
- static int new_file(int,int);
- static void editkeys(int);
- static void statusline(void);
- static int findstring(void);
- static char *find(char *, unsigned);
- static int read_file(char *, char *, int, int, int);
- static int bufferok(char *);
- static void notice(char *);
- void (*edit_extend)(void);
-
- static char fkeys[] = {LOAD_FILE,SAVE_FILE,
- MERGE_FILE,NEW_FILE,QUIT};
- static char forced[] = {MOVE_BLOCK,COPY_BLOCK,
- DELETE_BLOCK,HIDE_BLOCK,
- PARAGRAPH,BEGIN_BLOCK,
- END_BLOCK,FIND,FIND_AGAIN};
- static char options[] = {REFORM,INS};
-
- static int (*ffuncs[])() =
- {load_file,save_file,merge_file,new_file,edit};
- static int (*efuncs[])() =
- {edit,edit,edit,edit,edit,edit,edit,edit,edit};
- static int (*ofuncs[])() =
- {edit,edit,edit};
-
- MENU emn [] = {
- {"File", NULL, fselcs, filehelp, fkeys, ffuncs, 0},
- {"Edit", NULL, eselcs, edithelp, forced, efuncs, 0},
- {"Options", NULL, oselcs, opthelp, options, ofuncs, 0},
- {NULL}
- };
-
- /* ------ filename data entry template and buffer ------- */
- static char filename[65];
- static char savefn [65];
- static char filemask[65];
-
- FIELD fn_template[] = {
- {2,14,1,filename,filemask,"filename"},
- {0}
- };
-
- /* ------- text find data entry template and buffer ------ */
- static char findstr[71];
- static char findmask[71];
-
- FIELD find_template[] = {
- { 2,8,1,findstr,findmask,"findstr"},
- {0}
- };
-
- extern int forcechar;
- extern struct edit_env ev;
-
- static void editkeys(int c)
- {
- switch(c) {
- case REFORM:
- ev.reforming ^= TRUE;
- break;
- case NEW_FILE:
- new_file(1,1);
- break;
- case LOAD_FILE:
- load_file(1,1);
- break;
- case SAVE_FILE:
- save_file(1,1);
- break;
- case MERGE_FILE:
- merge_file(1,1);
- break;
- case FIND:
- if (!findstring())
- break;
- case FIND_AGAIN:
- ev.nowptr++;
- ev.nowptr = find(ev.nowptr, ev.lstptr-ev.nowptr);
- if (ev.nowptr != NULL) {
- ev.curr_x = (ev.nowptr-ev.topptr) % ev.wwd;
- if (ev.nowptr >= ev.bfptr+ev.wwd*ev.wdo->ht)
- ev.bfptr = ev.nowptr - ev.curr_x;
- ev.curr_y = (ev.nowptr - ev.bfptr) / ev.wwd;
- }
- else
- error_message("Not found ...");
- break;
- case ALT_F:
- editmenu(1);
- break;
- case ALT_E:
- editmenu(2);
- break;
- case ALT_O:
- editmenu(3);
- break;
- case EDITOR_MENU:
- editmenu(0);
- break;
- default:
- if (edit_extend)
- (*edit_extend)();
- else
- putch(BELL);
- break;
- }
- }
-
- static void editmenu(n)
- {
- menu_select(emn, n);
- }
-
- static int edit(hs,vs)
- {
- forcechar = emn[hs-1].mskeys[vs-1] & 255;
- return TRUE;
- }
-
- /* ---------- edit a file -------------- */
- void fileedit(char *file)
- {
- char *bf, *mb;
- extern void (*editfunc)();
- extern void (*status_line)();
-
- setmem(filename, 64, ' ');
- setmem(filemask, 64, '_');
- setmem(findmask, 70, '_');
- setmem(findstr, 70, ' ');
- establish_window(1,2,80,24,TEXTFG,TEXTBG,TRUE);
- editfunc = editkeys;
- status_line = statusline;
- mb = display_menubar(emn);
- statusline();
- if ((bf = malloc(BUFLEN)) != NULL) {
- setmem(bf, BUFLEN, ' ');
- strcpy(filename, file);
- filename[strlen(filename)] = ' ';
- if (*file)
- read_file(" Loading ... ",bf,0,FALSE,FALSE);
- while (TRUE) {
- text_editor(bf, MAXLINES, EDITWIDTH);
- if (bufferok("quit"))
- break;
- }
- free(bf);
- }
- restore_menubar(mb);
- delete_window();
- }
-
- /* ---------- load a file --------------- */
- static int load_file(hs,vs)
- {
- if (bufferok("reload"))
- strcpy(savefn, filename);
- if (get_filename(" Load what file? ", TRUE) != ESC) {
- setmem(ev.topptr, BUFLEN, ' ');
- read_file(" Loading ... ",ev.topptr,0,FALSE,TRUE);
- forcechar = BEGIN_BUFFER;
- ev.text_changed = FALSE;
- }
- else
- strcpy(filename, savefn);
- return TRUE;
- }
-
- /* ---------- merge a file into the edit buffer -------- */
- static int merge_file(hs,vs)
- {
- strcpy(savefn, filename);
- if (get_filename(" Merge what file? ", TRUE) != ESC) {
- if (read_file(" Merging ... ",
- curr(0, ev.curr_y),
- lineno(ev.curr_y), TRUE, TRUE)) {
- forcechar = REPAINT;
- ev.text_changed = TRUE;
- }
- }
- strcpy(filename, savefn);
- return TRUE;
- }
-
- /* --------- save the file -------------- */
- static int save_file(hs,vs)
- {
- if (get_filename(" Save as what file? ", FALSE) != ESC)
- if (write_file())
- ev.text_changed = FALSE;
- return TRUE;
- }
-
- /* ---------- start a new file ------------- */
- static int new_file(hs,vs)
- {
- if (bufferok("erase"))
- if (get_filename(" Build as what file? ",TRUE)!=ESC){
- setmem(ev.topptr, BUFLEN, ' ');
- forcechar = BEGIN_BUFFER;
- ev.text_changed = FALSE;
- }
- return TRUE;
- }
-
- /* -------- read a file name ------------- */
- static int get_filename(char *ttl, int clear)
- {
- int rtn;
-
- establish_window(1,23,80,25,ENTRYFG,ENTRYBG,TRUE);
- window_title(ttl);
- gotoxy(3,2);
- cputs("File name:");
- rtn = data_entry(fn_template, clear, 1);
- delete_window();
- return rtn;
- }
-
- /* --------- write a file ------------ */
- static int write_file()
- {
- FILE *fp;
- int ln, i, ln1;
- char *cp, buf[EDITWIDTH+1];
-
- if ((fp = fopen(filename, "w")) == NULL) {
- error_message(" Can't write that file! ");
- return FALSE;
- }
- notice(" Writing file ... ");
- /* ----- find the last significant line ----- */
- for (ln = MAXLINES-1; ln > -1; --ln) {
- cp = ev.topptr + ln * EDITWIDTH;
- for (i = 0; i < EDITWIDTH; i++)
- if (*(cp + i) != ' ')
- break;
- if (i < EDITWIDTH)
- break;
- }
- for (ln1 = 0; ln1 <= ln; ln1++) {
- movmem(ev.topptr + ln1 * EDITWIDTH, buf, EDITWIDTH);
- i = EDITWIDTH-1;
- cp = buf;
- while (i >= 0 && *(cp + i) == ' ')
- --i;
- if (i == -1 || *(cp + i) != ' ')
- i++;
- *(cp + i) = '\n';
- *(cp + i + 1) = '\0';
- fputs(cp, fp);
- }
- fclose(fp);
- delete_window();
- return TRUE;
- }
-
- /* -------------- read (load or merge) a file ----------- */
- static int
- read_file(char *nt,char *ln,int lines,int merging,int needed)
- {
- FILE *fp;
- char ibf[120];
- char *cp;
- int x;
-
- if ((fp = fopen(filename, "r")) != NULL) {
- notice(nt);
- while (fgets(ibf, 120, fp) && lines < MAXLINES) {
- lines++;
- if (merging) {
- movmem(ln,ln+EDITWIDTH,
- BUFLEN-lines*EDITWIDTH);
- setmem(ln,EDITWIDTH,' ');
- }
- cp = ibf, x = 0;
- while (*cp && *cp != '\n') {
- if (*cp == '\t')
- x += TAB-(x%TAB);
- else
- *(ln+x++) = *cp;
- cp++;
- }
- ln += EDITWIDTH;
- }
- fclose(fp);
- delete_window();
- return TRUE;
- }
- else if (needed)
- error_message("No such file can be found");
- return FALSE;
- }
-
- /* ----------- display a status line ----------- */
- static void statusline()
- {
- char stat[81], *st;
- int cl[81], *cp;
- static char msk[] =
- "Line:%3d Column:%2d %-9.9s %-21.21s F1:Help \
- F10:Menu ";
- unsigned y = 1;
- unsigned x = 1;
- unsigned attr = ((MENUFG | (MENUBG << 4)) << 8);
-
- if (ev.wwd) {
- y = (unsigned) (ev.nowptr-ev.topptr) / ev.wwd + 1;
- x = (unsigned) (ev.nowptr-ev.topptr) % ev.wwd + 1;
- }
- sprintf(stat,msk,y,x,
- (ev.edinsert ? "Insert" : "Overwrite"),
- (ev.reforming ? "Auto Paragraph Reform" : " "));
- for (st = stat, cp = cl; *st; st++)
- *cp++ = (*st & 255) | attr;
- __vram(__vptr(1,25),cl,80);
- set_help("editor");
- }
-
- /* -------- get a string to find --------- */
- static int findstring()
- {
- char *cp = findstr+60;
- int ans;
-
- establish_window(1,23,80,25,ENTRYFG,ENTRYBG,TRUE);
- gotoxy(2,2);
- cputs("Find?");
- ans = data_entry(find_template, TRUE, 1);
- delete_window();
- if (ans == ESC)
- return FALSE;
- while (*--cp == ' ')
- ;
- if (*cp)
- *(cp+1) = '\0';
- return TRUE;
- }
-
- /* -------- find a string in the buffer -------------- */
- static char *find(char *bf, unsigned len)
- {
- char *cp;
-
- for (cp = bf; cp < bf+len-strlen(findstr); cp++)
- if (strncmp(cp, findstr, strlen(findstr)) == 0)
- return cp;
- return NULL;
- }
-
- /* ---------- test for buffer changed ----------- */
- static int bufferok(char *s)
- {
- int c = 'Y';
- if (ev.text_changed) {
- establish_window(23,11,56,13,ERRORFG,ERRORBG,TRUE);
- gotoxy(2,2);
- cprintf("Text has changed, %s? (y/n)", s);
- hidecursor();
- do
- putch(BELL), c = getkey();
- while (toupper(c) != 'Y' && toupper(c) != 'N');
- delete_window();
- }
- return toupper(c) == 'Y';
- }
-
- /* -------- small message ------------ */
- static void notice(char *s)
- {
- int lf = (80-strlen(s))/2-1;
- int rt = lf+strlen(s)+2;
- establish_window(lf,11,rt,13,HELPFG,HELPBG,TRUE);
- gotoxy(2,2);
- cputs(s);
- }
-
-
- [LISTING 5]
-
- /* ----------- twrp.c ------------ */
- #include <conio.h>
- #include "window.h"
- #include "editor.h"
- #include "help.h"
-
- void main(int, char **);
- void fileedit(char *);
-
- void main(int argc, char **argv)
- {
- extern int inserting, MAXLINES;
-
- MAXLINES = 800;
- load_help("twrp.hlp");
- clear_screen();
- fileedit(argc > 1 ? argv[1] : "");
- clear_screen();
- inserting = FALSE;
- insert_line();
- }
-
- [LISTING 6]
-
- trwp (window.h, editor.h, help.h)
- editshel (editor.h, menu.h, entry.h, help.h, window.h)
- editor (editor.h, window.h)
- entry (entry.h, window.h)
- menu (menu.h, window.h)
- help (help.h, window.h)
- window (window.h)
-
-
-
-