Files
TempleOS-Rijn/Kernel/BlkDev/DskStrA.CPP
T
2018-09-08 21:46:29 +02:00

317 lines
7.5 KiB
C++

U8 *FileExtDot(U8 *src)
{//Find dot char in name.
I64 ch;
while (ch=*src++)
if (ch=='.' && *src!='/' && *src!='.')
return src-1;
return NULL;
}
U8 *FileExtRem(U8 *src,U8 *dst=NULL)
{//Remove filename extension from str.
U8 *ptr;
if (ptr=FileExtDot(src)) {
if (dst)
StrCpy(dst,ptr+1);
*ptr=0;
} else if (dst)
*dst=0;
return dst;
}
Bool IsDotZ(U8 *filename)
{//Does name end in .Z?
I64 i=StrLen(filename);
if (i>6 && filename[i-1]=='Z' && filename[i-2]=='.' && filename[i-6]=='.')
return TRUE;
else
return FALSE;
}
Bool IsDotC(U8 *filename)
{//Does name end in .C?
I64 i=StrLen(filename);
if (i>6 && filename[i-1]=='C' && filename[i-2]=='.' && filename[i-6]=='.')
return TRUE;
else
return FALSE;
}
Bool FilesFindMatch(U8 *test_filename,U8 *files_find_mask,I64 fuf_flags=0)
{//Does filename meet $LK,"Files Find",A="FI:::/Doc/FileUtils.TXT"$ mask?
U8 *st1=StrNew(files_find_mask),
*st2=MAlloc(StrLen(files_find_mask)+1);
Bool result=FALSE;
while (TRUE) {
StrFirstRem(st1,";",st2);
if (*st2) {
if (*st2=='~') {
if (WildMatch(test_filename,st2+1)) {
result=FALSE;
break;
}
} else {
if (WildMatch(test_filename,st2)) {
if (Bt(&fuf_flags,FUf_JUST_TXT) &&
!FilesFindMatch(test_filename,FILEMASK_TXT)) {
result=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_SRC) &&
!FilesFindMatch(test_filename,FILEMASK_SRC)) {
result=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_AOT) &&
!FilesFindMatch(test_filename,FILEMASK_AOT)) {
result=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_JIT) &&
!FilesFindMatch(test_filename,FILEMASK_JIT)) {
result=FALSE;
break;
} else if (Bt(&fuf_flags,FUf_JUST_GRA) &&
!FilesFindMatch(test_filename,FILEMASK_GRA)) {
result=FALSE;
break;
} else
result=TRUE;
}
}
} else
break;
}
Free(st1);
Free(st2);
return result;
}
U8 *DirNameAbs(U8 *_dirname)
{//MAlloc absolute dir string with drv letter.
I64 maxlen;
U8 drv[3],*result,*buf,*buf2,*buf3,*buf4,*dirname,*free_dirname;
if (!Fs->cur_dir || !*Fs->cur_dir)
return StrNew(_dirname);
free_dirname=dirname=MStrUtil(_dirname,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
*drv=Drv2Let;
drv[1]=':';
drv[2]=0;
if (*dirname && dirname[1]==':') {
if (*dirname==':')
*drv=blkdev.boot_drv_let;
else
*drv=*dirname;
dirname=dirname+2;
buf=StrNew("/");
} else
buf=StrNew(Fs->cur_dir);
if (*dirname=='/') {
Free(buf);
buf=StrNew("/");
dirname++;
}
buf2=StrNew(dirname);
maxlen=StrLen(buf)+1+StrLen(buf2)+1;
buf3=MAlloc(maxlen);
buf4=MAlloc(maxlen);
StrCpy(buf3,buf);
while (*buf2) {
StrFirstRem(buf2,"/",buf4);
if (!*buf4)
StrCpy(buf3,"/");
else if (!StrCmp(buf4,"..")) {
StrLastRem(buf3,"/");
if (!*buf3)
StrCpy(buf3,"/");
} else if (!StrCmp(buf4,".")) {
;
} else if (*buf4) {
if (StrCmp(buf3,"/"))
CatPrint(buf3,"/");
CatPrint(buf3,buf4);
}
}
Free(buf);
result=MAlloc(StrLen(buf3)+3);
StrCpy(result,drv);
StrCpy(result+2,buf3);
Free(buf2);
Free(buf3);
Free(buf4);
Free(free_dirname);
return result;
}
U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0)
{//Absolute filename. Accepts $LK,"FUF_Z_OR_NOT_Z",A="MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS",A="MN:FUF_SCAN_PARENTS"$.
U8 *result,*filename,*buf,*buf_file,*buf_dir,*free_filename,*free_buf;
CDirEntry de;
free_filename=filename=MStrUtil(_filename,
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
free_buf=buf=StrNew(filename);
if (*buf && buf[1]==':') {
buf+=2;
filename+=2;
}
buf_file=MAlloc(StrLen(free_filename)+1);
StrLastRem(buf,"/",buf_file);
if (*filename=='/' && !*buf)
StrCpy(buf,"/");
buf_dir=DirNameAbs(free_buf);
Free(free_buf);
result=MAlloc(StrLen(buf_dir)+1+StrLen(buf_file)+1);
StrCpy(result,buf_dir);
if (result[StrLen(result)-1]!='/')
CatPrint(result,"/");
CatPrint(result,buf_file);
Free(buf_file);
Free(buf_dir);
Free(free_filename);
if (fuf_flags && FileFind(result,&de,fuf_flags|FUF_JUST_FILES)) {
Free(result);
result=de.full_name;
}
return result;
}
U8 *ChgExt(U8 *filename,U8 *extension)
{//Change filename extension.
U8 *result=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
StrCpy(result,filename);
if (FileExtDot(filename))
FileExtRem(result);
return CatPrint(result,".%s",extension);
}
U8 *DftExt(U8 *filename,U8 *extension)
{//Give extension if has none.
U8 *result=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
StrCpy(result,filename);
if (!FileExtDot(filename))
CatPrint(result,".%s",extension);
return result;
}
CDirEntry *Cd2DirEntry(CDirEntry *tempde,U8 *abs_name)
{
I64 i;
while (tempde) {
i=StrLen(tempde->full_name);
if (StrNCmp(tempde->full_name,abs_name,i)||
i && tempde->full_name[i-1]!='/' && abs_name[i] && abs_name[i]!='/')
tempde=tempde->next;
else
if (StrLen(abs_name)==i)
return tempde;
else
return Cd2DirEntry(tempde->sub,abs_name);
}
return NULL;
}
I64 FileAttr(U8 *name,I64 attr=0)
{
if (IsDotZ(name))
attr|=RS_ATTR_COMPRESSED;
else
attr&=~RS_ATTR_COMPRESSED;
if (IsDotC(name))
attr|=RS_ATTR_CONTIGUOUS;
return attr;
}
Bool FileNameChk(U8 *filename)
{//Return check for valid filename, not checking existence.
U8 *ptr=filename;
if (!filename) return FALSE;
if (!*ptr) return FALSE;
if (*ptr=='.') {
if (!ptr[1]) return TRUE;
if (ptr[1]=='.' && !ptr[2]) return TRUE;
}
if (StrLen(filename)>=CDIR_FILENAME_LEN) return FALSE;
while (*ptr)
if (!Bt(chars_bmp_filename,*ptr++))
return FALSE;
return TRUE;
}
U8 *ToggleZorNotZ(U8 *name)
{//MAlloc name with Z if not Z or vice versa.
U8 *result;
if (IsDotZ(name)) {
result=StrNew(name);
result[StrLen(name)-2]=0;
} else
result=MStrPrint("%s.Z",name);
return result;
}
U8 *FileNameTempTxt()
{//Make pretty-safe temp filename in home dir.
return MStrPrint("::/Home/SysTemp%X.TXT.Z",GetTSC>>8&0xFFFFFFFF);
}
U8 *CurDir(CTask *task=NULL,CTask *mem_task=NULL)
{//MAlloc copy of cur dir with drv letter.
U8 *st;
if (!task) task=Fs;
if (!task->cur_dir)
return NULL;
st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
*st=Drv2Let(task->cur_dv);
st[1]=':';
StrCpy(st+2,task->cur_dir);
return st;
}
U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
{/*Strips file from dirname, scans for file upward until found or
returns default.
("/Kernel/KHashA.CPP.Z",NULL,NULL) returns "D:/Kernel"
("/Kernel",NULL,"PRJ.Z") returns "D:/Kernel/Kernel.PRJ.Z"
("/Kernel/BlkDev",NULL,"PRJ.Z") returns "D:/Kernel/Kernel.PRJ.Z"
("/Apps/Psalmody","Load","CPP.Z") returns "D:/Apps/Psalmody/Load.CPP.Z"
*/
U8 *st=DirNameAbs(dirname),*st2,*st3,*result,*dft=NULL,*ext;
if (_extension && *_extension) {
if (*_extension=='.')
ext=StrNew(_extension);
else
ext=MStrPrint(".%s",_extension);
} else
ext=StrNew("");
while (StrOcc(st,'/')&&!IsDir(st))
StrLastRem(st,"/");
while (StrOcc(st,'/')) {
st2=StrNew(st);
st3=StrNew(st);
StrLastRem(st2,"/",st3);
if (name)
result=MStrPrint("%s/%s%s",st,name,ext);
else {
if (*ext)
result=MStrPrint("%s/%s%s",st,st3,ext);
else
result=StrNew(st);
}
if (!dft)
dft=StrNew(result);
if (!*ext && (!name||!*name) || FileFind(result)) {
Free(st3);
Free(st2);
Free(st);
Free(dft);
Free(ext);
return result;
}
Free(st);
st=st2;
Free(st3);
}
Free(st);
Free(ext);
return dft;
}