1
0
Fork 0

-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:
Peter Veenstra 2015-10-02 20:13:57 +00:00
parent 57ff3dfc95
commit cf9f8b2d3e

View file

@ -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;
}