📄 util.c
字号:
#include "pcdisk.h"
/*****************************************************************************
PC_ALLSPACE - Test if size characters in a string are spaces
Description
Test if the first size spaces of string are ' ' characters.
Returns
YES if all spaces.
*****************************************************************************/
/* Return YES if n bytes of p are spaces */
BOOL pc_allspace(UTEXT *p, INT i) /* __fn__*/
{
while (i--)
if (*p++ != ' ')
return (NO);
return (YES);
}
/****************************************************************************
COPYBUF - Copy one buffer to another
Description
Essentially strncpy. Copy size BYTES from from to to.
Returns
Nothing
****************************************************************************/
VOID copybuff(VOID *vto, VOID *vfrom, INT size) /* __fn__*/
{
UTINY *to = (UTINY *) vto;
UTINY *from = (UTINY *) vfrom;
while (size--)
*to++ = *from++;
}
/******************************************************************************
PC_CPPAD - Copy one buffer to another and right fill with spaces
Description
Copy up to size characters from "from" to "to". If less than size
characters are transferred before reaching \0 fill "to" with ' '
characters until its length reaches size.
Note: "to" is NOT ! Null terminated.
Returns
Nothing
*****************************************************************************/
VOID pc_cppad(UTEXT *to, UTEXT *from, INT size) /* __fn__*/
{
while (size--)
{
if (*from)
*to++ = *from++;
else
*to++ = ' ';
}
}
/***************************************************************************
PC_ISDOT - Test if a filename is exactly '.'
Description
Test to see if fname is exactly '.' followed by seven spaces and fext is
exactly three spaces.
Returns
YES if file:ext == '.'
***************************************************************************/
/* Return YES if File is exactly '.' */
BOOL pc_isdot(UTEXT *fname, UTEXT *fext) /* __fn__*/
{
return ((*fname == '.') &&
pc_allspace(fname+1,7) && pc_allspace(fext,3) );
}
/******************************************************************************
PC_ISDOTDOT - Test if a filename is exactly {'.','.'};
Description
Test to see if fname is exactly '..' followed by six spaces and fext is
exactly three spaces.
Returns
YES if file:ext == {'.','.'}
****************************************************************************/
/* Return YES if File is exactly '..' */
BOOL pc_isdotdot(UTEXT *fname, UTEXT *fext) /* __fn__*/
{
return ( (*fname == '.') && (*(fname+1) == '.') &&
pc_allspace(fname+2,6) && pc_allspace(fext,3) );
}
/****************************************************************************
PC_MEMFILL - Fill a buffer with a character
Description
Fill to with size instances of c
Returns
Nothing
*****************************************************************************/
/* Fill a string */
VOID pc_memfill(VOID *vto, INT size, UTINY c) /* __fn__*/
{
UTINY *to = (UTINY *) vto;
while (size--)
*to++ = c;
}
/***************************************************************************
PC_MFILE - Build a file spec (xxx.yyy) from a file name and extension
Description
Fill in to with a concatenation of file and ext. File and ext are
not assumed to be null terminated but must be blank filled to [8,3]
chars respectively. 'to' will be a null terminated string file.ext.
Returns
A pointer to 'to'.
****************************************************************************/
UTEXT *pc_mfile(UTEXT *to, UTEXT *filename, UTEXT *ext) /* __fn__*/
{
UTEXT *p;
COUNT i;
UTEXT *retval = to;
p = filename;
i = 0;
while(*p)
{
if (*p == ' ')
break;
else
{
*to++ = *p++;
i++;
}
if (i == 8)
break;
}
if (p != filename)
{
*to++ = '.';
p = ext;
i = 0;
while(*p)
{
if (*p == ' ')
break;
else
{
*to++ = *p++;
i++;
}
if (i == 3)
break;
}
}
/* Get rid of trailing '.' s */
if ( (to > retval) && *(to-1) == '.')
to--;
*to = '\0';
return (retval);
}
/***************************************************************************
PC_MPATH - Build a path sppec from a filename and pathname
Description
Fill in "to" with a concatenation of path and filename. If path
does not end with a path separator, one will be placed between
path and filename.
"TO" will be null terminated.
Returns
A pointer to 'to'.
*****************************************************************************/
UTEXT *pc_mpath(UTEXT *to, UTEXT *path, UTEXT *filename) /* __fn__*/
{
UTEXT *retval = to;
UTEXT *p;
UTEXT c = '\0';
p = path;
while(*p)
if (*p == ' ')
break;
else
*to++ = (c = *p++);
if (c != BACKSLASH)
*to++ = BACKSLASH;
p = filename;
while(*p)
*to++ = *p++;
*to = '\0';
return (retval);
}
/******************************************************************************
PC_PARSEDRIVE - Get a drive number from a path specifier
Description
Take a path specifier in path and extract the drive number from it.
If the second character in path is ':' then the first char is assumed
to be a drive specifier and 'A' is subtracted from it to give the
drive number. If the drive number is valid, driveno is updated and
a pointer to the text just beyond ':' is returned. Otherwise null
is returned.
If the second character in path is not ':' then the default drive number
is put in driveno and path is returned.
Returns
Returns NULL on a bad drive number otherwise a pointer to the first
character in the rest of the path specifier.
***************************************************************************/
/* Extract drive no from D: or use defualt. return the rest of the string
or NULL if a bad drive no is requested */
TEXT *pc_parsedrive(COUNT *driveno, TEXT *path) /* __fn__*/
{
TEXT *p = path;
COUNT dno;
/* get drive no */
if ( *p && (*(p+1) == ':'))
{
dno = (COUNT) (*p - 'A');
p += 2;
}
else
dno = NU_Get_Default_Drive();
if ( (dno < 0) || (dno >= NDRIVES) )
return (NULL);
else
{
*driveno = dno;
return (p);
}
}
/***************************************************************************
PC_FILEPARSE - Parse a file xxx.yyy into filename/pathname
Description
Take a file named "XXX.YY" and return SPACE padded NULL terminated
filename "XXX " and fileext "YY " components. If the name or ext are
less than [8,3] characters the name/ext is space filled and null termed.
If the name/ext is greater than [8,3] the name/ext is truncated. '.'
is used to seperate file from ext, the special cases of "." and ".." are
also handled.
Returns
Returns YES
****************************************************************************/
/* Take a string "xxx[.yy]" and put it into filename and fileext */
/* Note: add a check legal later */
BOOL pc_fileparse(TEXT *filename, TEXT *fileext, TEXT *p) /* __fn__*/
{
COUNT i = 0;
/* Defaults */
pc_memfill(filename, 8, ' ');
filename[8] = '\0';
pc_memfill(fileext, 3, ' ');
fileext[3] = '\0';
/* Special cases of . and .. */
if (*p == '.')
{
*filename = '.';
if (*(p+1) == '.')
{
*(++filename) = '.';
return (YES);
}
else if (*(p + 1) == '\0')
return (YES);
else
return (NO);
}
i = 0;
while (*p)
{
if (*p == '.')
{
p++;
break;
}
else
if (i++ < 8)
*filename++ = *p;
p++;
}
i = 0;
while (*p)
{
if (i++ < 3)
*fileext++ = *p;
p++;
}
return (YES);
}
/****************************************************************************
PC_NIBBLEPARSE - Nibble off the left most part of a pathspec
Description
Take a pathspec (no leading D:). and parse the left most element into
filename and files ext. (SPACE right filled.).
Returns
Returns a pointer to the rest of the path specifier beyond file.ext
****************************************************************************/
/* Parse a path. Return NULL if problems or a pointer to the "next" */
TEXT *pc_nibbleparse(TEXT *filename, TEXT *fileext, TEXT *path) /* __fn__*/
{
TEXT *p;
TEXT tbuf[EMAXPATH];
TEXT *t = &tbuf[0];
p = path;
if (!p) /* Path must exist */
return (NULL);
while (*p)
{
if (*p == BACKSLASH)
{
p++;
break;
}
else
*t++ = *p++;
}
*t = '\0';
if (pc_fileparse(filename, fileext, &tbuf[0]))
return (p);
else
return (NULL);
}
/****************************************************************************
PC_PARSEPATH - Parse a path specifier into path,file,ext
Description
Take a path specifier in path and break it into three null terminated
strings topath,filename and file ext.
The result pointers must contain enough storage to hold the results.
Filename and fileext are BLANK filled to [8,3] spaces.
Rules:
SPEC PATH FILE EXT
B:JOE B: 'JOE ' ' '
B:\JOE B:\ 'JOE ' ' '
B:\DIR\JOE B:\DIR 'JOE ' ' '
B:DIR\JOE B:DIR 'JOE ' ' '
Returns
Returns YES.
****************************************************************************/
BOOL pc_parsepath(TEXT *topath, TEXT *filename, TEXT *fileext, TEXT *path) /*__fn__*/
{
TEXT *pfile;
TEXT *pto;
TEXT *pfr;
TEXT *pslash;
BOOL colon;
pto = topath;
pfr = path;
pslash = NULL;
if (path[0] && path[1] == ':')
colon = YES;
else
colon = NO;
*pto = 0;
while (*pfr)
{
*pto = *pfr++;
if (*pto == BACKSLASH)
pslash = pto;
pto++;
}
*pto = '\0';
if (pslash)
pfile = pslash+1;
else
{
if (colon)
pfile = topath + 2;
else
pfile = topath;
}
if (!pc_fileparse(filename, fileext, pfile))
return (NO);
if (!pslash)
{
if (colon)
*(topath+2) = '\0';
else
*topath = '\0';
}
else
{
if ( (colon && (pslash == topath + 2)) ||
(!colon && (pslash == topath)) )
*(pslash+1) = '\0';
else
*pslash = '\0';
}
return(YES);
}
/******************************************************************************
PC_PATCMP - Compare a pattern with a string
Description
Compare size bytes of p against pattern. Applying the following rules.
If size == 8.
(To handle the way dos handles deleted files)
if p[0] = DELETED, never match
if pattern[0] == DELETED, match with 0x5
'?' in pattern always matches the current char in p.
'*' in pattern always matches the rest of p.
Returns
Returns YES if they match
****************************************************************************/
BOOL pc_patcmp(UTEXT *p, UTEXT *pattern, INT size) /* __fn__*/
{
/* Kludge. never match a deleted file */
if (size == 8)
{
if (*p == PCDELETE)
return (NO);
else if (*pattern == PCDELETE) /* But E5 in the Pattern matches 0x5 */
{
if ( (*p == 0x5) || (*p == '?') )
{
size -= 1;
p++;
pattern++;
}
else
return (NO);
}
}
while (size--)
{
if (*pattern == '*') /* '*' matches the rest of the name */
return (YES);
if (*pattern != *p)
if (*pattern != '?')
return (NO);
pattern++;
p++;
}
return (YES);
}
/****************************************************************************
pc_strcat - strcat
Description
strcat
Returns
Nothing
****************************************************************************/
VOID pc_strcat(TEXT *to, TEXT *from) /* __fn__*/
{
while (*to) to++;
while (*from) *to++ = *from++;
*to = '\0';
}
/******************************************************************************
PC_STR2UPPER - Copy a string and make sure the dest is in Upper case
Description
Copy a null termed string. Change all lower case chars to upper case
Returns
Nothing
****************************************************************************/
VOID pc_str2upper(TEXT *to, TEXT *from) /* __fn__*/
{
TEXT c;
while(*from)
{
c = *from++;
if ((c >= 'a') && (c <= 'z'))
c = (TEXT) ('A' + c - 'a');
*to++ = c;
}
*to = '\0';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -