home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / dos-mg2a < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  51.1 KB

  1. Path: xanth!mcnc!gatech!cwjcc!hal!ncoast!allbery
  2. From: jbs@ll-xn.UUCP (Jeff Siegal)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i015: Support for MG2A under MS-DOS
  5. Message-ID: <8808060436.AA26237@EDDIE.MIT.EDU>
  6. Date: 6 Aug 88 04:36:30 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: jbs@ll-xn.UUCP (Jeff Siegal)
  9. Lines: 2174
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 15
  13. Submitted-by: "Jeff Siegal" <jbs@ll-xn.UUCP>
  14. Archive-name: dos-mg2a
  15.  
  16. The enclosed shar file adds MS-DOS to the systems supported by the
  17. current release of MG (2A).  It should be extracted into an empty
  18. directory called "msdos", under "sys" in the mg source directory.
  19.  
  20. Jeff Siegal
  21. ----
  22. #! /bin/sh
  23. # To extract, remove mail header lines and type "sh filename"
  24. if [ ! -s ./README ]
  25. then
  26. if [ ! -d . ]
  27. then
  28.     mkdir .
  29.     echo mkdir .
  30. fi
  31. echo x - ./README
  32. sed -e 's/^X//' > ./README << '!FaR!OuT!'
  33. XThis is the source for the MS-DOS version of mg2a.  These files are
  34. Xintended to reside in a directory sys/msdos underneath the main mg2a
  35. Xsource directory. 
  36. X
  37. XThis code will run under both "Turbo C 1.5" and "Microsoft C 5.1"
  38. X
  39. XTo compile using Turbo C 1.5, copy makefile.tc from the sys/msdos
  40. Xdirectory into the main mg2a source directory, then cd into the main
  41. Xdirectory and use the Turbo C "make" program (just type "make"). 
  42. X
  43. XTo compile using Microsoft C 5.1, cd into the main directory and type
  44. X"make sys\msdos\makefile.msc"
  45. X
  46. XA few random notes:
  47. X
  48. Xo   The display routines rely on the ROM BIOS interface.  This has the
  49. X    advantage of being more portable, but at the expense of display
  50. X    speed.  Direct memory-mapped display code or using ANSI sequences with
  51. X    NANSI or FANSI-Console could be much faster.  To keep the program
  52. X    small and maintain portability, enhancements such as these should
  53. X    be supported as compile-time options (e.g. with #ifdef's)
  54. X
  55. X    The only display mode supported is 24 x 80.  To fix this, you will
  56. X    need to change NROW and NCOL ttydef.h to be the largest # of rows
  57. X    and columns supported, then you will have to change either
  58. X    ttresize() in "tty.c" or setttysize() in "ttyio.c" to check the
  59. X    BIOS parameter memory for the current screen size.
  60. X
  61. Xo   Note that the keyboard support also goes through the BIOS.
  62. X    The "backspace" key generates DELETE (so that it does a
  63. X    delete-backwards, while control-h still returns control-h (i.e.
  64. X    HELP).  Arrow keys, HOME, END, PgUp, PgDn, etc.  are supported
  65. X    (look in ttykbd.c) The ALT key works like a META key for alpha
  66. X    keys, but the BIOS doesn't return keycodes for certain ALT
  67. X    key combinations (I wish ALT-SHIFT-< worked!)  8 bit characters
  68. X    (the line drawing set!) are supported, but to enter them, you
  69. X    must use ALT-ddd (where ddd are digits on the numeric keypad).
  70. X
  71. Xo   The dired mode SEEMS to work, but I am not real happy with "dired" in the
  72. X    first place, and the MS-DOS implementation isn't very well tested.
  73. X    Presumably this is one area which will be enhanced in mg 2b.
  74. X
  75. Xo   REGEX compiles OK, but doesn't seem to work right.  I haven't done any
  76. X    extensive testing, and I'm not sure what is breaking down.  If you 
  77. X    want to play with this, you must add the
  78. X    string "-DREGEX" to the CDEFS macro in the makefile (don't try to
  79. X    add it to sysdef.h:  regex.c won't compile right (sigh)).
  80. X
  81. X    Anyway, I've got no use for REGEX at the moment, and compiling it
  82. X    in adds 15K to the base executable size of 90K.  I pass.
  83. X
  84. XGood luck with this.  We hope you find it useful.  Please send any
  85. Ximprovements you make.
  86. X
  87. XCredits:
  88. X
  89. XJohn P. Nelson (decvax!genrad!jpn, jpn@genrad.com) did the Turbo C
  90. Xport and most of the work (based on his earlier work on
  91. XMicroGnuEmacs).  Jeff Siegal (jbs@eddie.mit.edu) brought it up under
  92. XMicrosoft C and fixed a few bugs. 
  93. X
  94. XThis document was written by John P. Nelson and modified by Jeff Siegal.
  95. !FaR!OuT!
  96. fi
  97. if [ ! -s ./alloca.c ]
  98. then
  99. if [ ! -d . ]
  100. then
  101.     mkdir .
  102.     echo mkdir .
  103. fi
  104. echo x - ./alloca.c
  105. sed -e 's/^X//' > ./alloca.c << '!FaR!OuT!'
  106. X/* alloca is only required by the GNU regex code */
  107. X#ifdef REGEX
  108. X/*
  109. X    alloca -- (mostly) portable public-domain implementation
  110. X
  111. X    last edit:    86/01/26    D A Gwyn
  112. X
  113. X    This implementation of the PWB library alloca() function,
  114. X    which is used to allocate space off the run-time stack so
  115. X    that it is automatically reclaimed upon procedure exit, 
  116. X    was inspired by discussions with J. Q. Johnson of Cornell.
  117. X
  118. X    It should work under any C implementation that uses an
  119. X    actual procedure stack (as opposed to a linked list of
  120. X    frames).  There are some preprocessor constants that can
  121. X    be defined when compiling for your specific system, for
  122. X    improved efficiency; however, the defaults should be okay.
  123. X
  124. X    The general concept of this implementation is to keep
  125. X    track of all alloca()-allocated blocks, and reclaim any
  126. X    that are found to be deeper in the stack than the current
  127. X    invocation.  This heuristic does not reclaim storage as
  128. X    soon as it becomes invalid, but it will do so eventually.
  129. X
  130. X    As a special case, alloca(0) reclaims storage without
  131. X    allocating any.  It is a good idea to use alloca(0) in
  132. X    your main control loop, etc. to force garbage collection.
  133. X*/
  134. X#ifndef lint
  135. Xstatic char    SCCSid[] = "@(#)alloca.c    1.1";    /* for the "what" utility */
  136. X#endif
  137. X
  138. X#ifdef X3J11
  139. Xtypedef void    *pointer;        /* generic pointer type */
  140. X#else
  141. Xtypedef char    *pointer;        /* generic pointer type */
  142. X#endif
  143. X
  144. X#define    NULL    0            /* null pointer constant */
  145. X
  146. Xextern void    free();
  147. Xextern pointer    malloc();
  148. X
  149. X/*
  150. X    Define STACK_DIRECTION if you know the direction of stack
  151. X    growth for your system; otherwise it will be automatically
  152. X    deduced at run-time.
  153. X
  154. X    STACK_DIRECTION > 0 => grows toward higher addresses
  155. X    STACK_DIRECTION < 0 => grows toward lower addresses
  156. X    STACK_DIRECTION = 0 => direction of growth unknown
  157. X*/
  158. X
  159. X#ifndef STACK_DIRECTION
  160. X#define    STACK_DIRECTION    0        /* direction unknown */
  161. X#endif
  162. X
  163. X#if STACK_DIRECTION != 0
  164. X
  165. X#define    STACK_DIR    STACK_DIRECTION    /* known at compile-time */
  166. X
  167. X#else    /* STACK_DIRECTION == 0; need run-time code */
  168. X
  169. Xstatic int    stack_dir = 0;        /* 1 or -1 once known */
  170. X#define    STACK_DIR    stack_dir
  171. X
  172. Xstatic void
  173. Xfind_stack_direction( /* void */ )
  174. X    {
  175. X    static char    *addr = NULL;    /* address of first
  176. X                       `dummy', once known */
  177. X    auto char    dummy;        /* to get stack address */
  178. X
  179. X    if ( addr == NULL )
  180. X        {            /* initial entry */
  181. X        addr = &dummy;
  182. X
  183. X        find_stack_direction();    /* recurse once */
  184. X        }
  185. X    else                /* second entry */
  186. X        if ( &dummy > addr )
  187. X            stack_dir = 1;    /* stack grew upward */
  188. X        else
  189. X            stack_dir = -1;    /* stack grew downward */
  190. X    }
  191. X
  192. X#endif    /* STACK_DIRECTION == 0 */
  193. X
  194. X/*
  195. X    An "alloca header" is used to:
  196. X    (a) chain together all alloca()ed blocks;
  197. X    (b) keep track of stack depth.
  198. X
  199. X    It is very important that sizeof(header) agree with malloc()
  200. X    alignment chunk size.  The following default should work okay.
  201. X*/
  202. X
  203. X#ifndef    ALIGN_SIZE
  204. X#define    ALIGN_SIZE    sizeof(double)
  205. X#endif
  206. X
  207. Xtypedef union hdr
  208. X    {
  209. X    char    align[ALIGN_SIZE];    /* to force sizeof(header) */
  210. X    struct    {
  211. X        union hdr    *next;    /* for chaining headers */
  212. X        char        *deep;    /* for stack depth measure */
  213. X        }    h;
  214. X    }    header;
  215. X
  216. X/*
  217. X    alloca( size ) returns a pointer to at least `size' bytes of
  218. X    storage which will be automatically reclaimed upon exit from
  219. X    the procedure that called alloca().  Originally, this space
  220. X    was supposed to be taken from the current stack frame of the
  221. X    caller, but that method cannot be made to work for some
  222. X    implementations of C, for example under Gould's UTX/32.
  223. X*/
  224. X
  225. Xpointer
  226. Xalloca( size )                /* returns pointer to storage */
  227. X    unsigned    size;        /* # bytes to allocate */
  228. X    {
  229. X    static header    *last = NULL;    /* -> last alloca header */
  230. X    auto char    probe;        /* probes stack depth: */
  231. X    register char    *depth = &probe;
  232. X
  233. X#if STACK_DIRECTION == 0
  234. X    if ( STACK_DIR == 0 )        /* unknown growth direction */
  235. X        find_stack_direction();
  236. X#endif
  237. X
  238. X    /* Reclaim garbage, defined as all alloca()ed storage that
  239. X       was allocated from deeper in the stack than currently. */
  240. X
  241. X    {
  242. X    register header    *hp;        /* traverses linked list */
  243. X
  244. X    for ( hp = last; hp != NULL; )
  245. X        if ( STACK_DIR > 0 && hp->h.deep > depth
  246. X          || STACK_DIR < 0 && hp->h.deep < depth
  247. X           )    {
  248. X            register header    *np = hp->h.next;
  249. X
  250. X            free( (pointer)hp );    /* collect garbage */
  251. X
  252. X            hp = np;    /* -> next header */
  253. X            }
  254. X        else
  255. X            break;        /* rest are not deeper */
  256. X
  257. X    last = hp;            /* -> last valid storage */
  258. X    }
  259. X
  260. X    if ( size == 0 )
  261. X        return NULL;        /* no allocation required */
  262. X
  263. X    /* Allocate combined header + user data storage. */
  264. X
  265. X    {
  266. X    register pointer    new = malloc( sizeof(header) + size );
  267. X                    /* address of header */
  268. X
  269. X    if ( new == NULL )
  270. X        return NULL;        /* abort() is traditional */
  271. X
  272. X    ((header *)new)->h.next = last;
  273. X    ((header *)new)->h.deep = depth;
  274. X
  275. X    last = (header *)new;
  276. X
  277. X    /* User storage begins just after header. */
  278. X
  279. X    return (pointer)((char *)new + sizeof(header));
  280. X    }
  281. X    }
  282. X#endif
  283. !FaR!OuT!
  284. fi
  285. if [ ! -s ./chrdef.h ]
  286. then
  287. if [ ! -d . ]
  288. then
  289.     mkdir .
  290.     echo mkdir .
  291. fi
  292. echo x - ./chrdef.h
  293. sed -e 's/^X//' > ./chrdef.h << '!FaR!OuT!'
  294. X/*
  295. X * sys/msdos/chardef.h: character set specific #defines for mg 2a
  296. X */
  297. X
  298. X#ifndef    CHARMASK
  299. X/*
  300. X * casting should be at least as efficent as anding with 0xff,
  301. X * and won't have the size problems.  Override in sysdef.h if no
  302. X * unsigned char type.
  303. X */
  304. X#define    CHARMASK(c)    ((unsigned char) (c))
  305. X#endif
  306. X
  307. X/*
  308. X * These flags, and the macros below them,
  309. X * make up a do-it-yourself set of "ctype" macros that
  310. X * understand the DEC multinational set, and let me ask
  311. X * a slightly different set of questions.
  312. X */
  313. X#define _W    0x01            /* Word.            */
  314. X#define _U    0x02            /* Upper case letter.        */
  315. X#define _L    0x04            /* Lower case letter.        */
  316. X#define _C    0x08            /* Control.            */
  317. X#define _P    0x10            /* end of sentence punctuation    */
  318. X#define    _D    0x20            /* is decimal digit        */
  319. X
  320. X#define ISWORD(c)    ((cinfo[CHARMASK(c)]&_W)!=0)
  321. X#define ISCTRL(c)    ((cinfo[CHARMASK(c)]&_C)!=0)
  322. X#define ISUPPER(c)    ((cinfo[CHARMASK(c)]&_U)!=0)
  323. X#define ISLOWER(c)    ((cinfo[CHARMASK(c)]&_L)!=0)
  324. X#define ISEOSP(c)    ((cinfo[CHARMASK(c)]&_P)!=0)
  325. X#define    ISDIGIT(c)    ((cinfo[CHARMASK(c)]&_D)!=0)
  326. X#define TOUPPER(c)    ((c)-0x20)
  327. X#define TOLOWER(c)    ((c)+0x20)
  328. X
  329. X/*
  330. X * generally useful thing for chars
  331. X */
  332. X#define CCHR(x)        ((x) ^ 0x40)    /* CCHR('?') == DEL */
  333. X
  334. X#ifndef    METACH
  335. X#define    METACH    CCHR('[')
  336. X#endif
  337. X
  338. X#ifdef    XKEYS
  339. X#define    K00    256
  340. X#define    K01    257
  341. X#define    K02    258
  342. X#define    K03    259
  343. X#define    K04    260
  344. X#define    K05    261
  345. X#define    K06    262
  346. X#define    K07    263
  347. X#define    K08    264
  348. X#define    K09    265
  349. X#define    K0A    266
  350. X#define    K0B    267
  351. X#define    K0C    268
  352. X#define    K0D    269
  353. X#define    K0E    270
  354. X#define    K0F    271
  355. X#define    K10    272
  356. X#define    K11    273
  357. X#define    K12    274
  358. X#define    K13    275
  359. X#define    K14    276
  360. X#define    K15    277
  361. X#define    K16    278
  362. X#define    K17    279
  363. X#define    K18    280
  364. X#define    K19    281
  365. X#define    K1A    282
  366. X#define    K1B    283
  367. X#define    K1C    284
  368. X#define    K1D    285
  369. X#define    K1E    286
  370. X#define    K1F    287
  371. X#define    K20    288
  372. X#define    K21    289
  373. X#define    K22    290
  374. X#define    K23    291
  375. X#define    K24    292
  376. X#define    K25    293
  377. X#define    K26    294
  378. X#define    K27    295
  379. X#define    K28    296
  380. X#define    K29    297
  381. X#define    K2A    298
  382. X#define    K2B    299
  383. X#define    K2C    300
  384. X#define    K2D    301
  385. X#define    K2E    302
  386. X#define    K2F    303
  387. X#endif
  388. !FaR!OuT!
  389. fi
  390. if [ ! -s ./cinfo.c ]
  391. then
  392. if [ ! -d . ]
  393. then
  394.     mkdir .
  395.     echo mkdir .
  396. fi
  397. echo x - ./cinfo.c
  398. sed -e 's/^X//' > ./cinfo.c << '!FaR!OuT!'
  399. X/*
  400. X *        Character class tables.
  401. X * Do it yourself character classification
  402. X * macros, that understand the multinational character set,
  403. X * and let me ask some questions the standard macros (in
  404. X * ctype.h) don't let you ask.
  405. X */
  406. X#include    "def.h"
  407. X
  408. X/*
  409. X * This table, indexed by a character drawn
  410. X * from the 256 member character set, is used by my
  411. X * own character type macros to answer questions about the
  412. X * type of a character. It handles the full multinational
  413. X * character set, and lets me ask some questions that the
  414. X * standard "ctype" macros cannot ask.
  415. X */
  416. Xchar    cinfo[256] = {
  417. X    _C,        _C,        _C,        _C,    /* 0x0X */
  418. X    _C,        _C,        _C,        _C,
  419. X    _C,        _C,        _C,        _C,
  420. X    _C,        _C,        _C,        _C,
  421. X    _C,        _C,        _C,        _C,    /* 0x1X */
  422. X    _C,        _C,        _C,        _C,
  423. X    _C,        _C,        _C,        _C,
  424. X    _C,        _C,        _C,        _C,
  425. X    0,        _P,        0,        0,    /* 0x2X */
  426. X    _W,        _W,        0,        _W,
  427. X    0,        0,        0,        0,
  428. X    0,        0,        _P,        0,
  429. X    _D|_W,        _D|_W,        _D|_W,        _D|_W,    /* 0x3X */
  430. X    _D|_W,        _D|_W,        _D|_W,        _D|_W,
  431. X    _D|_W,        _D|_W,        0,        0,
  432. X    0,        0,        0,        _P,
  433. X    0,        _U|_W,        _U|_W,        _U|_W,    /* 0x4X */
  434. X    _U|_W,        _U|_W,        _U|_W,        _U|_W,
  435. X    _U|_W,        _U|_W,        _U|_W,        _U|_W,
  436. X    _U|_W,        _U|_W,        _U|_W,        _U|_W,
  437. X    _U|_W,        _U|_W,        _U|_W,        _U|_W,    /* 0x5X */
  438. X    _U|_W,        _U|_W,        _U|_W,        _U|_W,
  439. X    _U|_W,        _U|_W,        _U|_W,        0,
  440. X    0,        0,        0,        0,
  441. X    0,        _L|_W,        _L|_W,        _L|_W,    /* 0x6X */
  442. X    _L|_W,        _L|_W,        _L|_W,        _L|_W,
  443. X    _L|_W,        _L|_W,        _L|_W,        _L|_W,
  444. X    _L|_W,        _L|_W,        _L|_W,        _L|_W,
  445. X    _L|_W,        _L|_W,        _L|_W,        _L|_W,    /* 0x7X */
  446. X    _L|_W,        _L|_W,        _L|_W,        _L|_W,
  447. X    _L|_W,        _L|_W,        _L|_W,        0,
  448. X    0,        0,        0,        0,
  449. X    _W,        _W,        _W,        _W,    /* 0x8X */
  450. X    _W,        _W,        _W,        _W,
  451. X    _W,        _W,        _W,        _W,
  452. X    _W,        _W,        _W,        _W,
  453. X    _W,        _W,        _W,        _W,    /* 0x9X */
  454. X    _W,        _W,        _W,        _W,
  455. X    _W,        _W,        _W,        0,
  456. X    0,        0,        0,        0,
  457. X    _W,        _W,        _W,        _W,    /* 0xAX */
  458. X    _W,        _W,        _W,        _W,
  459. X    0,        0,        0,        0,
  460. X    0,        0,        0,        0,
  461. X    0,        0,        0,        0,    /* 0xBX */
  462. X    0,        0,        0,        0,
  463. X    0,        0,        0,        0,
  464. X    0,        0,        0,        0,
  465. X    0,        0,        0,        0,    /* 0xCX */
  466. X    0,        0,        0,        0,
  467. X    0,        0,        0,        0,
  468. X    0,        0,        0,        0,
  469. X    0,        0,        0,        0,    /* 0xDX */
  470. X    0,        0,        0,        0,
  471. X    0,        0,        0,        0,
  472. X    0,        0,        0,        0,
  473. X    0,        0,        0,        0,    /* 0xEX */
  474. X    0,        0,        0,        0,
  475. X    0,        0,        0,        0,
  476. X    0,        0,        0,        0,
  477. X    0,        0,        0,        0,    /* 0xFX */
  478. X    0,        0,        0,        0,
  479. X    0,        0,        0,        0,
  480. X    0,        0,        0,        0,
  481. X};
  482. X
  483. X/*
  484. X * Find the name of a keystroke.  Needs to be changed to handle 8-bit printing
  485. X * characters and function keys better.     Returns a pointer to the terminating
  486. X * '\0'.
  487. X */
  488. X
  489. Xchar *keyname(cp, k)
  490. Xregister char *cp;
  491. Xregister int k;
  492. X{
  493. X    register char *np;
  494. X#ifdef    FKEYS
  495. X    extern char *keystrings[];
  496. X#endif
  497. X
  498. X    if(k < 0) k = CHARMASK(k);            /* sign extended char */
  499. X    switch(k) {
  500. X    case CCHR('@'): np = "NUL"; break;
  501. X    case CCHR('I'): np = "TAB"; break;
  502. X    case CCHR('J'): np = "LFD"; break; /* yuck, but that's what GNU calls it */
  503. X    case CCHR('M'): np = "RET"; break;
  504. X    case CCHR('['): np = "ESC"; break;
  505. X    case ' ':    np = "SPC"; break; /* yuck again */
  506. X    case CCHR('?'): np = "DEL"; break;
  507. X    default:
  508. X#ifdef    FKEYS
  509. X        if(k >= KFIRST && k <= KLAST &&
  510. X            (np = keystrings[k - KFIRST]) != NULL)
  511. X        break;
  512. X#endif
  513. X        if(k > CCHR('?')) {
  514. X        *cp++ = '0';
  515. X        *cp++ = ((k>>6)&7) + '0';
  516. X        *cp++ = ((k>>3)&7) + '0';
  517. X        *cp++ = (k&7) + '0';
  518. X        *cp = '\0';
  519. X        return cp;
  520. X        }
  521. X        if(k < ' ') {
  522. X        *cp++ = 'C';
  523. X        *cp++ = '-';
  524. X        k = CCHR(k);
  525. X        if(ISUPPER(k)) k = TOLOWER(k);
  526. X        }
  527. X        *cp++ = k;
  528. X        *cp = '\0';
  529. X        return cp;
  530. X    }
  531. X    (VOID) strcpy(cp, np);
  532. X    return cp + strlen(cp);
  533. X}
  534. !FaR!OuT!
  535. fi
  536. if [ ! -s ./fileio.c ]
  537. then
  538. if [ ! -d . ]
  539. then
  540.     mkdir .
  541.     echo mkdir .
  542. fi
  543. echo x - ./fileio.c
  544. sed -e 's/^X//' > ./fileio.c << '!FaR!OuT!'
  545. X/*
  546. X * Name:    Mg 2a
  547. X *         MSDOS file I/O (TurboC 1.5)
  548. X */
  549. X#include    "def.h"
  550. X#include    <stdio.h>
  551. X
  552. X#ifdef MSC
  553. X#include    <dos.h>
  554. X#endif /* MSC */
  555. X
  556. X#ifndef F_OK
  557. X#define F_OK    0
  558. X#define X_OK    1
  559. X#define W_OK    2
  560. X#define R_OK    4
  561. X#endif
  562. X
  563. X#ifndef NO_DIR
  564. Xextern char *wdir;
  565. X#endif
  566. X
  567. Xstatic    FILE    *ffp;
  568. X
  569. X/*
  570. X * Open a file for reading.
  571. X */
  572. Xffropen(fn)
  573. Xchar    *fn;
  574. X{
  575. X    if ((ffp=fopen(fn, "rb")) == NULL)
  576. X        return (FIOFNF);
  577. X    return (FIOSUC);
  578. X}
  579. X
  580. X/*
  581. X * Open a file for writing.
  582. X * Return TRUE if all is well, and
  583. X * FALSE on error (cannot create).
  584. X */
  585. Xffwopen(fn)
  586. Xchar    *fn;
  587. X{
  588. X    if ((ffp=fopen(fn, "wb")) == NULL) {
  589. X        ewprintf("Cannot open file for writing");
  590. X        return (FIOERR);
  591. X    }
  592. X    return (FIOSUC);
  593. X}
  594. X
  595. X/*
  596. X * Close a file.
  597. X * Should look at the status.
  598. X */
  599. Xffclose()
  600. X{
  601. X    (VOID) fclose(ffp);
  602. X    return (FIOSUC);
  603. X}
  604. X
  605. X/*
  606. X * Write a line to the already
  607. X * opened file. The "buf" points to the
  608. X * buffer, and the "nbuf" is its length, less
  609. X * the free newline. Return the status.
  610. X * Check only at the newline.
  611. X */
  612. Xffputline(buf, nbuf)
  613. Xregister char    buf[];
  614. X{
  615. X    register int    i;
  616. X
  617. X    for (i=0; i<nbuf; ++i)
  618. X        putc(buf[i]&0xFF, ffp);
  619. X    putc('\r', ffp);    /* MSDOS wants \r\n line seperators */
  620. X    putc('\n', ffp);
  621. X    if (ferror(ffp) != FALSE) {
  622. X        ewprintf("Write I/O error");
  623. X        return (FIOERR);
  624. X    }
  625. X    return (FIOSUC);
  626. X}
  627. X
  628. X/*
  629. X * Write a buffer to the already
  630. X * opened file. bp points to the
  631. X * buffer. Return the status.
  632. X * Check only at the newline and
  633. X * end of buffer.
  634. X */
  635. Xffputbuf(bp)
  636. XBUFFER *bp;
  637. X{
  638. X    register char *cp;
  639. X    register char *cpend;
  640. X    register LINE *lp;
  641. X    register LINE *lpend;
  642. X
  643. X    lpend = bp->b_linep;
  644. X    lp = lforw(lpend);
  645. X    do {
  646. X    cp = <ext(lp)[0];        /* begining of line    */
  647. X    cpend = &cp[llength(lp)];    /* end of line        */
  648. X    while(cp != cpend) {
  649. X        putc(*cp, ffp);
  650. X        cp++;    /* putc may evalualte arguments more than once */
  651. X    }
  652. X    lp = lforw(lp);
  653. X    if(lp == lpend) break;        /* no implied newline on last line */
  654. X    putc('\r', ffp);    /* MSDOS wants \r\n line seperators */
  655. X    putc('\n', ffp);
  656. X    } while(!ferror(ffp));
  657. X    if(ferror(ffp)) {
  658. X    ewprintf("Write I/O error");
  659. X    return FIOERR;
  660. X    }
  661. X    return FIOSUC;
  662. X}
  663. X
  664. X/*
  665. X * Read a line from a file, and store the bytes
  666. X * in the supplied buffer. Stop on end of file or end of
  667. X * line. Don't get upset by files that don't have an end of
  668. X * line on the last line; this seem to be common on CP/M-86 and
  669. X * MS-DOS.  Delete any CR followed by a NL:  This is the normal
  670. X * format for MS_DOS files, but also occurs when files are transferred
  671. X * from VMS or MS-DOS to Unix.
  672. X */
  673. Xffgetline(buf, nbuf, nbytes)
  674. Xregister char    buf[];
  675. Xregister int    *nbytes;
  676. X{
  677. X    register int    c;
  678. X    register int    i;
  679. X
  680. X    i = 0;
  681. X    for (;;) {
  682. X        c = getc(ffp);
  683. Xrescan:
  684. X        if (c == '\r') {        /* Delete any non-stray    */
  685. X            c = getc(ffp);        /* carriage returns.    */
  686. X            if (c != '\n') {
  687. X                buf[i++] = '\r';
  688. X                if (i >= nbuf) return FIOLONG;
  689. X                goto rescan;
  690. X            }
  691. X        }
  692. X        if (c==EOF || c=='\n')        /* End of line.        */
  693. X            break;
  694. X        buf[i++] = c;
  695. X        if (i >= nbuf) return FIOLONG;
  696. X    }
  697. X    if (c == EOF  && ferror(ffp) != FALSE) {
  698. X        ewprintf("File read error");
  699. X        return FIOERR;
  700. X    }
  701. X    *nbytes = i;
  702. X    return c==EOF ? FIOEOF : FIOSUC;
  703. X}
  704. X
  705. X#ifndef    NO_BACKUP
  706. X/*
  707. X * Rename the file "fname" into a backup copy.
  708. X * On Unix the backup has the same name as the
  709. X * original file, with a "~" on the end - unfortunately
  710. X * this does not map well to MS-DOS - the old .bak convention
  711. X * is used.
  712. X */
  713. Xfbackupfile(fname)
  714. Xchar    *fname;
  715. X{
  716. X    register char    *nname, *ptr;
  717. X    char *strchr();
  718. X
  719. X    if ((nname=malloc(strlen(fname)+3+1)) == NULL)
  720. X        return (ABORT);
  721. X    (void) strcpy(nname, fname);
  722. X    if ((ptr = strchr(nname, '.')) != 0)
  723. X        strcpy(ptr, ".bak");
  724. X    else
  725. X        strcat(ptr, ".bak");
  726. X
  727. X    if (strcmp(fname, nname) == 0) {
  728. X        free(nname);
  729. X        return FALSE;
  730. X    }
  731. X
  732. X    (void) unlink(nname);        /* Ignore errors.    */
  733. X    (void) rename(fname, nname);
  734. X    free(nname);
  735. X    return (TRUE);
  736. X}
  737. X#endif
  738. X
  739. X/*
  740. X * The string "fn" is a file name.
  741. X * convert all filenames to lower case, and convert all '\\' characters
  742. X * to forward slashes.  This is simply my preference, uppercase and
  743. X * back slashes are also viable.
  744. X */
  745. X/*ARGSUSED*/
  746. Xadjustmsdos(fn)
  747. Xregister char    *fn;
  748. X{
  749. X    register char c;
  750. X
  751. X    while ((c = *fn) != '0') {
  752. X        if (ISUPPER(c))
  753. X            *fn = TOLOWER(c);
  754. X        if (c=='/')
  755. X            *fn = '\\';
  756. X        ++fn;
  757. X    }
  758. X}
  759. X
  760. X
  761. X
  762. X#ifndef    NO_STARTUP
  763. X#define STARTUPNAME ".mg"
  764. X/*
  765. X * find the users startup file, and return it's name. Check for
  766. X * if MGSTARTUP is defined, then use that.   Otherwise, look
  767. X * for .mg in the current directory, then in the root directory.
  768. X */
  769. Xchar *
  770. Xstartupfile() 
  771. X{
  772. X    register char    *file;
  773. X    static char    temp[NFILEN];
  774. X    char        *getenv();
  775. X
  776. X    if ((file = getenv("MGSTARTUP")) != NULL )
  777. X        {
  778. X        if (access(file, F_OK) == 0)
  779. X            return file;
  780. X        return NULL;
  781. X        }
  782. X    if (access (STARTUPNAME, F_OK) == 0)
  783. X        return STARTUPNAME;
  784. X    strcpy(temp, "/");
  785. X    strcat(temp, STARTUPNAME);
  786. X    if (access (temp, F_OK) == 0)
  787. X        return temp;
  788. X    return NULL;
  789. X}
  790. X#endif
  791. X
  792. X/*******************************************************************/
  793. X/* new stuff between release 1a and 2a                             */
  794. X/*******************************************************************/
  795. X
  796. X/* convert all filenames to a canonical format, which in the case of
  797. X * MSDOS is X:/currentdir/filename.  Note that each drive letter has
  798. X * it's OWN current directory, so if the user specifies a drive letter,
  799. X * we use that drive's current directory, not it's root.
  800. X */
  801. X
  802. X/* MSC doesn't have getdrive and getcurdir routines; simulate them. 
  803. X * They are both pretty gross.  Blame Microsoft */
  804. X
  805. X#ifdef MSC
  806. Xunsigned getdisk()
  807. X{
  808. X    unsigned currentdrive;
  809. X
  810. X    _dos_getdrive(¤tdrive);
  811. X    return currentdrive-1;
  812. X}
  813. X
  814. Xvoid getcurdir(unsigned drivenumber, char *buf)
  815. X{
  816. X    unsigned currentdrive = getdisk()+1;
  817. X    unsigned number_of_drives;        /* unused */
  818. X    static char bufr[NFILEN];
  819. X
  820. X    _dos_setdrive(drivenumber, &number_of_drives);
  821. X    getcwd(&bufr[0], NFILEN-1);
  822. X    _dos_setdrive(currentdrive, &number_of_drives);
  823. X    strcpy(buf, &bufr[3]);
  824. X}
  825. X#endif
  826. X
  827. Xchar *adjustname(fn)
  828. Xregister char *fn;
  829. X{
  830. X    register char *cp;
  831. X    static char fnb[NFILEN];
  832. X    struct passwd *pwent;
  833. X
  834. X    cp = fnb;
  835. X    /* handle A:foo\bar */
  836. X    if (fn[0] && fn[1] == ':') {
  837. X    *cp++ = *fn++;
  838. X    *cp++ = *fn++;
  839. X    *cp = '\0';
  840. X    adjustmsdos(fnb);    /* force case to lower */
  841. X    if (*fn != '/' && *fn != '\\') {
  842. X        *cp++ = '\\';
  843. X        getcurdir(fnb[0]-'a'+1, cp);
  844. X        cp = fnb + strlen(fnb);
  845. X    }
  846. X    else
  847. X        *cp++ = *fn++;
  848. X    }
  849. X    /* handle \foo\bar */
  850. X    else if (*fn == '/' || *fn == '\\') {
  851. X    *cp++ = (char) (getdisk() + 'a');
  852. X    *cp++ = ':';
  853. X    *cp++ = *fn++;
  854. X    }
  855. X    else {
  856. X    strcpy(fnb, wdir);
  857. X    cp = fnb + strlen(fnb);
  858. X    }
  859. X
  860. X    if(cp != fnb && cp[-1] != '/' && cp[-1] != '\\') *cp++ = '\\';
  861. X
  862. X    /* at this point, we should have a drive, and at least a single */
  863. X    /* slash.  Now copy over the rest of the filename, while handling */
  864. X    /* certain pathalogical cases */
  865. X
  866. X    /* convert "//" to "/", "/./" to "/", and "/x/../" to "/" */
  867. X    while(*fn) {
  868. X        switch(*fn) {
  869. X        case '.':
  870. X        switch(fn[1]) {
  871. X                case '\0':
  872. X                *--cp = '\0';
  873. X            adjustmsdos(fnb);
  874. X                return fnb;
  875. X                case '/':
  876. X            case '\\':
  877. X                    fn += 2;
  878. X                continue;
  879. X            case '.':
  880. X                if(fn[2]=='/' || fn[2]=='\\' || fn[2] == '\0') {
  881. X                --cp;
  882. X                while(cp > fnb && *--cp != '/' && *cp != '\\')
  883. X                ;
  884. X                if (cp==fnb) cp += 2;
  885. X                ++cp;
  886. X                if(fn[2]=='\0') {
  887. X                    *--cp = '\0';
  888. X                adjustmsdos(fnb);
  889. X                    return fnb;
  890. X                }
  891. X                    fn += 3;
  892. X                    continue;
  893. X                }
  894. X                break;
  895. X            default:
  896. X                break;
  897. X            }
  898. X        break;
  899. X        case '/':
  900. X        case '\\':
  901. X            fn++;
  902. X            continue;
  903. X        default:
  904. X            break;
  905. X    }
  906. X    while(*fn && (*cp++ = *fn++) != '/' && fn[-1] != '\\')
  907. X        ;
  908. X    }
  909. X    if (cp != fnb + 3 && cp[-1]=='\\') --cp;
  910. X    *cp = '\0';
  911. X    adjustmsdos(fnb);
  912. X    return fnb;
  913. X}
  914. X
  915. X#ifndef NO_DIRED
  916. X#include "kbd.h"
  917. X#define DIRFILE "_dirlist_.$$$"
  918. X
  919. XBUFFER *dired_(dirname)
  920. Xchar *dirname;
  921. X{
  922. X    register BUFFER *bp;
  923. X    char line[256];
  924. X    BUFFER *findbuffer();
  925. X    char *strncpy();
  926. X    int i;
  927. X
  928. X    if((dirname = adjustname(dirname)) == NULL) {
  929. X    ewprintf("Bad directory name");
  930. X    return NULL;
  931. X    }
  932. X    if((bp = findbuffer(dirname)) == NULL) {
  933. X    ewprintf("Could not create buffer");
  934. X    return NULL;
  935. X    }
  936. X    if(bclear(bp) != TRUE) return FALSE;
  937. X    (VOID) strcpy(line, "dir ");
  938. X    (VOID) strcat(line, dirname);
  939. X    (VOID) strcat(line, " > ");
  940. X    (VOID) strcat(line, DIRFILE);
  941. X    system(line);
  942. X    if (ffropen(DIRFILE) != FIOSUC) {
  943. X     ewprintf("Can't open temporary dir file");
  944. X     return NULL;
  945. X    }
  946. X    line[0] = line[1] = ' ';
  947. X    if (ffgetline(&line[2], sizeof(line)-3, &i) != FIOSUC) {
  948. X    ffclose();
  949. X    (void)unlink(DIRFILE);
  950. X    ewprintf("No such directory: `%s'", dirname);
  951. X        return NULL;
  952. X    }
  953. X    while (ffgetline(&line[2], sizeof(line)-3, &i) == FIOSUC) {
  954. X    line[i+2] = '\0';
  955. X    (VOID) addline(bp, line);
  956. X    }
  957. X    ffclose();
  958. X    (void)unlink(DIRFILE);
  959. X
  960. X    bp->b_dotp = lforw(bp->b_linep);        /* go to first line */
  961. X    (VOID) strncpy(bp->b_fname, dirname, NFILEN);
  962. X    if((bp->b_modes[0] = name_mode("dired")) == NULL) {
  963. X    bp->b_modes[0] = &map_table[0];
  964. X    ewprintf("Could not find mode dired");
  965. X    return NULL;
  966. X    }
  967. X    bp->b_nmodes = 0;
  968. X    return bp;
  969. X}
  970. X
  971. X/* this is really ugly, but then so was the UNIX version! */
  972. X#define BASENAME 2
  973. X#define EXT    11
  974. X#define DIR    15
  975. Xd_makename(lp, fn)
  976. Xregister LINE *lp;
  977. Xregister char *fn;
  978. X{
  979. X    register char *cp;
  980. X    register char *last;
  981. X    int len;
  982. X    extern char *strchr();
  983. X
  984. X    if(llength(lp) != 41) return ABORT;
  985. X    if(lgetc(lp,BASENAME) == ' ') return ABORT;
  986. X    if(lgetc(lp,EXT-1) != ' ') return ABORT;
  987. X    (VOID) strcpy(fn, curbp->b_fname);
  988. X    cp = fn + strlen(fn);
  989. X    if ((cp[-1] != '\\') && (cp[-1] != '/'))    /* append '/' if needed    */
  990. X    *cp++ = '\\';
  991. X    if ((last = strchr(lp->l_text+BASENAME, ' ')) == 0) return ABORT;
  992. X    len = last - (lp->l_text+BASENAME);
  993. X    bcopy(lp->l_text+BASENAME, cp, len);
  994. X    cp += len;
  995. X    if ((last = strchr(lp->l_text+EXT, ' ')) == 0) return ABORT;
  996. X    len = last - (lp->l_text+EXT);
  997. X    if (len != 0) {
  998. X    *cp++ = '.';
  999. X    bcopy(lp->l_text+EXT, cp, len);
  1000. X    }
  1001. X    cp[len] = '\0';
  1002. X    return (strncmp(lp->l_text+DIR, "<DIR>", 5) == 0);
  1003. X}
  1004. X
  1005. X/* sorry, this is a hack - jpn */
  1006. X/* I should probably fix this */
  1007. Xcopy(frname, toname)
  1008. Xchar *frname, *toname;
  1009. X{
  1010. X    char buffer[512];
  1011. X    int pid;
  1012. X    int status;
  1013. X    char cmdbuf[80];
  1014. X
  1015. X    sprintf(cmdbuf, "Copy %s %s", frname, toname);
  1016. X    system(cmdbuf);
  1017. X    return TRUE;
  1018. X}
  1019. X
  1020. Xunlinkdir(f)
  1021. Xchar *f;
  1022. X{
  1023. X    return (rmdir(f));
  1024. X}
  1025. X
  1026. X#endif /* NO_DIRED */
  1027. !FaR!OuT!
  1028. fi
  1029. if [ ! -s ./makefile.msc ]
  1030. then
  1031. if [ ! -d . ]
  1032. then
  1033.     mkdir .
  1034.     echo mkdir .
  1035. fi
  1036. echo x - ./makefile.msc
  1037. sed -e 's/^X//' > ./makefile.msc << '!FaR!OuT!'
  1038. X# Microsoft C 5.1 Makefile for MG 2A.
  1039. XSYS    = msdos
  1040. XCDEFS    = /DMSC
  1041. XDEBUG   = 
  1042. XCFLAGS    = /AL /Oilt /Gs $(CDEFS) $(DEBUG)
  1043. XCC      = cl
  1044. X
  1045. X# standard headers
  1046. XDEF = def.h sysdef.h ttydef.h chrdef.h
  1047. X
  1048. X# implicit compilation rule
  1049. X.c.obj:
  1050. X    $(CC) /c $(CFLAGS) $*.c
  1051. X
  1052. X# files that can be removed, because they are really just copies
  1053. XHCLEAN = sysdef.h ttydef.h chrdef.h varargs.h
  1054. XCCLEAN = cinfo.c fileio.c spawn.c tty.c ttyio.c ttykbd.c
  1055. X
  1056. X# object file list
  1057. XOBJ = alloca.obj basic.obj buffer.obj cinfo.obj dir.obj dired.obj display.obj \
  1058. X    echo.obj extend.obj file.obj fileio.obj help.obj kbd.obj keymap.obj \
  1059. X    line.obj macro.obj main.obj match.obj modes.obj paragrap.obj \
  1060. X    random.obj regex.obj region.obj re_searc.obj search.obj spawn.obj \
  1061. X    tty.obj ttyio.obj ttykbd.obj version.obj window.obj word.obj
  1062. X
  1063. X# this doesn't work right: del only takes one argument (sigh).
  1064. X#clean:
  1065. X#    -del $(HCLEAN)
  1066. X#    -del $(CCLEAN)
  1067. X#    -del *.obj
  1068. X#    -del mg.exe
  1069. X
  1070. X# files copied from msdos directory
  1071. Xsysdef.h: sys\$(SYS)\sysdef.h
  1072. X    copy sys\$(SYS)\sysdef.h
  1073. X
  1074. Xttydef.h: sys\$(SYS)\ttydef.h
  1075. X    copy sys\$(SYS)\ttydef.h
  1076. X
  1077. Xchrdef.h: sys\$(SYS)\chrdef.h
  1078. X    copy sys\$(SYS)\chrdef.h
  1079. X
  1080. Xvarargs.h: sys\$(SYS)\varargs.h
  1081. X    copy sys\$(SYS)\varargs.h
  1082. X
  1083. Xalloca.c: sys\default\alloca.c
  1084. X    copy sys\default\alloca.c
  1085. X
  1086. Xcinfo.c: sys\$(SYS)\cinfo.c
  1087. X    copy sys\$(SYS)\cinfo.c
  1088. X
  1089. Xfileio.c: sys\$(SYS)\fileio.c
  1090. X    copy sys\$(SYS)\fileio.c
  1091. X
  1092. Xspawn.c: sys\$(SYS)\spawn.c
  1093. X    copy sys\$(SYS)\spawn.c
  1094. X
  1095. Xtty.c:   sys\$(SYS)\tty.c
  1096. X    copy sys\$(SYS)\tty.c
  1097. X
  1098. Xttyio.c: sys\$(SYS)\ttyio.c
  1099. X    copy sys\$(SYS)\ttyio.c
  1100. X
  1101. Xttykbd.c: sys\$(SYS)\ttykbd.c
  1102. X    copy sys\$(SYS)\ttykbd.c
  1103. X
  1104. X# header dependencies
  1105. X
  1106. Xbasic.obj: basic.c $(DEF)
  1107. X
  1108. Xbuffer.obj: buffer.c $(DEF) kbd.h
  1109. X
  1110. Xdir.obj: dir.c $(DEF)
  1111. X
  1112. Xdired.obj: dired.c $(DEF)
  1113. X
  1114. Xdisplay.obj: display.c $(DEF) kbd.h
  1115. X
  1116. Xecho.obj: echo.c $(DEF) key.h varargs.h macro.h
  1117. X
  1118. Xextend.obj: extend.c $(DEF) kbd.h macro.h key.h
  1119. X
  1120. Xfile.obj: file.c $(DEF)
  1121. X
  1122. Xhelp.obj: help.c $(DEF) kbd.h key.h macro.h
  1123. X
  1124. Xkbd.obj: kbd.c $(DEF) kbd.h key.h macro.h
  1125. X
  1126. Xkeymap.obj: keymap.c $(DEF) kbd.h
  1127. X
  1128. Xline.obj: line.c $(DEF)
  1129. X
  1130. Xmacro.obj: macro.c $(DEF) key.h macro.h
  1131. X
  1132. Xmain.obj: main.c $(DEF) macro.h
  1133. X
  1134. Xmatch.obj: match.c $(DEF) key.h
  1135. X
  1136. Xmodes.obj: modes.c $(DEF) kbd.h
  1137. X
  1138. Xparagrap.obj: paragrap.c $(DEF)
  1139. X
  1140. Xrandom.obj: random.c $(DEF)
  1141. X
  1142. Xregex.obj: regex.c $(DEF) regex.h
  1143. X
  1144. Xregion.obj: region.c $(DEF)
  1145. X
  1146. Xre_searc.obj: re_searc.c $(DEF) macro.h regex.h
  1147. X
  1148. Xsearch.obj: search.c $(DEF) macro.h
  1149. X
  1150. Xversion.obj: version.c $(DEF)
  1151. X
  1152. Xwindow.obj: window.c $(DEF)
  1153. X
  1154. Xword.obj: word.c $(DEF)
  1155. X
  1156. Xalloca.obj: alloca.c
  1157. X
  1158. Xcinfo.obj: $(DEF) cinfo.c
  1159. X
  1160. Xfileio.obj: $(DEF) kbd.h fileio.c
  1161. X
  1162. Xspawn.obj: $(DEF) spawn.c
  1163. X
  1164. Xtty.obj: $(DEF) tty.c
  1165. X
  1166. Xttyio.obj: $(DEF) ttyio.c
  1167. X
  1168. Xttykbd.obj: $(DEF) ttykbd.c
  1169. X
  1170. X# add /Fm to the CC line to get a load map
  1171. Xmg.exe: $(OBJ)
  1172. X    $(CC) $(CFLAGS) /FeMG.EXE *.obj
  1173. X
  1174. !FaR!OuT!
  1175. fi
  1176. if [ ! -s ./makefile.tc ]
  1177. then
  1178. if [ ! -d . ]
  1179. then
  1180.     mkdir .
  1181.     echo mkdir .
  1182. fi
  1183. echo x - ./makefile.tc
  1184. sed -e 's/^X//' > ./makefile.tc << '!FaR!OuT!'
  1185. X# Turbo C Makefile for MG 2A.
  1186. XSYS    = msdos
  1187. XCDEFS    =
  1188. X# suppress some annoying warnings
  1189. XWARN    = -w-stu -w-par
  1190. XCFLAGS    = -ml $(CDEFS) $(WARN)
  1191. XCC      = tcc
  1192. X
  1193. X# standard headers
  1194. XDEF = def.h sysdef.h ttydef.h chrdef.h
  1195. X
  1196. X# implicit compilation rule
  1197. X.c.obj:
  1198. X    $(CC) -c $(CFLAGS) $<
  1199. X
  1200. X# files that can be removed, because they are really just copies
  1201. XHCLEAN = sysdef.h ttydef.h chrdef.h varargs.h
  1202. XCCLEAN = cinfo.c fileio.c spawn.c tty.c ttyio.c ttykbd.c
  1203. X
  1204. X# object file list
  1205. XOBJ = alloca.obj basic.obj buffer.obj cinfo.obj dir.obj dired.obj display.obj \
  1206. X    echo.obj extend.obj file.obj fileio.obj help.obj kbd.obj keymap.obj \
  1207. X    line.obj macro.obj main.obj match.obj modes.obj paragrap.obj \
  1208. X    random.obj regex.obj region.obj re_searc.obj search.obj spawn.obj \
  1209. X    tty.obj ttyio.obj ttykbd.obj version.obj window.obj word.obj
  1210. X
  1211. X# add -M to the CC line to get a load map
  1212. Xmg.exe: $(OBJ)
  1213. X    $(CC) -emg $(CFLAGS) *.obj
  1214. X
  1215. X# this doesn't work right: del only takes one argument (sigh).
  1216. Xclean:
  1217. X    -del $(HCLEAN)
  1218. X    -del $(CCLEAN)
  1219. X    -del *.obj
  1220. X    -del mg.exe
  1221. X
  1222. X# files copied from msdos directory
  1223. Xsysdef.h: sys/$(SYS)/sysdef.h
  1224. X    copy sys/$(SYS)/sysdef.h
  1225. X
  1226. Xttydef.h: sys/$(SYS)/ttydef.h
  1227. X    copy sys/$(SYS)/ttydef.h
  1228. X
  1229. Xchrdef.h: sys/$(SYS)/chrdef.h
  1230. X    copy sys/$(SYS)/chrdef.h
  1231. X
  1232. Xvarargs.h: sys/$(SYS)/varargs.h
  1233. X    copy sys/$(SYS)/varargs.h
  1234. X
  1235. Xalloca.c: sys/$(SYS)/alloca.c
  1236. X    copy sys/$(SYS)/alloca.c
  1237. X
  1238. Xcinfo.c: sys/$(SYS)/cinfo.c
  1239. X    copy sys/$(SYS)/cinfo.c
  1240. X
  1241. Xfileio.c: sys/$(SYS)/fileio.c
  1242. X    copy sys/$(SYS)/fileio.c
  1243. X
  1244. Xspawn.c: sys/$(SYS)/spawn.c
  1245. X    copy sys/$(SYS)/spawn.c
  1246. X
  1247. Xtty.c:   sys/$(SYS)/tty.c
  1248. X    copy sys/$(SYS)/tty.c
  1249. X
  1250. Xttyio.c: sys/$(SYS)/ttyio.c
  1251. X    copy sys/$(SYS)/ttyio.c
  1252. X
  1253. Xttykbd.c: sys/$(SYS)/ttykbd.c
  1254. X    copy sys/$(SYS)/ttykbd.c
  1255. X
  1256. X# header dependencies
  1257. Xbasic.obj: $(DEF)
  1258. Xbuffer.obj: $(DEF) kbd.h
  1259. Xdir.obj: $(DEF)
  1260. Xdired.obj: $(DEF)
  1261. Xdisplay.obj: $(DEF) kbd.h
  1262. Xecho.obj: $(DEF) key.h varargs.h macro.h
  1263. Xextend.obj: $(DEF) kbd.h macro.h key.h
  1264. Xfile.obj: $(DEF)
  1265. Xhelp.obj: $(DEF) kbd.h key.h macro.h
  1266. Xkbd.obj: $(DEF) kbd.h key.h macro.h
  1267. Xkeymap.obj: $(DEF) kbd.h
  1268. Xline.obj: $(DEF)
  1269. Xmacro.obj: $(DEF) key.h macro.h
  1270. Xmain.obj: $(DEF) macro.h
  1271. Xmatch.obj: $(DEF) key.h
  1272. Xmodes.obj: $(DEF) kbd.h
  1273. Xparagrap.obj: $(DEF)
  1274. Xrandom.obj: $(DEF)
  1275. Xregex.obj: $(DEF) regex.h
  1276. Xregion.obj: $(DEF)
  1277. Xre_searc.obj: $(DEF) macro.h regex.h
  1278. Xsearch.obj: $(DEF) macro.h
  1279. Xversion.obj: $(DEF)
  1280. Xwindow.obj: $(DEF)
  1281. Xword.obj: $(DEF)
  1282. X
  1283. Xalloca.obj: alloca.c
  1284. Xcinfo.obj: $(DEF) cinfo.c
  1285. Xfileio.obj: $(DEF) kbd.h fileio.c
  1286. Xspawn.obj: $(DEF) spawn.c
  1287. Xtty.obj: $(DEF) tty.c
  1288. Xttyio.obj: $(DEF) ttyio.c
  1289. Xttykbd.obj: $(DEF) ttykbd.c
  1290. !FaR!OuT!
  1291. fi
  1292. if [ ! -s ./spawn.c ]
  1293. then
  1294. if [ ! -d . ]
  1295. then
  1296.     mkdir .
  1297.     echo mkdir .
  1298. fi
  1299. echo x - ./spawn.c
  1300. sed -e 's/^X//' > ./spawn.c << '!FaR!OuT!'
  1301. X/*
  1302. X * Name:    Mg 2a
  1303. X *        Spawn CLI for MSDOS (TurboC 1.5)
  1304. X *
  1305. X */
  1306. X#include    "def.h"
  1307. X#include    <process.h>
  1308. X
  1309. Xextern    char    *getenv();
  1310. X
  1311. X/*
  1312. X * On MSDOS, we got no job control like system V, so always
  1313. X * run a subshell. Bound to "C-C", and used
  1314. X * as a subcommand by "C-Z". (daveb)
  1315. X *
  1316. X * Returns 0 if the shell executed OK, something else if
  1317. X * we couldn't start shell or it exited badly.
  1318. X */
  1319. Xspawncli(f, n, k)
  1320. X{
  1321. X    char *comspec;
  1322. X    int        errp = FALSE;
  1323. X
  1324. X    ttcolor(CTEXT);
  1325. X    ttnowindow();
  1326. X    ttmove(nrow-1, 0);
  1327. X    if (epresf != FALSE) {
  1328. X        tteeol();
  1329. X        epresf = FALSE;
  1330. X    }
  1331. X    ttclose();
  1332. X    sgarbf = TRUE;                /* Force repaint.    */
  1333. X    if ((comspec = getenv("COMSPEC")) == NULL)
  1334. X        errp = -1;
  1335. X    else
  1336. X        errp = spawnl(P_WAIT, comspec, "COMMAND.COM", (char *)NULL);
  1337. X
  1338. X    ttopen();
  1339. X    if(errp == -1)
  1340. X        ewprintf("Failed to create process");
  1341. X
  1342. X    return ( errp );
  1343. X}
  1344. !FaR!OuT!
  1345. fi
  1346. if [ ! -s ./sysdef.h ]
  1347. then
  1348. if [ ! -d . ]
  1349. then
  1350.     mkdir .
  1351.     echo mkdir .
  1352. fi
  1353. echo x - ./sysdef.h
  1354. sed -e 's/^X//' > ./sysdef.h << '!FaR!OuT!'
  1355. X/*
  1356. X * Name:    Mg 2a
  1357. X *        MSDOS system header file (TurboC 1.5)
  1358. X */
  1359. X
  1360. X/* can't include these, the ANSI style prototypes conflict with the
  1361. X * definitions in defs.h
  1362. X */
  1363. X/* #include <stdlib.h> */
  1364. X/* #include <string.h> */
  1365. X/* #include <dir.h> */
  1366. X/* #include <stdio.h> */
  1367. X#define NULL    0L
  1368. X
  1369. X#define    KBLOCK    1024            /* Kill grow.            */
  1370. X#define    GOOD    0            /* Good exit status.        */
  1371. X#define    MAXPATH    256            /* Maximum length of path for chdir */
  1372. X
  1373. X#define LOCAL_VARARGS            /* use sys/default/varargs.h */
  1374. X#define DO_METAKEY            /* ALT acts like META */
  1375. X#define METABIT 0x200
  1376. X#define FKEYS                /* we have dedicated function keys */
  1377. X/* #define NO_DIRED */            /* dired works now */
  1378. X#define C_ALLOCA            /* used by regex, C version of alloca*/
  1379. X
  1380. Xtypedef long    RSIZE;            /* Type for file/region sizes    */
  1381. Xtypedef short    KCHAR;            /* Type for internal keystrokes    */
  1382. X/* typedef short    KEY;        /* Type for internal keystrokes    */
  1383. X
  1384. X/*
  1385. X * Macros used by the buffer name making code.
  1386. X * Start at the end of the file name, scan to the left
  1387. X * until BDC1 (or BDC2, if defined) is reached. The buffer
  1388. X * name starts just to the right of that location, and
  1389. X * stops at end of string (or at the next BDC3 character,
  1390. X * if defined). BDC2 and BDC3 are mainly for VMS.
  1391. X */
  1392. X#define    BDC1    '/'
  1393. X#define    BDC2    '\\'
  1394. X
  1395. X#define bcopy(s,d,n)    memcpy(d,s,n)    /* memory-to-memory copy    */
  1396. X#define bcmp(s1,s2,n)    memcmp(s2,s1,n) /* memory comparison        */
  1397. X#define bzero(s,n)    memset(s,0,n)    /* memory zero            */
  1398. X
  1399. X#define fncmp    stricmp
  1400. X#define getwd(cwd)    getcwd(cwd,NFILEN) /* get current working dir    */
  1401. Xextern char *getcwd();
  1402. X
  1403. X#define MALLOCROUND(m)    (m+=7,m&=~7)    /* round up to 8 byte boundry    */
  1404. !FaR!OuT!
  1405. fi
  1406. if [ ! -s ./tty.c ]
  1407. then
  1408. if [ ! -d . ]
  1409. then
  1410.     mkdir .
  1411.     echo mkdir .
  1412. fi
  1413. echo x - ./tty.c
  1414. sed -e 's/^X//' > ./tty.c << '!FaR!OuT!'
  1415. X/*
  1416. X * Mg 2b  (turboc 1.5/MSC 1.5)
  1417. X *   IBM-PC and compatible BIOS based display driver.
  1418. X *   - this will tend to be a bit slower than a driver that
  1419. X *     writes directly to the memory mapped screen, but with
  1420. X *     the large # of display adapters floating around, I'd
  1421. X *     rather let the bios do the work.
  1422. X * 
  1423. X *     I DO recommend FANSI-CONSOLE which significantly speeds
  1424. X *     up display bios calls, however.
  1425. X */
  1426. X#include    "def.h"
  1427. X#include    <dos.h>
  1428. X
  1429. X#define    BEL    0x07            /* BEL character.        */
  1430. X
  1431. Xextern    int    ttrow;
  1432. Xextern    int    ttcol;
  1433. Xextern    int    tttop;
  1434. Xextern    int    ttbot;
  1435. Xextern    int    tthue;
  1436. X
  1437. Xstatic int biocol = 0;
  1438. X
  1439. Xint    tceeol = 2;            /* Costs are set later */
  1440. Xint    tcinsl = 5;
  1441. Xint    tcdell = 5;
  1442. X
  1443. Xstatic    int insdel = TRUE;    /* Do we have both insert & delete line? */
  1444. Xstatic int rendition =0x07;
  1445. X
  1446. Xint    ttputc();
  1447. X
  1448. X/*
  1449. X * Initialize the terminal when the editor
  1450. X * gets started up.
  1451. X */
  1452. Xttinit() {
  1453. X}
  1454. X
  1455. X/*
  1456. X * Clean up the terminal, in anticipation of
  1457. X * a return to the command interpreter.
  1458. X */
  1459. Xtttidy() {
  1460. X}
  1461. X
  1462. X/*
  1463. X * Move the cursor to the specified
  1464. X * origin 0 row and column position.
  1465. X */
  1466. Xttmove(row, col) {
  1467. X    ttcol = col;
  1468. X    ttrow = row;
  1469. X    _move(row, col);
  1470. X}
  1471. X
  1472. X_move(row, col) {
  1473. X    union REGS rg;
  1474. X
  1475. X    biocol = col;
  1476. X    rg.h.ah = 2;        /* set cursor position function code */
  1477. X    rg.h.dl = col;
  1478. X    rg.h.dh = row;
  1479. X    rg.h.bh = 0;        /* set screen page number */
  1480. X    int86(0x10, &rg, &rg);
  1481. X}
  1482. X
  1483. X/*
  1484. X * Erase to end of line.
  1485. X */
  1486. Xtteeol() {
  1487. X    union REGS rg;
  1488. X
  1489. X    rg.h.ah = 9;    /* write character/rendition */
  1490. X    rg.h.bh = 0;
  1491. X    rg.x.cx = ncol-biocol;
  1492. X    rg.h.al = ' ';
  1493. X    rg.h.bl = rendition;
  1494. X
  1495. X    int86(0x10, &rg, &rg);
  1496. X}
  1497. X
  1498. X/*
  1499. X * Erase to end of page.
  1500. X */
  1501. Xtteeop() {
  1502. X    ttdell(ttrow, nrow, nrow - ttrow);
  1503. X}
  1504. X
  1505. X/*
  1506. X * Make a noise.
  1507. X */
  1508. Xttbeep() {
  1509. X    union REGS rg;
  1510. X
  1511. X    rg.h.ah = 14;    /* write tty */
  1512. X    rg.h.al = BEL;
  1513. X
  1514. X    int86(0x10, &rg, &rg);
  1515. X}
  1516. X
  1517. X/*
  1518. X * Insert nchunk blank line(s) onto the
  1519. X * screen, scrolling the last line on the
  1520. X * screen off the bottom.
  1521. X */
  1522. Xttinsl(row, bot, nchunk) {
  1523. X    union REGS rg;
  1524. X    
  1525. X    if (row == bot) {        /* Case of one line insert is     */
  1526. X    ttmove(row, 0);        /*    special            */
  1527. X    tteeol();
  1528. X    return;
  1529. X    }
  1530. X
  1531. X    rg.h.ah = 7;    /* scroll down */
  1532. X    rg.h.bh = 0x07;
  1533. X    rg.h.al = nchunk;
  1534. X    rg.h.ch = row;
  1535. X    rg.h.cl = 0;
  1536. X    rg.h.dh = bot;
  1537. X    rg.h.dl = ncol - 1;
  1538. X
  1539. X    int86(0x10, &rg, &rg);
  1540. X}
  1541. X
  1542. X/*
  1543. X * Delete nchunk line(s) from "row", replacing the
  1544. X * bottom line on the screen with a blank line. 
  1545. X */
  1546. X
  1547. Xttdell(row, bot, nchunk)
  1548. X{
  1549. X    union REGS rg;
  1550. X
  1551. X    if (row == bot) {        /* One line special case    */
  1552. X    ttmove(row, 0);
  1553. X    tteeol();
  1554. X    return;
  1555. X    }
  1556. X    rg.h.ah = 6;    /* scroll up */
  1557. X    rg.h.bh = 0x07;
  1558. X    rg.h.al = nchunk;
  1559. X    rg.h.ch = row;
  1560. X    rg.h.cl = 0;
  1561. X    rg.h.dh = bot;
  1562. X    rg.h.dl = ncol - 1;
  1563. X
  1564. X    int86(0x10, &rg, &rg);
  1565. X}
  1566. X
  1567. X/*
  1568. X * Switch to full screen scroll. This is
  1569. X * used by "spawn.c" just before is suspends the
  1570. X * editor, and by "display.c" when it is getting ready
  1571. X * to exit.
  1572. X */
  1573. Xttnowindow()
  1574. X{
  1575. X}
  1576. X
  1577. X/*
  1578. X * Set the current writing color to the
  1579. X * specified color. Watch for color changes that are
  1580. X * not going to do anything (the color is already right)
  1581. X * and don't send anything to the display.
  1582. X * The rainbow version does this in putline.s on a
  1583. X * line by line basis, so don't bother sending
  1584. X * out the color shift.
  1585. X */
  1586. Xttcolor(color) register int color; {
  1587. X    if (color != tthue) {
  1588. X    if (color == CTEXT) {        /* Normal video.    */
  1589. X        rendition = 0x07;
  1590. X    } else if (color == CMODE) {    /* Reverse video.    */
  1591. X        rendition = 0x70;
  1592. X    }
  1593. X    tthue = color;            /* Save the color.    */
  1594. X    }
  1595. X}
  1596. X
  1597. X/*
  1598. X * This routine is called by the
  1599. X * "refresh the screen" command to try and resize
  1600. X * the display. The new size, which must be deadstopped
  1601. X * to not exceed the NROW and NCOL limits, it stored
  1602. X * back into "nrow" and "ncol". Display can always deal
  1603. X * with a screen NROW by NCOL. Look in "window.c" to
  1604. X * see how the caller deals with a change.
  1605. X */
  1606. Xttresize() {
  1607. X    setttysize();
  1608. X}
  1609. X
  1610. X/* calculate the cost of doing string s */
  1611. Xcharcost (s) char *s; {
  1612. X    return strlen(s);
  1613. X}
  1614. X
  1615. Xttputc(c)
  1616. Xunsigned char c;
  1617. X{
  1618. X    union REGS rg;
  1619. X
  1620. X    if (c == '\b') {
  1621. X    if (biocol-1 > 0) {
  1622. X        _move(ttrow, biocol-1);
  1623. X    }
  1624. X    return;
  1625. X    }
  1626. X    else if (c == '\r') {
  1627. X    _move(ttrow, 0);
  1628. X    return;
  1629. X    }
  1630. X    rg.h.ah = 9;    /* write character/rendition */
  1631. X    rg.h.bh = 0;
  1632. X    rg.x.cx = 1;
  1633. X    rg.h.al = c;
  1634. X    rg.h.bl = rendition;
  1635. X
  1636. X    int86(0x10, &rg, &rg);
  1637. X
  1638. X    if (biocol+1 >= ncol)
  1639. X    _move(ttrow + 1, 0);
  1640. X    else
  1641. X    _move(ttrow, biocol + 1);
  1642. X}
  1643. X
  1644. Xstruct nap
  1645. X    {
  1646. X    long napvalue;
  1647. X    long basetime;
  1648. X    };
  1649. X
  1650. Xttwait()
  1651. X    {
  1652. X    struct nap timer;
  1653. X    napstart(200, &timer);
  1654. X    while (napchk(&timer) == 0)
  1655. X    if (typeahead())
  1656. X        return 0;
  1657. X    return 1;
  1658. X    }
  1659. X
  1660. X/***************************/
  1661. X/* MSDOS time functions    */
  1662. X/***************************/
  1663. X
  1664. X/* Apparantly Turbo C has a sleep library routine; MSC doesn't -jbs */
  1665. X
  1666. X#define gettime(_a) ((((long)(_a.x.cx)) << 16)+_a.x.dx)
  1667. X
  1668. X#ifdef MSC
  1669. Xsleep(amount)
  1670. X    {
  1671. X    while (amount--)
  1672. X    nap(100);
  1673. X    }
  1674. X#endif
  1675. X
  1676. X/* nap in units of 100ths of seconds via busy loops. */
  1677. Xnap(amount)
  1678. X    {
  1679. X    struct nap tim;
  1680. X    napstart(amount, &tim);
  1681. X    while(napchk(&tim) == 0)
  1682. X    ;
  1683. X    }
  1684. X
  1685. Xnapstart(amount,sav)
  1686. Xint amount;
  1687. Xregister struct nap *sav;
  1688. X    {
  1689. X    union REGS inregs, outregs;
  1690. X    int hunds, secs;
  1691. X
  1692. X    inregs.h.ah = 0x2c;            /* get time */
  1693. X    int86(0x21, &inregs, &outregs);
  1694. X
  1695. X    /* glitch in hardware RTC (time warp) makes this necessary */
  1696. X    inregs = outregs;
  1697. X    inregs.h.dl = 0;        /* seconds counter may be slow to increment */
  1698. X    if (inregs.h.dh > 0)
  1699. X    --inregs.h.dh;        /* paranoia */
  1700. X    if (inregs.h.cl > 0)
  1701. X    --inregs.h.cl;        /* more paranoia */
  1702. X    /* end of glitch handling */
  1703. X
  1704. X    sav->basetime = gettime(inregs);    /* in case of wraparound */
  1705. X
  1706. X    /* convert hundredths of seconds to future time structure */
  1707. X    secs = outregs.h.dh;
  1708. X    hunds = outregs.h.dl + amount;
  1709. X
  1710. X    while (hunds >= 100) {
  1711. X    hunds -= 100;
  1712. X    ++secs;
  1713. X    }
  1714. X    outregs.h.dl = hunds;
  1715. X    while (secs >= 60) {
  1716. X    secs -= 60;
  1717. X    ++outregs.h.cl;            /* increment minutes */
  1718. X    }
  1719. X    outregs.h.dh = secs;
  1720. X
  1721. X    /* check for minute and hour wraparound */
  1722. X    if (outregs.h.cl >= 60)
  1723. X    {
  1724. X    outregs.h.cl -= 60;
  1725. X    ++outregs.h.ch;            /* increment hours */
  1726. X    }
  1727. X    if (outregs.h.ch >= 24)
  1728. X    {
  1729. X    outregs.h.ch -= 24;
  1730. X    }
  1731. X    sav->napvalue = gettime(outregs);
  1732. X    }
  1733. X
  1734. Xnapchk(sav)
  1735. Xregister struct nap *sav;
  1736. X    {
  1737. X    union REGS inregs, outregs;
  1738. X    long current;
  1739. X
  1740. X    inregs.h.ah = 0x2c;            /* get time */
  1741. X    int86(0x21, &inregs, &outregs);
  1742. X
  1743. X    current = gettime(outregs);
  1744. X
  1745. X    if(sav->napvalue > sav->basetime)
  1746. X    {
  1747. X    if (current >= sav->napvalue || current < sav->basetime)
  1748. X        return 1;
  1749. X    }
  1750. X    else if (current >= sav->napvalue && current < sav->basetime)
  1751. X    return 1;
  1752. X    return 0;
  1753. X    }
  1754. !FaR!OuT!
  1755. fi
  1756. if [ ! -s ./ttydef.h ]
  1757. then
  1758. if [ ! -d . ]
  1759. then
  1760.     mkdir .
  1761.     echo mkdir .
  1762. fi
  1763. echo x - ./ttydef.h
  1764. sed -e 's/^X//' > ./ttydef.h << '!FaR!OuT!'
  1765. X/*
  1766. X *    Termcap terminal file, nothing special, just make it big
  1767. X *    enough for windowing systems.
  1768. X */
  1769. X
  1770. X#define    GOSLING            /* Compile in fancy display.    */
  1771. X/* #define    MEMMAP        */    /* Not memory mapped video.    */
  1772. X
  1773. X#define    NROW    25                /* Rows.            */
  1774. X#define    NCOL    80            /* Columns.            */
  1775. X#define    MOVE_STANDOUT            /* don't move in standout mode    */
  1776. X/* #define    STANDOUT_GLITCH        /* possible standout glitch    */
  1777. X#define XKEYS
  1778. X
  1779. X#define KFIRST    K00
  1780. X#define KHOME    K00
  1781. X#define KDOWN    K01
  1782. X#define    KUP    K02
  1783. X#define    KLEFT    K03
  1784. X#define    KRIGHT    K04
  1785. X#define    KPGUP    K05
  1786. X#define    KPGDN    K06
  1787. X#define    KEND    K07
  1788. X#define    KDELETE    K08
  1789. X#define    KINSERT    K09
  1790. X#define KCLEFT    K0A
  1791. X#define KCRIGHT    K0B
  1792. X#define KCPGUP    K0C
  1793. X#define KCPGDN    K0D
  1794. X#define KCHOME    K0E
  1795. X#define KCEND    K0F
  1796. X
  1797. X#define    KF1    K10
  1798. X#define KF2    K11
  1799. X#define KF3    K12
  1800. X#define KF4    K13
  1801. X#define KF5    K14
  1802. X#define KF6    K15
  1803. X#define KF7    K16
  1804. X#define KF8    K17
  1805. X#define    KF9    K18
  1806. X#define KF10    K19
  1807. X#define    KSF1    K1A
  1808. X#define    KSF2    K1B
  1809. X#define    KSF3    K1C
  1810. X#define    KSF4    K1D
  1811. X#define    KSF5    K1E
  1812. X#define    KSF6    K1F
  1813. X#define    KSF7    K20
  1814. X#define    KSF8    K21
  1815. X#define    KSF9    K22
  1816. X#define    KSF10    K23
  1817. X#define KCF1    K24
  1818. X#define KCF2    K25
  1819. X#define KCF3    K26
  1820. X#define KCF4    K27
  1821. X#define KCF5    K28
  1822. X#define KCF6    K29
  1823. X#define KCF7    K2A
  1824. X#define KCF8    K2B
  1825. X#define KCF9    K2C
  1826. X#define KCF10    K2D
  1827. X#define KLAST    K2D
  1828. X
  1829. X#define    NFUND_XMAPS    1
  1830. X#define    FUND_XMAPS    {KFIRST,KLAST,ibm_keys,(KEYMAP*)NULL}
  1831. Xextern    int (*(ibm_keys[]))(); /* should be FN ibmkeys[], but not defined yet */
  1832. X/*
  1833. X * Extra map segments for dired mode -- just use fundamental mode segments
  1834. X */
  1835. X#define    NDIRED_XMAPS    NFUND_XMAPS
  1836. X#define    DIRED_XMAPS    FUND_XMAPS
  1837. X
  1838. !FaR!OuT!
  1839. fi
  1840. if [ ! -s ./ttyio.c ]
  1841. then
  1842. if [ ! -d . ]
  1843. then
  1844.     mkdir .
  1845.     echo mkdir .
  1846. fi
  1847. echo x - ./ttyio.c
  1848. sed -e 's/^X//' > ./ttyio.c << '!FaR!OuT!'
  1849. X/*
  1850. X * Name:    Mg 2b
  1851. X *        MSDOS terminal I/O (TurboC 1.5)
  1852. X *
  1853. X * The functions in this file
  1854. X * negotiate with the operating system for
  1855. X * keyboard characters, and write characters to
  1856. X * the display
  1857. X *
  1858. X * This version goes along with tty/ibmbios/tty.c.
  1859. X * Terminal size is determined there, rather than here.
  1860. X */
  1861. X#include    "def.h"
  1862. X
  1863. X#include    <stdio.h>
  1864. X#include    <fcntl.h>
  1865. X#include    <signal.h>
  1866. X
  1867. Xstatic int ttyactivep = FALSE;        /* terminal in editor mode?    */
  1868. X
  1869. Xint    nrow;                /* Terminal size, rows.        */
  1870. Xint    ncol;                /* Terminal size, columns.    */
  1871. X
  1872. X/*
  1873. X * This function gets called once, to set up
  1874. X * the terminal channel.  This is essentially a no-op
  1875. X * on msdos, since I/O will all be done via bios calls.
  1876. X */
  1877. Xttopen()
  1878. X{
  1879. X    if (ttyactivep)
  1880. X        return;
  1881. X
  1882. X    signal(SIGINT, SIG_IGN);
  1883. X
  1884. X    nrow = 25;            /* initial guess */
  1885. X    ncol = 80;
  1886. X
  1887. X    ttyactivep = TRUE;
  1888. X}
  1889. X
  1890. X/*
  1891. X * This function gets called just
  1892. X * before we go back home to the shell. Another
  1893. X * MSDOS no_op.
  1894. X */
  1895. Xttclose()
  1896. X{
  1897. X    if(!ttyactivep)
  1898. X        return;
  1899. X    ttyactivep = FALSE;
  1900. X}
  1901. X
  1902. X/********************************************************************/
  1903. X/* ttputc, ttgetc & typeahead have been deleted from this file, and */
  1904. X/* moved into the tty specific code.  There is no operating-system  */
  1905. X/* generic way to do these                                          */
  1906. X/********************************************************************/
  1907. X
  1908. X/*
  1909. X * Flush output.  This function is a no-op
  1910. X */
  1911. Xttflush()
  1912. X{
  1913. X}
  1914. X
  1915. X/*
  1916. X * panic:  print error and die, leaving core file.
  1917. X */
  1918. Xpanic(s)
  1919. Xchar *s;
  1920. X{
  1921. X    fprintf(stderr, "%s\r\n", s);
  1922. X#ifdef SYSCLEANUP
  1923. X    SYSCLEANUP;
  1924. X#endif
  1925. X    exit(1);
  1926. X}
  1927. X
  1928. X
  1929. X/*
  1930. X** This should check the size of the window, and reset if needed.
  1931. X*/
  1932. X
  1933. Xsetttysize()
  1934. X{
  1935. X    nrow = 25;
  1936. X    ncol = 80;
  1937. X}
  1938. X
  1939. X
  1940. Xvoid interrupt donothing()
  1941. X    {
  1942. X    return;    /* continue program */
  1943. X    }
  1944. X
  1945. X/* Turbo C does not have a "signal" function. */
  1946. X/* since all I need to use it for is to ignore ^C, this substitute works ok */
  1947. Xsignal(sig, action)
  1948. Xint sig;
  1949. Xint (*action)();
  1950. X    {
  1951. X    if (sig != SIGINT || action != SIG_IGN)
  1952. X    {
  1953. X    printf("Runtime error in signal: only SIGINT, SIG_IGN supported!\n");
  1954. X    exit(1);
  1955. X    }
  1956. X    setvect(0x23, donothing);
  1957. X    }
  1958. !FaR!OuT!
  1959. fi
  1960. if [ ! -s ./ttykbd.c ]
  1961. then
  1962. if [ ! -d . ]
  1963. then
  1964.     mkdir .
  1965.     echo mkdir .
  1966. fi
  1967. echo x - ./ttykbd.c
  1968. sed -e 's/^X//' > ./ttykbd.c << '!FaR!OuT!'
  1969. X/*
  1970. X * Name:    Mg 2a
  1971. X *        IBM BIOS keyboard driver (TurboC 1.5)
  1972. X *
  1973. X */
  1974. X
  1975. X#include    "def.h"
  1976. X#include    <dos.h>
  1977. X
  1978. X#ifdef MSC
  1979. X#include    <bios.h>
  1980. X#endif /* MSC */
  1981. X
  1982. X#define KMETA    METABIT
  1983. X
  1984. Xchar    *keystrings[] = {
  1985. X    "Home",        "Down-Arrow",    "Up-Arrow",    "Left-Arrow",
  1986. X    "Right-Arrow",    "Page-Up",    "Page-Down",    "End",
  1987. X    "Delete",    "Insert",    "Control-Left", "Control-Right",
  1988. X    "Control-PgUp",    "Control-PgDn",    "Control-Home",    "Control-End",
  1989. X    "F1",        "F2",        "F3",        "F4",
  1990. X    "F5",        "F6",        "F7",        "F8",
  1991. X    "F9",        "F10",        "FS1",        "FS2",
  1992. X    "FS3",        "FS4",        "FS5",        "FS6",
  1993. X    "FS7",        "FS8",        "FS9",        "FS10",
  1994. X    "FC1",        "FC2",        "FC3",        "FC4",
  1995. X    "FC5",        "FC6",        "FC7",        "FC8",
  1996. X    "FC9",        "FC10",
  1997. X};
  1998. X
  1999. X/* convert IBM bios extended scan codes to appropriate function key values */
  2000. Xstatic KCHAR extended[] = {
  2001. X    -1,        -1,        -1,        0,      /* 0-3 */
  2002. X    -1,        -1,        -1,        -1,      /* 4-7 */
  2003. X    -1,        -1,        -1,        -1,      /* 8-11 */
  2004. X    -1,        -1,        -1,        -1,      /* 12-15 */
  2005. X    KMETA|'Q',    KMETA|'W',    KMETA|'E',    KMETA|'R',/* 16-19 */
  2006. X    KMETA|'T',    KMETA|'Y',    KMETA|'U',    KMETA|'I',/* 20-23 */
  2007. X    KMETA|'O',    KMETA|'P',    -1,        -1,      /* 24-27 */
  2008. X    -1,        -1,        KMETA|'A',    KMETA|'S',/* 28-31 */
  2009. X    KMETA|'D',    KMETA|'F',    KMETA|'G',    KMETA|'H',/* 32-35 */
  2010. X    KMETA|'J',    KMETA|'K',    KMETA|'L',    -1,      /* 36-39 */
  2011. X    -1,        -1,        -1,        -1,      /* 40-43 */
  2012. X    KMETA|'Z',    KMETA|'X',    KMETA|'C',    KMETA|'V',/* 44-47 */
  2013. X    KMETA|'B',    KMETA|'N',    KMETA|'M',    -1,      /* 48-51 */
  2014. X    -1,        -1,        /* oops - miscounted */      /* 52-53 */
  2015. X    -1,        -1,        -1,        -1,      /* 54-57 */
  2016. X    -1,        KF1,        KF2,        KF3,      /* 58-61 */
  2017. X    KF4,        KF5,        KF6,        KF7,      /* 62-65 */
  2018. X    KF8,        KF9,        KF10,        -1,      /* 66-69 */
  2019. X    -1,        KHOME,        KUP,        KPGUP,      /* 70-73 */
  2020. X    -1,        KLEFT,        -1,        KRIGHT,      /* 74-77 */
  2021. X    -1,        KEND,        KDOWN,        KPGDN,      /* 78-81 */
  2022. X    KINSERT,    KDELETE,    KSF1,        KSF2,      /* 82-85 */
  2023. X    KSF3,        KSF4,        KSF5,        KSF6,      /* 86-89 */
  2024. X    KSF7,        KSF8,        KSF9,        KSF10,      /* 90-93 */
  2025. X    KCF1,        KCF2,        KCF3,        KCF4,      /* 94-97 */
  2026. X    KCF5,        KCF6,        KCF7,        KCF8,      /* 98-101 */
  2027. X    KCF9,        KCF10,        KMETA|KF1,    KMETA|KF2,/* 102-105 */
  2028. X    KMETA|KF3,    KMETA|KF4,    KMETA|KF5,    KMETA|KF6,/* 106-109 */
  2029. X    KMETA|KF7,    KMETA|KF8,    KMETA|KF9,    KMETA|KF10,/* 110-113 */
  2030. X    -1,        KCLEFT,        KCRIGHT,    KCEND,      /* 114-117 */
  2031. X    KCPGDN,        KCHOME,        KMETA|'1',    KMETA|'2',/* 118-121 */
  2032. X    KMETA|'3',    KMETA|'4',    KMETA|'5',    KMETA|'6',/* 122-125 */
  2033. X    KMETA|'7',    KMETA|'8',    KMETA|'9',    KMETA|'0',/* 126-129 */
  2034. X    KMETA|'-',    KMETA|'=',    KCPGUP,              /* 130-132 */
  2035. X};
  2036. X
  2037. X#define NEXTENDED (sizeof(extended)-sizeof(KCHAR))
  2038. X
  2039. Xstatic KCHAR savedkey = -1;
  2040. X
  2041. Xgetkbd() {
  2042. X    return (ttgetc());
  2043. X}
  2044. X
  2045. X/*
  2046. X * Get keyboard character, and interpret
  2047. X * any special keys on the keyboard.
  2048. X */
  2049. Xttgetc() {
  2050. X    KCHAR temp;
  2051. X
  2052. X    while (savedkey == -1)
  2053. X    getakey();
  2054. X
  2055. X    temp = savedkey;
  2056. X    savedkey = -1;
  2057. X    return temp;
  2058. X}
  2059. X
  2060. Xgetakey() {
  2061. X    union REGS rg;
  2062. X
  2063. X    rg.h.ah = 0;        /* read keyboard */
  2064. X    int86(0x16, &rg, &rg);
  2065. X    if (rg.h.al) {
  2066. X    if (rg.h.al == '\b' && rg.h.ah == 0x0E)
  2067. X        rg.h.al = 0x7F;    /* transform backspace key into delete */
  2068. X                /* control H is still backspace */
  2069. X    savedkey = rg.h.al;    /* normal key value */
  2070. X    }
  2071. X    else {
  2072. X    if (rg.h.ah >= NEXTENDED)
  2073. X        savedkey = -1;
  2074. X    else
  2075. X        savedkey = extended[rg.h.ah];
  2076. X    }
  2077. X}
  2078. X
  2079. Xpollkbd()
  2080. X{
  2081. X#ifdef MSC
  2082. X    return _bios_keybrd(_KEYBRD_READY);
  2083. X#else
  2084. X    return bioskey(1);
  2085. X#endif /* MSC */
  2086. X}
  2087. X
  2088. Xtypeahead() {
  2089. X    if (savedkey != -1)
  2090. X    return 1;
  2091. X    if (pollkbd())
  2092. X    getakey();
  2093. X    return (savedkey != -1);
  2094. X}
  2095. X
  2096. Xttykeymapinit() {
  2097. X    /* mg 2a no longer lets me easily bind things at run time. */
  2098. X    /* instead, I make up a keymap, and link it in at compile time */
  2099. X}
  2100. X
  2101. Xextern    int    gotobol();        /* Move to start of line    */
  2102. Xextern    int    backchar();        /* Move backward by characters    */
  2103. Xextern    int    gotoeol();        /* Move to end of line        */
  2104. Xextern    int    forwchar();        /* Move forward by characters    */
  2105. Xextern    int    gotobob();        /* Move to start of buffer    */
  2106. Xextern    int    gotoeob();        /* Move to end of buffer    */
  2107. Xextern    int    gotobop();        /* Move to start of display page*/
  2108. Xextern    int    gotoeop();        /* Move to end of display page    */
  2109. Xextern    int    forwline();        /* Move forward by lines    */
  2110. Xextern    int    backline();        /* Move backward by lines    */
  2111. Xextern    int    forwpage();        /* Move forward by pages    */
  2112. Xextern    int    backpage();        /* Move backward by pages    */
  2113. Xextern    int    openline();        /* Open up a blank line        */
  2114. Xextern    int    forwdel();        /* Forward delete        */
  2115. Xextern    int    rescan();        /* for unmapped keys        */
  2116. Xextern    int    backword();        /* Backup by words        */
  2117. Xextern    int    forwword();        /* Advance by words        */
  2118. Xextern    int    killline();        /* Kill forward            */
  2119. X
  2120. XPF    ibm_keys[] = {
  2121. X    gotobol,    /* Home            (0x100)    */
  2122. X    forwline,    /* Down                */
  2123. X    backline,    /* Up                */
  2124. X    backchar,    /* Left                */
  2125. X    forwchar,    /* Right            */
  2126. X    backpage,    /* Page Up            */
  2127. X    forwpage,    /* Page Dn            */
  2128. X    gotoeol,    /* End                */
  2129. X    forwdel,    /* Delete            */
  2130. X    openline,    /* Insert            */
  2131. X    backword,    /* Control Left            */
  2132. X    forwword,    /* Control Right        */
  2133. X    gotobob,    /* Control PgUp               */
  2134. X    gotoeob,    /* Control PgDn             */
  2135. X    gotobop,    /* Control HOME            */
  2136. X    gotoeop,    /* Control END            */
  2137. X
  2138. X    /* function keys - initially unassigned */
  2139. X    rescan, rescan, rescan, rescan,
  2140. X    rescan, rescan, rescan, rescan,
  2141. X    rescan, rescan, rescan, rescan,
  2142. X    rescan, rescan, rescan, rescan,
  2143. X    rescan, rescan, rescan, rescan,
  2144. X    rescan, rescan, rescan, rescan,
  2145. X    rescan, rescan, rescan, rescan,
  2146. X    rescan, rescan,
  2147. X};
  2148. !FaR!OuT!
  2149. fi
  2150. if [ ! -s ./varargs.h ]
  2151. then
  2152. if [ ! -d . ]
  2153. then
  2154.     mkdir .
  2155.     echo mkdir .
  2156. fi
  2157. echo x - ./varargs.h
  2158. sed -e 's/^X//' > ./varargs.h << '!FaR!OuT!'
  2159. X/* varargs.h for MicroGnuEmacs 2a.  This one will work on systems that    */
  2160. X/* the non-varargs version of mg 1 did.                    */
  2161. X/* based on the one I wrote for os9/68k .  I did not look at the bsd code. */
  2162. X
  2163. X/* by Robert A. Larson */
  2164. X
  2165. X/* assumptions made about how arguments are passed:            */
  2166. X/*    arguments are stored in a block of memory with no padding between. */
  2167. X/*    The first argument will have the lowest address            */
  2168. X
  2169. X/* varargs is a "portable" way to write a routine that takes a variable */
  2170. X/* number of arguements.  This implemination agrees with both the 4.2bsd*/
  2171. X/* and Sys V documentation of varargs.  Note that just because varargs.h*/
  2172. X/* is used does not mean that it is used properly.            */
  2173. X
  2174. X#define va_dcl        unsigned va_alist;
  2175. X
  2176. Xtypedef    char *va_list;
  2177. X
  2178. X#define    va_start(pvar)        ((pvar) = (char *)&va_alist)
  2179. X
  2180. X#define va_arg(pvar,type)    (((pvar)+=sizeof(type)),*(((type *)(pvar)) - 1))
  2181. X
  2182. X#define va_end(pvar)        /* va_end is simple */
  2183. !FaR!OuT!
  2184. fi
  2185. exit
  2186.