From 1f118ea90dd0a22bd40e76a96900ffb36aa93134 Mon Sep 17 00:00:00 2001 From: Warren Dukes Date: Fri, 12 Nov 2004 01:44:27 +0000 Subject: now more flexible list, search, find, where you can enter pairs of "conditionals". Note that logical and is implied. git-svn-id: https://svn.musicpd.org/mpd/trunk@2624 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- src/command.c | 44 ++++++++++++------- src/dbUtils.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++----------- src/dbUtils.h | 15 +++++-- 3 files changed, 152 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/command.c b/src/command.c index e2bf84460..248fa1542 100644 --- a/src/command.c +++ b/src/command.c @@ -444,17 +444,18 @@ int handleFind(FILE * fp, unsigned int * permission, int argArrayLength, { int ret; - LocateTagItem * item = newLocateTagItem(argArray[1], argArray[2]); + LocateTagItem * items; + int numItems = newLocateTagItemArrayFromArgArray(argArray+1, + argArrayLength-1, &items); - if(!item) { - commandError(fp, ACK_ERROR_ARG, "\%s\" isn't recognized", - argArray[1]); + if(numItems <= 0) { + commandError(fp, ACK_ERROR_ARG, "incorrect ags", NULL); return -1; } - ret = findSongsIn(fp, NULL, item); + ret = findSongsIn(fp, NULL, numItems, items); - freeLocateTagItem(item); + freeLocateTagItemArray(numItems, items); return ret; } @@ -464,17 +465,18 @@ int handleSearch(FILE * fp, unsigned int * permission, int argArrayLength, { int ret; - LocateTagItem * item = newLocateTagItem(argArray[1], argArray[2]); + LocateTagItem * items; + int numItems = newLocateTagItemArrayFromArgArray(argArray+1, + argArrayLength-1, &items); - if(!item) { - commandError(fp, ACK_ERROR_ARG, "\%s\" isn't recognized", - argArray[1]); + if(numItems <= 0) { + commandError(fp, ACK_ERROR_ARG, "incorrect ags", NULL); return -1; } - ret = searchForSongsIn(fp, NULL, item); + ret = searchForSongsIn(fp, NULL, numItems, items); - freeLocateTagItem(item); + freeLocateTagItemArray(numItems, items); return ret; } @@ -636,10 +638,20 @@ int handleList(FILE * fp, unsigned int * permission, int argArrayLength, argArray[2]); numConditionals = 1; } + else { + numConditionals = newLocateTagItemArrayFromArgArray(argArray+2, + argArrayLength-2, &conditionals); + + if(numConditionals < 0) { + commandError(fp, ACK_ERROR_ARG, + "not able to parse args", NULL); + return -1; + } + } ret = listAllUniqueTags(fp, tagType, numConditionals,conditionals); - if(conditionals) free(conditionals); + if(conditionals) freeLocateTagItemArray(numConditionals, conditionals); return ret; } @@ -904,8 +916,8 @@ void initCommands() { addCommand(COMMAND_LSINFO ,PERMISSION_READ, 0, 1,handleLsInfo,NULL); addCommand(COMMAND_RM ,PERMISSION_CONTROL, 1, 1,handleRm,NULL); addCommand(COMMAND_PLAYLISTINFO,PERMISSION_READ, 0, 1,handlePlaylistInfo,NULL); - addCommand(COMMAND_FIND ,PERMISSION_READ, 2, 2,handleFind,NULL); - addCommand(COMMAND_SEARCH ,PERMISSION_READ, 2, 2,handleSearch,NULL); + addCommand(COMMAND_FIND ,PERMISSION_READ, 2,-1,handleFind,NULL); + addCommand(COMMAND_SEARCH ,PERMISSION_READ, 2,-1,handleSearch,NULL); addCommand(COMMAND_UPDATE ,PERMISSION_ADMIN, 0, 1,handleUpdate,listHandleUpdate); addCommand(COMMAND_NEXT ,PERMISSION_CONTROL, 0, 0,handleNext,NULL); addCommand(COMMAND_PREVIOUS ,PERMISSION_CONTROL, 0, 0,handlePrevious,NULL); @@ -915,7 +927,7 @@ void initCommands() { addCommand(COMMAND_RANDOM ,PERMISSION_CONTROL, 1, 1,handleRandom,NULL); addCommand(COMMAND_STATS ,PERMISSION_READ, 0, 0,handleStats,NULL); addCommand(COMMAND_CLEAR_ERROR ,PERMISSION_CONTROL, 0, 0,handleClearError,NULL); - addCommand(COMMAND_LIST ,PERMISSION_READ, 1, 2,handleList,NULL); + addCommand(COMMAND_LIST ,PERMISSION_READ, 1,-1,handleList,NULL); addCommand(COMMAND_MOVE ,PERMISSION_CONTROL, 2, 2,handleMove,NULL); addCommand(COMMAND_MOVEID ,PERMISSION_CONTROL, 2, 2,handleMoveId,NULL); addCommand(COMMAND_SWAP ,PERMISSION_CONTROL, 2, 2,handleSwap,NULL); diff --git a/src/dbUtils.c b/src/dbUtils.c index dd698789c..9c08c8020 100644 --- a/src/dbUtils.c +++ b/src/dbUtils.c @@ -11,12 +11,17 @@ #define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10 #define LOCATE_TAG_FILE_KEY "filename" -typedef struct ListCommandItem { +typedef struct _ListCommandItem { mpd_sint8 tagType; int numConditionals; LocateTagItem * conditionals; } ListCommandItem; +typedef struct _LocateTagItemArray { + int numItems; + LocateTagItem * items; +} LocateTagItemArray; + int getLocateTagItemType(char * str) { int i; @@ -31,21 +36,67 @@ int getLocateTagItemType(char * str) { return -1; } +static int initLocateTagItem(LocateTagItem * item, char * typeStr, + char * needle) +{ + item->tagType = getLocateTagItemType(typeStr); + + if(item->tagType < 0) return -1; + + item->needle = strdup(needle); + + return 0; +} + LocateTagItem * newLocateTagItem(char * typeStr, char * needle) { LocateTagItem * ret = malloc(sizeof(LocateTagItem)); - ret->tagType = getLocateTagItemType(typeStr); - - if(ret->tagType < 0) { + if(initLocateTagItem(ret, typeStr, needle) < 0) { free(ret); - return NULL; + ret = NULL; } - ret->needle = strdup(needle); - return ret; } +void freeLocateTagItemArray(int count, LocateTagItem * array) { + int i; + + for(i = 0; i < count; i++) free(array[i].needle); + + free(array); +} + +int newLocateTagItemArrayFromArgArray(char * argArray[], + int numArgs, + LocateTagItem ** arrayRet) +{ + int i,j; + LocateTagItem * item; + + if(numArgs == 0) return 0; + + if(numArgs%2 != 0) return -1; + + *arrayRet = malloc(sizeof(LocateTagItem)*numArgs/2); + + for(i = 0, item = *arrayRet; i < numArgs/2; i++, item++) { + if(initLocateTagItem(item, argArray[i*2], argArray[i*2+1]) < 0) + goto fail; + } + + return numArgs/2; + +fail: + for(j = 0; j < i; j++) { + free((*arrayRet)[j].needle); + } + + free(*arrayRet); + *arrayRet = NULL; + return -1; +} + void freeLocateTagItem(LocateTagItem * item) { free(item->needle); free(item); @@ -96,25 +147,48 @@ static inline int strstrSearchTag(Song * song, int type, char * str) { return ret; } -int searchInDirectory(FILE * fp, Song * song, void * item) { - if(strstrSearchTag(song, ((LocateTagItem *)item)->tagType, - ((LocateTagItem *)item)->needle)) { - printSongInfo(fp, song); +int searchInDirectory(FILE * fp, Song * song, void * data) { + LocateTagItemArray * array = data; + int i; + + for(i = 0; i < array->numItems; i++) { + if(!strstrSearchTag(song, array->items[i].tagType, + array->items[i].needle)) + { + return 0; + } } + + printSongInfo(fp, song); + return 0; } -int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item) { - char * originalNeedle = item->needle; +int searchForSongsIn(FILE * fp, char * name, int numItems, + LocateTagItem * items) +{ int ret = -1; + int i; - item->needle = strDupToUpper(originalNeedle); + char ** originalNeedles = malloc(numItems*sizeof(char *)); + LocateTagItemArray array; - ret = traverseAllIn(fp,name,searchInDirectory, NULL, - (void *)item); + for(i = 0; i < numItems; i++) { + originalNeedles[i] = items[i].needle; + items[i].needle = strDupToUpper(originalNeedles[i]); + } - free(item->needle); - item->needle = originalNeedle; + array.numItems = numItems; + array.items = items; + + ret = traverseAllIn(fp,name,searchInDirectory, NULL, &array); + + for(i = 0; i < numItems; i++) { + free(items[i].needle); + items[i].needle = originalNeedles[i]; + } + + free(originalNeedles); return ret; } @@ -137,17 +211,31 @@ static inline int tagItemFoundAndMatches(Song * song, int type, char * str) { return 0; } -int findInDirectory(FILE * fp, Song * song, void * item) { - if(tagItemFoundAndMatches(song, ((LocateTagItem *)item)->tagType, - ((LocateTagItem *)item)->needle)) { - printSongInfo(fp, song); +int findInDirectory(FILE * fp, Song * song, void * data) { + LocateTagItemArray * array = data; + int i; + + for(i = 0; i < 0; i++) { + if(!tagItemFoundAndMatches(song, array->items[i].tagType, + array->items[i].needle)) + { + return 0; + } } + + printSongInfo(fp, song); + return 0; } -int findSongsIn(FILE * fp, char * name, LocateTagItem * item) { +int findSongsIn(FILE * fp, char * name, int numItems, LocateTagItem * items) { + LocateTagItemArray array; + + array.numItems = numItems; + array.items = items; + return traverseAllIn(fp, name, findInDirectory, NULL, - (void *)item); + (void *)&array); } int printAllIn(FILE * fp, char * name) { diff --git a/src/dbUtils.h b/src/dbUtils.h index a24311a5a..f79894bb6 100644 --- a/src/dbUtils.h +++ b/src/dbUtils.h @@ -12,10 +12,17 @@ typedef struct _LocateTagItem { char * needle; } LocateTagItem; +int getLocateTagItemType(char * str); + /* returns NULL if not a known type */ LocateTagItem * newLocateTagItem(char * typeString, char * needle); -int getLocateTagItemType(char * str); +/* return number of items or -1 on error */ +int newLocateTagItemArrayFromArgArray(char * argArray[], int numArgs, + LocateTagItem ** arrayRet); + + +void freeLocateTagItemArray(int count, LocateTagItem * array); void freeLocateTagItem(LocateTagItem * item); @@ -25,9 +32,11 @@ int addAllIn(FILE * fp, char * name); int printInfoForAllIn(FILE * fp, char * name); -int searchForSongsIn(FILE * fp, char * name, LocateTagItem * item); +int searchForSongsIn(FILE * fp, char * name, int numItems, + LocateTagItem * items); -int findSongsIn(FILE * fp, char * name, LocateTagItem * item); +int findSongsIn(FILE * fp, char * name, int numItems, + LocateTagItem * items); int countSongsIn(FILE * fp, char * name); -- cgit v1.2.3