From: Andre Noll Date: Fri, 2 Oct 2015 21:17:09 +0000 (+0000) Subject: server: Convert com_cpsi() to lopsub. X-Git-Tag: v0.6.0~2^2~65 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=caeefe70444bcac624a148401e012cdc528957b6 server: Convert com_cpsi() to lopsub. Allows to get rid of enum cpsi_flags as we pass the flags via the serialized parse result to the callback and the action handler (copy_selector_info()). Also the open-coded command line parser in com_cpsi() can be removed. --- diff --git a/afs.cmd b/afs.cmd index 807e1e6e..35c3601c 100644 --- a/afs.cmd +++ b/afs.cmd @@ -127,28 +127,6 @@ H: in pattern and not by an asterisk (*) or a question mark H: (?) metacharacter, nor by a bracket expression ([]) containing H: a slash (see fnmatch(3)). --- -N: cpsi -P: AFS_READ | AFS_WRITE -D: Copy audio file selector info. -U: cpsi [-a] [-y] [-i] [-l] [-n] [-v] source pattern... -H: If no option, or only the -v option is given, all fields of the -H: audio file selector info are copied to all files matching pattern. -H: Otherwise, only the given options are taken into account. -H: -H: Options: -H: -H: -a Copy attributes. -H: -H: -y Copy the lyrics id. -H: -H: -i Copy the image id. -H: -H: -l Copy the lastplayed time. -H: -H: -n Copy the numplayed count. -H: -H: -v Verbose mode. ---- N: select P: AFS_READ | AFS_WRITE D: Activate a mood or a playlist. diff --git a/aft.c b/aft.c index f1864081..b442de8e 100644 --- a/aft.c +++ b/aft.c @@ -2224,34 +2224,13 @@ int com_rm(struct command_context *cc) cc->argv + i, com_rm_callback, afs_cb_result_handler, cc); } -/** - * Flags used by the cpsi command. - * - * \sa com_cpsi(). - */ -enum cpsi_flags { - /** Whether the lyrics id should be copied. */ - CPSI_FLAG_COPY_LYRICS_ID = 1, - /** Whether the image id should be copied. */ - CPSI_FLAG_COPY_IMAGE_ID = 2, - /** Whether the lastplayed time should be copied. */ - CPSI_FLAG_COPY_LASTPLAYED = 4, - /** Whether the numplayed count should be copied. */ - CPSI_FLAG_COPY_NUMPLAYED = 8, - /** Whether the attributes should be copied. */ - CPSI_FLAG_COPY_ATTRIBUTES = 16, - /** Activates verbose mode. */ - CPSI_FLAG_VERBOSE = 32, -}; - /** Data passed to the action handler of com_cpsi(). */ struct cpsi_action_data { - /** command line flags (see \ref cpsi_flags). */ - unsigned flags; /** Values are copied from here. */ struct afs_info source_afsi; /** What was passed to com_cpsi_callback(). */ struct afs_callback_arg *aca; + bool copy_all; }; static int copy_selector_info(__a_unused struct osl_table *table, @@ -2262,24 +2241,32 @@ static int copy_selector_info(__a_unused struct osl_table *table, int ret; struct afs_info old_afsi, target_afsi; struct afsi_change_event_data aced; + bool a_given, y_given, i_given, l_given, n_given, v_given; + + a_given = SERVER_CMD_OPT_GIVEN(CPSI, ATTRIBUTE_BITMAP, cad->aca->lpr); + y_given = SERVER_CMD_OPT_GIVEN(CPSI, LYRICS_ID, cad->aca->lpr); + i_given = SERVER_CMD_OPT_GIVEN(CPSI, IMAGE_ID, cad->aca->lpr); + l_given = SERVER_CMD_OPT_GIVEN(CPSI, LASTPLAYED, cad->aca->lpr); + n_given = SERVER_CMD_OPT_GIVEN(CPSI, NUMPLAYED, cad->aca->lpr); + v_given = SERVER_CMD_OPT_GIVEN(CPSI, VERBOSE, cad->aca->lpr); ret = get_afsi_object_of_row(row, &target_afsi_obj); if (ret < 0) return ret; load_afsi(&target_afsi, &target_afsi_obj); old_afsi = target_afsi; - if (cad->flags & CPSI_FLAG_COPY_LYRICS_ID) + if (cad->copy_all || y_given) target_afsi.lyrics_id = cad->source_afsi.lyrics_id; - if (cad->flags & CPSI_FLAG_COPY_IMAGE_ID) + if (cad->copy_all || i_given) target_afsi.image_id = cad->source_afsi.image_id; - if (cad->flags & CPSI_FLAG_COPY_LASTPLAYED) + if (cad->copy_all || l_given) target_afsi.last_played = cad->source_afsi.last_played; - if (cad->flags & CPSI_FLAG_COPY_NUMPLAYED) + if (cad->copy_all || n_given) target_afsi.num_played = cad->source_afsi.num_played; - if (cad->flags & CPSI_FLAG_COPY_ATTRIBUTES) + if (cad->copy_all || a_given) target_afsi.attributes = cad->source_afsi.attributes; save_afsi(&target_afsi, &target_afsi_obj); /* in-place update */ - if (cad->flags & CPSI_FLAG_VERBOSE) + if (v_given) para_printf(&cad->aca->pbout, "copied afsi to %s\n", name); aced.aft_row = row; aced.old_afsi = &old_afsi; @@ -2288,86 +2275,60 @@ static int copy_selector_info(__a_unused struct osl_table *table, static int com_cpsi_callback(struct afs_callback_arg *aca) { - struct cpsi_action_data cad = { - .flags = *(unsigned *)aca->query.data, - .aca = aca - }; + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(CPSI); + bool a_given, y_given, i_given, l_given, n_given, v_given; + struct cpsi_action_data cad = {.aca = aca}; int ret; - char *source_path = (char *)aca->query.data + sizeof(cad.flags); struct pattern_match_data pmd = { .table = audio_file_table, .loop_col_num = AFTCOL_HASH, .match_col_num = AFTCOL_PATH, - .patterns = {.data = source_path + strlen(source_path) + 1, - .size = aca->query.size - sizeof(cad.flags) - - strlen(source_path) - 1}, + .input_skip = 1, /* skip first argument (source file) */ .data = &cad, .action = copy_selector_info }; - ret = get_afsi_of_path(source_path, &cad.source_afsi); + ret = lls_deserialize_parse_result(aca->query.data, cmd, &aca->lpr); + assert(ret >= 0); + pmd.lpr = aca->lpr; + + a_given = SERVER_CMD_OPT_GIVEN(CPSI, ATTRIBUTE_BITMAP, aca->lpr); + y_given = SERVER_CMD_OPT_GIVEN(CPSI, LYRICS_ID, aca->lpr); + i_given = SERVER_CMD_OPT_GIVEN(CPSI, IMAGE_ID, aca->lpr); + l_given = SERVER_CMD_OPT_GIVEN(CPSI, LASTPLAYED, aca->lpr); + n_given = SERVER_CMD_OPT_GIVEN(CPSI, NUMPLAYED, aca->lpr); + v_given = SERVER_CMD_OPT_GIVEN(CPSI, VERBOSE, aca->lpr); + cad.copy_all = !a_given && !y_given && !i_given && !l_given && !n_given; + + ret = get_afsi_of_path(lls_input(0, aca->lpr), &cad.source_afsi); if (ret < 0) goto out; ret = for_each_matching_row(&pmd); if (ret < 0) goto out; if (pmd.num_matches > 0) { - if (cad.flags & CPSI_FLAG_VERBOSE) + if (v_given) para_printf(&aca->pbout, "updated afsi of %u file(s)\n", pmd.num_matches); } else ret = -E_NO_MATCH; out: + lls_free_parse_result(aca->lpr, cmd); return ret; } -int com_cpsi(struct command_context *cc) +static int com_cpsi(struct command_context *cc, struct lls_parse_result *lpr) { - unsigned flags = 0; - int i; - struct osl_object options = {.data = &flags, .size = sizeof(flags)}; - - for (i = 1; i < cc->argc; i++) { - const char *arg = cc->argv[i]; - if (arg[0] != '-') - break; - if (!strcmp(arg, "--")) { - i++; - break; - } - if (!strcmp(arg, "-y")) { - flags |= CPSI_FLAG_COPY_LYRICS_ID; - continue; - } - if (!strcmp(arg, "-i")) { - flags |= CPSI_FLAG_COPY_IMAGE_ID; - continue; - } - if (!strcmp(arg, "-l")) { - flags |= CPSI_FLAG_COPY_LASTPLAYED; - continue; - } - if (!strcmp(arg, "-n")) { - flags |= CPSI_FLAG_COPY_NUMPLAYED; - continue; - } - if (!strcmp(arg, "-a")) { - flags |= CPSI_FLAG_COPY_ATTRIBUTES; - continue; - } - if (!strcmp(arg, "-v")) { - flags |= CPSI_FLAG_VERBOSE; - continue; - } - break; + const struct lls_command *cmd = SERVER_CMD_CMD_PTR(CPSI); + char *errctx; + int ret = lls(lls_check_arg_count(lpr, 2, INT_MAX, &errctx)); + if (ret < 0) { + send_errctx(cc, errctx); + return ret; } - if (i + 1 >= cc->argc) /* need at least source file and pattern */ - return -E_AFT_SYNTAX; - if (!(flags & ~CPSI_FLAG_VERBOSE)) /* no copy flags given */ - flags = ~(unsigned)CPSI_FLAG_VERBOSE | flags; - return send_option_arg_callback_request(&options, cc->argc - i, - cc->argv + i, com_cpsi_callback, afs_cb_result_handler, cc); + return send_lls_callback_request(com_cpsi_callback, cmd, lpr, cc); } +EXPORT_SERVER_CMD_HANDLER(cpsi); struct change_atts_data { uint64_t add_mask, del_mask; diff --git a/m4/lls/server_cmd.suite.m4 b/m4/lls/server_cmd.suite.m4 index b246db48..b8ee2fc6 100644 --- a/m4/lls/server_cmd.suite.m4 +++ b/m4/lls/server_cmd.suite.m4 @@ -85,6 +85,35 @@ aux_info_prefix = Permissions: Check all playlists for paths not contained in the audio file table. [/help] +[subcommand cpsi] + purpose = copy selected parts of the audio file selector info + non-opts-name = source pattern... + aux_info = AFS_READ | AFS_WRITE + [description] + If no option, or only --verbose is given, all fields of the audio + file selector info structure are copied to each row of the audio file + table whose path matches at least one of the given patterns. Otherwise, + only those fields which correspond to the given options are copied. + [/description] + [option attribute-bitmap] + short_opt = a + summary = copy the attribute bitmap + [option image-id] + short_opt = i + summary = copy the image id + [option lyrics-id] + short_opt = y + summary = copy the lyrics id + [option lastplayed] + short_opt = l + summary = copy the lastplayed timestamp + [option numplayed] + short_opt = n + summary = copy the numplayed counter + [option verbose] + short_opt = v + summary = enable verbose mode + [subcommand ff] purpose = jump N seconds forward or backward synopsis = n[-]