1 
2 /* mye.c, from ee.c, Yijun Ding, Copyright 1991
3 modified April 2002. Copyright (C) 1998,2002 Terry Loveall, <loveall@qwest.net>
4 
5 Code starts after the Users Manual.
6 
7 Compile under Linux with termcap lib support
8         gcc mye.c -O2 -ltermcap -o mye ; strip mye
9 
10 Compile under Linux for gdb with termcap lib support
11         gcc mye.c. -O2 -g -ltermcap -o mye
12 
13 Compile with MSVC:      cl -DMSVC -Ox mye.c
14 
15 ------------------------------------------------------------------------------
16 Users Manual:
17 
18 Based upon the original work ee.c of Yijun Ding, copyright 1991. His logic
19 simplicity was elegant. Any problems are mine.
20 
21 The original work is public domain with source and so is mye.c. I would
22 appreciate hearing about any bug fixes or improvements.
23 
24 This is a simple, basic text editor. It requires only three graphic support
25 routines from the OS: goto X-Y, set character attribute and clear screen. For
26 input it uses the old WordStar style control key sequences; i.e. ^Kh or ^K^H
27 are all equivalant. It will compile on NT with MSVC and lcc and on Linux with
28 gcc.
29 
30 On Linux, it uses termios rather than curses, so will run with minimum library
31 support (like on a rescue/boot disk). Function keys under Linux probably won't
32 work depending upon execution context. They might work on the text console and
33 almost certainly won't on any kind of xterm.
34 
35 For input, mye uses a version of the old WordStar style control key sequences;
36 i.e. ^k^h or ^kh, always lower case control chars. ^kc copies marked block to
37 clipboard, right mouse pastes from clipboard. ^ky deletes marked block to
38 block buffer, ^kv copies from from block buffer to cursor position.
39 
40 Basic navigation is on the left of the keyboard:
41 
42   Q W E R      ^E    ^W  ^R
43    A S D F   ^S  ^D             ^A   ^F
44     Z X C      ^X    ^Z  ^C
45 
46     ^E - up
47     ^X - down
48     ^D - right
49     ^S - left
50 
51     ^W - scroll down 1 line
52     ^Z - scroll up 1 line
53 
54     ^R - page up
55     ^C - page down
56 
57     ^F - word right
58     ^A - word left
59 
60     ^Q^D - goto end of line
61     ^Q^S - goto start of line
62 
63     ^Q^R - goto start of file
64     ^Q^C - goto end of file
65 
66     ^Q^F - find
67     ^Q^A - find and replace
68 
69 Once you learn the 'magic diamond' of EXDS with ^Q extensions, function keys
70 and mouse become irrelevant. Following are the rest of the key commands:
71 
72     ^B - word wrap text until the next double newline
73     ^G - delete character under cursor
74     ^H - delete character left of cursor
75     ^I - insert tab char
76     ^J - newline
77     ^K - prefix for file/block operations
78     ^L - repeat last find
79     ^M - insert newline
80     ^N - insert newline
81     ^O - prefix for display and change mode flags
82     ^P - inline literal
83     ^T - delete from cursor to start of next string
84     ^U - undo
85     ^V - toggle insert/overwrite mode
86     ^Y - delete cursor line
87 
88     ^QI - goto line
89     ^QL - refresh screen
90     ^QM - get new right margin
91     ^QY - delete from cursor to end of line
92 
93     ^KB - toggle mark block
94     ^KC - copy marked block to selection
95     ^KD - exit if file not modified
96     ^KF - open new file
97     ^KH - help
98     ^KK - toggle mark block
99     ^KM - record macro
100     ^KN - get and change directory
101     ^KP - play macro
102     ^KQ - exit if file not modified
103     ^KR - read a file and paste into cursor position
104     ^KS - save and continue
105     ^KT - get new tab size
106     ^KU - redo
107     ^KV - paste block buffer into cursor position
108     ^KW - write marked block to file
109     ^KX - exit if file not modified
110     ^KY - cut marked block to block buffer
111 
112 Under NT the following function keys are operational:
113 
114    (key)     (description)                                   (same as)
115 ----------------------------------------------------------------------
116     F2      file save (if modified)                             ^KS
117     F3      open new file (prompts to save if file modified)    ^KF
118     F7      toggle mark block                                   ^KB
119     F8      toggle mark block                                   ^KK
120     Insert  toggle insert/overwrite                             ^V
121     Del     delete character under cursor or marked block       ^G
122     Home    move cursor to beginning of line                    ^QS
123     End     move cursor to end of line                          ^QD
124     PgUp    move up one screen                                  ^R
125     PgDn    move down one screen                                ^C
126 
127 Modes:
128 
129 Changing modes of operation is performed by ^o followed by one of the
130 displayed upper/lower case characters MFOCTBNRA. This will toggle the specific
131 flag. Modes are indicated as being on by displaying their upper case
132 character. The file modified M flag can be toggled off explicitly. The block
133 mark B active flag indicates a complex state. Toggle it off with the block
134 mark key sequences, NOT with ^oB.
135 
136 M : file modified               set by anything that modifies file.
137 F : word wrap at text entry     toggle with ^oF
138 O : overwrite                   toggle with ^oO, ^V or function key Insert
139 C : search is case sensitive    toggle with ^oC
140 T : expand/compress tabs        toggle with ^oT
141 B : block mark active           toggle ^KB, ^KK, F7 or F8 (don't with ^oB)
142 N : autoiNdent active           toggle ^on
143 R : macro record                toggle ^KM (don't with ^oB)
144 A : replace all occurences flag toggle with ^oA
145 
146 The editor does display tab chars as multiple spaces. Tab (0x09) chars are
147 displayed as tabsize spaces. Default tab size is 4. To change tab-width to 8
148 the command line is  'mye -t8'. To change from within the editor use ^KT.
149 
150 To go to a specified line on initial file opening, the command line is
151 'mye -+507 somefile'. The minus plus sequence is required. Input a ^J to go to
152 a line from within e.
153 
154 Turning on (F)ill mode enables wordwrap during text entry. Block reformat
155 wraps the text at the right screen edge until a double newline is encounterd.
156 To reformat a paragraph, place the cursor at the desired point of reformat and
157 enter a ^b. To change the right margin use ^Q^M.
158 
159 As noted, undo and redo are available. U for undo, ^KU for redo. A complete
160 record of the edit session is maintained. Undoing all actions in the undo
161 buffer will reset the Marked flag.
162 
163 Find and 'Search and Replace' will pick up any marked blocks, text under
164 the cursor or user input in that order. Found text is highlighted. Set replace
165 ALL flag wth ^oA option before running SAR to replace all occurences.
166 
167 For general dialog entry if the first character entered is not ^H, ^C, ^L, or
168 Enter, the dialog string is discarded. ^L moves the cursor to the end of the
169 dialog string.
170 
171 For a complete understanding of the operation of mye, study the code. It is the
172 ultimate authority on operation.
173 
174 Remember, when all else fails READ THE SCREEN.
175 -----------------------------------------------------------------------------*/
176 
177 #include <stdio.h>
178 #include <string.h>
179 #include <stdlib.h>
180 #include <sys/stat.h>
181 #include <stdlib.h>
182 #include <ctype.h>
183 #include <signal.h>
184 
185 /* Target dependent include files ********************************* */
186 
187 #ifdef MSVC
188 
189 #include <windows.h>
190 #include <conio.h>
191 #include <ctype.h>
192 #include <io.h>
193 #include <direct.h>
194 
195 #else /* not MSVCd */
196 
197 #include <termios.h>    /* use termios.h for termcap output */
198 #include <unistd.h>
199 
200 #endif /* MSVC */
201 
202 #include "version.h"
203 #include "messages.def"
204 #include "edit.h"
205 
206 int funckey = 0;	/* function key flag */
207 int exitf = 1;		/* exitf = 0 = exit */
208 #ifdef NOEDIT
209 int noedit = 0;
210 #endif
211 
212 /* code */
213 
214 /* NT I/O specific code ********************************* */
215 
216 #ifdef MSVC
217 
218 /* MSVC specific variables */
219 COORD outxy ;                   /* output COORD for SetConsoleCursorPosition */
220 CONSOLE_SCREEN_BUFFER_INFO csbi;/* to get MS screen buffer info */
221 HANDLE stdIn,stdOut,stdErr;     /* handles to output window/buffer */
222 BOOL bSuccess;                  /* OS result flag */
223 
224 /* MSVC specific protos */
225 void clreol();
226 void clrscr();
227 void gotoxy(int horz,int vert);
228 
229 /* MSVC specific macros */
230 
231 #define cprintf(x,y)    _cprintf(x,y)
232 
233 #define ttopen()     stdIn=GetStdHandle(STD_INPUT_HANDLE);\
234     stdOut=GetStdHandle(STD_OUTPUT_HANDLE);\
235     stdErr=GetStdHandle(STD_ERROR_HANDLE);\
236     bSuccess = GetConsoleScreenBufferInfo(stdOut, &csbi);\
237     if (!(bSuccess)) return(0);\
238     screen_height=((csbi.srWindow.Bottom)-(csbi.srWindow.Top))-2;\
239     screen_width=((csbi.srWindow.Right)-(csbi.srWindow.Left))+1
240 
241 #define highvideo()   SetConsoleTextAttribute(stdOut,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_GREEN)
242 #define lowvideo()    SetConsoleTextAttribute(stdOut,0x0e)
243 #define ttclose()     SetConsoleTextAttribute(stdOut,0x0e)
244 
gotoxy(int horz,int vert)245 void gotoxy(int horz,int vert)
246 {
247     outxy.X=horz;
248     outxy.Y=vert;
249     SetConsoleCursorPosition(stdOut,outxy);
250 }
251 
252 /* Microsoft get a key */
get_key()253 int get_key()
254 {
255 
256     static  char k1[]="<=ABDHPKMRSGOIQ";    /* input func key second byte */
257     static  char k2[]="rfbczEXSDngsdvw";    /* F2,F3,F7,F8,F10,up,dn,le,ri,Ins,Del,home,End,PgUp,PgDn*/
258     int key1,key2;
259     char *s;
260 
261     if(((key1=getch()) == 0xE0) || ((key1 == 0))) {
262         key2=getch();
263 #ifdef DEBUG
264     {   /* display up to 4 chars of func key input */
265         char tbuf[80];
266         show_top();
267         sprintf(tbuf, "Line %d/%d, Col %d, char %2x_%2x-%2x+%2x",
268             ytru+1, ytot, xtru, -1, -1, key1, key2);
269         show_note(tbuf);
270     }
271 #endif /* DEBUG */
272         if((s=strchr(k1, key2)) == 0)
273             return HLP;
274         if((key1 = k2[s-k1]) > 'a')
275             funckey=1;
276         return key1&0x1F;
277     }
278     return key1;
279 }
280 
clreol()281 void clreol()   /* clear from cursor to end of line */
282 {
283   int i,ox=outxy.X,oy=outxy.Y;
284 
285   for(i=outxy.X; i<screen_width; ++i) putch(' ');
286   gotoxy(ox,oy);
287 }
288 
289 /* clrscr(): clear the screen by filling it with blanks, home cursor*/
290 
clrscr()291 void clrscr()
292 {
293     COORD coordScreen = { 0, 0 }; /* here's where we'll home the cursor */
294     BOOL bSuccess;
295     DWORD cCharsWritten;
296     CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
297     DWORD dwConSize; /* number of character cells in the current buffer */
298 
299     /* get the number of character cells in the current buffer */
300     bSuccess = GetConsoleScreenBufferInfo(stdOut, &csbi);
301     if (!(bSuccess)) return;    /* error return on any failure */
302 
303     dwConSize = csbi.dwSize.X * csbi.dwSize.Y; /* figure screen size */
304 
305     /* fill the screen with blanks from home cursor position */
306     bSuccess = FillConsoleOutputCharacter(stdOut, (TCHAR) ' ',
307         dwConSize, coordScreen, &cCharsWritten);
308     if (!(bSuccess)) return;
309 
310     /* get the current text attribute */
311     bSuccess = GetConsoleScreenBufferInfo(stdOut, &csbi);
312     if (!(bSuccess)) return;
313 
314     /* now set the buffer's attributes accordingly */
315     bSuccess = FillConsoleOutputAttribute(stdOut, csbi.wAttributes,
316         dwConSize, coordScreen, &cCharsWritten);
317     return;
318 }
319 
320 #else /* not MSVC */
321 
322 /******************** Start of termcap I/O *******************/
323 /*  uses termios.h for termcap I/O on quick and dirty Editor */
324 
325 /* portable interface defines. */
326 
327 #define getstate(p)     ((void) tcgetattr(0, (p)))
328 #define w_setstate(p)   ((void) tcsetattr(0, TCSADRAIN, (p)))
329 
330 /*
331 #define oflush()        (void) fflush(stdout)
332 #define cprintf(x,y)    fprintf(stdout,x,y)
333 */
334 
335 #define _cputs(s)       fputs (s, stdout)
336 #define putch(c)        putchar(c)
337 #define getch()         getchar()
338 #define ttclose()       sys_endv()
339 #define clrscr()        erase()
340 
341 #define highvideo()     tputs(SO, 1, foutch)
342 #define lowvideo()      tputs(SE, 1, foutch)
343 
344 /* Termcap-related declarations. */
345 extern	int	tgetent();
346 extern	int	tgetnum();
347 extern	int	tputs();
348 extern  char    *tgetstr();
349 extern  char    *tgoto();
350 
351 typedef struct termios  Termstate;
352 
353 static Termstate    cooked_state, raw_state;
354 
355 /* Local termios func declarations. */
356 void foutch(int c);
357 void cputs(char *str);
358 static void fail(char *str);
359 void ttopen();
360 void ttyopen();
361 void sys_endv();
362 void erase();
363 void gotoxy(int horz,int vert);
364 void clreol();
365 
366 /* termios data declarations. */
367 unsigned int    COLS = 0;       /* screen dimensions; 0 at start */
368 unsigned int    LINES = 0;
369 
370 /* termcap string, num and boolean defs. */
371 static  char    *CL;            /* erase line/display */
372 static  char    *CM;            /* cursor motion string */
373 static  char    *SO, *SE;       /* standout mode start/end */
374 //static  char    *colours[10];   /* colour caps c0 .. c9 */
375 //static  int     ncolours;       /* number of colour caps we have */
376 
377 /* use MS style COORD to track cursor pos */
378 typedef struct {
379     int X;      /* x coordinate */
380     int Y;      /* y coordinate */
381 } COORD;        /* x-y structure */
382 
383 COORD outxy;    /* cursor coordinates for screen positioning */
384 
385 /* qde state info */
386 static enum {
387     m_SYS = 0,
388     m_QDE
389 }   termmode;
390 
391 /* tputs char output callback func */
foutch(int c)392 void foutch(int c)
393 {
394     putchar(c);
395 }
396 
cputs(char * prntstr)397 void cputs(char *prntstr)
398 {
399 	int strl = strlen(prntstr);
400         _cputs(prntstr);
401 	outxy.X += strl;
402 }
403 
404 /* fail() is called by ttyopen() on terminal open failure */
405 
fail(char * str)406 static void fail(char *str)
407 {
408     /* Assume we are in raw mode already, so go back into cooked. */
409 
410     (void) fputs(str, stderr);  /* tell operator why failed */
411     putc('\n', stderr);
412     sys_endv();
413 
414     exit(2);                    /* tell OS we failed */
415 }
416 
417 /* Initialise the terminal so that we can do single-character I/O */
418 
ttopen()419 void ttopen()
420 {
421     /* Set up tty flags in raw and cooked structures.
422      * Do this before any termcap-initialisation stuff
423      * so that start sequences can be sent.*/
424 
425     getstate(&cooked_state);
426     raw_state = cooked_state;
427 
428     cfmakeraw(&raw_state);
429 
430     /* Now set up the terminal interface. */
431     ttyopen();
432     clrscr();
433 
434     /* Go into raw/cbreak mode, and say so. */
435     w_setstate(&raw_state);
436 
437     termmode = m_QDE;
438 }
439 
440 /* Look up term entry in termcap database, and set up all the strings. */
441 
ttyopen()442 void ttyopen()
443 {
444     char    tcbuf[4096];        /* buffer for termcap entry */
445     char    *termtype;          /* terminal type */
446     static  char strings[512];  /* space for storing strings */
447     char    *strp = strings;    /* ptr to space left in strings */
448     int iv;
449 
450     termtype = getenv("TERM");
451     if (termtype == NULL) fail("Can't find TERM in environment.");
452 
453     switch (tgetent(tcbuf, termtype)) {
454     case -1: fail("Can't open termcap.");    /*NOTREACHED*/
455     case 0:  fail("Can't find entry for your terminal in termcap.");
456     }
457 
458     /* Screen dimensions. */
459     iv = tgetnum("co");
460     /* check that x is there */
461     if (iv <= 0) fail("`co' entry in termcap is invalid or missing.");
462 
463     COLS = (unsigned) iv;
464 
465     iv = tgetnum("li");
466     /* check that y is there */
467     if (iv <= 0) fail("`li' entry in termcap is invalid or missing.");
468 
469     LINES = (unsigned) iv;
470 
471     /* set output screen height and width */
472     screen_height=LINES;
473     screen_width=COLS;
474 
475     /* output control */
476     CL = tgetstr("cl", &strp);  /* clear erase */
477     CM = tgetstr("cm", &strp);  /* move goto */
478     SO = tgetstr("so", &strp);  /* standout mode start */
479     SE = tgetstr("se", &strp);  /* standout mode end */
480 
481     if (CM == NULL) {
482         fail("qde can't work without cursor motion.");
483     }
484 
485 }
486 
487 /* ReSet terminal into the mode it was in when we started. */
488 
sys_endv()489 void sys_endv()
490 {
491     if (termmode == m_SYS) return;
492 
493     (void) fflush(stdout);
494 
495     /* Restore terminal modes. */
496 	w_setstate(&cooked_state);
497     termmode = m_SYS;
498 }
499 
500 /* Erase display (may optionally home cursor). */
501 
erase()502 void erase()
503 {
504     tputs(CL, (int) LINES, &foutch);
505 }
506 
507 /* Goto the specified location. */
508 
gotoxy(int horz,int vert)509 void gotoxy(int horz,int vert)
510 {
511     outxy.X=horz;
512     outxy.Y=vert;
513 
514     tputs(tgoto(CM, horz, vert), (int) LINES, &foutch);
515 }
516 
517 /* Erase from cursor to end of line. */
518 
clreol()519 void clreol()
520 {
521   int i,ox=outxy.X,oy=outxy.Y;
522 
523   for(i=outxy.X; i<screen_width; ++i) putch(' ');
524   gotoxy(ox,oy);
525 }
526 
527 /* get a key */
528 
get_key()529 int get_key()
530 {
531 #ifdef EMACS
532     static  char k1[]="ABCDFH256"; /* up,dn,rt,le,ins,pgup,pgdn */
533     static  char k2[]="PNFBEAnvw";
534     static  char k3[]=" ._%<>3bfgjlmnpquvwx";
535 #else
536     static  char k1[]="ABCD256"; /* up,dn,rt,le,ins,pgup,pgdn */
537     static  char k2[]="EXDSnvw";
538 #endif
539 #define DEL_CHAR 8
540 
541     int key1=0,key2=0,key3=0,key4=0;
542     char    *s;
543 
544     if((key1 = getch()) == -1) {    /* -1 is ERR */
545         key1 = getch();
546     }
547 #ifdef EMACS
548     if (doCtrlQ)
549 	return key1;
550 #endif
551     if (key1 == 9 || key1 == 17)
552 	return key1;
553     if(key1 == 13)
554     	return 10;
555 
556     if(key1 == 127)
557 	return DEL_CHAR; /* delete cursor char */
558 
559     if(key1 == 27) {
560         key2 = getch();
561 #ifdef EMACS
562 	key2 = tolower(key2);
563 	if (strchr(k3, key2)) {
564         	doEscap = 1;
565 		return key2;
566 	}
567 #endif
568   	if (key2=='!') {
569 		doEscap = 2;
570 		show_note(ALT_KEY_BINDINGS);
571 		key3 = getch();
572 		return tolower(key3);
573 	}
574         key3 = getch();
575         if ((key3 <= 0x40)||(key3 >= 0x5b))
576 		key4 = getch();
577         else
578 		key4 = 0x7e;
579 #ifdef SUPERDEBUG
580     {
581         char tbuf[80];
582         show_top();
583 	/* sprintf(tbuf, "Line %d/%d, Col %d, char %2x_%2x-%2x+%2x", */
584         sprintf(tbuf, "Line %d/%d, Col %d, S/char %d %d %d %d",
585             ytru+1, ytot, xtru, key1, key2, key3, key4);
586         show_note(tbuf);
587 	fflush(stdout);
588 	usleep(2000000);
589     }
590 #endif /* SUPERDEBUG */
591         if ((key4 != 0x7e)&(key3 != 0x5b)) { getch();}
592 	if (key3=='1' || key3=='2') {
593 	    if (key3=='1') key4 = key4-'0'-(key4>='6');
594 	    if (key3=='2') key4 = key4-'0'+9;
595 	    funckey=1;
596 	    return key4;
597 	}
598 	if (key3=='3') return DEL_CHAR;
599         if((s=strchr(k1, key3)) != NULL && (key1 = k2[s-k1]) > 'a')
600             funckey=1;
601         key1=key1&0x1F;
602         if (key1==0x1b) key1=0;
603     }
604 #ifdef DEBUG
605     {
606         char tbuf[80];
607         show_top();
608 	/* sprintf(tbuf, "Line %d/%d, Col %d, char %2x_%2x-%2x+%2x", */
609         sprintf(tbuf, "Line %d/%d, Col %d, char %d %d %d %d",
610             ytru+1, ytot, xtru, key1, key2, key3, key4);
611         show_note(tbuf);
612     }
613 #endif /* DEBUG */
614     return key1;
615 }
616 
617 /********************** End of termcap input ***********************/
618 
619 #endif /* not MSVC */
620 
bell()621 void bell()
622 {
623 		putch(7);
624 }
625 
626 /* End of I/O specific code****************************** */
627 
628 #ifdef EMACS
629 #include "term_bind_em.c"
630 #endif
631 #ifdef WORDSTAR
632 #include "term_bind_ws.c"
633 #endif
634 
635 char *RcFile = NULL;
636 
parse_arg(char * arg1,char * arg2)637 void parse_arg(char *arg1, char *arg2)
638 {
639 	if(*arg1=='-') {
640 		if (!strcasecmp(arg1, "-f"))
641 			strcpy(ewin.name, arg2);
642 		else
643 		if (!strcasecmp(arg1, "-t"))
644 			tabsize = atoi(arg2);
645 		else
646 		if (!strcasecmp(arg1, "-j"))
647 			ewin.jump = atoi(arg2);
648 		else
649 		if (!strcasecmp(arg1, "-rc"))
650 			RcFile = strdup(arg2);
651 	}
652 #ifndef MINIMAL
653 	if(*arg1=='@') {
654 		char *ptr;
655 		int i;
656 		i = tolower(arg1[1])-'a';
657 		if (i>=0 && i<26) {
658 			ptr = arg2;
659 			while(isspace(*ptr)) ++ptr;
660 			if (binding[i]) free(binding[i]);
661 			binding[i] = strdup(ptr);
662 		}
663 	}
664 #endif /* MINIMAL */
665 }
666 
667 #ifndef MINIMAL
parse_rc(FILE * f)668 void parse_rc(FILE *f)
669 {
670 	char buf[512], *ptr;
671 	int i, l;
672 	while ((ptr=fgets(buf, 510, f))) {
673 		while (isspace(*ptr)) ++ptr;
674 	        if (strlen(ptr)<2 || *ptr == '#') continue;
675 		i = 0;
676 		while(ptr[i] && !isspace(ptr[i])) ++i;
677 		if (!ptr[i]) continue;
678 		ptr[i++] = '\0';
679 		if (ptr[i]) {
680 			l = strlen(ptr+i)+i-1;
681 			if (l>=i && ptr[l]=='\n') ptr[l] = '\0';
682 			parse_arg(ptr, ptr+i);
683 		}
684 	}
685 }
686 
read_rc()687 void read_rc()
688 {
689 	FILE *fr = NULL;
690 	char name[NLEN], *ptr;
691 
692 	if ((ptr=getenv("HOME"))) {
693 		if (RcFile) {
694 			if (ptr && *RcFile == '~' && RcFile[1] == '/')
695 				sprintf(name, "%s/%s", ptr, RcFile+2);
696 			else
697 				strcpy(name, RcFile);
698 		}
699 		else
700 			sprintf(name, "%s/.%s", ptr, DEFAULT_RC);
701 		fr = fopen(name, "r");
702 	}
703 
704 	if (!fr) {
705 		sprintf(name, "%s/%s", SHAREDIR, DEFAULT_RC);
706 		fr = fopen(name, "r");
707 	}
708 
709 	if (fr) {
710 		parse_rc(fr);
711 		fclose(fr);
712 	}
713 }
714 #endif /* MINIMAL */
715 
init(int argc,char * argv[])716 void init(int argc, char *argv[])
717 {
718 	int i;
719 
720 	/* Default settings */
721 	*ewin.name = '\0';
722 	amax = AMAX;
723 	bmax = BMAX;
724 	umax = UMAX;
725 
726 #ifndef MINIMAL
727 	memset((void *)binding, 0, 26*sizeof(char *));
728 
729 	for (i=1; i<argc; i++) {
730 		if (i<argc-1 && !strcasecmp(argv[i], "-rc"))
731 		RcFile = strdup(argv[++i]);
732 	}
733 	read_rc();
734 #endif /* MINIMAL */
735 
736 	/* get command line options */
737 	for (i=1; i<argc; i++) {
738 		if ((i<argc-1) &&
739 			(argv[i][0]=='-'
740 #ifndef MINIMAL
741 || argv[i][0]=='@'
742 #endif
743 			)) {
744 				parse_arg(argv[i], argv[i+1]);
745 				++i;
746 		} else {
747 			if (*ewin.name) break;
748 		        /* case of syntax  'filename:linenumber' */
749 			{
750                             char* p = strchr(argv[i], ':');
751                             if (p) {
752                                  *p++ = '\0';
753                                  ewin.jump = atoi(p);
754                             }
755 			}
756 			strcpy(ewin.name, argv[i]);
757 		}
758 	}
759 
760 	/* alloc memory for the main buffer and block buffer */
761 	edbuf = (char *) malloc((size_t)(amax+tabsize+1));
762         bb = (char *) malloc((size_t)(bmax+tabsize+1));
763 	unbuf = (void *) malloc((size_t)(umax+tabsize+1));
764 
765 	if (!edbuf || !bb || !unbuf) {
766 		fprintf(stderr,"Memory allocation failed, aborting !!\n");
767 		exit(1);
768         }
769 }
770 
main(int argc,char * argv[])771 int main(int argc,char *argv[])
772 {
773 	int skey;
774 /* edit engine init */
775 	ttopen();
776 	y1 = YTOP;
777 	x = 1; y=0;
778 
779 	/* get command line options */
780 	init(argc, argv);
781 
782 	/* set path */
783 	if (cfdpath == NULL) {
784 		cfdpath = (char *) malloc(BUFSIZ);
785 		getcwd(cfdpath, BUFSIZ);
786 #ifdef MSVC
787 		if (strcmp(cfdpath, "\\") != 0)
788 			strcat(cfdpath, "\\");
789 #else
790 		if (strcmp(cfdpath, "/") != 0)
791 			strcat(cfdpath, "/");
792 #endif /* MSVC */
793 	}
794 
795 	do_open();
796 	scr_update();
797 
798 /* end of edit engine init */
799 	/* main event loop, dispatch function calls in response to events */
800 	while(exitf)  {
801 		skey = get_key();
802 		switch(executive) {
803 			case MAIN:
804 				main_exec(skey);
805 				break;
806 			case DIALOG:
807 				dialog(skey);
808 				break;
809 			case OPTIONS:
810 				options(skey);
811 				break;
812 		}
813 	}
814     return(0);
815 }
816