-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.c
273 lines (233 loc) · 6.13 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
#include <stdio.h>
/* make global definitions not external */
#define maindef
#include "estruct.h" /* global structures and defines */
#include "etype.h" /* variable prototype definitions */
#include "edef.h" /* global definitions */
#include "english.h" /* human language definitions */
#include "ebind.h" /* default key bindings */
/* for many different systems, increase the default stack space */
#ifndef GOOD
#define GOOD 0
#endif
#if CALLED
emacs(int argc, char *argv[])
#else
main(int argc, char *argv[])
#endif
{
register int status;
/* Initialize the editor */
vtinit(); /* Terminal */
edinit("main"); /* Buffers, windows */
if (argc > 1)
{
strcpy(curbp->b_fname, argv[1]);
readin(curbp->b_fname);
curbp->b_dotp = lforw(curbp->b_linep);
curbp->b_doto = 0;
curbp->b_active = TRUE;
}
status = editloop();
vttidy();
#if CALLED
return (status);
#else
exit(status);
#endif
}
/*
* This is called to let the user edit something. Note that if you
* arrange to be able to call this from a macro, you will have invented the
* "recursive-edit" function.
*/
editloop()
{
register int c; /* command character */
register int oldflag; /* old last flag value */
/* setup to process commands */
lastflag = 0; /* Fake last flags. */
loop:
/* if we were called as a subroutine and want to leave, do so */
if (eexitflag)
return (eexitval);
/* execute the "command" macro...normally null */
oldflag = lastflag; /* preserve lastflag through this */
lastflag = oldflag;
/* Fix up the screen */
update(FALSE);
/* get the next command from the keyboard */
c = getkey();
/* if there is something on the command line, clear it */
if (mpresf != FALSE)
{
mlerase();
update(FALSE);
}
/* override the arguments if prefixed */
if (prefix)
{
if (islower(c & 255))
c = (c & ~255) | toupper(c & 255);
c |= prefix;
prefix = 0;
}
/* and execute the command */
execute(c);
goto loop;
}
/*
* Initialize all of the buffers and windows. The buffer name is passed down
* as an argument, because the main routine may have been told to read in a
* file by default, and we want the buffer name to be right.
*/
edinit(char bname[])
{
register BUFFER *bp;
register WINDOW *wp;
int cmark; /* current mark */
/* initialize some important globals */
bp = bfind(bname, TRUE); /* First buffer */
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
if (bp == (BUFFER *) NULL || wp == (WINDOW *) NULL)
meexit(1);
curbp = bp; /* Make this current */
wheadp = wp;
curwp = wp;
wp->w_wndp = (WINDOW *) NULL; /* Initialize window */
wp->w_bufp = bp;
bp->b_nwnd = 1; /* Displayed. */
wp->w_linep = bp->b_linep;
wp->w_dotp = bp->b_linep;
wp->w_doto = 0;
for (cmark = 0; cmark < NMARKS; cmark++)
{
wp->w_markp[cmark] = (LINE *) NULL;
wp->w_marko[cmark] = 0;
}
wp->w_toprow = 0;
wp->w_fcol = 0;
wp->w_ntrows = term.t_nrow - 1; /* "-1" for mode line. */
wp->w_force = 0;
wp->w_flag = WFMODE | WFHARD; /* Full. */
}
/*
* This is the general command execution routine. It handles the fake binding
* of all the keys to "self-insert". It also clears out the "thisflag" word,
* and arranges to move it to the "lastflag", so that the next command can
* look at it. Return the status of command.
*/
execute(int c)
{
register int status;
KEYTAB *key; /* key entry to execute */
/* if the keystroke is a bound function...do it */
key = getbind(c);
if (key != (KEYTAB *) NULL)
{
thisflag = 0;
status = execkey(key);
lastflag = thisflag;
return (status);
}
/*
* If a space was typed, fill column is defined, the argument is non-
* negative, wrap mode is enabled, and we are now past fill column, and we
* are not read-only, perform word wrap.
*/
if ((c >= 0x20 && c <= 0xFF))
{ /* Self inserting. */
thisflag = 0; /* For the future. */
/*
* if we are in overwrite mode, not at eol, and next char is not a tab or
* we are at a tab stop, delete a char forword
*/
if (curwp->w_bufp->b_mode & MDOVER &&
curwp->w_doto < curwp->w_dotp->l_used &&
(lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
(curwp->w_doto) % tabsize == (tabsize - 1)))
ldelete(1L);
status = linsert(1, c);
/* check auto-save mode */
if (curbp->b_mode & MDASAVE)
if (--gacount == 0)
{
/* and save the file if needed */
upscreen();
filesave();
gacount = gasave;
}
lastflag = thisflag;
return (status);
}
TTbeep();
mlwrite(TEXT19); /* complain */
/* "[Key not bound]" */
lastflag = 0; /* Fake last flags. */
return (FALSE);
}
/*
* Quit command. If an argument, always quit. Otherwise confirm if a buffer
* has been changed and not written out. Normally bound to "C-X C-C".
*/
quit()
{
register int status; /* return status */
if ((curbp->b_flag & BFCHG) == 0 || (status = mlyesno(TEXT104)) == TRUE)
/* "Modified buffers exist. Leave anyway" */
status = meexit(GOOD);
mlerase();
return (status);
}
meexit(int status)
{
eexitflag = TRUE; /* flag a program exit */
eexitval = status;
/* and now.. we leave and let the main loop kill us */
return (TRUE);
}
/*
* Abort. Beep the beeper. Kill off any keyboard macro, etc., that is in
* progress. Sometimes called as a routine, to do general aborting of stuff.
*/
ctrlg()
{
TTbeep();
mlwrite(TEXT8);
/* "[Aborted]" */
return (ABORT);
}
/*
* tell the user that this command is illegal while we are in VIEW
* (read-only) mode
*/
rdonly()
{
TTbeep();
mlwrite(TEXT109);
/* "[Key illegal in VIEW mode]" */
return (FALSE);
}
meta() /* set META prefixing pending */
{
prefix |= META;
return (TRUE);
}
cex() /* set ^X prefixing pending */
{
prefix |= CTLX;
return (TRUE);
}
/*
* bytecopy: copy a string...with length restrictions ALWAYS null
* terminate
*/
char *bytecopy(char *dst, char *src, int maxlen)
{
char *dptr; /* ptr into dst */
dptr = dst;
while (*src && (maxlen-- > 0))
*dptr++ = *src++;
*dptr = 0;
return (dst);
}