|
|
1.1 root 1: /*
2: * This program is in public domain; written by Dave G. Conroy.
3: * This file contains the main driving routine, and some keyboard processing
4: * code, for the MicroEMACS screen editor.
5: * Modified by W. L. Sheldon for use with the COHERENT Operating System -
6: * VT100 terminal key bindings.
7: */
8:
9: #include <stdio.h>
10: #include "ed.h"
11:
12: #if VMS
13: #include <ssdef.h>
14: #define GOOD (SS$_NORMAL)
15: #define BAD (SS$_ABORT)
16: #endif
17:
18: #ifndef GOOD
19: #define GOOD 0
20: #define BAD 1
21: #endif
22:
23: int currow; /* Working cursor row */
24: int curcol; /* Working cursor column */
25: int curgoal; /* Goal column */
26: BUFFER *curbp; /* Current buffer */
27: WINDOW *curwp; /* Current window */
28: BUFFER *bheadp; /* BUFFER listhead */
29: WINDOW *wheadp; /* WINDOW listhead */
30: BUFFER *blistp; /* Buffer list BUFFER */
31: #if LIBHELP
32: BUFFER *helpbp; /* Help buffer */
33: #endif
34: BUFFER *errbp; /* Error file BUFFER */
35: uchar pat[NPAT]; /* Pattern */
36:
37: uchar errfile[NFILEN]; /* Error file name */
38:
39: #if LIBHELP
40: uchar *helpfile=0; /* Help file name ptr. */
41: uchar *helpindex=0; /* Help index file name ptr. */
42: uchar hfname[NFILEN]; /* Help file name place */
43: uchar hiname[NFILEN]; /* Help index file name place */
44: #endif
45: extern char *strcpy(); /* copy string */
46: extern char *getenv();
47:
48: /*
49: * File-name list for command line...
50: */
51: uchar *cfiles[NCFILES]; /* Command line specified files */
52: int cfilecnt; /* File count... */
53:
54: /*
55: * Command line switch flags...
56: */
57: unsigned int runswitch;
58:
59: #if LK201
60: /*
61: * Mapping table for all of the funny keys with the numeric parameters
62: * on the LK201.
63: * Indexed by the code, which is between 0 (unused) and 34 (F20).
64: * An entry of 0 means no mapping. The map goes to command keys.
65: * If I had a "special" bit, I could use the code in the escape sequence
66: * as a key code, and return (for example) "do" as SPECIAL + 29.
67: * Then the dispatch would be done by the default keymap. This is probably a
68: * better way to go.
69: */
70: short lkmap[] = {
71: #if EXKEYS
72: 0,
73: FN18, /* 1 Find */
74: FN19, /* 2 Insert here */
75: FN1A, /* 3 Remove */
76: FN1B, /* 4 Select */
77: FN1C, /* 5 Previous screen */
78: FN1D, /* 6 Next screen */
79: 0,
80: 0,
81: 0,
82: FN17, /* 10 Compose */
83: 0,
84: FN3, /* 12 Print screen */
85: 0,
86: FN4, /* 14 F4 */
87: 0,
88: 0,
89: FN6, /* 17 F6 */
90: FN7, /* 18 F7 */
91: FN8, /* 19 F8 */
92: FN9, /* 20 F9 */
93: FNA, /* 21 F10 */
94: 0,
95: 0,
96: 0,
97: 0,
98: FNE, /* 26 F14 */
99: 0,
100: FN15, /* 28 Help */
101: FN16, /* 29 Do C-X E */
102: 0,
103: FN11, /* 31 F17 C-X P */
104: FN12, /* 32 F18 C-X N */
105: FN13, /* 33 F19 C-X Z */
106: FN14 /* 34 F20 C-X C-Z */
107: #else
108: 0,
109: OBND|CTRL|'S', /* 1 Find */
110: OBND|CTRL|'Y', /* 2 Insert here */
111: OBND|CTRL|'W', /* 3 Remove */
112: OBND|CTRL|'@', /* 4 Select */
113: OBND|META|'V', /* 5 Previous screen */
114: OBND|CTRL|'V', /* 6 Next screen */
115: 0,
116: 0,
117: 0,
118: 0, /* 10 Compose */
119: 0,
120: 0, /* 12 Print screen */
121: 0,
122: 0, /* 14 F4 */
123: 0,
124: 0,
125: 0, /* 17 F6 */
126: 0, /* 18 F7 */
127: 0, /* 19 F8 */
128: 0, /* 20 F9 */
129: 0, /* 21 F10 */
130: 0,
131: 0,
132: 0,
133: 0,
134: 0, /* 26 F14 */
135: 0,
136: 0, /* 28 Help */
137: OBND|PFX1|'E', /* 29 Do C-X E */
138: 0,
139: OBND|PFX1|'P', /* 31 F17 C-X P */
140: OBND|PFX1|'N', /* 32 F18 C-X N */
141: OBND|PFX1|'Z', /* 33 F19 C-X Z */
142: OBND|PFX1|CTRL|'Z' /* 34 F20 C-X C-Z */
143: #endif
144: };
145: #endif
146:
147: main(argc, argv)
148: uchar *argv[];
149: {
150: register int c;
151: register int f;
152: register int n;
153: uchar bname[NBUFN];
154:
155: #if MSDOS
156: setkeys();
157: #endif
158: #if IBM
159: vidnit();
160: #endif
161: for (c = 0; c < MAXREB; c++) /* nothing in the new table */
162: bind.table[c].k_synonym = bind.table[c].k_code = -1;
163: runswitch = 0; /* Initialize the switches */
164: bind.ffold = FALSE; /* initialize the fold flg */
165: bind.bracket = 1; /* initialize bracket mode */
166: bind.pfx1 = CTRL|'X'; /* initialize prefix keys */
167: bind.pfx2 = bind.pfx3 = -1;
168: bind.repeat = CTRL|'U';
169: argproc(argc, argv); /* Parse the arg list */
170: #if GEM
171: if (runswitch & CF_GRABMEM) /* Get largest chunk of */
172: grabmem(0, 0); /* memory (ST only) */
173: #endif
174: #if _I386
175: {
176: /*
177: * Speed up processing on 80386 for small files.
178: */
179: char *junk;
180:
181: if (NULL != (junk = malloc(128L * 1024L)))
182: free(junk);
183: }
184: #endif
185: topen(); /* Force the length setup */
186: strcpy(bname, "main"); /* Work out the name of */
187: if (cfilecnt > 0) /* the default buffer. */
188: makename(bname, cfiles[0]); /* Make a buffer name */
189: edinit(bname); /* Buffers, windows. */
190: vtinit(); /* Displays. */
191: if (cfilecnt > 0) { /* If there are files */
192: update(); /* You have to update */
193: readin(cfiles[0]); /* in case "[New file]" */
194: }
195: if (cfilecnt > 1) { /* If more than one */
196: n = (term.t_nrow - cfilecnt - 1) / cfilecnt;
197: for (c = 1; c < cfilecnt ; c++) { /* For all other files... */
198: splitwind(0,0); /* Split this window... */
199: if ((f=curwp->w_ntrows-n) != 0)
200: shrinkwind(0,f); /* Even out the windows */
201: nextwind(0,0); /* Go on to the next one */
202: visitfile(cfiles[c]); /* Read in that file */
203: }
204: }
205: if ((runswitch & CF_ERROR) != 0) {
206: splitwind(0,0); /* Split this window */
207: f = curwp->w_ntrows - ERRLINES; /* Make error window small */
208: if (f > 0)
209: shrinkwind(0,f);
210: readerr();
211: nextwind();
212: mlerase();
213: update();
214: nexterr(0,1);
215: update();
216: }
217: lastflag = 0; /* Fake last flags. */
218: if (NULL != bind.macs[MAXMAC]) /* initialization macro */
219: doMac(bind.macs + MAXMAC, FALSE, 1);
220:
221: for (;;) {
222: update(); /* Fix up the screen */
223: c = getbind(0); /* Get a key */
224: if (mpresf != FALSE) { /* If a message there */
225: mlerase(); /* get rid of it... */
226: update(); /* Fix screen */
227: if (c == ' ') /* ITS EMACS does this */
228: continue; /* (eat a space) */
229: }
230: f = FALSE;
231: n = 1;
232: if (c == bind.repeat) { /* ^U, start argument */
233: int ctmp;
234:
235: f = TRUE; /* We have a count */
236: n = getnum("Arg", 4, &ctmp); /* get the count */
237: c = ctmp; /* And get the last chr */
238: }
239: if (kbdmip != NULL) { /* Save macro strokes. */
240: if (kbdmip > (kbdm + ((NKBDM - 3)/2))) {
241: ctrlg(FALSE, 0);
242: continue;
243: }
244: if (f != FALSE) {
245: *kbdmip++ = bind.repeat;
246: *kbdmip++ = n;
247: }
248: *kbdmip++ = c;
249: }
250: bracketoff();
251: execute(c, f, n); /* Do it. */
252: }
253: }
254:
255: /*
256: * Initialize all of the buffers and windows.
257: * The buffer name is passed down as an argument, because the main routine may
258: * have been told to read in a file by default, and we want the buffer name to
259: * be right.
260: */
261: edinit(bname)
262: uchar bname[];
263: {
264: register BUFFER *bp;
265: register WINDOW *wp;
266:
267: bp = bfind(bname, TRUE, 0); /* First buffer */
268: blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
269: #if LIBHELP
270: helpbp = bfind("[Help]", TRUE, BFTEMP|BFHELP); /* Help buffer */
271: #endif
272: wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
273: if (bp==NULL || wp==NULL || blistp==NULL)
274: abort();
275: curbp = bp; /* Make this current */
276: wheadp = wp;
277: curwp = wp;
278: wp->w_wndp = NULL; /* Initialize window */
279: wp->w_bufp = bp;
280: bp->b_nwnd = 1; /* Displayed. */
281: wp->w_linep = bp->b_linep;
282: wp->w_dotp = bp->b_linep;
283: wp->w_doto = 0;
284: wp->w_markp = NULL;
285: wp->w_marko = 0;
286: wp->w_toprow = 0;
287: wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */
288: wp->w_force = 0;
289: wp->w_flag = WFMODE|WFHARD; /* Full. */
290: }
291:
292:
293: /*
294: * Read in a key. Do the standard keyboard preprocessing.
295: * Convert the keys to the internal character set. On the LK201, which lacks
296: * a reasonable ESC key, make the grave accent a meta key too; this is a fairly
297: * common customization around Digital. Also read and decode the arrow keys,
298: * and other special keys. This is done in Rainbow mode; does this work on all
299: * the terminals with LK201 keyboards?
300: */
301: getkey()
302: {
303: register int c;
304: #if LK201
305: register int n;
306: for (;;) {
307: if ((c = tgetc()) == AGRAVE) /* Alternate M- prefix. */
308: return (META | getCtl());
309: if (c == METACH) { /* M-, or special key. */
310: if ((c = tgetc()) == '[') { /* Arrows and extras. */
311: switch (c = tgetc()) {
312: case 'A':
313: return (OBND | CTRL | 'P');
314: case 'B':
315: return (OBND | CTRL | 'N');
316: case 'C':
317: return (OBND | CTRL | 'F');
318: case 'D':
319: return (OBND | CTRL | 'B');
320: }
321: if (c >= '0' && c <= '9') {
322: n = 0;
323: do {
324: n = 10*n + c - '0';
325: }
326: while ((c = tgetc()) >= '0' && c <= '9');
327: if (c == '~' && n <= 34 && (c = lkmap[n]))
328: return (c);
329: }
330: continue;
331: }
332: if (c == 'O') {
333: switch (tgetc()) {
334: case 'P': /* PF1 => M-X (Future) */
335: return (OBND | META | 'X');
336: case 'Q': /* PF2 => C-Q */
337: return (OBND | CTRL | 'Q');
338: case 'R': /* PF3 => C-S */
339: return (OBND | CTRL | 'S');
340: case 'S': /* PF4 => C-R */
341: return (OBND | CTRL | 'R');
342: }
343: continue;
344: }
345: return (META | toCtl(c));
346: }
347: break;
348: }
349: #else
350: #if VT100
351: for (;;) {
352: if ((c = tgetc()) == METACH) { /* Apply M- prefix */
353: if ((c = tgetc()) == '[') { /* Arrow keys. */
354: switch (tgetc()) {
355: case 'A':
356: return (OBND | CTRL | 'P');
357: case 'B':
358: return (OBND | CTRL | 'N');
359: case 'C':
360: return (OBND | CTRL | 'F');
361: case 'D':
362: return (OBND | CTRL | 'B');
363: case 'P':
364: return (OBND | CTRL | 'D'); /* DEL key */
365: case 'H':
366: return (OBND | CTRL | 'A'); /* HOME key */
367: case '1':
368: switch (tgetc()) {
369: case 'x':
370: return (OBND | META | '?'); /* F1 help C/ASM word */
371: case 'y':
372: return (OBND | PFX1 | '2'); /* Alt-F1 open 2nd window */
373: }
374: case '2':
375: switch (tgetc()) {
376: case '4':
377: if ((tgetc()) == 'H')
378: return (OBND | CTRL | 'E'); /* END key */
379: case 'x':
380: return (OBND | PFX1 | CTRL | 'V'); /* new file F2 */
381: }
382: case 'V':
383: return (OBND | META | 'V'); /* PGUP key */
384: case 'U':
385: return (OBND | CTRL | 'V'); /* PGDN key */
386: case '3':
387: switch (tgetc()) {
388: case 'x':
389: return (OBND | META | 'S'); /* F3 search forward */
390: case 'y':
391: return (OBND | META | '/'); /* ALT-F3 cont search */
392: }
393: case '4':
394: tgetc();
395: return (OBND | META | 'R'); /* F4 search backward */
396: case '5':
397: tgetc();
398: return (OBND | META | '%'); /* F5 search & replace */
399: case '6':
400: tgetc();
401: return (OBND | PFX1 | 'N'); /* F6 next window */
402: case '8':
403: tgetc();
404: return (OBND | CTRL | 'Z'); /* F8 save/exit */
405: case '0':
406: switch (tgetc()) {
407: case 'x':
408: return (OBND | PFX1 | '1'); /* F10 close other wndws */
409: case 'y':
410: return (OBND | META | 'J');
411: }
412: }
413: continue;
414: }
415: if (c == 'O') { /* function keys */
416: switch (tgetc()) {
417: case 'P': /* PF1 => M-X (Future) */
418: return (OBND | META | 'X');
419: case 'Q': /* PF2 => C-Q */
420: return (OBND | CTRL | 'Q');
421: case 'R': /* PF3 => C-S */
422: return (OBND | CTRL | 'S');
423: case 'S': /* PF4 => C-R */
424: return (OBND | CTRL | 'R');
425: }
426: continue;
427: }
428: return (META | toCtl(c));
429: }
430: break;
431: }
432: #else
433: if ((c = tgetc()) == METACH) /* Apply M- prefix */
434: return (META | getCtl());
435: #endif
436: #endif
437: if (c == 0x0D && bind.autoindent)
438: return (OBND | CTRL | 'J');
439: if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
440: return (CTRL | '@' | c);
441: return (c);
442: }
443:
444: /*
445: * Apply control modifications to a key
446: */
447: toCtl(c)
448: register int c;
449: {
450: if (c>='a' && c<='z') /* Force to upper */
451: return (c - 0x20);
452: if (c>=0x00 && c<=0x1F) /* C0 control -> C- */
453: return (c | CTRL | '@');
454: return (c);
455: }
456:
457: getCtl()
458: {
459: return (toCtl(tgetc()));
460: }
461:
462: /*
463: * Fancy quit command, as implemented by Norm.
464: * If the current buffer has changed do a write current buffer and exit emacs,
465: * otherwise simply exit.
466: */
467: quickexit(f, n)
468: {
469: if ((curbp->b_flag&BFCHG) != 0 /* Changed. */
470: && (curbp->b_flag&(BFTEMP|BFERROR|BFNOWRT)) == 0)
471: /* Real and not R/O... */
472: filesave(f, n);
473: quit(f, n); /* conditionally quit */
474: }
475:
476: /*
477: * Quit command. If an argument, always quit. Otherwise confirm
478: * if a buffer has been changed and not written out.
479: * Normally bound to "C-X C-C".
480: */
481: quit(f, n)
482: {
483: register int s = FALSE;
484:
485: if (f != FALSE /* Argument forces it. */
486: || anycb() == FALSE /* All buffers clean. */
487: || (s=mlyesno("Quit")) == TRUE) { /* User says it's OK. */
488: vttidy();
489: #if MSDOS
490: resetkeys();
491: #endif
492: if (f != FALSE || s != FALSE)
493: exit(BAD);
494: else
495: exit(GOOD);
496: }
497: #if MSDOS
498: setkeys();
499: #endif
500: return (s);
501: }
502:
503: /*
504: * Get binding char. Turn prefix chars into or'ed bits.
505: */
506: getbind(bound)
507: register int bound;
508: {
509: register int c;
510:
511: if (((c = getkey()) == bind.pfx1) && !(bound & PFX1))
512: return (PFX1 | toCtl(getbind(bound | PFX1)));
513: if ((c == bind.pfx2) && !(bound & PFX2))
514: return (PFX2 | toCtl(getbind(bound | PFX2)));
515: if ((c == bind.pfx3) && !(bound & PFX3))
516: return (PFX3 | toCtl(getbind(bound | PFX3)));
517: return (c);
518: }
519:
520: /*
521: * Abort.
522: * Beep the beeper.
523: * Kill off any keyboard macro,
524: * etc., that is in progress.
525: * Sometimes called as a routine,
526: * to do general aborting of
527: * stuff.
528: */
529: ctrlg(f, n)
530: {
531: tbeep();
532: if (kbdmip != NULL) {
533: if (NULL != kbdm) {
534: free(kbdm);
535: kbdm = NULL;
536: }
537: kbdmip = NULL;
538: }
539: return (ABORT);
540: }
541:
542: #if MSDOS
543: setkeys() /* redefine cursor keys */
544: /* so that they make */
545: /* sense to microEMACS */
546: /* as described in IBM */
547: /* DOS tech. reference */
548: /* manual */
549: {
550: #if !IBM
551: static uchar *ctlseq[] = {
552: "\033[0;72;16p", /* up = <ctrl-p> */
553: "\033[0;77;6p", /* right = <ctrl-f> */
554: "\033[0;75;2p", /* left = <ctrl-b> */
555: "\033[0;80;14p", /* down = <ctrl-n> */
556: "\033[0;81;22p", /* pg dn = <ctrl-v> */
557: "\033[0;73;27;86p", /* pg up = <esc>V */
558: "\033[0;71;27;60p", /* home = <esc>< */
559: "\033[0;79;27;62p", /* end = <esc>> */
560: "\033[0;83;127p", /* del = del */
561: "\033[0;3;27;46p", /* <ctrl-@> = <exc>. */
562: NULL
563: };
564: register uchar **ctlp;
565:
566: for (ctlp = ctlseq; NULL != *ctlp; ctlp++)
567: mlwrite(*ctlp);
568: #endif
569: }
570:
571:
572:
573: resetkeys() /* redefine cursor keys */
574: /* to default values */
575: {
576: #if !IBM
577: static uchar *ctlseq[] = {
578: "\033[0;72;0;72p",
579: "\033[0;77;0;77p",
580: "\033[0;75;0;75p",
581: "\033[0;80;0;80p",
582: "\033[0;81;0;81p",
583: "\033[0;73;0;73p",
584: "\033[0;71;0;71p",
585: "\033[0;79;0;79p",
586: "\033[0;83;0;83p",
587: "\033[0;3;0;3p",
588: NULL
589: };
590: register uchar **ctlp;
591:
592: for (ctlp = ctlseq; NULL != *ctlp; ctlp++)
593: mlwrite(*ctlp);
594: #endif
595: }
596: #endif
597:
598: argproc(argc, argv)
599: int argc;
600: uchar **argv;
601: {
602: int i;
603: uchar *flexn;
604: extern uchar *flexName();
605: uchar *ptr;
606:
607: if (!bind.tabsiz &&
608: (NULL == (ptr = getenv("TABSIZ")) ||
609: !(bind.tabsiz = atoi(ptr))))
610: bind.tabsiz = 8;
611: cfilecnt = 0;
612: flexn = NULL;
613: for (i = 1; i < argc; i++) {
614: ptr = argv[i]; /* Get this argument... */
615: if (*ptr == '-') { /* Is this a switch? */
616: switch (ptr[1]) {
617: case 'd':
618: runswitch |= CF_DEBUG;
619: break;
620: case 'e':
621: runswitch |= CF_ERROR;
622: if (ptr[2] == 0) {
623: if (++i == argc) {
624: runswitch &= ~CF_ERROR;
625: continue;
626: }
627: strcpy(errfile, argv[i]);
628: }
629: else {
630: strcpy(errfile, &ptr[2]);
631: }
632: break;
633: case 'f':
634: if (ptr[2] == 0) {
635: if (++i == argc)
636: continue;
637: flexn = argv[i];
638: }
639: else
640: flexn = ptr + 1;
641: break;
642: #if LIBHELP
643: case 'h': /* Alternate help */
644: if (ptr[2] == 0) {
645: if (++i == argc) {
646: continue;
647: }
648: strcpy(hfname, argv[i]);
649: }
650: else {
651: strcpy(hfname, &ptr[2]);
652: }
653: strcpy(hiname, hfname);
654: #if GEM || MSDOS
655: strcat(hfname, ".hlp");
656: #endif
657: strcat(hiname, ".idx");
658: helpfile = hfname;
659: helpindex = hiname;
660: break;
661: #endif
662: case 'w':
663: runswitch |= CF_WARN;
664: break;
665: #if NATIVE && GEM
666: case 'l': /* long screen */
667: runswitch |= CF_LONGSCR;
668: break;
669: case 't': /* very long screen */
670: runswitch |= CF_VLONG;
671: break;
672: #endif
673: #if GEM
674: case 'x': /* grab all memory */
675: runswitch |= CF_GRABMEM;
676: break;
677: #endif
678: default:
679: break;
680: }
681: /* Process this switch */
682: }
683: else { /* Otherwise... */
684: if (cfilecnt >= NCFILES)
685: continue;
686: cfiles[cfilecnt++] = ptr; /* This is a file. */
687: #if GEM
688: fixname(cfiles[cfilecnt-1]);
689: #endif
690: }
691: }
692: if (NULL == flexn)
693: loadBup(flexName(), TRUE);
694: else
695: loadBup(flexn, ABORT);
696: }
697:
698: #if EXKEYS
699: /*
700: * Do nothing. ("Dead")
701: */
702: ignore()
703: {
704: return TRUE;
705: }
706: #endif
707:
708: /*
709: * Get a numeric argument...
710: */
711: getnum(prompt, n, lastc)
712: register uchar *prompt;
713: register int n;
714: register int *lastc;
715: {
716: register int mflag = 0;
717: register int c;
718:
719: mflag = 0; /* that can be discarded. */
720: mlwrite("%s: %d", prompt, n);
721: while ((c = getbind(0)) >='0' && c<='9'
722: || c==bind.repeat || c=='-'){
723: if (c == bind.repeat)
724: n = n*4;
725: /*
726: * If dash, and start of argument string, set arg.
727: * to -1. Otherwise, insert it.
728: */
729: else if (c == '-') {
730: if (mflag)
731: break;
732: n = 0;
733: mflag = -1;
734: }
735: /*
736: * If first digit entered, replace previous argument
737: * with digit and set sign. Otherwise, append to arg.
738: */
739: else {
740: if (!mflag) {
741: n = 0;
742: mflag = 1;
743: }
744: n = 10*n + c - '0';
745: }
746: mlwrite("%s: %d", prompt, (mflag >=0) ? n : (n ? -n : -1));
747: }
748: *lastc = c; /* Return the terminal char. */
749: /*
750: * Make arguments preceded by a minus sign negative and change
751: * the special argument "^U -" to an effective "^U -1".
752: */
753: if (mflag == -1) {
754: if (n == 0)
755: n++;
756: n = -n;
757: }
758: return n;
759: }
760:
761: #if GEM
762: /*
763: * The following routine gets around a problem with GEMDOS Malloc(),
764: * it forces a single, very large Malloc() so very large files can
765: * be read.
766: * It is available only on the Atari ST, and is bound to M-+
767: * it can also be specified using the -x switch
768: */
769: #include <osbind.h>
770:
771: grabmem(f, n)
772: int f, n;
773: {
774: extern char *lmalloc();
775: register char *p = NULL;
776: register long t;
777:
778: t = Malloc(-1L); /* How big is free memory? */
779: while (p == NULL) { /* Until we have a block */
780: t -= 4096L; /* shrink the block */
781: if (t < 2048) { /* if too small, tell user */
782: mlwrite( "[Cannot allocate memory]" );
783: return 1; /* and fail */
784: }
785: p = lmalloc(t); /* Try to get this chunk */
786: } /* loop until success or fail */
787: free(p); /* return chunk to arena */
788: mlwrite( "[Allocated %ld bytes]", t ); /* tell user how much */
789: return 0; /* and return success */
790: }
791: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.