]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - aft.c
paraslash 0.7.3
[paraslash.git] / aft.c
diff --git a/aft.c b/aft.c
index 0aa9c6ba7ac4588f1889bf4dda8ec52d3b9cf4d7..f1aca7fb8ccc3e31575303a4762d6a7ea35a054f 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -1362,28 +1362,67 @@ err:
        return ret;
 }
 
+static int mop_loop(const char *arg, struct afs_callback_arg *aca,
+               struct ls_options *opts)
+{
+       int ret;
+       char *msg;
+
+       if (!arg || strcmp(arg, ".") == 0)
+               return score_loop(prepare_ls_row, NULL, opts);
+       if (!strncmp(arg, "m/", 2)) {
+               struct mood_instance *m;
+               ret = mood_load(arg + 2, &m, &msg);
+               if (ret < 0)
+                       afs_error(aca, "%s", msg);
+               free(msg);
+               if (ret < 0)
+                       return ret;
+               ret = mood_loop(m, prepare_ls_row, opts);
+               mood_unload(m);
+               return ret;
+       }
+       if (!strncmp(arg, "p/", 2)) {
+               struct playlist_instance *pi;
+               ret = playlist_load(arg + 2, &pi, &msg);
+               if (ret < 0)
+                       afs_error(aca, "%s", msg);
+               free(msg);
+               if (ret < 0)
+                       return ret;
+               ret = playlist_loop(pi, prepare_ls_row, opts);
+               playlist_unload(pi);
+               return ret;
+       }
+       afs_error(aca, "bad mood/playlist specifier: %s\n", arg);
+       return -ERRNO_TO_PARA_ERROR(EINVAL);
+}
+
 static int com_ls_callback(struct afs_callback_arg *aca)
 {
        const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS);
        struct ls_options *opts = aca->query.data;
-       int i = 0, ret;
+       int ret;
        time_t current_time;
-       const struct lls_opt_result *r_r;
+       const struct lls_opt_result *r_r, *r_a;
+       uint32_t limit, k, n;
 
        ret = lls_deserialize_parse_result(
                (char *)aca->query.data + sizeof(*opts), cmd, &opts->lpr);
        assert(ret >= 0);
        r_r = SERVER_CMD_OPT_RESULT(LS, REVERSE, opts->lpr);
-
+       r_a = SERVER_CMD_OPT_RESULT(LS, ADMISSIBLE, opts->lpr);
        aca->pbout.flags = (opts->mode == LS_MODE_PARSER)? PBF_SIZE_PREFIX : 0;
-       if (admissible_only(opts))
-               ret = score_loop(prepare_ls_row, opts);
-       else
+       if (admissible_only(opts)) {
+               const char *arg = lls_string_val(0, r_a);
+               ret = mop_loop(arg, aca, opts);
+       } else
                ret = osl(osl_rbtree_loop(audio_file_table, AFTCOL_PATH, opts,
                        prepare_ls_row));
        if (ret < 0)
                goto out;
-       if (opts->num_matching_paths == 0) {
+       n = opts->num_matching_paths;
+       if (n == 0) {
                ret = lls_num_inputs(opts->lpr) > 0? -E_NO_MATCH : 0;
                goto out;
        }
@@ -1391,20 +1430,14 @@ static int com_ls_callback(struct afs_callback_arg *aca)
        if (ret < 0)
                goto out;
        time(&current_time);
-       if (lls_opt_given(r_r))
-               for (i = opts->num_matching_paths - 1; i >= 0; i--) {
-                       ret = print_list_item(opts->data_ptr[i], opts,
-                               &aca->pbout, current_time);
-                       if (ret < 0)
-                               goto out;
-               }
-       else
-               for (i = 0; i < opts->num_matching_paths; i++) {
-                       ret = print_list_item(opts->data_ptr[i], opts,
-                               &aca->pbout, current_time);
-                       if (ret < 0)
-                               goto out;
-               }
+       limit = SERVER_CMD_UINT32_VAL(LS, LIMIT, opts->lpr);
+       for (k = 0; k < n && (limit == 0 || k < limit); k++) {
+               uint32_t idx = lls_opt_given(r_r)? n - 1 - k : k;
+               ret = print_list_item(opts->data_ptr[idx], opts, &aca->pbout,
+                       current_time);
+               if (ret < 0)
+                       goto out;
+       }
 out:
        lls_free_parse_result(opts->lpr, cmd);
        free(opts->data);