Fix many incompatibilities in DIR switch parsing, including those noted in Bug 4744.

svn path=/trunk/; revision=42338
This commit is contained in:
Jeffrey Morlan 2009-08-02 15:16:03 +00:00
parent 3871f9be2f
commit 54817d5b14

View file

@ -176,22 +176,16 @@ typedef struct _DirSwitchesFlags
{ {
DWORD dwAttribVal; /* The desired state of attribute */ DWORD dwAttribVal; /* The desired state of attribute */
DWORD dwAttribMask; /* Which attributes to check */ DWORD dwAttribMask; /* Which attributes to check */
BOOL bUnSet; /* A helper flag if "-" was given with the switch */
BOOL bParSetted; /* A helper flag if parameters of switch were given */
} stAttribs; /* Displays files with this attributes only */ } stAttribs; /* Displays files with this attributes only */
struct struct
{ {
enum EOrderBy eCriteria[3]; /* Criterias used to order by */ enum EOrderBy eCriteria[3]; /* Criterias used to order by */
BOOL bCriteriaRev[3]; /* If the criteria is in reversed order */ BOOL bCriteriaRev[3]; /* If the criteria is in reversed order */
short sCriteriaCount; /* The quantity of criterias */ short sCriteriaCount; /* The quantity of criterias */
BOOL bUnSet; /* A helper flag if "-" was given with the switch */
BOOL bParSetted; /* A helper flag if parameters of switch were given */
} stOrderBy; /* Ordered by criterias */ } stOrderBy; /* Ordered by criterias */
struct struct
{ {
enum ETimeField eTimeField; /* The time field that will be used for */ enum ETimeField eTimeField; /* The time field that will be used for */
BOOL bUnSet; /* A helper flag if "-" was given with the switch */
BOOL bParSetted; /* A helper flag if parameters of switch were given */
} stTimeField; /* The time field to display or use for sorting */ } stTimeField; /* The time field to display or use for sorting */
} DIRSWITCHFLAGS, *LPDIRSWITCHFLAGS; } DIRSWITCHFLAGS, *LPDIRSWITCHFLAGS;
@ -247,6 +241,7 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */ BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */
LPTSTR ptrStart; /* A pointer to the first character of a parameter */ LPTSTR ptrStart; /* A pointer to the first character of a parameter */
LPTSTR ptrEnd; /* A pointer to the last character of a parameter */ LPTSTR ptrEnd; /* A pointer to the last character of a parameter */
BOOL bOrderByNoPar; /* A flag to indicate /O with no switch parameter */
LPTSTR temp; LPTSTR temp;
/* Initialize parameter array */ /* Initialize parameter array */
@ -261,10 +256,7 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
/* We suppose that switch parameters /* We suppose that switch parameters
were given to avoid setting them to default were given to avoid setting them to default
if the switch was not given */ if the switch was not given */
lpFlags->stAttribs.bParSetted = TRUE; bOrderByNoPar = FALSE;
lpFlags->stOrderBy.bParSetted = TRUE;
lpFlags->stTimeField.bParSetted = TRUE;
/* Main Loop (see README_DIR.txt) */ /* Main Loop (see README_DIR.txt) */
/* scan the command line char per char, and we process its char */ /* scan the command line char per char, and we process its char */
@ -278,24 +270,46 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
/* When a switch is expecting */ /* When a switch is expecting */
if (cCurSwitch == _T('/')) if (cCurSwitch == _T('/'))
{ {
while (*Line == _T(' '))
Line++;
bNegative = (*Line == _T('-'));
Line += bNegative;
cCurChar = *Line;
cCurUChar = _totupper(*Line);
if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O'))) if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O')))
{ {
cCurSwitch = cCurUChar; /* If positive, prepare for parameters... if negative, reset to defaults */
switch (cCurUChar) switch (cCurUChar)
{ {
case _T('A'): case _T('A'):
lpFlags->stAttribs.bUnSet = bNegative; lpFlags->stAttribs.dwAttribVal = 0L;
lpFlags->stAttribs.bParSetted = FALSE; lpFlags->stAttribs.dwAttribMask = 0L;
if (bNegative)
lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
break; break;
case _T('T'): case _T('T'):
lpFlags->stTimeField.bUnSet = bNegative; if (bNegative)
lpFlags->stTimeField.bParSetted = FALSE; lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE;
break; break;
case _T('O'): case _T('O'):
lpFlags->stOrderBy.bUnSet = bNegative; bOrderByNoPar = !bNegative;
lpFlags->stOrderBy.bParSetted = FALSE; lpFlags->stOrderBy.sCriteriaCount = 0;
break; break;
} }
if (!bNegative)
{
/* Positive switch, so it can take parameters. */
cCurSwitch = cCurUChar;
Line++;
/* Skip optional leading colon */
if (*Line == _T(':'))
Line++;
continue;
}
} }
else if (cCurUChar == _T('L')) else if (cCurUChar == _T('L'))
lpFlags->bLowerCase = ! bNegative; lpFlags->bLowerCase = ! bNegative;
@ -324,24 +338,20 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
DirHelp(); DirHelp();
return FALSE; return FALSE;
} }
else if (cCurChar == _T('-'))
{
bNegative = TRUE;
}
else else
{ {
error_invalid_switch ((TCHAR)_totupper (*Line)); error_invalid_switch ((TCHAR)_totupper (*Line));
return FALSE; return FALSE;
} }
/* We check if we calculated the negative value and realese the flag */ /* Make sure there's no extra characters at the end of the switch */
if ((cCurChar != _T('-')) && bNegative) if (Line[1] && Line[1] != _T('/') && Line[1] != _T(' '))
bNegative = FALSE; {
error_parameter_format(Line[1]);
/* if not a,o,t or - option then next parameter is not a switch */ return FALSE;
if ((cCurSwitch == _T('/')) && (!bNegative)) }
cCurSwitch = _T(' ');
cCurSwitch = _T(' ');
} }
else if (cCurSwitch == _T(' ')) else if (cCurSwitch == _T(' '))
{ {
@ -393,20 +403,14 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
if ((cCurChar == _T('/')) || ( cCurChar == _T(' '))) if ((cCurChar == _T('/')) || ( cCurChar == _T(' ')))
{ {
/* Wrong desicion path, reprocess current character */ /* Wrong desicion path, reprocess current character */
cCurSwitch = cCurChar; cCurSwitch = _T(' ');
continue; continue;
} }
/* Process parameter switch */ /* Process parameter switch */
switch(cCurSwitch) switch(cCurSwitch)
{ {
case _T('A'): /* Switch parameters for /A (attributes filter) */ case _T('A'): /* Switch parameters for /A (attributes filter) */
/* Ok a switch parameter was given */ if(cCurChar == _T('-'))
lpFlags->stAttribs.bParSetted = TRUE;
if (cCurChar == _T(':'))
/* =V= dead command, used to make the "if" work */
cCurChar = cCurChar;
else if(cCurChar == _T('-'))
bPNegative = TRUE; bPNegative = TRUE;
else if(cCurUChar == _T('D')) else if(cCurUChar == _T('D'))
{ {
@ -455,14 +459,7 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
} }
break; break;
case _T('T'): /* Switch parameters for /T (time field) */ case _T('T'): /* Switch parameters for /T (time field) */
if(cCurUChar == _T('C'))
/* Ok a switch parameter was given */
lpFlags->stTimeField.bParSetted = TRUE;
if (cCurChar == _T(':'))
/* =V= dead command, used to make the "if" work */
cCurChar = cCurChar;
else if(cCurUChar == _T('C'))
lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ; lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ;
else if(cCurUChar == _T('A')) else if(cCurUChar == _T('A'))
lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ; lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ;
@ -476,12 +473,9 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
break; break;
case _T('O'): /* Switch parameters for /O (order) */ case _T('O'): /* Switch parameters for /O (order) */
/* Ok a switch parameter was given */ /* Ok a switch parameter was given */
lpFlags->stOrderBy.bParSetted = TRUE; bOrderByNoPar = FALSE;
if (cCurChar == _T(':')) if(cCurChar == _T('-'))
/* <== dead command, used to make the "if" work */
cCurChar = cCurChar;
else if(cCurChar == _T('-'))
bPNegative = TRUE; bPNegative = TRUE;
else if(cCurUChar == _T('N')) else if(cCurUChar == _T('N'))
{ {
@ -530,38 +524,16 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */
Line++; Line++;
} }
/* Calculate the switches with no switch paramater */ /* /O with no switch parameters acts like /O:GN */
if (!(lpFlags->stAttribs.bParSetted)) if (bOrderByNoPar)
{ {
lpFlags->stAttribs.dwAttribVal = 0L; lpFlags->stOrderBy.sCriteriaCount = 2;
lpFlags->stAttribs.dwAttribMask = lpFlags->stAttribs.dwAttribVal; lpFlags->stOrderBy.eCriteria[0] = ORDER_DIRECTORY;
}
if (!(lpFlags->stOrderBy.bParSetted))
{
lpFlags->stOrderBy.sCriteriaCount = 1;
lpFlags->stOrderBy.eCriteria[0] = ORDER_NAME;
lpFlags->stOrderBy.bCriteriaRev[0] = FALSE; lpFlags->stOrderBy.bCriteriaRev[0] = FALSE;
lpFlags->stOrderBy.eCriteria[1] = ORDER_NAME;
lpFlags->stOrderBy.bCriteriaRev[1] = FALSE;
} }
if (!(lpFlags->stTimeField.bParSetted))
lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE ;
/* Calculate the unsetted switches (the "-" prefixed)*/
if (lpFlags->stAttribs.bUnSet)
{
lpFlags->stAttribs.bUnSet = FALSE;
lpFlags->stAttribs.dwAttribVal = 0L;
lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
}
if (lpFlags->stOrderBy.bUnSet)
{
lpFlags->stOrderBy.bUnSet = FALSE;
lpFlags->stOrderBy.sCriteriaCount = 0;
}
if (lpFlags->stTimeField.bUnSet )
{
lpFlags->stTimeField.bUnSet = FALSE;
lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE;
}
return TRUE; return TRUE;
} }
@ -1600,12 +1572,9 @@ CommandDir(LPTSTR rest)
stFlags.bWideList = FALSE; stFlags.bWideList = FALSE;
stFlags.bWideListColSort = FALSE; stFlags.bWideListColSort = FALSE;
stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE; stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE;
stFlags.stTimeField.bUnSet = FALSE;
stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
stFlags.stAttribs.dwAttribVal = 0L; stFlags.stAttribs.dwAttribVal = 0L;
stFlags.stAttribs.bUnSet = FALSE;
stFlags.stOrderBy.sCriteriaCount = 0; stFlags.stOrderBy.sCriteriaCount = 0;
stFlags.stOrderBy.bUnSet = FALSE;
nErrorLevel = 0; nErrorLevel = 0;