home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
util
/
vim-3.0.lha
/
Vim
/
src
/
msdos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-12
|
19KB
|
1,008 lines
/* vi:ts=4:sw=4
*
* VIM - Vi IMproved by Bram Moolenaar
*
* Read the file "credits.txt" for a list of people who contributed.
* Read the file "uganda.txt" for copying and usage conditions.
*/
/*
* msdos.c
*
* MSDOS system-dependent routines.
* A cheap plastic imitation of the amiga dependent code.
* A lot in this file was made by Juergen Weigert (jw).
*/
#include <io.h>
#include "vim.h"
#include "globals.h"
#include "param.h"
#include "proto.h"
#include <conio.h>
#include <fcntl.h>
#include <bios.h>
#include <alloc.h>
static int WaitForChar __ARGS((int));
static int change_drive __ARGS((int));
static int cbrk_handler __ARGS(());
typedef struct filelist
{
char_u **file;
int nfiles;
int maxfiles;
} FileList;
static void addfile __ARGS((FileList *, char_u *, int));
static int pstrcmp(); /* __ARGS((char **, char **)); BCC does not like this */
static void strlowcpy __ARGS((char_u *, char_u *));
static int expandpath __ARGS((FileList *, char_u *, int, int, int));
static int cbrk_pressed = FALSE; /* set by ctrl-break interrupt */
static int ctrlc_pressed = FALSE; /* set when ctrl-C or ctrl-break detected */
static int delayed_redraw = FALSE; /* set when ctrl-C detected */
long
mch_avail_mem(special)
int special;
{
return coreleft();
}
void
vim_delay()
{
delay(500);
}
/*
* this version of remove is not scared by a readonly (backup) file
*
* returns -1 on error, 0 otherwise (just like remove())
*/
int
vim_remove(name)
char_u *name;
{
(void)setperm(name, 0); /* default permissions */
return unlink(name);
}
/*
* mch_write(): write the output buffer to the screen
*/
void
mch_write(s, len)
char_u *s;
int len;
{
char_u *p;
int row, col;
if (term_console) /* translate ESC | sequences into bios calls */
while (len--)
{
if (s[0] == '\n')
putch('\r');
else if (s[0] == ESC && len > 1 && s[1] == '|')
{
switch (s[2])
{
case 'J': clrscr();
goto got3;
case 'K': clreol();
goto got3;
case 'L': insline();
goto got3;
case 'M': delline();
got3: s += 3;
len -= 2;
continue;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': p = s + 2;
row = getdigits(&p); /* no check for length! */
if (p > s + len)
break;
if (*p == ';')
{
++p;
col = getdigits(&p); /* no check for length! */
if (p > s + len)
break;
if (*p == 'H' || *p == 'r')
{
if (*p == 'H') /* set cursor position */
gotoxy(col, row);
else /* set scroll region */
window(1, row, Columns, col);
len -= p - s;
s = p + 1;
continue;
}
}
else if (*p == 'm')
{
if (row == 0)
normvideo();
else
textattr(row);
len -= p - s;
s = p + 1;
continue;
}
}
}
putch(*s++);
}
else
write(1, s, (unsigned)len);
}
#define POLL_SPEED 10 /* milliseconds between polls */
/*
* Simulate WaitForChar() by slowly polling with bioskey(1) or kbhit().
*
* If Vim should work over the serial line after a 'ctty com1' we must use
* kbhit() and getch(). (jw)
* Usually kbhit() is not used, because then CTRL-C and CTRL-P
* will be catched by DOS (mool).
*
* return TRUE if a character is available, FALSE otherwise
*/
static int
WaitForChar(msec)
int msec;
{
for (;;)
{
if ((p_biosk ? bioskey(1) : kbhit()) || cbrk_pressed)
return TRUE;
if (msec <= 0)
break;
delay(POLL_SPEED);
msec -= POLL_SPEED;
}
return FALSE;
}
/*
* GetChars(): low level input funcion.
* Get a characters from the keyboard.
* If time == 0 do not wait for characters.
* If time == n wait a short time for characters.
* If time == -1 wait forever for characters.
*
* return the number of characters obtained
*/
int
GetChars(buf, maxlen, time)
char_u *buf;
int maxlen;
int time;
{
int len = 0;
int c;
/*
* if we got a ctrl-C when we were busy, there will be a "^C" somewhere
* on the sceen, so we need to redisplay it.
*/
if (delayed_redraw)
{
delayed_redraw = FALSE;
updateScreen(CLEAR);
setcursor();
flushbuf();
}
if (time >= 0)
{
if (WaitForChar(time) == 0) /* no character available */
return 0;
}
else /* time == -1 */
{
/*
* If there is no character available within 2 seconds (default)
* write the autoscript file to disk
*/
if (WaitForChar((int)p_ut) == 0)
updatescript(0);
}
/*
* Try to read as many characters as there are.
* Works for the controlling tty only.
*/
--maxlen; /* may get two chars at once */
/*
* we will get at least one key. Get more if they are available
* After a ctrl-break we have to read a 0 (!) from the buffer.
* bioskey(1) will return 0 if no key is available and when a
* ctrl-break was typed. When ctrl-break is hit, this does not always
* implies a key hit.
*/
cbrk_pressed = FALSE;
if (p_biosk)
while ((len == 0 || bioskey(1)) && len < maxlen)
{
c = bioskey(0); /* get the key */
if (c == 0) /* ctrl-break */
c = 3; /* return a CTRL-C */
if ((c & 0xff) == 0)
{
if (c == 0x0300) /* CTRL-@ is 0x0300, translated into K_ZERO */
c = K_ZERO;
else /* extended key code 0xnn00 translated into K_NUL, nn */
{
c >>= 8;
*buf++ = K_NUL;
++len;
}
}
*buf++ = c;
len++;
}
else
while ((len == 0 || kbhit()) && len < maxlen)
{
switch (c = getch())
{
case 0:
*buf++ = K_NUL;
break;
case 3:
cbrk_pressed = TRUE;
/*FALLTHROUGH*/
default:
*buf++ = c;
}
len++;
}
return len;
}
/*
* return non-zero if a character is available
*/
int
mch_char_avail()
{
return WaitForChar(0);
}
/*
* We have no job control, fake it by starting a new shell.
*/
void
mch_suspend()
{
OUTSTR("new shell started\n");
(void)call_shell(NULL, 0, TRUE);
}
extern int _fmode;
/*
* we do not use windows, there is not much to do here
*/
void
mch_windinit()
{
_fmode = O_BINARY; /* we do our own CR-LF translation */
flushbuf();
(void)mch_get_winsize();
}
void
check_win(argc, argv)
int argc;
char **argv;
{
if (!isatty(0) || !isatty(1))
{
fprintf(stderr, "VIM: no controlling terminal\n");
exit(2);
}
/*
* In some cases with DOS 6.0 on a NEC notebook there is a 12 seconds
* delay when starting up that can be avoided by the next two lines.
* Don't ask me why!
* This could be fixed by removing setver.sys from config.sys. Forget it.
gotoxy(1,1);
cputs(" ");
*/
}
/*
* fname_case(): Set the case of the filename, if it already exists.
* msdos filesystem is far to primitive for that. do nothing.
*/
void
fname_case(name)
char_u *name;
{
}
/*
* mch_settitle(): set titlebar of our window.
* Dos console has no title.
*/
void
mch_settitle(title, icon)
char_u *title;
char_u *icon;
{
}
/*
* Restore the window/icon title. (which we don't have)
*/
void
mch_restore_title(which)
int which;
{
}
/*
* Get name of current directory into buffer 'buf' of length 'len' bytes.
* Return OK for success, FAIL for failure.
*/
int
vim_dirname(buf, len)
char_u *buf;
int len;
{
return (getcwd(buf, len) != NULL ? OK : FAIL);
}
/*
* Change default drive (just like _chdrive of Borland C 3.1)
*/
static int
change_drive(drive)
int drive;
{
unsigned dummy;
union REGS regs;
regs.h.ah = 0x0e;
regs.h.dl = drive - 1;
intdos(®s, ®s); /* set default drive */
regs.h.ah = 0x19;
intdos(®s, ®s); /* get default drive */
if (regs.h.al == drive - 1)
return 0;
else
return -1;
}
/*
* get absolute filename into buffer 'buf' of length 'len' bytes
*
* return FAIL for failure, OK otherwise
*/
int
FullName(fname, buf, len)
char_u *fname, *buf;
int len;
{
if (fname == NULL) /* always fail */
{
*buf = NUL;
return FAIL;
}
if (isFullName(fname)) /* allready expanded */
{
STRNCPY(buf, fname, len);
return OK;
}
#ifdef __BORLANDC__ /* the old Turbo C does not have this */
if (_fullpath(buf, fname, len) == NULL)
{
STRNCPY(buf, fname, len); /* failed, use