-Add DOS_ToUpper which seems closer than just toupper, we might need to use it at more places than just the driveletter, but it is a big change.
-Rework FCB_ParseName: -- Remove special code for . and .. as it was wrong -- Continue reading the input string, when the max length of the field has been reached (123456789.12345 is read and returned as 12345678.123) -- strip spaces before and after reading the separators. -- The drive is always parsed (if present), it doesn't depend on the existence of said drive. -- Fix parsing of .EXE and other extension only names -- Always clear out current block and record size. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3940
This commit is contained in:
parent
57ff3dfc95
commit
cf9f8b2d3e
1 changed files with 72 additions and 48 deletions
|
@ -774,7 +774,21 @@ bool DOS_CreateTempFile(char * const name,Bit16u * entry) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#define FCB_SEP ":.;,=+"
|
||||
char DOS_ToUpper(char c) {
|
||||
unsigned char uc = *reinterpret_cast<unsigned char*>(&c);
|
||||
if (uc > 0x60 && uc < 0x7B) uc -= 0x20;
|
||||
else if (uc > 0x7F && uc < 0xA5) {
|
||||
const unsigned char t[0x25] = {
|
||||
0x00, 0x9a, 0x45, 0x41, 0x8E, 0x41, 0x8F, 0x80, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x00, 0x00,
|
||||
0x00, 0x92, 0x00, 0x4F, 0x99, 0x4F, 0x55, 0x55, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x41, 0x49, 0x4F, 0x55, 0xA5};
|
||||
if (t[uc - 0x80]) uc = t[uc-0x80];
|
||||
}
|
||||
char sc = *reinterpret_cast<char*>(&uc);
|
||||
return sc;
|
||||
}
|
||||
|
||||
#define FCB_SEP ":;,=+"
|
||||
#define ILLEGAL ":.;,=+ \t/\"[]<>|"
|
||||
|
||||
static bool isvalid(const char in){
|
||||
|
@ -822,77 +836,87 @@ Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *
|
|||
fcb.GetName(fcb_name.full);
|
||||
fcb_name.part.drive[0]-='A'-1;fcb_name.part.drive[1]=0;
|
||||
fcb_name.part.name[8]=0;fcb_name.part.ext[3]=0;
|
||||
/* Strip of the leading sepetaror */
|
||||
if((parser & PARSE_SEP_STOP) && *string) { //ignore leading seperator
|
||||
char sep[] = FCB_SEP;char a[2];
|
||||
a[0]= *string;a[1]='\0';
|
||||
if (strcspn(a,sep)==0) string++;
|
||||
}
|
||||
/* strip leading spaces */
|
||||
while((*string==' ')||(*string=='\t')) string++;
|
||||
|
||||
/* Strip of the leading separator */
|
||||
if((parser & PARSE_SEP_STOP) && *string) {
|
||||
char sep[] = FCB_SEP;char a[2];
|
||||
a[0] = *string;a[1] = '\0';
|
||||
if (strcspn(a,sep) == 0) string++;
|
||||
}
|
||||
|
||||
/* Skip following spaces as well */
|
||||
while((*string==' ')||(*string=='\t')) string++;
|
||||
|
||||
/* Check for a drive */
|
||||
if (string[1]==':') {
|
||||
unsigned char d = *reinterpret_cast<unsigned char*>(&string[0]);
|
||||
if (!isvalid(toupper(d))) {string += 2; goto savefcb;} //TODO check (for ret value)
|
||||
fcb_name.part.drive[0]=0;
|
||||
hasdrive=true;
|
||||
if (isalpha(string[0]) && Drives[toupper(string[0])-'A']) {
|
||||
fcb_name.part.drive[0]=(char)(toupper(string[0])-'A'+1);
|
||||
if (isalpha(d) && Drives[toupper(d)-'A']) { //Floppies under dos always exist, but don't bother with that at this level
|
||||
; //THIS* was here
|
||||
} else ret=0xff;
|
||||
fcb_name.part.drive[0]=DOS_ToUpper(string[0])-'A'+1; //Always do THIS* and continue parsing, just return the right code
|
||||
string+=2;
|
||||
}
|
||||
/* Special checks for . and .. */
|
||||
if (string[0]=='.') {
|
||||
string++;
|
||||
if (!string[0]) {
|
||||
hasname=true;
|
||||
ret=PARSE_RET_NOWILD;
|
||||
strcpy(fcb_name.part.name,". ");
|
||||
goto savefcb;
|
||||
}
|
||||
if (string[1]=='.' && !string[1]) {
|
||||
string++;
|
||||
hasname=true;
|
||||
ret=PARSE_RET_NOWILD;
|
||||
strcpy(fcb_name.part.name,".. ");
|
||||
goto savefcb;
|
||||
}
|
||||
goto checkext;
|
||||
}
|
||||
/* Copy the name */
|
||||
|
||||
/* Check for extension only file names */
|
||||
if (string[0] == '.') {string++;goto checkext;}
|
||||
|
||||
/* do nothing if not a valid name */
|
||||
if(!isvalid(string[0])) goto savefcb;
|
||||
|
||||
hasname=true;finished=false;fill=' ';index=0;
|
||||
while (index<8) {
|
||||
if (!finished) {
|
||||
if (string[0]=='*') {fill='?';fcb_name.part.name[index]='?';if (!ret) ret=1;finished=true;}
|
||||
else if (string[0]=='?') {fcb_name.part.name[index]='?';if (!ret) ret=1;}
|
||||
else if (isvalid(string[0])) {fcb_name.part.name[index]=(char)(toupper(string[0]));}
|
||||
else { finished=true;continue; }
|
||||
string++;
|
||||
} else {
|
||||
fcb_name.part.name[index]=fill;
|
||||
/* Copy the name */
|
||||
while (true) {
|
||||
unsigned char nc = *reinterpret_cast<unsigned char*>(&string[0]);
|
||||
char ncs = (char)toupper(nc); //Should use DOS_ToUpper, but then more calls need to be changed.
|
||||
if (ncs == '*') { //Handle *
|
||||
fill = '?';
|
||||
ncs = '?';
|
||||
}
|
||||
index++;
|
||||
if (ncs == '?' && !ret && index < 8) ret = 1; //Don't override bad drive
|
||||
if (!isvalid(ncs)) { //Fill up the name.
|
||||
while(index < 8)
|
||||
fcb_name.part.name[index++] = fill;
|
||||
break;
|
||||
}
|
||||
if (index < 8) {
|
||||
fcb_name.part.name[index++] = (fill == '?')?fill:ncs;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
if (!(string[0]=='.')) goto savefcb;
|
||||
string++;
|
||||
checkext:
|
||||
/* Copy the extension */
|
||||
hasext=true;finished=false;fill=' ';index=0;
|
||||
while (index<3) {
|
||||
if (!finished) {
|
||||
if (string[0]=='*') {fill='?';fcb_name.part.ext[index]='?';finished=true;}
|
||||
else if (string[0]=='?') {fcb_name.part.ext[index]='?';if (!ret) ret=1;}
|
||||
else if (isvalid(string[0])) {fcb_name.part.ext[index]=(char)(toupper(string[0]));}
|
||||
else { finished=true;continue; }
|
||||
string++;
|
||||
} else {
|
||||
fcb_name.part.ext[index]=fill;
|
||||
while (true) {
|
||||
unsigned char nc = *reinterpret_cast<unsigned char*>(&string[0]);
|
||||
char ncs = (char)toupper(nc);
|
||||
if (ncs == '*') { //Handle *
|
||||
fill = '?';
|
||||
ncs = '?';
|
||||
}
|
||||
index++;
|
||||
if (ncs == '?' && !ret && index < 3) ret = 1;
|
||||
if (!isvalid(ncs)) { //Fill up the name.
|
||||
while(index < 3)
|
||||
fcb_name.part.ext[index++] = fill;
|
||||
break;
|
||||
}
|
||||
if (index < 3) {
|
||||
fcb_name.part.ext[index++] = (fill=='?')?fill:ncs;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
savefcb:
|
||||
if (!hasdrive & !(parser & PARSE_DFLT_DRIVE)) fcb_name.part.drive[0] = 0;
|
||||
if (!hasname & !(parser & PARSE_BLNK_FNAME)) strcpy(fcb_name.part.name," ");
|
||||
if (!hasext & !(parser & PARSE_BLNK_FEXT)) strcpy(fcb_name.part.ext," ");
|
||||
fcb.SetName(fcb_name.part.drive[0],fcb_name.part.name,fcb_name.part.ext);
|
||||
fcb.ClearBlockRecsize(); //Undocumented bonus work.
|
||||
*change=(Bit8u)(string-string_begin);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue