📄 playtree.c
字号:
#include "config.h"#include <stdlib.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#ifdef MP_DEBUG#include <assert.h>#endif#include "m_config.h"#include "playtree.h"#include "mp_msg.h"static intplay_tree_is_valid(play_tree_t* pt);play_tree_t*play_tree_new(void) { play_tree_t* r = (play_tree_t*)calloc(1,sizeof(play_tree_t)); if(r == NULL) mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",sizeof(play_tree_t)); r->entry_type = PLAY_TREE_ENTRY_NODE; return r;}voidplay_tree_free(play_tree_t* pt, int childs) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL);#endif if(childs) { for(iter = pt->child; iter != NULL; ) { play_tree_t* nxt=iter->next; play_tree_free(iter,1); iter = nxt; } pt->child = NULL; } play_tree_remove(pt,0,0); for(iter = pt->child ; iter != NULL ; iter = iter->next) iter->parent = NULL; //if(pt->params) free(pt->params); if(pt->files) { int i; for(i = 0 ; pt->files[i] != NULL ; i++) free(pt->files[i]); free(pt->files); } free(pt);}voidplay_tree_free_list(play_tree_t* pt, int childs) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL);#endif for(iter = pt ; iter->prev != NULL ; iter = iter->prev) /* NOTHING */; while(iter) { play_tree_t* nxt = iter->next; play_tree_free(iter,childs); iter = nxt; } }voidplay_tree_append_entry(play_tree_t* pt, play_tree_t* entry) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL);#endif if(pt == entry) return; for(iter = pt ; iter->next != NULL ; iter = iter->next) /* NOTHING */; entry->parent = iter->parent; entry->prev = iter; entry->next = NULL; iter->next = entry;}voidplay_tree_prepend_entry(play_tree_t* pt, play_tree_t* entry) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL);#endif for(iter = pt ; iter->prev != NULL; iter = iter->prev) /* NOTHING */; entry->prev = NULL; entry->next = iter; entry->parent = iter->parent; iter->prev = entry; if(entry->parent) {#ifdef MP_DEBUG assert(entry->parent->child == iter);#endif entry->parent->child = entry; }}voidplay_tree_insert_entry(play_tree_t* pt, play_tree_t* entry) { #ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL);#endif entry->parent = pt->parent; entry->prev = pt; if(pt->next) {#ifdef MP_DEBUG assert(pt->next->prev == pt);#endif entry->next = pt->next; entry->next->prev = entry; } else entry->next = NULL; pt->next = entry;} voidplay_tree_remove(play_tree_t* pt, int free_it,int with_childs) {#ifdef MP_DEBUG assert(pt != NULL);#endif // Middle of list if(pt->prev && pt->next) {#ifdef MP_DEBUG assert(pt->prev->next == pt); assert(pt->next->prev == pt);#endif pt->prev->next = pt->next; pt->next->prev = pt->prev; } // End of list else if(pt->prev) { #ifdef MP_DEBUG assert(pt->prev->next == pt);#endif pt->prev->next = NULL; } // Begining of list else if(pt->next) {#ifdef MP_DEBUG assert(pt->next->prev == pt);#endif pt->next->prev = NULL; if(pt->parent) {#ifdef MP_DEBUG assert(pt->parent->child == pt);#endif pt->parent->child = pt->next; } } // The only one else if(pt->parent) {#ifdef MP_DEBUG assert(pt->parent->child == pt);#endif pt->parent->child = NULL; } pt->prev = pt->next = pt->parent = NULL; if(free_it) play_tree_free(pt,with_childs);}voidplay_tree_set_child(play_tree_t* pt, play_tree_t* child) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL); assert(pt->entry_type == PLAY_TREE_ENTRY_NODE);#endif //DEBUG_FF: Where are the childs freed ? // Attention in using this function! for(iter = pt->child ; iter != NULL ; iter = iter->next) iter->parent = NULL; // Go back to first one for(iter = child ; iter->prev != NULL ; iter = iter->prev) /* NOTHING */; pt->child = iter; for( ; iter != NULL ; iter= iter->next) iter->parent = pt;}voidplay_tree_set_parent(play_tree_t* pt, play_tree_t* parent) { play_tree_t* iter;#ifdef MP_DEBUG assert(pt != NULL);#endif if(pt->parent) pt->parent->child = NULL; for(iter = pt ; iter != NULL ; iter = iter->next) iter->parent = parent; if(pt->prev) { for(iter = pt->prev ; iter->prev != NULL ; iter = iter->prev) iter->parent = parent; iter->parent = parent; parent->child = iter; } else parent->child = pt;} voidplay_tree_add_file(play_tree_t* pt,char* file) { int n = 0; char* e;#ifdef MP_DEBUG assert(pt != NULL); assert(pt->child == NULL); assert(file != NULL);#endif if(pt->entry_type != PLAY_TREE_ENTRY_NODE && pt->entry_type != PLAY_TREE_ENTRY_FILE) return; if(pt->files) { for(n = 0 ; pt->files[n] != NULL ; n++) /* NOTHING */; } pt->files = (char**)realloc(pt->files,(n+2)*sizeof(char*)); if(pt->files ==NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(n+2)*sizeof(char*)); return; } e = pt->files[n] = strdup(file); pt->files[n+1] = NULL; pt->entry_type = PLAY_TREE_ENTRY_FILE;}intplay_tree_remove_file(play_tree_t* pt,char* file) { int n,f = -1;#ifdef MP_DEBUG assert(pt != NULL); assert(file != NULL); assert(pt->entry_type != PLAY_TREE_ENTRY_NODE);#endif for(n=0 ; pt->files[n] != NULL ; n++) { if(strcmp(file,pt->files[n]) == 0) f = n; } if(f < 0) // Not found return 0;#ifdef MP_DEBUG assert(n > f);#endif free(pt->files[f]); if(n > 1) { memmove(&pt->files[f],&pt->files[f+1],(n-f)*sizeof(char*)); pt->files = (char**)realloc(pt->files,n*sizeof(char*)); if(pt->files == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",(n+2)*sizeof(char*)); return -1; } } else { free(pt->files); pt->files = NULL; } return 1;}voidplay_tree_set_param(play_tree_t* pt, char* name, char* val) { int n = 0,ni = -1;#ifdef MP_DEBUG assert(pt != NULL); assert(name != NULL);#endif if(pt->params) { for( ; pt->params[n].name != NULL ; n++) { if(strcasecmp(pt->params[n].name,name) == 0) ni = n; } } if(ni > 0) { if(pt->params[n].value != NULL) free(pt->params[n].value); pt->params[n].value = val != NULL ? strdup(val) : NULL; return; } pt->params = (play_tree_param_t*)realloc(pt->params,(n+2)*sizeof(play_tree_param_t)); if(pt->params == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't realloc params (%d bytes of memory)\n",(n+2)*sizeof(play_tree_param_t)); return; } pt->params[n].name = strdup(name); pt->params[n].value = val != NULL ? strdup(val) : NULL; memset(&pt->params[n+1],0,sizeof(play_tree_param_t)); return;}intplay_tree_unset_param(play_tree_t* pt, char* name) { int n,ni = -1;#ifdef MP_DEBUG assert(pt != NULL); assert(name != NULL); assert(pt->params != NULL);#endif for(n = 0 ; pt->params[n].name != NULL ; n++) { if(strcasecmp(pt->params[n].name,name) == 0) ni = n; } if(ni < 0) return 0; if(pt->params[ni].name) free(pt->params[ni].name); if(pt->params[ni].value) free(pt->params[ni].value); if(n > 1) { memmove(&pt->params[ni],&pt->params[ni+1],(n-ni)*sizeof(play_tree_param_t)); pt->params = (play_tree_param_t*)realloc(pt->params,n*sizeof(play_tree_param_t)); if(pt->params == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",n*sizeof(play_tree_param_t)); return -1; } } else { free(pt->params); pt->params = NULL; } return 1;}voidplay_tree_set_params_from(play_tree_t* dest,play_tree_t* src) { int i;#ifdef MP_DEBUG assert(dest != NULL); assert(src != NULL);#endif if(!src->params) return; for(i = 0; src->params[i].name != NULL ; i++) play_tree_set_param(dest,src->params[i].name,src->params[i].value); if(src->flags & PLAY_TREE_RND) // pass the random flag too dest->flags |= PLAY_TREE_RND;}// all childs if deep < 0voidplay_tree_set_flag(play_tree_t* pt, int flags , int deep) { play_tree_t* i; pt->flags |= flags; if(deep && pt->child) { if(deep > 0) deep--; for(i = pt->child ; i ; i = i->next) play_tree_set_flag(i,flags,deep); }}voidplay_tree_unset_flag(play_tree_t* pt, int flags , int deep) { play_tree_t* i; pt->flags &= ~flags; if(deep && pt->child) { if(deep > 0) deep--; for(i = pt->child ; i ; i = i->next) play_tree_unset_flag(i,flags,deep); }}//////////////////////////////////// ITERATOR //////////////////////////////////////static void play_tree_iter_push_params(play_tree_iter_t* iter) { int n; play_tree_t* pt;#ifdef MP_DEBUG assert(iter != NULL); assert(iter->config != NULL); assert(iter->tree != NULL);#endif pt = iter->tree; // We always push a config because we can set some option // while playing m_config_push(iter->config); if(pt->params == NULL) return; for(n = 0; pt->params[n].name != NULL ; n++) { int e; if((e = m_config_set_option(iter->config,pt->params[n].name,pt->params[n].value)) < 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error %d while setting option '%s' with value '%s'\n",e, pt->params[n].name,pt->params[n].value); } } if(!pt->child) iter->entry_pushed = 1; return;}play_tree_iter_t*play_tree_iter_new(play_tree_t* pt,m_config_t* config) { play_tree_iter_t* iter;#ifdef MP_DEBUG assert(pt != NULL); assert(config != NULL);#endif if( ! play_tree_is_valid(pt)) return NULL; iter = (play_tree_iter_t*)calloc(1,sizeof(play_tree_iter_t)); if(! iter) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate new iterator (%d bytes of memory)\n",sizeof(play_tree_iter_t));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -