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
1 changed files with 107 additions and 58 deletions

View File

@ -607,7 +607,7 @@ struct memdiskinfo {
UBYTE version; /* Memdisk major version */
UDWORD base; /* Pointer to disk data in high memory */
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 oldint15; /* Old INT 15h */
UWORD olddosmem; /* Amount of DOS memory before Memdisk loaded */
@ -624,6 +624,39 @@ struct memdiskopt {
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
config.sys equivalent line to pLine and return updated cLine.
Call repeatedly until end of string (*cLine == '\0').
@ -632,79 +665,91 @@ struct memdiskopt {
end of line. MEMDISK options may appear nearly anywhere on line and are
ignored - see memdisk_opts for list of recognized options.
*/
BYTE FAR * GetNextMemdiskLine(BYTE FAR *cLine, BYTE *pLine)
{
int ws = TRUE;
BYTE FAR *ptr;
BYTE FAR * GetNextMemdiskLine(BYTE FAR *cLine, BYTE *pLine)
{
STATIC struct memdiskopt memdiskopts[] = {
{"initrd", 6}, {"BOOT_IMAGE", 10},
{"c", 1}, {"h", 1}, {"s", 1},
{"floppy", 6}, {"harddisk", 8}, {"iso", 3},
{"raw", 3}, {"bigraw", 6}, {"int", 3}, {"safeint", 7},
{"nopass", 6}, {"nopassany", 9},
{"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 { */
for (; *cLine && (*cLine != '{'); ++cLine)
;
int ws = TRUE; /* treat start of line same as if whitespace seen */
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 { */
if (!*cLine)
/* exit early if already at end of command line */
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;
return cLine;
}
cLine++;
/* if not in last {} then simply copy chars up to } (or next {) */
if (*cLine) goto copy_char;
/* scan for end marker }, start of next line {, or end of line */
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 */
/* otherwise if last character was whitespace (or start of line) check for memdisk option to skip */
if (ws)
{
int i;
for (i = 0; i < 16; ++i)
for (i = 0; i < 9; ++i)
{
/* 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 */
if (!*tmp || (*tmp == '=') || iswh(*tmp))
if (!c || (c == '=') || iswh(c))
{
cLine = tmp;
if (*cLine == '=')
/* matched option so point past it */
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 = */
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(*pLine);
++cLine;
ws = iswh(*ptr);
copy_char:
*pLine = *ptr;
++pLine;
}
}
*pLine = 0;
/* return location to begin next scan from */
if (*ptr == '}') ptr++;
return ptr;
}
return cLine;
}
#endif
@ -724,7 +769,10 @@ VOID DoConfig(int nPass)
{
UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */
mdsk = query_memdisk(drv);
if (mdsk != NULL) cLine = mdsk->cmdline;
if (mdsk != NULL)
{
cLine = ProcessMemdiskLine(mdsk->cmdline);
}
}
#endif
@ -832,6 +880,7 @@ VOID DoConfig(int nPass)
#endif
DebugPrintf(("CONFIG=[%s]\n", szLine));
printf("CONFIG=[%s]\n", szLine);
/* Skip leading white space and get verb. */
pLine = scan(szLine, szBuf);