📄 vxd_clib.c
字号:
#define WANTVXDWRAPS
#include "basedef.h"
#include "vmm.h"
#include "vmmreg.h"
#include "vxdwraps.h"
#include "vwin32.h"
#include "vxd_clib.h"
#undef FORCE_ALT_SCREEN
#undef ENABLE_ALT_SCREEN
#define ENABLE_PRINTF
/*** ATOI/ATOL Support ***/
int VXD_atoi(const char *pzArg)
{
char ch;
int iValue = 0;
if (pzArg != 0) {
ch = 0;
do {
iValue = 10*iValue + ch - '0';
ch = *pzArg++;
} while (('0' <= ch)&&(ch <= '9'));
}
return (iValue);
}
long VXD_atol(const char *pzArg)
{
char ch;
long lValue = 0;
if (pzArg != 0) {
ch = 0;
do {
lValue = 10*lValue + ch - '0';
ch = *pzArg++;
} while (('0' <= ch)&&(ch <= '9'));
}
return (lValue);
}
/*** PRINTF/SPRINTF/VSPRINTF Support ***/
#define FLAG_NONE 0x000 /* no flags */
#define FLAG_LEFTADJ 0x001 /* left adjust */
#define FLAG_ZEROPAD 0x002 /* zero pad */
#define FLAG_ALTFORM 0x004 /* alternate form */
#define FLAG_SHORTINT 0x008 /* short integer */
#define FLAG_LONGINT 0x010 /* long integer */
#define FLAG_SIGNED 0x020 /* signed integer */
#define FLAG_HEXPREFIX 0x040 /* hex prefix */
#define FLAG_STRING 0x080 /* string conversion */
#define FLAG_NEARPTR 0x100 /* near pointer */
#define FLAG_FARPTR 0x200 /* far pointer */
#define CONV_SIZE 32 /* binary conversion might require 32 chars */
/* This implementation does not support floating point but implements several */
/* extensions to the ANSI C specifiction. The implementation supports the */
/* following conversions: */
/* %d, %i, %u, %o, %x, %X, %p, %c, %s, %n, and %% standard ANSI conversions */
/* ' ', '0', '+', '-', '#' flags, 'h' , 'l', and 'L' size modifiers */
/* minimum_width and precision specifiers including '*' for runtime support */
/* synonyms %Lx = %lx, %D = %Ld = %ld, %U = %Lu = %lu, and %O = %Lo = %lo */
/* extension for binary conversion %b and %B = %Lb = %lB */
/* if the NEARFAR_POINTERS constant is defined, the implementation supports: */
/* %lp = %P = %Fp far pointer conversions, %hp %Np near pointer conversions */
/* %ls = %S = %Fs far string conversions, %hs %Ns near string conversions */
/* %Fn far count conversion, %Nn near count conversions */
#undef NEARFAR_POINTERS
int VXD_vsprintf(char *pzOutBuf, const char *pzFmt, va_list ap)
{
int nChars; /* number of characters printed */
char ch; /* current format character */
unsigned long ulValue; /* value for conversion */
int flags; /* holds value for flags */
char chSign; /* hold the sign to be printed (' ', '+', '-', or \0) */
int min_width; /* minimum width specifier */
int precision; /* precision number */
int base; /* base for integer conversion */
char *mchDigit; /* map of digit set to use */
int size; /* size of conversion text */
#ifdef NEARFAR_POINTERS
char _far *lpch; /* pointer in temp holding buffer */
#else
char *lpch; /* pointer in temp holding buffer */
#endif /* NEARFAR_POINTERS */
char chBufTemp[CONV_SIZE]; /* temp holding buffer for conversion */
nChars = 0;
for (;;) {
ch = *pzFmt++;
if (ch != '%') {
*pzOutBuf++ = ch;
if (ch == '\0') return (nChars);
++nChars;
continue;
}
/* parse flags */
flags = FLAG_NONE;
chSign = '\0';
mchDigit = "0123456789abcdef";
ch = *pzFmt++;
for (;;) {
if (ch == ' ') {
if (chSign == '\0') chSign = ' ';
} else if (ch == '+') {
chSign = '+';
} else if (ch == '-') {
flags |= FLAG_LEFTADJ;
} else if (ch == '0') {
flags |= FLAG_ZEROPAD;
} else if (ch == '#') {
flags |= FLAG_ALTFORM;
} else {
break;
}
ch = *pzFmt++;
}
/* parse min_width */
min_width = 0;
if (ch == '*') {
min_width = va_arg(ap, int);
ch = *pzFmt++;
} else {
while (('0' <= ch)&&(ch <= '9')) {
min_width = 10*min_width + ch - '0';
ch = *pzFmt++;
}
}
/* parse precision */
precision = -1;
if (ch == '.') {
ch = *pzFmt++;
if (ch == '*') {
precision = va_arg(ap, int);
ch = *pzFmt++;
} else {
precision = 0;
while (('0' <= ch)&&(ch <= '9')) {
precision = 10*precision + ch - '0';
ch = *pzFmt++;
}
}
}
/* parse conversion size */
for (;;) {
if (ch == 'h') flags |= FLAG_SHORTINT;
else if (ch == 'l') flags |= FLAG_LONGINT;
else if (ch == 'L') flags |= FLAG_LONGINT;
#ifdef NEARFAR_POINTERS
else if (ch == 'N') flags |= FLAG_NEARPTR;
else if (ch == 'F') flags |= FLAG_FARPTR;
#endif /* NEARFAR_POINTERS */
else break;
ch = *pzFmt++;
}
/* parse conversion */
switch (ch) {
default: /* unknown conversion or NULL */
*pzOutBuf++ = ch;
if (ch == '\0') return (nChars);
++nChars;
continue;
case 'n': /* save characters output so far */
#ifdef NEARFAR_POINTERS
if (flags & FLAG_FARPTR) {
void _far *vlp = va_arg(ap, void _far *);
if (flags & FLAG_LONGINT) *((long _far *)vlp) = nChars;
else if (flags & FLAG_SHORTINT) *((short _far *)vlp) = (short)nChars;
else *((int _far *)vlp) = nChars;
} else if (flags & FLAG_NEARPTR) {
void *vnp = va_arg(ap, void _near *);
if (flags & FLAG_LONGINT) *((long _near *)vnp) = nChars;
else if (flags & FLAG_SHORTINT) *((short _near *)vnp) = (short)nChars;
else *((int _near *)vnp) = nChars;
}
#endif /* NEARFAR_POINTERS */
{
void *vp = va_arg(ap, void *);
if (flags & FLAG_LONGINT) *((long *)vp) = nChars;
else if (flags & FLAG_SHORTINT) *((short *)vp) = (short)nChars;
else *((int *)vp) = nChars;
}
continue;
case '%': /* % conversion */
lpch = "%";
size = 1;
chSign = '\0';
break;
case 'c': /* character conversion */
lpch = chBufTemp;
*lpch = (char)va_arg(ap, int);
size = 1;
chSign = '\0';
break;
#ifdef NEARFAR_POINTERS
case 'S': /* far string conversion */
flags |= FLAG_FARPTR;
/* FALLTHROUGH */
#endif /* NEARFAR_POINTERS */
case 's': /* string conversion */
#ifdef NEARFAR_POINTERS
if ((flags & FLAG_LONGINT)||(flags & FLAG_FARPTR)) {
lpch = va_arg(ap, char _far *);
} else if ((flags & FLAG_SHORTINT)||(flags & FLAG_NEARPTR)) {
lpch = va_arg(ap, char _near *);
} else
#endif /* NEARFAR_POINTERS */
{
lpch = va_arg(ap, char *);
}
if (lpch == 0) {
lpch = "(null)";
size = sizeof ("(null)");
if (size > precision) size = precision;
} else {
#ifdef NEARFAR_POINTERS
char _far *lpchTemp = lpch;
#else
char *lpchTemp = lpch;
#endif /* NEARFAR_POINTERS */
size = 0;
if (precision >= 0) {
while (*lpchTemp++ != '\0') {
if (++size >= precision) break;
}
} else {
while (*lpchTemp++ != '\0') ++size;
}
}
chSign = '\0';
flags |= FLAG_STRING;
break;
#ifdef NEARFAR_POINTERS
case 'P': /* far pointer conversion */
flags |= FLAG_LONGINT;
/* FALLTHROUGH */
#endif /* NEARFAR_POINTERS */
case 'p': /* pointer conversion */
#ifdef NEARFAR_POINTERS
if ((flags & FLAG_LONGINT)||(flags & FLAG_FARPTR)) {
ulValue = (unsigned long)va_arg(ap, void _far *);
} else if ((flags & FLAG_SHORTINT)||(flags & FLAG_NEARPTR)) {
ulValue = (unsigned long)va_arg(ap, void _near *);
} else
#endif /* NEARFAR_POINTERS */
{
ulValue = (unsigned long)va_arg(ap, void *);
}
base = 16;
chSign = '\0';
goto L_number;
case 'X': /* hexadecimal conversion (caps) */
mchDigit = "0123456789ABCDEF";
/* FALLTHROUGH */
case 'x': /* hexadecimal conversion (lowercase) */
base = 16;
chSign = '\0';
goto L_read_number;
case 'O': /* EXTENSION: long octal conversion */
flags |= FLAG_LONGINT;
/* FALLTHROUGH */
case 'o': /* octal conversion */
base = 8;
chSign = '\0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -