rework memdisk command line processing so only last line skips memdisk options (less likely to skip options unexpectly)

This commit is contained in:
Kenneth J. Davis 2012-11-09 19:32:55 -05:00
parent 69f76c377e
commit a9c0702807

View File

@ -607,7 +607,7 @@ struct memdiskinfo {
UBYTE version; /* Memdisk major version */ UBYTE version; /* Memdisk major version */
UDWORD base; /* Pointer to disk data in high memory */ UDWORD base; /* Pointer to disk data in high memory */
UDWORD size; /* Size of disk in 512 byte sectors */ UDWORD size; /* Size of disk in 512 byte sectors */
char FAR * cmdline; /* Command line */ char FAR * cmdline; /* Command line; currently <= 2047 chars */
ADDRESS oldint13; /* Old INT 13h */ ADDRESS oldint13; /* Old INT 13h */
ADDRESS oldint15; /* Old INT 15h */ ADDRESS oldint15; /* Old INT 15h */
UWORD olddosmem; /* Amount of DOS memory before Memdisk loaded */ UWORD olddosmem; /* Amount of DOS memory before Memdisk loaded */
@ -624,6 +624,39 @@ struct memdiskopt {
UWORD size; UWORD size;
}; };
/* preprocesses memdisk command line to allow simpler handling
{ is replaced by unsigned offset to start of next config line
e.g. "{{HI{HI}{HI{HI" --> "13HI4HI}3HI3HI"
FreeDOS supports max 256 length config lines, memdisk 4 max command length 2047
*/
BYTE FAR * ProcessMemdiskLine(BYTE FAR *cLine)
{
BYTE FAR *ptr;
BYTE FAR *sLine = cLine;
printf("\nMEMDISK:%S:\n", cLine);
/* skip everything until end of line or starting { */
for (; *cLine && (*cLine != '{'); ++cLine)
printf("%c", *cLine);
printf("\n1st { offset is %u, ", (unsigned)(BYTE)(cLine - sLine));
sLine = cLine;
for (ptr = cLine; *cLine; ptr = cLine)
{
/* skip everything until end of line or starting { */
for (++cLine; *cLine && (*cLine != '{'); ++cLine)
;
/* calc offset from previous { to next { or eol and replace previous { with offset */
*ptr = (BYTE)(cLine - ptr);
printf("->%u, ", (unsigned)(*ptr));
}
printf("End\n");
return sLine;
}
/* Given a pointer to a memdisk command line and buffer will copy the next /* Given a pointer to a memdisk command line and buffer will copy the next
config.sys equivalent line to pLine and return updated cLine. config.sys equivalent line to pLine and return updated cLine.
Call repeatedly until end of string (*cLine == '\0'). Call repeatedly until end of string (*cLine == '\0').
@ -634,76 +667,88 @@ struct memdiskopt {
*/ */
BYTE FAR * GetNextMemdiskLine(BYTE FAR *cLine, BYTE *pLine) BYTE FAR * GetNextMemdiskLine(BYTE FAR *cLine, BYTE *pLine)
{ {
int ws = TRUE;
BYTE FAR *ptr;
STATIC struct memdiskopt memdiskopts[] = { STATIC struct memdiskopt memdiskopts[] = {
{"initrd", 6}, {"BOOT_IMAGE", 10}, {"initrd", 6}, {"BOOT_IMAGE", 10},
{"c", 1}, {"h", 1}, {"s", 1},
{"floppy", 6}, {"harddisk", 8}, {"iso", 3}, {"floppy", 6}, {"harddisk", 8}, {"iso", 3},
{"raw", 3}, {"bigraw", 6}, {"int", 3}, {"safeint", 7},
{"nopass", 6}, {"nopassany", 9}, {"nopass", 6}, {"nopassany", 9},
{"edd", 3}, {"noedd", 5} {"edd", 3}, {"noedd", 5}
/*
{"c", 1}, {"h", 1}, {"s", 1},
{"raw", 3}, {"bigraw", 6}, {"int", 3}, {"safeint", 7}
*/
}; };
/* skip everything until end of line or starting { */ int ws = TRUE; /* treat start of line same as if whitespace seen */
for (; *cLine && (*cLine != '{'); ++cLine) BYTE FAR *ptr = cLine; /* start of current cfg line, where { was */
; printf("%u -> \n", (unsigned)(*cLine));
/* exit early if end of line reached, else skip past { */ /* exit early if already at end of command line */
if (!*cLine) if (!*cLine) return cLine;
/* point to start of next line; terminates current line if no } found before here */
cLine += *cLine;
/* restore original character we overwrite with offset, for next iteration of cfg file */
*ptr = '{';
/* ASSERT ptr points to start of line { and cLine points to start of next line { (or eol)*/
/* copy chars to pLine buffer until } or start of next line */
for (++ptr; (*ptr != '}') && (ptr < cLine); ++ptr)
{ {
*pLine = 0; /* if not in last {} then simply copy chars up to } (or next {) */
return cLine; if (*cLine) goto copy_char;
}
cLine++;
/* scan for end marker }, start of next line {, or end of line */ /* otherwise if last character was whitespace (or start of line) check for memdisk option to skip */
for (ptr = cLine; *ptr && (*ptr != '}') && (*ptr != '{'); ++ptr)
;
/* copy to pLine buffer, skipping memdisk options */
while (*cLine && (cLine < ptr))
{
/* if last character was whitespace (or start of line) check for memdisk option to skip */
if (ws) if (ws)
{ {
int i; int i;
for (i = 0; i < 16; ++i) for (i = 0; i < 9; ++i)
{ {
/* compare with option */ /* compare with option */
if (fmemcmp(cLine, memdiskopts[i].name, memdiskopts[i].size) == 0) if (fmemcmp(ptr, memdiskopts[i].name, memdiskopts[i].size) == 0)
{ {
BYTE FAR *tmp = cLine + memdiskopts[i].size; BYTE c = *(ptr + memdiskopts[i].size);
/* ensure character after is end of line, =, or whitespace */ /* ensure character after is end of line, =, or whitespace */
if (!*tmp || (*tmp == '=') || iswh(*tmp)) if (!c || (c == '=') || iswh(c))
{ {
cLine = tmp; /* matched option so point past it */
if (*cLine == '=') ptr += memdiskopts[i].size;
/* allow extra whitespace between option and = by skipping it */
while (iswh(*ptr))
++ptr;
/* if option has = value then skip it as well */
if (*ptr == '=')
{ {
/* allow extra whitespace between = and value by skipping it */
while (iswh(*ptr))
++ptr;
/* skip past all characters after = */ /* skip past all characters after = */
for (; *cLine && (cLine < ptr) && !iswh(*cLine); ++cLine) for (; (*ptr != '}') && (ptr < cLine) && !iswh(*ptr); ++ptr)
; ;
} }
break; break; /* memdisk option found, no need to keep check rest in list */
} }
} }
} }
} }
if (cLine < ptr) if (ptr < cLine)
{ {
*pLine = *cLine; ws = iswh(*ptr);
ws = iswh(*pLine); copy_char:
++cLine; *pLine = *ptr;
++pLine; ++pLine;
} }
} }
*pLine = 0; *pLine = 0;
/* return location to begin next scan from */ /* return location to begin next scan from */
if (*ptr == '}') ptr++; return cLine;
return ptr;
} }
#endif #endif
@ -724,7 +769,10 @@ VOID DoConfig(int nPass)
{ {
UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */ UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */
mdsk = query_memdisk(drv); mdsk = query_memdisk(drv);
if (mdsk != NULL) cLine = mdsk->cmdline; if (mdsk != NULL)
{
cLine = ProcessMemdiskLine(mdsk->cmdline);
}
} }
#endif #endif
@ -832,6 +880,7 @@ VOID DoConfig(int nPass)
#endif #endif
DebugPrintf(("CONFIG=[%s]\n", szLine)); DebugPrintf(("CONFIG=[%s]\n", szLine));
printf("CONFIG=[%s]\n", szLine);
/* Skip leading white space and get verb. */ /* Skip leading white space and get verb. */
pLine = scan(szLine, szBuf); pLine = scan(szLine, szBuf);