You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
511 lines
10 KiB
511 lines
10 KiB
/*** zaux.c - helper routines for Z
|
|
*
|
|
* Modifications
|
|
*
|
|
* 26-Nov-1991 mz Strip off near/far
|
|
*
|
|
*************************************************************************/
|
|
#define INCL_SUB
|
|
#define INCL_DOSERRORS
|
|
#define INCL_DOSMISC
|
|
|
|
#include "mep.h"
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
|
|
/*** ParseCmd - Parse "command" line into two pieces
|
|
*
|
|
* Given a text string, returns a pointer to the first word (non-whitespace)
|
|
* in the text, which is null terminated by this routine, and a pointer to
|
|
* the second word.
|
|
*
|
|
* Input:
|
|
* pText = Pointer to text string
|
|
* ppCmd = Pointer to place to put pointer to first word
|
|
* ppArg = Pointer to place to put pointer to second word
|
|
*
|
|
* Output:
|
|
* Returns nothing. Pointers update, and string possible modified to include
|
|
* null terminator after first word.
|
|
*
|
|
*************************************************************************/
|
|
void
|
|
ParseCmd (
|
|
char *pText,
|
|
char **ppCmd,
|
|
char **ppArg
|
|
)
|
|
{
|
|
REGISTER char *pCmd; /* working pointer */
|
|
REGISTER char *pArg; /* working pointer */
|
|
|
|
pArg = whitescan (pCmd = whiteskip (pText));
|
|
if (*pArg) {
|
|
*pArg++ = '\0';
|
|
pArg = whiteskip (pArg);
|
|
}
|
|
*ppCmd = pCmd;
|
|
*ppArg = pArg;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
whiteskip (
|
|
const char *p
|
|
)
|
|
{
|
|
return strbskip ((char *)p, (char *)rgchWSpace);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char *
|
|
whitescan (
|
|
const char *p
|
|
)
|
|
{
|
|
return strbscan ((char *)p, (char *)rgchWSpace);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** RemoveTrailSpace - remove trailing white space characters from line
|
|
*
|
|
* Input:
|
|
* p = pointer to line to be stripped.
|
|
*
|
|
* Output:
|
|
* Returns new length of line.
|
|
*
|
|
*************************************************************************/
|
|
int
|
|
RemoveTrailSpace (
|
|
REGISTER char *p
|
|
)
|
|
{
|
|
REGISTER int len = strlen (p);
|
|
|
|
while (len && strchr(rgchWSpace,p[len-1])) {
|
|
len--;
|
|
}
|
|
|
|
p[len] = 0;
|
|
return len;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** DoubleSlashes - given a character string, double all backslashes
|
|
*
|
|
* Input:
|
|
* pbuf = pointer to character buffer
|
|
*
|
|
* Output:
|
|
* Returns pbuf
|
|
*
|
|
*************************************************************************/
|
|
char *
|
|
DoubleSlashes (
|
|
char * pbuf
|
|
)
|
|
{
|
|
REGISTER int l;
|
|
REGISTER char *p;
|
|
|
|
p = pbuf;
|
|
l = strlen (p);
|
|
while (l) {
|
|
if (*p == '\\') {
|
|
memmove ((char *) (p+1),(char *) p, l+1);
|
|
*p++ = '\\';
|
|
}
|
|
p++;
|
|
l--;
|
|
}
|
|
return pbuf;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** UnDoubleSlashes - given a character string, un-double all backslashes
|
|
*
|
|
* Input:
|
|
* pbuf = pointer to character buffer
|
|
*
|
|
* Output:
|
|
* Returns pbuf
|
|
*
|
|
*************************************************************************/
|
|
char *
|
|
UnDoubleSlashes (
|
|
char * pbuf
|
|
)
|
|
{
|
|
REGISTER char *p1;
|
|
REGISTER char *p2;
|
|
|
|
p1 = p2 = pbuf;
|
|
while (*p1) {
|
|
if ((*p2++ = *p1++) == '\\') {
|
|
if (*p1 == '\\') {
|
|
p1++;
|
|
}
|
|
}
|
|
}
|
|
return pbuf;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** fIsNum - see if a string is entirely digits
|
|
*
|
|
* Input:
|
|
* p = pointer to string
|
|
*
|
|
* Output:
|
|
* Returns TRUE if valid number.
|
|
*
|
|
*************************************************************************/
|
|
flagType
|
|
fIsNum (
|
|
char *p
|
|
)
|
|
{
|
|
if (*p == '-') {
|
|
p++;
|
|
}
|
|
return (flagType)(*strbskip (p, "0123456789") == 0);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** OS2toErrTxt - Get Error Text for OS/2 error
|
|
*
|
|
* Get the error message text for an OS/2 returned error.
|
|
*
|
|
* Input:
|
|
* erc = OS/2 error number
|
|
* buf = location to place the error (BUFSIZE)
|
|
*
|
|
* Output:
|
|
* Returns buf
|
|
*
|
|
*************************************************************************/
|
|
char *
|
|
OS2toErrText (
|
|
int erc,
|
|
char * buf
|
|
)
|
|
{
|
|
|
|
sprintf(buf, "Windows error No. %lu", GetLastError());
|
|
return buf;
|
|
|
|
erc;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** OS2toErrno - Convert OS/2 error code to C runtime error
|
|
*
|
|
* Purpose:
|
|
* Maps errors returned by some OS/2 calls to equivalent C runtime errors,
|
|
* such that routines which differ in OS/2 implementation can return equivalent
|
|
* errors as their DOS counterparts.
|
|
*
|
|
* Input:
|
|
* code = OS/2 returned error code
|
|
*
|
|
* Output:
|
|
* returns a C runtime error constant
|
|
*
|
|
* Exceptions:
|
|
* none
|
|
*
|
|
* Notes:
|
|
* CONSIDER: It's been suggested that this routine, and error message
|
|
* CONSIDER: presentation under OS/2 be changed to use DosGetMessage.
|
|
*
|
|
*************************************************************************/
|
|
int
|
|
OS2toErrno (
|
|
int code
|
|
)
|
|
{
|
|
buffer L_buf;
|
|
|
|
printerror (OS2toErrText (code,L_buf));
|
|
|
|
return code;
|
|
}
|
|
|
|
|
|
|
|
|
|
union argPrintfType {
|
|
long *pLong;
|
|
int *pInt;
|
|
char **pStr;
|
|
char **fpStr;
|
|
};
|
|
|
|
|
|
/*** ZFormat - replace the C runtime formatting routines.
|
|
*
|
|
* Purpose:
|
|
*
|
|
* ZFormat is a near-replacement for the *printf routines in the C runtime.
|
|
*
|
|
* Input:
|
|
* pStr - destination string where formatted result is placed.
|
|
* fmt - formatting string. Formats currently understood are:
|
|
* %c single character
|
|
* %[n][l]d %[n][l]x
|
|
* %[m.n]s
|
|
* %[m.n]|{dpfe}F - print drive, path, file, extension
|
|
* of current file.
|
|
* * may be used to copy in values for m and n from arg
|
|
* list.
|
|
* %%
|
|
* arg - is a list of arguments
|
|
*
|
|
* Output:
|
|
*
|
|
* Returns 0 on success, MSGERR_* on failure. The MSGERR_* value may
|
|
* be passed to disperr, as in:
|
|
*
|
|
* if (err = ZFormat (pszUser))
|
|
* disperr (err, pszUser).
|
|
*
|
|
* Note that the error message wants to display the offending string.
|
|
*
|
|
* Currently, the only return value is:
|
|
*
|
|
* MSGERR_ZFORMAT 8020 Unrecognized %% command in '%s'
|
|
*
|
|
*************************************************************************/
|
|
|
|
int
|
|
ZFormat (
|
|
REGISTER char *pStr,
|
|
const REGISTER char *fmt,
|
|
va_list vl
|
|
)
|
|
{
|
|
char c;
|
|
char * pchar;
|
|
int * pint;
|
|
|
|
|
|
|
|
*pStr = 0;
|
|
while (c = *fmt++) {
|
|
if (c != '%') {
|
|
*pStr++ = c;
|
|
} else {
|
|
flagType fFar = FALSE;
|
|
flagType fLong = FALSE;
|
|
flagType fW = FALSE;
|
|
flagType fP = FALSE;
|
|
flagType fdF = FALSE;
|
|
flagType fpF = FALSE;
|
|
flagType ffF = FALSE;
|
|
flagType feF = FALSE;
|
|
char fill = ' ';
|
|
int base = 10;
|
|
int w = 0;
|
|
int p = 0;
|
|
int s = 1;
|
|
int l;
|
|
|
|
c = *fmt;
|
|
if (c == '-') {
|
|
s = -1;
|
|
c = *++fmt;
|
|
}
|
|
if (isdigit (c) || c == '.' || c == '*') {
|
|
/* parse off w.p
|
|
*/
|
|
fW = TRUE;
|
|
if (c == '*') {
|
|
pint = va_arg (vl, int *);
|
|
w = *pint;
|
|
fmt++;
|
|
} else {
|
|
if (c == '0') {
|
|
fill = '0';
|
|
}
|
|
w = s * atoi (fmt);
|
|
fmt = strbskip (fmt, "0123456789");
|
|
}
|
|
if (*fmt == '.') {
|
|
fP = TRUE;
|
|
if (fmt[1] == '*') {
|
|
p = va_arg (vl, int);
|
|
fmt += 2;
|
|
} else {
|
|
p = atoi (fmt+1);
|
|
fmt = strbskip (fmt+1, "0123456789");
|
|
}
|
|
}
|
|
}
|
|
if (*fmt == 'l') {
|
|
fLong = TRUE;
|
|
fmt++;
|
|
}
|
|
if (*fmt == 'F') {
|
|
fFar = TRUE;
|
|
fmt++;
|
|
}
|
|
if (*fmt == '|') {
|
|
while (*fmt != 'F') {
|
|
switch (*++fmt) {
|
|
case 'd': fdF = TRUE; break;
|
|
case 'p': fpF = TRUE; break;
|
|
case 'f': ffF = TRUE; break;
|
|
case 'e': feF = TRUE; break;
|
|
case 'F': if (fmt[-1] == '|') {
|
|
fdF = TRUE;
|
|
fpF = TRUE;
|
|
ffF = TRUE;
|
|
feF = TRUE;
|
|
}
|
|
break;
|
|
default :
|
|
// va_end(vl);
|
|
return MSGERR_ZFORMAT;
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (*fmt++) {
|
|
case 'c':
|
|
p = va_arg (vl, int);
|
|
*pStr++ = (char)p;
|
|
*pStr = 0;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
base = 16;
|
|
case 'd':
|
|
if (fLong) {
|
|
|
|
_ltoa ( va_arg (vl, long), pStr, base);
|
|
|
|
} else {
|
|
_ltoa ( (long)va_arg (vl, int), pStr, base);
|
|
|
|
}
|
|
break;
|
|
|
|
case 's':
|
|
pchar = va_arg (vl, char *);
|
|
if (fFar) {
|
|
if (!fP) {
|
|
p = strlen ( pchar );
|
|
}
|
|
memmove ((char *) pStr, pchar , p);
|
|
|
|
} else {
|
|
if (!fP) {
|
|
p = strlen ( pchar );
|
|
}
|
|
memmove ((char *) pStr, pchar , p);
|
|
|
|
}
|
|
fill = ' ';
|
|
pStr[p] = 0;
|
|
break;
|
|
|
|
case 'F':
|
|
pStr[0] = 0;
|
|
if (fdF) {
|
|
drive (pFileHead->pName, pStr);
|
|
}
|
|
if (fpF) {
|
|
path (pFileHead->pName, strend(pStr));
|
|
}
|
|
if (ffF) {
|
|
filename (pFileHead->pName, strend(pStr));
|
|
}
|
|
if (feF) {
|
|
extention (pFileHead->pName, strend(pStr));
|
|
}
|
|
break;
|
|
|
|
case '%':
|
|
*pStr++ = '%';
|
|
*pStr = 0;
|
|
break;
|
|
|
|
default:
|
|
// va_end(vl);
|
|
return MSGERR_ZFORMAT;
|
|
}
|
|
|
|
/* text is immediately at pStr. Check width to justification
|
|
*/
|
|
l = strlen (pStr);
|
|
if (w < 0) {
|
|
/* left-justify
|
|
*/
|
|
w = -w;
|
|
if (l < w) {
|
|
memset ((char *) &pStr[l], fill, w - l);
|
|
pStr[w] = 0;
|
|
}
|
|
} else if (l < w) {
|
|
/* right-justify
|
|
*/
|
|
memmove ((char *) &pStr[w-l], (char *) &pStr[0], l);
|
|
memset ((char *) &pStr[0], fill, w - l);
|
|
pStr[w] = 0;
|
|
}
|
|
pStr += strlen (pStr);
|
|
}
|
|
}
|
|
*pStr = 0;
|
|
// va_end(vl);
|
|
return 0;
|
|
}
|
|
|
|
/* FmtAssign - formatted assign
|
|
*
|
|
* FmtAssign is used to both format and perform an assignment
|
|
*
|
|
* pFmt character pointer to sprintf-style formatting
|
|
* arg set of unformatted arguments
|
|
*
|
|
* returns result of DoAssign upon formatted result
|
|
*/
|
|
flagType
|
|
__cdecl
|
|
FmtAssign (
|
|
char *pFmt,
|
|
...
|
|
)
|
|
{
|
|
char L_buf[ 512 ];
|
|
va_list L_pArgs;
|
|
|
|
va_start (L_pArgs, pFmt);
|
|
ZFormat (L_buf, pFmt, L_pArgs);
|
|
va_end (L_pArgs);
|
|
return DoAssign (L_buf);
|
|
}
|