BoolU4 YorN() { I8 ch; cout "(y or n)? "; while (TRUE) { ch=ToUpper(GetKey); if (ch=='Y') { coutln "$$FU$$$$BU$$YES$$FG$$$$BG$$"; return TRUE; } else if (ch=='N') { coutln "$$FU$$$$BU$$NO$$FG$$$$BG$$"; return FALSE; } } } I1 *PointAtListEntry(I8 entry_number, I1 *lst) { while (*lst && entry_number) { while (*lst) /* Advance to end of cur entry. */ lst++; lst++; /* Skip trailing zero */ entry_number--; if (*lst=='@') { /* Check for '@' alias list entry*/ entry_number++; lst++; } } return lst; } I8 MatchListEntry(I1 *src, I1 *lst,I8 flags=0,I8 *ambiguity_overkill_ptr=NULL) /* RETURNS: -2 if Ambiguous, -1 if not found, else entry_number */ { I8 l,entry_num=0,result=-1,unutilized_src; I1 *s; BoolU4 exact_match=FALSE; l=StrLen(src); if (ambiguity_overkill_ptr) *ambiguity_overkill_ptr=l; while (*lst) { if (*lst=='@') { /* Check for '@' alias list entry*/ entry_num--; lst++; } s=src; if (flags & MLE_IGNORE_CASE) while (*s && ToUpper(*s) == ToUpper(*lst)) { s++; lst++; } else while (*s && *s==*lst) { s++; lst++; } unutilized_src=l-(s-src); if (!(*s)) { /* Did we reach end of sourcecout */ if (!(*lst)) { /* Did we reach end of list entrycout */ if (!ambiguity_overkill_ptr) return entry_num; /* Found Exact match */ result=entry_num; exact_match=TRUE; } else { if (result!=-1) { if (ambiguity_overkill_ptr) *ambiguity_overkill_ptr=0; if (!exact_match) result=-2; /* AMBIGUOUS RESPONSE unless later exact match*/ } else { if (!(flags & MLE_EXACT)) result=entry_num; } } } else { if (ambiguity_overkill_ptr && *ambiguity_overkill_ptr>(unutilized_src-1)) *ambiguity_overkill_ptr=unutilized_src-1; } while (*lst) /* Advance to end of cur entry. */ lst++; lst++; /* Skip trailing zero */ entry_num++; } if (ambiguity_overkill_ptr && result==-1) *ambiguity_overkill_ptr=0; return result; } void UndefinedSysText(I1 *name) { PutSysText("ST_UNDEFINED_SYSTEXT"); PutS(name); throw(EXCEPT_UNDEF_SYSTEXT,name); } I1 *SysText(I1 *name) { SysHashEntry *temph=FindLocalHash(name,HTT_SYSTEXT); if (temph) return temph->user0; else UndefinedSysText(name); } I1 *SysTextSub(U8 sub,I1 *name) { SysHashEntry *temph=FindLocalHash(name,HTT_SYSTEXT); if (temph) return PointAtListEntry(sub,temph->user0); else UndefinedSysText(name); } I8 SysTextSubCount(I1 *name) { SysHashEntry *temph=FindLocalHash(name,HTT_SYSTEXT); if (temph) return temph->user1; else UndefinedSysText(name); } I8 MatchSysTextEntry(I1 *src, I1 *lst_name, I8 flags=0,I8 *ambiguity_overkill_ptr=NULL) { return MatchListEntry(src,SysText(lst_name), flags,ambiguity_overkill_ptr); } asm {CP_PUT_SYSTEXT:} void PutSysText(I1 *name) { PutS(SysText(name)); } SysHashEntry *LoadStr(I1 *name, I1 *st) { SysHashEntry *temph, *temph1=FindHashBucket(name,Fs->hash_table); temph=MAllocZ(sizeof(SysHashEntry)); temph->next=*temph1; *temph1=temph; temph->type=HTT_SYSTEXT; temph->string=NewString(name); temph->user0=NewString(st); temph->user1=-1; return temph; } SysHashEntry *LoadList(I1 *name, I1 *st) { U8 cnt=0; I1 *ptr; SysHashEntry *temph, *temph1=FindHashBucket(name,Fs->hash_table); temph=MAllocZ(sizeof(SysHashEntry)); temph->next=*temph1; *temph1=temph; temph->type=HTT_SYSTEXT; temph->string=NewString(name); ptr=st; while (*ptr) { while (*ptr++); cnt++; } temph->user0=MAlloc(ptr+1-st); MemCpy(temph->user0,st,ptr+1-st); temph->user1=cnt; return temph; } I8 Occurrences(I1 *src, I8 ch) { I8 i=0; while (*src) if (*src++ == ch) i++; return i; } I8 SpacesToTabs(I1 *dst2,I1 *src) { I1 *src2,*dst=dst2; I8 i,changed=0,space_cnt,space_cnt2,col=0; while (*src) { src2=src; space_cnt=0; while (*src2==CH_SPACE) { space_cnt++; src2++; } if (space_cnt<2) { if (*src==CH_TAB) col=0; else { col++; if (col==8) col=0; } *(dst++)=*(src++); } else { while (col+space_cnt>=8) { space_cnt2=8-col; if (space_cnt2==1) *(dst++)=CH_SPACE; else { *(dst++)=CH_TAB; changed=changed+(space_cnt2-1); } space_cnt=space_cnt-space_cnt2; col=0; } for (i=0;i=l-2) { temp=MAlloc(l<<1); MemCpy(temp,dst,i+1); Free(dst); l<<=1; dst=temp; } } col=j; } else { dst[col]=ch; if (col>=l-2) { temp=MAlloc(l<<1); MemCpy(temp,dst,col+1); Free(dst); l*=2; dst=temp; } col++; } } dst[col]=0; return dst; } I1 *StringUtil(I1 *u, I8 mask) { I1 *src,*dst; I8 ch; src=u; if (mask & SU_REMOVE_LEADING) while (*src==CH_SPACE || *src==CH_SHIFT_SPACE || *src==CH_TAB) src++; dst=u; while (ch=*src++) { if (ch==CH_SPACE || ch==CH_SHIFT_SPACE || ch==CH_TAB) { if (!(mask & SU_REMOVE_SPACES)) { if (mask & SU_SINGLE_SPACE) { (*dst++) = CH_SPACE; while (ch= *src++ && (ch==CH_SPACE || ch==CH_SHIFT_SPACE || ch==CH_TAB) ); src--; } else (*dst++) = ch; } } else { if (!(mask & SU_REMOVE_CTRL_CHARS) || ch>=CH_SHIFT_SPACE) (*dst++)=ch; } } *dst=0; if (mask & SU_CAP_UNDERSCORES) { src=u; dst=u; while (*src) { *dst++=ToUpper(*src++); while (*src && *src!='_') *dst++=*src++; if (*src=='_') src++; } *dst=0; } if (mask & SU_REMOVE_TRAILING) while ( dst != u && (!*dst || *dst==CH_SPACE || *dst==CH_SHIFT_SPACE || *dst==CH_TAB)) (*dst--)=0; if (mask & SU_DISCARD_PARITY) for (dst=u;*dst;dst++) { ch=*dst; *dst=ch & 127; } if (mask & SU_TO_UPPER) for (dst=u;*dst;dst++) { ch=*dst; if (ch>=0x61 && ch<=0x7A) *dst = ch-0x20; } if (mask & SU_TO_LOWER) for (dst=u;*dst;dst++) { ch=*dst; if (ch>=0x41 && ch<=0x5A) *dst = ch+0x20; } if (mask & SU_SAFE_DOLLAR) for (dst=u;*dst;dst++) { ch=*dst; if (!Bt(safe_dollar_chars_bitmap,*dst)) *dst = '.'; } if (mask & SU_S2T) SpacesToTabs(u,u); return u; } I1 *MStringUtil(I1 *src,U8 flags) { I1 *dst=NewString(src),*dst2,*temp; StringUtil(dst,flags); if (flags & SU_T2S) { temp=TabsToSpaces(dst); Free(dst); dst=temp; } dst2=NewString(dst); //Shorten Free(dst); return dst2; } I1 *RemoveFirstSeg(I1 *src, I1 *marker, I1 *dst) { I1 *temp,*temp1,ch; temp = src; temp1= dst; while ( (ch= *src++) && !Occurrences(marker,ch) ) *dst++=ch; *dst = 0; if (ch) StrCpy(temp,src); else *temp=0; return temp1; } I1 *RemoveLastSeg(I1 *src, I1 *marker, I1 *dst) { I1 *temp; temp=src+StrLen(src); while (temp>src && !Occurrences(marker,*temp)) temp--; if (Occurrences(marker,*temp)) { StrCpy(dst,temp+1); *temp=0; } else { StrCpy(dst,src); *src=0; } return dst; } I1 *SearchString(I1 *src,I1 *pattern,U8 flags=0) { BoolU4 cont; U1 *src2; I1 *saved_src=src; I8 plen=StrLen(pattern); do { cont=FALSE; if (flags & SS_IGNORE_CASE) src=StrIStr(src,pattern); else src=StrStr(src,pattern); if (src && flags & SS_WHOLE_LABELS) { src2=src+plen; if (Bt(alpha_numeric_bitmap,*src2)) { src++; //TODO: Numbers could be false negative if (*src) cont=TRUE; else src=NULL; } else { if (src!=saved_src) { src2=src-1; if (Bt(alpha_numeric_bitmap,*src2)) { src++; if (*src) cont=TRUE; else src=NULL; } } } } } while (cont); return src; } BoolU4 WildCardMatch(I1 *wild_st,I1 *src_st) { U8 ch1,ch2; while (TRUE) { if ( !(ch1 = *src_st++)) { if (*wild_st) return FALSE; else return TRUE; } else { if ( !(ch2 = *wild_st++)) return FALSE; else { if (ch2 == '*') { if (!(ch2 = *wild_st++)) return TRUE; while (ch2 != ch1) if (!(ch1 = *src_st++)) return FALSE; } else if (ch2!='?') if (ch1!=ch2) return FALSE; } } } } BoolU4 WildFileNameList(I1 *wild_st,I1 *src_st) { BoolU4 result=FALSE; I1 *buf1=NewString(wild_st), *buf2=MAlloc(StrLen(wild_st)+1); while (TRUE) { RemoveFirstSeg(buf1,";",buf2); if (*buf2) { if (*buf2=='~') { if (WildCardMatch(buf2+1,src_st)) { result=FALSE; break; } } else { if (WildCardMatch(buf2,src_st)) result=TRUE; } } else break; } Free(buf1); Free(buf2); return result; } I1 *Add2String(I1 *base,I1 *addition) { //doubles length I1 *result; I8 blen=StrLen(base),alen=StrLen(addition); I8 bmem=MSize(base); if (blen+alen+1>bmem) { result=MAlloc(bmem<<1+alen+1); MemCpy(result,base,blen); StrCpy(result+blen,addition); Free(base); } else { result=base; StrCpy(result+blen,addition); } return result; } void CheckLTPartition(LTPartition *p) { if (!p || p->ch_L!='L' || p->ch_P!='P' || p->ch_E!='E') throw(EXCEPT_PARTITION,9); } I1 PartitionToDrive(LTPartition *p=NULL) { if (!p) p=Fs->cur_partition; CheckLTPartition(p); return p->drive; } LTPartition *DriveToPartition(I1 drive=0) { LTPartition *p; if (!drive) p=Fs->cur_partition; else if (drive==':') p=default_partition; else p=drive_to_partition[ToUpper(drive)-'A']; CheckLTPartition(p); return p; } void CheckLTBlkDev(LTBlkDev *bdev) { if (!bdev || bdev->ch_L!='L' || bdev->ch_B!='B' || bdev->ch_D!='D') throw(EXCEPT_BLKDEV,1); if (!bdev->type || bdev->type>LTBDT_FILE) throw(EXCEPT_BLKDEV,2); } LTBlkDev *DriveToBlkDev(I1 drive=0) { LTPartition *p=DriveToPartition(drive); LTBlkDev *bdev=p->bdev; CheckLTBlkDev(bdev); return bdev; } BoolU4 DriveIsWritable(I1 drive=0) { LTBlkDev *bdev=DriveToBlkDev(drive); if (bdev->flags & LTBDF_READ_ONLY) return FALSE; else return TRUE; } I1 *CurDir() { I1 *st=MAlloc(StrLen(Fs->cur_dir)+3); st[0]=PartitionToDrive; st[1]=':'; StrCpy(st+2,Fs->cur_dir); return st; } I1 *AbsoluteDirName(I1 *name) { I8 maxlen; I1 drive[3],*hdir,*cur_dir,*buf2,*buf3,*buf,*my_name,*temp_name; if (!Fs->cur_dir) return NewString(name); if (!*Fs->cur_dir) return NewString(name); my_name=MStringUtil(name, SU_REMOVE_LEADING|SU_REMOVE_TRAILING| SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS); temp_name=my_name; drive[0]=PartitionToDrive; drive[1]=':'; drive[2]=0; if (*my_name && my_name[1]==':') { if (*my_name==':') drive[0]=default_drive; else drive[0]=*my_name; my_name=my_name+2; cur_dir=NewString("/"); } else cur_dir=NewString(Fs->cur_dir); if (*my_name=='/') { Free(cur_dir); cur_dir=NewString("/"); my_name++; } buf2=NewString(my_name); maxlen=StrLen(cur_dir)+1+StrLen(buf2)+1; buf3=MAlloc(maxlen); buf =MAlloc(maxlen); StrCpy(buf3,cur_dir); while (*buf2) { RemoveFirstSeg(buf2,"/",buf); if (!*buf) StrCpy(buf3,"/"); else if (!StrCmp(buf,"..")) { RemoveLastSeg(buf3,"/",buf); if (!*buf3) StrCpy(buf3,"/"); } else if (!StrCmp(buf,".")) { ; } else if (*buf) { if (!StrCmp(buf,"HOME")) { Free(buf3); hdir=HomeDirString; buf3=MAlloc(maxlen+StrLen(hdir)); StrCpy(buf3,hdir+2); Free(hdir); drive[0]=default_drive; } else { if (StrCmp(buf3,"/")) StrCat(buf3,"/"); StrCat(buf3,buf); } } } Free(cur_dir); cur_dir=MAlloc(StrLen(buf3)+3); StrCpy(cur_dir,drive); StrCpy(cur_dir+2,buf3); Free(buf); Free(buf2); Free(buf3); Free(temp_name); return cur_dir; } I1 *AbsoluteFileName(I1 *name) { I1 *buf,*buf2,*buf3,*my_name,*temp_name,*temp_buf; my_name=MStringUtil(name, SU_REMOVE_LEADING|SU_REMOVE_TRAILING| SU_DISCARD_PARITY|SU_REMOVE_CTRL_CHARS); temp_name=my_name; buf=NewString(my_name); temp_buf=buf; if (*buf && buf[1]==':') { buf+=2; my_name+=2; } buf2=MAlloc(StrLen(temp_name)+1); RemoveLastSeg(buf,"/",buf2); if (*my_name=='/' && !*buf) StrCpy(buf,"/"); buf3=AbsoluteDirName(temp_buf); Free(temp_buf); buf=MAlloc(StrLen(buf3)+1+StrLen(buf2)+1); StrCpy(buf,buf3); if (buf[StrLen(buf)-1]!='/') StrCat(buf,"/"); StrCat(buf,buf2); Free(buf2); Free(buf3); Free(temp_name); return buf; } I1 *ChangeExtension(I1 *name,I1 *extension) { I1 *buf=MAlloc(StrLen(name)+1), *result=MAlloc(StrLen(name)+1+StrLen(extension)+1); StrCpy(result,name); if (Occurrences(name,'.')) RemoveLastSeg(result,".",buf); StrCat(result,"."); StrCat(result,extension); Free(buf); return result; } I1 *DefaultExtension(I1 *name,I1 *extension) { I1 *result=MAlloc(StrLen(name)+1+StrLen(extension)+1); StrCpy(result,name); if (!Occurrences(name,'.')) { StrCat(result,"."); StrCat(result,extension); } return result; } U8 FileAttr(I1 *name,U8 attr=0) { I1 *ptr=name,ch=0; while (*ptr && *ptr!='.') ptr++; if (*ptr=='.') ch=ToUpper(ptr[StrLen(ptr)-1]); if (ch=='Z') attr|=LT_ATTR_COMPRESSED; else attr&=~LT_ATTR_COMPRESSED; //TODO: temporary attr|=LT_ATTR_CONTIGUOUS; return attr; } BoolU4 CheckFileName(I1 *name) { I1 *ptr=name; if (!name) return FALSE; if (!*ptr) return FALSE; if (*ptr=='.') { if (!ptr[1]) return TRUE; if (ptr[1]=='.' && !ptr[2]) return TRUE; } if (StrLen(name)>LT_MAX_FILENAME_LEN) return FALSE; while (*ptr) if (!Bt(filename_chars_bitmap,*ptr++)) return FALSE; return TRUE; }