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
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
							
								
								
									
										136
									
								
								src/dbUtils.c
									
									
									
									
									
								
							
							
						
						
									
										136
									
								
								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) { | ||||
|   | ||||
| @@ -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); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Warren Dukes
					Warren Dukes