⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 嵌入式操作系统Nucleus Plus中使用的文件系统
💻 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 + -