298 lines
7.5 KiB
C
Raw Normal View History

/*
+------------------------------------------------------------------------------
| Project : Device Filesystem
+------------------------------------------------------------------------------
| Copyright 2004, 2005 www.fayfayspace.org.
| All rights reserved.
|------------------------------------------------------------------------------
| File : dfs_utl.c, some misc functions of Device FileSystem
|------------------------------------------------------------------------------
| Chang Logs:
| Date Author Notes
| 2005-01-26 ffxz The first version
+------------------------------------------------------------------------------
*/
#include <string.h>
#include <dfs_fs.h>
#include <dfs_util.h>
/*
+------------------------------------------------------------------------------
| Function : dir_name
+------------------------------------------------------------------------------
| Description : Gets the directory name in specified path string
|
| Parameters : path, the specified path string
| path_name, return the path name in this parameter
| len, the length of path name
| Returns : the status of path_name:
| 0 , successful
| -1, failed
| For Example :
| path, dir_name
| /, /
| /usr, /
| /usr/lib, /usr
| /usr/lib/, /usr
+------------------------------------------------------------------------------
*/
int dir_name(const char* path, char* dirname, int len)
{
int pos;
if ( path[0] == '/' && path[1] == '\0' )
{
*dirname++ = '/';
*dirname = '\0';
return 0;
}
pos = strlen(path);
while ( *(path + pos - 1) =='/' ) pos --;
while ( pos > 0 && *(path + pos - 1) != '/' ) pos --;
while ( pos > 0 && *(path + pos - 1) == '/' ) pos --;
if ( pos > len ) return -1;
if ( pos != 0)
{
memcpy(dirname, path, pos);
*(dirname+pos) = '\0';
}
else
{
*dirname++ = '/';
*dirname = '\0';
}
return 0;
}
/*
+------------------------------------------------------------------------------
| Function : file_name
+------------------------------------------------------------------------------
| Description : Gets the file name in specified path string
|
| Parameters : path, the specified path string
| filename, return the path name in this parameter
| len, the length of file name
| Returns : the status of file_name:
| 0 , successful
| -1, failed
| For Example :
| path, filename
| /, RT_NULL
| /usr, usr
| /usr/lib, lib
| /usr/lib/, lib
+------------------------------------------------------------------------------
*/
int file_name(const char* path, char* filename, int len)
{
int pos, size;
if ( path[0] == '/' && path[1] == '\0' )
{
*filename = '\0';
return 0;
}
pos = strlen(path);
while ( *(path + pos -1)=='/' ) pos --;
size = pos;
while ( *(path + pos -1) != '/' && pos > 0 ) pos --;
if ( size - pos > len ) return -1;
else size = size - pos ;
memcpy(filename, path + pos, size);
*(filename+size) = '\0';
return 0;
}
/*
+------------------------------------------------------------------------------
| Function : next_path_name
+------------------------------------------------------------------------------
| Description : Gets the next directory name from specified path string
|
| Parameters : path, the specified path string
| pos, the specified position of path string
| next, return the next path in this parameter
| Returns : the position of next directory item,
| -1, if pos reach in the end of the specified path string
| For Example :
+------------------------------------------------------------------------------
*/
int next_dir_name(const char* path, int pos, char* next)
{
const char* q;
if ( pos > strlen(path) || pos < 0|| path == RT_NULL ) return -1;
q = path + pos;
/* check for firt '/' */
while ( *q == '/' ) q++;
if ( *q == '\0' )
{
*next = '\0';
return -1;
}
while ( *q != '/' && *q != '\0' )
{
*next++ = *q++;
}
*next = '\0';
return q - path + 1;
}
/*
+------------------------------------------------------------------------------
| Function : build_fullpath
+------------------------------------------------------------------------------
| Description : make up the full path from directory and filename
|
| Parameters : path, the specified path string
| filename, return the path name in this parameter
| fullpath, the returned full path name
| Returns : null
+------------------------------------------------------------------------------
*/
void build_fullpath(const char *directory, const char *filename, char *fullpath)
{
char elem[DFS_PATH_MAX + 1];
int pos, start, len;
len = 0;
/* check parameters */
RT_ASSERT(directory != RT_NULL);
RT_ASSERT(filename != RT_NULL);
RT_ASSERT(fullpath != RT_NULL);
/* copy full of directory */
strncpy(fullpath, directory, DFS_PATH_MAX + 1);
for (pos = 0; filename[pos] != '\0'; )
{
/* strip '//' */
while (filename[pos] == '/') pos++;
/* get the filename element, save to elem array */
for (start = pos; filename[pos] != '/' && filename[pos] != '\0'; pos++)
len = pos - start + 1;
strncpy(elem, filename + start, DFS_PATH_MAX + 1);
/* clear the end of elem */
elem[(len < DFS_PATH_MAX + 1? len : DFS_PATH_MAX + 1)] = '\0';
/* strip '..' */
if (elem[0] == '.' && elem[1] == '.')
{
if (strlen(fullpath) == 0) strcpy(fullpath, ""); /* empty filename */
else if (fullpath[0] == '/' && fullpath[1] !='\0')
{
int i = strlen(fullpath);
while (fullpath[i - 1] == '/') i--;
while (i > 0 && fullpath[i - 1] != '/') i--;
fullpath[i] = '\0';
}
}
/* not '.', copy as normally */
else if (elem[0] != '.')
{
len = strlen(fullpath);
if (len == 0) strncpy(fullpath, elem, DFS_PATH_MAX + 1);
else if (fullpath[len - 1] == '/')
{
if (elem[0] == '/') strncat(fullpath, elem + 1, DFS_PATH_MAX + 1);
else strncat(fullpath, elem, DFS_PATH_MAX + 1);
}
else
{
if (elem[0] == '/') strcat(fullpath, elem);
else
{
strncat(fullpath, "/", DFS_PATH_MAX + 1);
strncat(fullpath + 1, elem, DFS_PATH_MAX + 1);
}
}
}
}
if ( fullpath[0] != '/' && fullpath[(len = strlen(fullpath)) - 1] == '/')
{
fullpath[len - 1] = '\0';
}
}
int str_is_prefix(const char* prefix, const char* str)
{
while ((*prefix) && (*str) && (*prefix == *str))
{
prefix ++;
str ++;
}
if (*prefix == 0) return 0;
return -1;
}
#if !defined(RT_USING_MINILIBC) && !defined(RT_USING_NEWLIB)
#if !defined(__ICCARM__)
char *strrchr(const char *t, int c)
{
register char ch;
register const char *l=0;
ch = c;
for (;;)
{
if ((*t == ch)) l=t;
if ((!*t)) return (char*)l; ++t;
}
return (char*)l;
}
#endif
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION / 10000 < 35)
int strncasecmp ( const char* s1, const char* s2, size_t len )
{
register unsigned int x2;
register unsigned int x1;
register const char* end = s1 + len;
while (1)
{
if ((s1 >= end) )
return 0;
x2 = *s2 - 'A'; if ((x2 < 26u)) x2 += 32;
x1 = *s1 - 'A'; if ((x1 < 26u)) x1 += 32;
s1++; s2++;
if ((x2 != x1))
break;
if ((x1 == (unsigned int)-'A'))
break;
}
return x1 - x2;
}
#endif /* end of __ARMCC_VERSION */
#endif