Whamcloud - gitweb
b=15699
authornathan <nathan>
Fri, 14 Nov 2008 17:24:56 +0000 (17:24 +0000)
committernathan <nathan>
Fri, 14 Nov 2008 17:24:56 +0000 (17:24 +0000)
i=adilger
i=manoj
move string-based mask setting into a standalone fn; will also be used by changelogs

libcfs/include/libcfs/Makefile.am
libcfs/include/libcfs/libcfs.h
libcfs/include/libcfs/libcfs_string.h [new file with mode: 0644]
libcfs/libcfs/Makefile.in
libcfs/libcfs/debug.c
libcfs/libcfs/libcfs_string.c [new file with mode: 0644]

index c9f9478..7b1959e 100644 (file)
@@ -9,4 +9,4 @@ EXTRA_DIST := curproc.h libcfs_private.h libcfs.h list.h lltrace.h \
                user-tcpip.h user-bitops.h bitmap.h \
                libcfs_prim.h libcfs_time.h libcfs_hash.h \
                libcfs_debug.h libcfsutil.h libcfs_ioctl.h \
-               libcfs_pack.h libcfs_unpack.h
+               libcfs_pack.h libcfs_unpack.h libcfs_string.h
index 08be620..d888670 100644 (file)
@@ -283,6 +283,7 @@ int cfs_univ2oflags(int flags);
 #include <libcfs/libcfs_ioctl.h>
 #include <libcfs/libcfs_prim.h>
 #include <libcfs/libcfs_time.h>
+#include <libcfs/libcfs_string.h>
 
 /* container_of depends on "likely" which is defined in libcfs_private.h */
 static inline void *__container_of(void *ptr, unsigned long shift)
diff --git a/libcfs/include/libcfs/libcfs_string.h b/libcfs/include/libcfs/libcfs_string.h
new file mode 100644 (file)
index 0000000..72a5ef9
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * libcfs/include/libcfs/libcfs_string.h
+ *
+ * Generic string manipulation functions.
+ *
+ * Author: Nathan Rutman <nathan.rutman@sun.com>
+ */
+
+#ifndef __LIBCFS_STRING_H__
+#define __LIBCFS_STRING_H__
+
+/* libcfs_string.c */
+/* Convert a text string to a bitmask */
+int libcfs_str2mask(const char *str, const char *(*bit2str)(int bit),
+                    int *oldmask, int minmask, int allmask);
+
+
+#endif
index 823782a..d106b09 100644 (file)
@@ -24,7 +24,8 @@ sources:
 
 endif
 
-libcfs-all-objs := debug.o nidstrings.o lwt.o module.o tracefile.o watchdog.o
+libcfs-all-objs := debug.o nidstrings.o lwt.o module.o tracefile.o watchdog.o \
+       libcfs_string.o
 
 libcfs-objs := $(libcfs-linux-objs) $(libcfs-all-objs)
 
index 23b1b78..dd40428 100644 (file)
@@ -127,7 +127,7 @@ int libcfs_panic_in_progress;
 const char *
 libcfs_debug_subsys2str(int subsys)
 {
-        switch (subsys) {
+        switch (1 << subsys) {
         default:
                 return NULL;
         case S_UNDEFINED:
@@ -184,7 +184,7 @@ libcfs_debug_subsys2str(int subsys)
 const char *
 libcfs_debug_dbg2str(int debug)
 {
-        switch (debug) {
+        switch (1 << debug) {
         default:
                 return NULL;
         case D_TRACE:
@@ -253,7 +253,6 @@ libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys)
                                                  libcfs_debug_dbg2str;
         int           len = 0;
         const char   *token;
-        int           bit;
         int           i;
 
         if (mask == 0) {                        /* "0" */
@@ -262,12 +261,10 @@ libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys)
                 len = 1;
         } else {                                /* space-separated tokens */
                 for (i = 0; i < 32; i++) {
-                        bit = 1 << i;
-
-                        if ((mask & bit) == 0)
+                        if ((mask & (1 << i)) == 0)
                                 continue;
 
-                        token = fn(bit);
+                        token = fn(i);
                         if (token == NULL)              /* unused bit */
                                 continue;
 
@@ -296,55 +293,11 @@ libcfs_debug_mask2str(char *str, int size, int mask, int is_subsys)
 }
 
 int
-libcfs_debug_token2mask(int *mask, const char *str, int len, int is_subsys)
+libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
 {
         const char *(*fn)(int bit) = is_subsys ? libcfs_debug_subsys2str :
                                                  libcfs_debug_dbg2str;
-        int           i;
-        int           j;
-        int           bit;
-        const char   *token;
-
-        /* match against known tokens */
-        for (i = 0; i < 32; i++) {
-                bit = 1 << i;
-
-                token = fn(bit);
-                if (token == NULL)              /* unused? */
-                        continue;
-
-                /* strcasecmp */
-                for (j = 0; ; j++) {
-                        if (j == len) {         /* end of token */
-                                if (token[j] == 0) {
-                                        *mask = bit;
-                                        return 0;
-                                }
-                                break;
-                        }
-
-                        if (token[j] == 0)
-                                break;
-
-                        if (str[j] == token[j])
-                                continue;
-
-                        if (str[j] < 'A' || 'Z' < str[j])
-                                break;
-
-                        if (str[j] - 'A' + 'a' != token[j])
-                                break;
-                }
-        }
-
-        return -EINVAL;                         /* no match */
-}
-
-int
-libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
-{
         int         m = 0;
-        char        op = 0;
         int         matched;
         int         n;
         int         t;
@@ -362,55 +315,8 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys)
                 return 0;
         }
 
-        /* <str> must be a list of debug tokens or numbers separated by
-         * whitespace and optionally an operator ('+' or '-').  If an operator
-         * appears first in <str>, '*mask' is used as the starting point
-         * (relative), otherwise 0 is used (absolute).  An operator applies to
-         * all following tokens up to the next operator. */
-
-        matched = 0;
-        while (*str != 0) {
-                while (isspace(*str)) /* skip whitespace */
-                        str++;
-
-                if (*str == 0)
-                        break;
-
-                if (*str == '+' || *str == '-') {
-                        op = *str++;
-
-                        /* op on first token == relative */
-                        if (!matched)
-                                m = *mask;
-
-                        while (isspace(*str)) /* skip whitespace */
-                                str++;
-
-                        if (*str == 0)          /* trailing op */
-                                return -EINVAL;
-                }
-
-                /* find token length */
-                for (n = 0; str[n] != 0 && !isspace(str[n]); n++);
-
-                /* match token */
-                if (libcfs_debug_token2mask(&t, str, n, is_subsys) != 0)
-                        return -EINVAL;
-
-                matched = 1;
-                if (op == '-')
-                        m &= ~t;
-                else
-                        m |= t;
-
-                str += n;
-        }
-
-        if (!matched)
-                return -EINVAL;
-
-        *mask = m;
-        return 0;
+        return libcfs_str2mask(str, fn, mask, is_subsys ? 0 : D_CANTMASK,
+                               0xffffffff);
 }
 
 /**
diff --git a/libcfs/libcfs/libcfs_string.c b/libcfs/libcfs/libcfs_string.c
new file mode 100644 (file)
index 0000000..40e5ebb
--- /dev/null
@@ -0,0 +1,132 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * String manipulation functions.
+ *
+ * libcfs/libcfs/libcfs_string.c
+ *
+ * Author: Nathan Rutman <nathan.rutman@sun.com>
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#include <libcfs/libcfs.h>
+
+/* non-0 = don't match */
+static int libcfs_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+        if (s1 == NULL || s2 == NULL)
+                return 1;
+
+        if (n == 0)
+                return 0;
+
+        while (n-- != 0 && tolower(*s1) == tolower(*s2)) {
+                if (n == 0 || *s1 == '\0' || *s2 == '\0')
+                        break;
+                s1++;
+                s2++;
+        }
+
+        return tolower(*(unsigned char *)s1) - tolower(*(unsigned char *)s2);
+}
+
+/* Convert a text string to a bitmask */
+int libcfs_str2mask(const char *str, const char *(*bit2str)(int bit),
+                    int *oldmask, int minmask, int allmask)
+{
+        char op = 0;
+        int newmask = minmask, i, len, found = 0;
+        ENTRY;
+
+        /* <str> must be a list of tokens separated by whitespace
+         * and optionally an operator ('+' or '-').  If an operator
+         * appears first in <str>, '*oldmask' is used as the starting point
+         * (relative), otherwise minmask is used (absolute).  An operator
+         * applies to all following tokens up to the next operator. */
+        while (*str != 0) {
+                while (isspace(*str))
+                        str++;
+                if (*str == 0)
+                        break;
+                if (*str == '+' || *str == '-') {
+                        op = *str++;
+                        if (!found)
+                                /* only if first token is relative */
+                                newmask = *oldmask;
+                        while (isspace(*str))
+                                str++;
+                        if (*str == 0)          /* trailing op */
+                                return -EINVAL;
+                }
+
+                /* find token length */
+                for (len = 0; str[len] != 0 && !isspace(str[len]) &&
+                      str[len] != '+' && str[len] != '-'; len++);
+
+                /* match token */
+                found = 0;
+                for (i = 0; i < 32; i++) {
+                        if (libcfs_strncasecmp(str, bit2str(i), len) == 0) {
+                                if (op == '-')
+                                        newmask &= ~(1 << i);
+                                else
+                                        newmask |= (1 << i);
+                                found = 1;
+                                break;
+                        }
+                }
+                if (!found && (libcfs_strncasecmp(str, "ALL", len) == 0)) {
+                        if (op == '-')
+                                newmask = minmask;
+                        else
+                                newmask = allmask;
+                        found = 1;
+                }
+                if (!found) {
+                        CWARN("unknown mask '%.*s'.\n"
+                              "mask usage: [+|-]<all|type> ...\n", len, str);
+                        return -EINVAL;
+                }
+                str += len;
+        }
+
+        *oldmask = newmask;
+        return 0;
+}
+EXPORT_SYMBOL(libcfs_str2mask);
+