Module: wine Branch: master Commit: 65b27c9ecd2c80aa91fa0c5425ddfb2f9f2cb37d URL: http://source.winehq.org/git/wine.git/?a=commit;h=65b27c9ecd2c80aa91fa0c5425...
Author: Dan Kegel dank@kegel.com Date: Sun May 22 07:59:22 2011 -0700
cmd: del /a: move parsing of attributes to helper function, use bitmasks.
---
programs/cmd/builtins.c | 111 +++++++++++++++++++++++------------------------ 1 files changed, 54 insertions(+), 57 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 944a997..7a6ae72 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -532,6 +532,53 @@ void WCMD_create_dir (void) { if (!create_full_path(param1)) WCMD_print_error (); }
+/* Parse the /A options given by the user on the commandline + * into a bitmask of wanted attributes (*wantSet), + * and a bitmask of unwanted attributes (*wantClear). + */ +static void WCMD_delete_parse_attributes(DWORD *wantSet, DWORD *wantClear) { + static const WCHAR parmA[] = {'/','A','\0'}; + WCHAR *p; + + /* both are strictly 'out' parameters */ + *wantSet=0; + *wantClear=0; + + /* For each /A argument */ + for (p=strstrW(quals, parmA); p != NULL; p=strstrW(p, parmA)) { + /* Skip /A itself */ + p += 2; + + /* Skip optional : */ + if (*p == ':') p++; + + /* For each of the attribute specifier chars to this /A option */ + for (; *p != 0 && *p != '/'; p++) { + BOOL negate = FALSE; + DWORD mask = 0; + + if (*p == '-') { + negate=TRUE; + p++; + } + + /* Convert the attribute specifier to a bit in one of the masks */ + switch (*p) { + case 'R': mask = FILE_ATTRIBUTE_READONLY; break; + case 'H': mask = FILE_ATTRIBUTE_HIDDEN; break; + case 'S': mask = FILE_ATTRIBUTE_SYSTEM; break; + case 'A': mask = FILE_ATTRIBUTE_ARCHIVE; break; + default: + WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); + } + if (negate) + *wantClear |= mask; + else + *wantSet |= mask; + } + } +} + /**************************************************************************** * WCMD_delete * @@ -551,11 +598,14 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) { int argsProcessed = 0; WCHAR *argN = command; BOOL foundAny = FALSE; - static const WCHAR parmA[] = {'/','A','\0'}; static const WCHAR parmQ[] = {'/','Q','\0'}; static const WCHAR parmP[] = {'/','P','\0'}; static const WCHAR parmS[] = {'/','S','\0'}; static const WCHAR parmF[] = {'/','F','\0'}; + DWORD wanted_attrs; + DWORD unwanted_attrs; + + WCMD_delete_parse_attributes(&wanted_attrs, &unwanted_attrs);
/* If not recursing, clear error flag */ if (expectDir) errorlevel = 0; @@ -644,64 +694,11 @@ BOOL WCMD_delete (WCHAR *command, BOOL expectDir) { } else strcpyW (fpath, fd.cFileName); if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - BOOL ok = TRUE; - WCHAR *nextA = strstrW (quals, parmA); + BOOL ok;
/* Handle attribute matching (/A) */ - if (nextA != NULL) { - ok = FALSE; - while (nextA != NULL && !ok) { - - WCHAR *thisA = (nextA+2); - BOOL stillOK = TRUE; - - /* Skip optional : */ - if (*thisA == ':') thisA++; - - /* Parse each of the /A[:]xxx in turn */ - while (*thisA && *thisA != '/') { - BOOL negate = FALSE; - BOOL attribute = FALSE; - - /* Match negation of attribute first */ - if (*thisA == '-') { - negate=TRUE; - thisA++; - } - - /* Match attribute */ - switch (*thisA) { - case 'R': attribute = (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY); - break; - case 'H': attribute = (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN); - break; - case 'S': attribute = (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM); - break; - case 'A': attribute = (fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE); - break; - default: - WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); - } - - /* Now check result, keeping a running boolean about whether it - matches all parsed attributes so far */ - if (attribute && !negate) { - stillOK = stillOK; - } else if (!attribute && negate) { - stillOK = stillOK; - } else { - stillOK = FALSE; - } - thisA++; - } - - /* Save the running total as the final result */ - ok = stillOK; - - /* Step on to next /A set */ - nextA = strstrW (nextA+1, parmA); - } - } + ok = ((fd.dwFileAttributes & wanted_attrs) == wanted_attrs) + && ((fd.dwFileAttributes & unwanted_attrs) == 0);
/* /P means prompt for each file */ if (ok && strstrW (quals, parmP) != NULL) {