home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
mtools_3.6.src.lzh
/
MTOOLS_3.6
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-11-12
|
3KB
|
190 lines
#include "sysincludes.h"
#include "msdos.h"
#include "vfat.h"
/*
* Get name component of filename.
*
* Formerly translated name to upper case; now preserves case.
* This is because long DOS names are case sensitive, but also because we
* want to preserve the user-specified case for the copied Unix files
*/
char *get_name(const char *filename, char *ans, char *mcwd)
{
char *s;
const char *temp;
temp = filename;
/* skip drive letter */
if (temp[0] && temp[1] == ':')
temp = &temp[2];
/* find the last separator */
if ((s = strrchr(temp, '/')))
temp = s + 1;
if ((s = strrchr(temp, '\\')))
temp = s + 1;
strncpy(ans, temp, VBUFSIZE-1);
ans[VBUFSIZE-1]='\0';
return ans;
}
static inline void strip_last_dir(char *begin, char **targetp)
{
char *tmp;
/* IN condition: begin stops with a slash */
/* remove slash */
(*targetp) --;
**targetp = '\0';
tmp = strrchr(begin,'/');
if(tmp) {
tmp++;
} else {
begin[0]='/';
tmp=begin+1;
}
*tmp = '\0';
*targetp = tmp;
}
static inline int handle_dot(char *begin, char **sourcep, char **targetp)
{
char *source = *sourcep;
switch(source[1]) {
case '/':
(*sourcep) += 2;
return 1;
case '.':
switch(source[2]) {
case '\0':
strip_last_dir(begin, targetp);
(*sourcep) += 2;
return 1;
case '/':
strip_last_dir(begin, targetp);
(*sourcep) += 3;
return 1;
default:
return 0;
}
case '\0':
(*sourcep) ++;
return 1;
default:
return 0;
}
}
static inline void canonize_path(char *begin)
{
char tmp, *source, *target;
/* transform all backslashes into slashes */
for(source = begin; *source; source++)
if(*source == '\\')
*source ='/';
/* prune off double slashes */
source = begin;
target = begin;
while(*source) {
tmp = *target++ = *source++;
if(tmp == '/') {
while(1) {
switch(source[0]) {
case '/':
source++;
continue;
case '.':
if(handle_dot(begin, &source,
&target))
continue;
break;
}
break;
}
if(!*source)
target--;
}
}
*target='\0';
if(!*begin) {
begin[0] = '/';
begin[1] = '\0';
}
}
/*
* Get the path component of the filename.
* Doesn't alter leading separator, always strips trailing separator (unless
* it is the path itself).
*
* Formerly translated name to upper case; now preserves case.
* This is because long DOS names are case sensitive, but also because we
* want to preserve the user-specified case for the copied Unix files
*/
char *get_path(const char *filename, char *ans, char *mcwd, int mode)
{
char *s;
const char *end;
const char *begin;
char drive;
begin = filename;
/* skip drive letter */
drive = '\0';
if (begin[0] && begin[1] == ':') {
drive = toupper(begin[0]);
begin += 2;
}
ans[0] = '/';
ans[1] = '\0';
if ((*begin != '/') && (!drive || drive == *mcwd))
strcpy(ans+1, mcwd + 2);
strcat(ans, "/");
/* cut last separator (if needed) */
if(mode)
end = begin + strlen(begin);
else {
if ((s = strrchr(begin, '/')))
end = s;
else
end = begin;
}
if(strlen(ans)+end-begin+1 > MAX_PATH){
fprintf(stderr,"Path too long\n");
exit(1);
}
strncat(ans, begin, end - begin);
ans[strlen(ans)+end-begin] = '\0';
canonize_path(ans);
return ans;
}
/*
* get the drive letter designation
*/
char get_drive(const char *filename, char def)
{
if (*filename && *(filename + 1) == ':')
return(toupper(*filename));
else
return def;
}