📄 util.c
字号:
/* UTIL.C - Contains string manipulation and byte order conversion routines */
#include <pcdisk.h>
extern KS_CONSTANT char char_backslash;
#if (VFAT)
static BOOLEAN _illegal_alias_char(char ch);
static BOOLEAN _illegal_lfn_char(char ch);
static BOOLEAN name_is_reserved(char *filename);
extern KS_CONSTANT char KS_FAR _bad_alias_chars[16];
extern KS_CONSTANT char KS_FAR _bad_lfn_chars[10];
extern KS_CONSTANT char KS_FAR * _reserved_names[13];
#endif /* VFAT */
/*****************************************************************************
PC_ALLSPACE - Test if size characters in a string are spaces
Description
Test if the first size spaces of string are ' ' characters.
Returns
TRUE if all spaces.
*****************************************************************************/
#if (RTFS_SUBDIRS)
/* Return TRUE if n bytes of p are spaces */
BOOLEAN pc_allspace(byte *p, int i) /* __fn__*/
{
while (i--)
if (*p++ != ' ')
return (FALSE);
return (TRUE);
}
#endif
/****************************************************************************
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__*/
{
byte *to = (byte *) vto;
byte *from = (byte *) 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
*****************************************************************************/
#if (RTFS_WRITE)
void pc_cppad(byte *to, byte *from, int size) /* __fn__*/
{
while (size--)
{
if (*from)
*to++ = *from++;
else
*to++ = ' ';
}
}
#endif
#if (RTFS_SUBDIRS)
/***************************************************************************
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
TRUE if file:ext == '.'
***************************************************************************/
/* Return TRUE if File is exactly '.' */
BOOLEAN pc_isdot(byte *fname, byte *fext) /* __fn__*/
{
#if (VFAT)
ARGSUSED_PVOID((PFVOID)fext);
#endif
return (BOOLEAN)((*fname == '.') &&
#if (VFAT)
((*(fname+1) == '\0') || (pc_allspace((fname+1),10))) );
#else
pc_allspace(fname+1,7) && pc_allspace(fext,3) );
#endif
}
#endif
/******************************************************************************
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
TRUE if file:ext == {'.','.'}
****************************************************************************/
#if (RTFS_SUBDIRS)
/* Return TRUE if File is exactly '..' */
BOOLEAN pc_isdotdot(byte *fname, byte *fext) /* __fn__*/
{
#if (VFAT)
ARGSUSED_PVOID((PFVOID)fext);
#endif
return (BOOLEAN)( (*fname == '.') && (*(fname+1) == '.') &&
#if (VFAT)
((*(fname+2) == '\0') || (pc_allspace((fname+2),9)) ) );
#else
pc_allspace(fname+2,6) && pc_allspace(fext,3) );
#endif
}
#endif
/****************************************************************************
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, byte c) /* __fn__*/
{
byte *to = (byte *) 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'.
****************************************************************************/
byte *pc_mfile(byte *to, byte *filename, byte *ext) /* __fn__*/
{
byte *p;
int i;
byte *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'.
*****************************************************************************/
byte *pc_mpath(byte *to, byte *path, byte *filename) /* __fn__*/
{
byte *retval = to;
byte *p;
byte c = '\0';
p = path;
while(*p)
if (*p == ' ')
break;
else
*to++ = (c = *p++);
// TBD - 10-27-98
if (c && (c != char_backslash))
*to++ = char_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.
***************************************************************************/
// Get the drive number form the path. Make sure one is provided
// and that it is valid.
// returns -1 if not valid otherwise return the driveno
int pc_parse_raw_drive(char *path) /* __fn__*/
{
char *p = path;
int dno;
/* get drive no */
if ( *p && (*(p+1) == ':'))
{
dno = (int) (pc_byte2upper(*p) - 'A');
}
else
return(-1);
if (!pc_validate_driveno(dno))
return (-1);
else
return(dno);
}
/* Extract drive no from D: or use defualt. return the rest of the string
or NULL if a bad drive no is requested */
char *pc_parsedrive(int *driveno, char *path) /* __fn__*/
{
char *p = path;
int dno;
/* get drive no */
if ( *p && (*(p+1) == ':'))
{
dno = (int) (pc_byte2upper(*p) - 'A');
p += 2;
}
else
dno = pc_getdfltdrvno();
if (!pc_validate_driveno(dno))
return (0);
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 TRUE
****************************************************************************/
/* Take a string "xxx[.yy]" and put it into filename and fileext */
/* Note: add a check legal later */
BOOLEAN pc_fileparse(char *filename, char *fileext, char *p) /* __fn__*/
{
int i;
/* 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 (TRUE);
}
else if (*(p + 1) == '\0')
return (TRUE);
else
return (FALSE);
}
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 (TRUE);
}
/****************************************************************************
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" */
char *pc_nibbleparse(char *filename, char *fileext, char *path) /* __fn__*/
{
char *p;
#if (VFAT)
char *t = filename;
#else
char tbuf[EMAXPATH];
char *t = &tbuf[0];
#endif
p = path;
if (!p) /* Path must exist */
return (0);
while (*p)
{
if (*p == char_backslash)
{
p++;
break;
}
else
*t++ = *p++;
}
*t = '\0';
#if (VFAT)
ARGSUSED_PVOID((PFVOID)fileext);
return (p);
#else
if (pc_fileparse(filename, fileext, &tbuf[0]))
return (p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -