]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
server: Convert com_setatt() to lopsub.
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 2 Oct 2015 21:22:01 +0000 (21:22 +0000)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 26 Mar 2017 09:02:28 +0000 (11:02 +0200)
Introduces ->input_skip for struct pattern_match data. The setatt
command uses this to strip the attribute modifies off the unnamed
arguments in the lopsub parse result. The remaining arguments are
the patterns which are to be matched against each file in the audio
file table.

afs.c
afs.cmd
afs.h
aft.c
m4/lls/server_cmd.suite.m4

diff --git a/afs.c b/afs.c
index 21035cda93710b3167d7374fd8e2e7f20ecbe41d..92c58cc8cbe142a4f403b6bd0654c21f8136757e 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -401,7 +401,7 @@ static int action_if_pattern_matches(struct osl_row *row, void *data)
                }
        }
        p = pattern_txt;
-       i = 0;
+       i = pmd->input_skip;
        for (;;) {
                if (pmd->lpr) {
                        if (i >= lls_num_inputs(pmd->lpr))
diff --git a/afs.cmd b/afs.cmd
index 5a3615bf1bc8f79771da9bd0a6c54f8877dff711..2b9e4f8e15947c6ee60a21cfea1eda9548079fa7 100644 (file)
--- a/afs.cmd
+++ b/afs.cmd
@@ -52,18 +52,6 @@ H:   b: by bit rate
 H:   d: by duration
 H:   a: by audio format
 ---
-N: setatt
-P: AFS_READ | AFS_WRITE
-D: Set attribute(s) for all files matching a pattern.
-U: setatt attribute{+|-}... pattern
-H: Set ('+') or unset ('-') the given attributes for all audio files matching
-H: pattern.  Example:
-H:
-H:         setatt rock+ punk+ pop- '*foo.mp3'
-H:
-H: sets the 'rock' and the 'punk' attribute and unsets the 'pop'
-H: attribute of all files ending with 'foo.mp3'.
----
 N: addatt
 P: AFS_READ | AFS_WRITE
 D: Add new attribute(s).
diff --git a/afs.h b/afs.h
index c73eb7361b80587780e3c952bb09b72fd3e7a4d4..3d13aea277d7459e9fd36d194cc4ff710473022c 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -149,6 +149,8 @@ struct pattern_match_data {
        struct lls_parse_result *lpr;
        /** Null-terminated array of patterns. */
        struct osl_object patterns;
+       /** Do not try to match the first inputs of lpr */
+       unsigned input_skip;
        /** Data pointer passed to the action function. */
        void *data;
        /** Gets increased by one for each match. */
diff --git a/aft.c b/aft.c
index 628f98fbeebef702d0cbccb104e2eac28053994d..f1864081cc2e362d1fc1c4dc31711489b1997c7e 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -2401,9 +2401,8 @@ static int change_atts(__a_unused struct osl_table *table,
 
 static int com_setatt_callback(struct afs_callback_arg *aca)
 {
-       char *p;
-       int ret;
-       size_t len;
+       const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SETATT);
+       int i, ret;
        struct change_atts_data cad = {.aca = aca};
        struct pattern_match_data pmd = {
                .table = audio_file_table,
@@ -2413,27 +2412,36 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
                .data = &cad,
                .action = change_atts
        };
+       unsigned num_inputs;
+
+       ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr);
+       assert(ret >= 0);
+       pmd.lpr = aca->lpr;
 
-       for (
-               p = aca->query.data;
-               p < (char *)aca->query.data + aca->query.size;
-               p += len + 1
-       ) {
-               char c;
+       num_inputs = lls_num_inputs(aca->lpr);
+       for (i = 0; i < num_inputs; i++) {
                unsigned char bitnum;
                uint64_t one = 1;
+               const char *arg = lls_input(i, aca->lpr);
+               char c, *p;
+               size_t len = strlen(arg);
 
-               len = strlen(p);
                ret = -E_ATTR_SYNTAX;
                if (len == 0)
                        goto out;
-               c = p[len - 1];
-               if (c != '+' && c != '-')
-                       break;
+               c = arg[len - 1];
+               if (c != '+' && c != '-') {
+                       if (cad.add_mask == 0 && cad.del_mask == 0)
+                               goto out; /* no attribute modifier given */
+                       goto set_atts;
+               }
+               p = para_malloc(len);
+               memcpy(p, arg, len - 1);
                p[len - 1] = '\0';
                ret = get_attribute_bitnum_by_name(p, &bitnum);
+               free(p);
                if (ret < 0) {
-                       para_printf(&aca->pbout, "attribute not found: %s\n", p);
+                       para_printf(&aca->pbout, "invalid argument: %s\n", arg);
                        goto out;
                }
                if (c == '+')
@@ -2441,29 +2449,32 @@ static int com_setatt_callback(struct afs_callback_arg *aca)
                else
                        cad.del_mask |= (one << bitnum);
        }
+       /* no pattern given */
        ret = -E_ATTR_SYNTAX;
-       if (!cad.add_mask && !cad.del_mask)
-               goto out;
-       pmd.patterns.data = p;
-       if (p >= (char *)aca->query.data + aca->query.size)
-               goto out;
-       pmd.patterns.size = (char *)aca->query.data + aca->query.size - p;
+       goto out;
+set_atts:
+       pmd.input_skip = i;
        ret = for_each_matching_row(&pmd);
-       if (ret < 0)
-               goto out;
-       if (pmd.num_matches == 0)
+       if (ret >= 0 && pmd.num_matches == 0)
                ret = -E_NO_MATCH;
 out:
+       lls_free_parse_result(aca->lpr, cmd);
        return ret;
 }
 
-int com_setatt(struct command_context *cc)
+static int com_setatt(struct command_context *cc, struct lls_parse_result *lpr)
 {
-       if (cc->argc < 3)
-               return -E_ATTR_SYNTAX;
-       return send_standard_callback_request(cc->argc - 1, cc->argv + 1,
-               com_setatt_callback, afs_cb_result_handler, cc);
+       const struct lls_command *cmd = SERVER_CMD_CMD_PTR(SETATT);
+       char *errctx;
+       int ret = lls(lls_check_arg_count(lpr, 2, INT_MAX, &errctx));
+
+       if (ret < 0) {
+               send_errctx(cc, errctx);
+               return ret;
+       }
+       return send_lls_callback_request(com_setatt_callback, cmd, lpr, cc);
 }
+EXPORT_SERVER_CMD_HANDLER(setatt);
 
 static int afs_stat_callback(struct afs_callback_arg *aca)
 {
index b10f3553aca058ab7ad85870ca6028c42a23cfb9..b113934164315741699cc3f119f122d0c34cb8c2 100644 (file)
@@ -193,6 +193,20 @@ aux_info_prefix = Permissions:
 
        [/description]
 
+[subcommand setatt]
+       purpose = set or unset attributes
+       synopsis = attribute{+|-}... pattern...
+       aux_info = AFS_READ | AFS_WRITE
+       [description]
+               Set ('+') or unset ('-') the given attributes for all audio files
+               matching the given pattern. Example:
+
+                       setatt rock+ punk+ pop- '*foo.mp3'
+
+               sets the 'rock' and the 'punk' attribute and unsets the 'pop' attribute
+               of all files ending with 'foo.mp3'.
+       [/description]
+
 [subcommand si]
        purpose = print server info
        aux_info = NO_PERMISSION_REQUIRED