locate: added struct locate_item_list

Instead of passing two parameters around (number of items, array of
items), combine both in a variable size struct.
This commit is contained in:
Max Kellermann 2009-01-24 15:56:30 +01:00
parent e100149124
commit ba7c996266
5 changed files with 112 additions and 88 deletions

View File

@ -833,22 +833,23 @@ static enum command_return
handle_find(struct client *client, int argc, char *argv[])
{
int ret;
struct locate_item *items;
int numItems = locate_item_list_parse(argv + 1,
argc - 1,
&items);
struct locate_item_list *list =
locate_item_list_parse(argv + 1, argc - 1);
if (list == NULL || list->length == 0) {
if (list != NULL)
locate_item_list_free(list);
if (numItems <= 0) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
ret = findSongsIn(client, NULL, numItems, items);
ret = findSongsIn(client, NULL, list->length, list->items);
if (ret == -1)
command_error(client, ACK_ERROR_NO_EXIST,
"directory or file not found");
locate_item_list_free(numItems, items);
locate_item_list_free(list);
return ret;
}
@ -857,22 +858,23 @@ static enum command_return
handle_search(struct client *client, int argc, char *argv[])
{
int ret;
struct locate_item *items;
int numItems = locate_item_list_parse(argv + 1,
argc - 1,
&items);
struct locate_item_list *list =
locate_item_list_parse(argv + 1, argc - 1);
if (list == NULL || list->length == 0) {
if (list != NULL)
locate_item_list_free(list);
if (numItems <= 0) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
ret = searchForSongsIn(client, NULL, numItems, items);
ret = searchForSongsIn(client, NULL, list->length, list->items);
if (ret == -1)
command_error(client, ACK_ERROR_NO_EXIST,
"directory or file not found");
locate_item_list_free(numItems, items);
locate_item_list_free(list);
return ret;
}
@ -881,22 +883,23 @@ static enum command_return
handle_count(struct client *client, int argc, char *argv[])
{
int ret;
struct locate_item *items;
int numItems = locate_item_list_parse(argv + 1,
argc - 1,
&items);
struct locate_item_list *list =
locate_item_list_parse(argv + 1, argc - 1);
if (list == NULL || list->length == 0) {
if (list != NULL)
locate_item_list_free(list);
if (numItems <= 0) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
ret = searchStatsForSongsIn(client, NULL, numItems, items);
ret = searchStatsForSongsIn(client, NULL, list->length, list->items);
if (ret == -1)
command_error(client, ACK_ERROR_NO_EXIST,
"directory or file not found");
locate_item_list_free(numItems, items);
locate_item_list_free(list);
return ret;
}
@ -904,19 +907,20 @@ handle_count(struct client *client, int argc, char *argv[])
static enum command_return
handle_playlistfind(struct client *client, int argc, char *argv[])
{
struct locate_item *items;
int numItems = locate_item_list_parse(argv + 1,
argc - 1,
&items);
struct locate_item_list *list =
locate_item_list_parse(argv + 1, argc - 1);
if (list == NULL || list->length == 0) {
if (list != NULL)
locate_item_list_free(list);
if (numItems <= 0) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
queue_find(client, playlist_get_queue(), numItems, items);
queue_find(client, playlist_get_queue(), list->length, list->items);
locate_item_list_free(numItems, items);
locate_item_list_free(list);
return COMMAND_RETURN_OK;
}
@ -924,19 +928,20 @@ handle_playlistfind(struct client *client, int argc, char *argv[])
static enum command_return
handle_playlistsearch(struct client *client, int argc, char *argv[])
{
struct locate_item *items;
int numItems = locate_item_list_parse(argv + 1,
argc - 1,
&items);
struct locate_item_list *list =
locate_item_list_parse(argv + 1, argc - 1);
if (list == NULL || list->length == 0) {
if (list != NULL)
locate_item_list_free(list);
if (numItems <= 0) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
return COMMAND_RETURN_ERROR;
}
queue_search(client, playlist_get_queue(), numItems, items);
queue_search(client, playlist_get_queue(), list->length, list->items);
locate_item_list_free(numItems, items);
locate_item_list_free(list);
return COMMAND_RETURN_OK;
}
@ -1111,8 +1116,7 @@ handle_clearerror(G_GNUC_UNUSED struct client *client,
static enum command_return
handle_list(struct client *client, int argc, char *argv[])
{
int numConditionals;
struct locate_item *conditionals = NULL;
struct locate_item_list *conditionals;
int tagType = locate_parse_type(argv[1]);
int ret;
@ -1135,25 +1139,26 @@ handle_list(struct client *client, int argc, char *argv[])
mpdTagItemKeys[TAG_ITEM_ALBUM]);
return COMMAND_RETURN_ERROR;
}
conditionals = locate_item_new(mpdTagItemKeys[TAG_ITEM_ARTIST],
argv[2]);
numConditionals = 1;
} else {
numConditionals =
locate_item_list_parse(argv + 2,
argc - 2, &conditionals);
if (numConditionals < 0) {
locate_item_list_parse(argv + 1, argc - 1);
conditionals = locate_item_list_new(1);
conditionals->items[0].tag = TAG_ITEM_ARTIST;
conditionals->items[0].needle = g_strdup(argv[2]);
} else {
conditionals =
locate_item_list_parse(argv + 2, argc - 2);
if (conditionals == NULL) {
command_error(client, ACK_ERROR_ARG,
"not able to parse args");
return COMMAND_RETURN_ERROR;
}
}
ret = listAllUniqueTags(client, tagType, numConditionals, conditionals);
ret = listAllUniqueTags(client, tagType, conditionals->length,
conditionals->items);
if (conditionals)
locate_item_list_free(numConditionals, conditionals);
locate_item_list_free(conditionals);
if (ret == -1)
command_error(client, ACK_ERROR_NO_EXIST,

View File

@ -92,20 +92,21 @@ searchForSongsIn(struct client *client, const char *name,
{
int ret;
int i;
struct locate_item *new_items =
g_memdup(items, sizeof(items[0]) * numItems);
struct locate_item_list *new_list;
struct search_data data;
new_list = locate_item_list_new(numItems);
for (i = 0; i < numItems; i++)
new_items[i].needle = g_utf8_casefold(new_items[i].needle, -1);
new_list->items[i].needle =
g_utf8_casefold(items[i].needle, -1);
data.client = client;
data.array.numItems = numItems;
data.array.items = new_items;
data.array.items = new_list->items;
ret = db_walk(name, searchInDirectory, NULL, &data);
locate_item_list_free(numItems, new_items);
locate_item_list_free(new_list);
return ret;
}

View File

@ -76,45 +76,45 @@ locate_item_new(const char *type_string, const char *needle)
}
void
locate_item_list_free(int count, struct locate_item *array)
locate_item_list_free(struct locate_item_list *list)
{
int i;
for (unsigned i = 0; i < list->length; ++i)
g_free(list->items[i].needle);
for (i = 0; i < count; i++)
free(array[i].needle);
free(array);
g_free(list);
}
int
locate_item_list_parse(char *argv[], int argc, struct locate_item **arrayRet)
struct locate_item_list *
locate_item_list_new(unsigned length)
{
int i, j;
struct locate_item *item;
struct locate_item_list *list;
if (argc == 0)
return 0;
list = g_malloc0(sizeof(*list) - sizeof(list->items[0]) +
length * sizeof(list->items[0]));
list->length = length;
return list;
}
struct locate_item_list *
locate_item_list_parse(char *argv[], int argc)
{
struct locate_item_list *list;
if (argc % 2 != 0)
return -1;
return NULL;
*arrayRet = g_new(struct locate_item, argc / 2);
list = locate_item_list_new(argc / 2);
for (i = 0, item = *arrayRet; i < argc / 2; i++, item++) {
if (!locate_item_init(item, argv[i * 2], argv[i * 2 + 1]))
goto fail;
for (unsigned i = 0; i < list->length; ++i) {
if (!locate_item_init(&list->items[i], argv[i * 2],
argv[i * 2 + 1])) {
locate_item_list_free(list);
return NULL;
}
}
return argc / 2;
fail:
for (j = 0; j < i; j++) {
free((*arrayRet)[j].needle);
}
free(*arrayRet);
*arrayRet = NULL;
return -1;
return list;
}
void

View File

@ -34,6 +34,17 @@ struct locate_item {
char *needle;
};
/**
* An array of struct locate_item objects.
*/
struct locate_item_list {
/** number of items */
unsigned length;
/** this is a variable length array */
struct locate_item items[1];
};
int
locate_parse_type(const char *str);
@ -41,12 +52,19 @@ locate_parse_type(const char *str);
struct locate_item *
locate_item_new(const char *type_string, const char *needle);
/**
* Allocates a new struct locate_item_list, and initializes all
* members with zero bytes.
*/
struct locate_item_list *
locate_item_list_new(unsigned length);
/* return number of items or -1 on error */
int
locate_item_list_parse(char *argv[], int argc, struct locate_item **arrayRet);
struct locate_item_list *
locate_item_list_parse(char *argv[], int argc);
void
locate_item_list_free(int count, struct locate_item *array);
locate_item_list_free(struct locate_item_list *list);
void
locate_item_free(struct locate_item *item);

View File

@ -84,20 +84,20 @@ queue_search(struct client *client, const struct queue *queue,
unsigned num_items, const struct locate_item *items)
{
unsigned i;
struct locate_item *new_items =
g_memdup(items, sizeof(items[0]) * num_items);
struct locate_item_list *new_list = locate_item_list_new(num_items);
for (i = 0; i < num_items; i++)
new_items[i].needle = g_utf8_casefold(new_items[i].needle, -1);
new_list->items[i].needle =
g_utf8_casefold(items[i].needle, -1);
for (i = 0; i < queue_length(queue); i++) {
const struct song *song = queue_get(queue, i);
if (locate_song_search(song, num_items, new_items))
if (locate_song_search(song, num_items, new_list->items))
queue_print_song_info(client, queue, i);
}
locate_item_list_free(num_items, new_items);
locate_item_list_free(new_list);
}
void