Dan Kegel : cmd: del /a: move parsing of attributes to helper function, use bitmasks.
Alexandre Julliard
julliard at winehq.org
Tue May 24 12:53:50 CDT 2011
Module: wine
Branch: master
Commit: 65b27c9ecd2c80aa91fa0c5425ddfb2f9f2cb37d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=65b27c9ecd2c80aa91fa0c5425ddfb2f9f2cb37d
Author: Dan Kegel <dank at 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) {
More information about the wine-cvs
mailing list