static void replace(char **s, const char *n) { mc_free(*s); if (n == NULL) { *s = mc_strdup(""); } else { *s = mc_strdup(n); } }
static char *getExt(const char *filename) { int i = strlen(filename) - 1; for (; i >= 0 && filename[i] != '.'; i--) ; if (i < 0) { return mc_strdup(""); } else { return mc_strdup(&filename[i + 1]); } }
static audio_result_t init(audio_worker_t* worker, const char* file_or_url, el_bool file) { //static int ogg_initialized = 0; //static int ogg_error = 0; ogg_t* ogg=(ogg_t*) mc_malloc(sizeof(ogg_t)); worker->can_seek = can_seek; worker->play = play; worker->pause = pause; worker->seek = seek; worker->guard = guard; worker->destroy = destroy; worker->length_in_ms = length_in_ms; worker->load_file = load_file; worker->load_url = load_url; worker->set_volume = set_volume; worker->worker_data = (void*) ogg; ogg->volume_scale = 1.0; ogg->client_notification = worker->fifo; ogg->player_control = audio_event_fifo_new(); //int error; ogg->is_open = el_false; ogg->length = -1; //sem_init(&ogg->length_set, 0, 0); ogg->length_set = psem_new(0); ogg->buffer = (char*) mc_malloc(BUFFER_SIZE(ogg)); ogg->ao_handle = aodev_new(); if (file) { ogg->can_seek = el_true; ogg->is_file = el_true; ogg->file_or_url = mc_strdup(file_or_url); post_event(ogg->player_control, INTERNAL_CMD_LOAD_FILE, -1); } else { // URL ogg->can_seek = el_false; ogg->is_file = el_false; ogg->file_or_url = mc_strdup(file_or_url); post_event(ogg->player_control, INTERNAL_CMD_LOAD_URL, -1); } int thread_id = pthread_create(&ogg->player_thread, NULL, player_thread, ogg); // wait until fully loaded (length is set) psem_wait(ogg->length_set); return AUDIO_OK; }
static scan_result_t scan_cb(scan_job_t* job, el_bool ready, const char* msg, const char* submsg, int n, int of_n) { scanjob_info_t* info = (scanjob_info_t*) mc_malloc(sizeof(scanjob_info_t)); info->ready = ready; info->msg = mc_strdup(msg); info->submsg = mc_strdup(submsg); info->n = n; info->of_n = of_n; scanjob_fifo_enqueue(job->fifo, info); return (job->cancelled) ? SCAN_CANCEL : SCAN_CONTINUE; }
void xs_env_set(xsMachine *the) { mc_env_t *env; char *val, *name; int pos; int argc = xsToInteger(xsArgc); if (argc < 1) return; env = xsGetHostData(xsThis); if (1 == argc || xsTypeOf(xsArg(1)) == xsUndefinedType) { int result; name = xsToString(xsArg(0)); result = mc_env_unset(env, name); xsSetBoolean(xsResult, result == 0); } else { if ((val = mc_strdup(xsToString(xsArg(1)))) == NULL) return; pos = argc > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType ? xsToInteger(xsArg(2)) : -1; name = xsToString(xsArg(0)); mc_env_set(env, name, val, pos); mc_free(val); } }
void library_view_col_order_set(GtkTreeViewColumn* col, library_view_t* view) { if (view->column_layout_changing) { return; } long long hash = playlist_model_tracks_hash(view->playlist_model); // column order int i; GList *cols = gtk_tree_view_get_columns(view->tview); char* val = mc_strdup(""); char* comma = ""; for(i = 0; i < PLAYLIST_MODEL_N_COLUMNS; ++i) { int k = g_list_index(cols, (gpointer) view->cols[i]); char pos[100]; sprintf(pos,"%s%d", comma, k); char* v1 = hre_concat(val, pos); mc_free(val); val = v1; comma = ","; } { char cfgitem[200]; sprintf(cfgitem,"library.cols.hash_%lld.%s", hash, "order"); el_config_set_string(btb_config(view->btb), cfgitem, val); mc_free(val); } }
static audio_result_t load_url(void* _minfo, const char* url) { ogg_t* minfo = (ogg_t*) _minfo; minfo->file_or_url = mc_strdup(url); post_event(minfo->player_control, INTERNAL_CMD_LOAD_URL, -1); psem_wait(minfo->length_set); return AUDIO_OK; }
static char *getFilePart(const char *s) { int i, j; for (i = 0; s[i] != '"' && s[i] != '\0'; i++) ; char *fl = mc_strdup(&s[i]); for (i = strlen(fl) - 1; i >= 0 && fl[i] != '"'; i--) ; fl[i + 1] = '\0'; return fl; }
static audio_result_t load_file(void* _mp3_info, const char* file) { mp3_t* mp3_info = (mp3_t*) _mp3_info; mc_free(mp3_info->file_or_url); mp3_info->file_or_url = mc_strdup(file); post_event(mp3_info->player_control, INTERNAL_CMD_LOAD_FILE, -1); psem_wait(mp3_info->length_set); return AUDIO_OK; }
static char *trim(const char *line) { int i, j; for (i = 0; line[i] != '\0' && isspace(line[i]); i++) ; char *k = mc_strdup(&line[i]); for (j = strlen(k) - 1; j >= 0 && isspace(k[j]); j--) ; if (j >= 0) { k[j + 1] = '\0'; } return k; }
el_bool ccover_get_composer(ccover_t cc, const char* filename, char** composer) { CCover* c = (CCover*) cc; TagLib::FileRef ref(filename); std::string s; if (c->GetComposer(ref, s)) { *composer = mc_strdup(s.c_str()); return el_true; } else { *composer = NULL; return el_false; } }
static char *stripExt(const char *_path, const char *ext) { char *path = mc_strdup(_path); if (path == NULL) { return NULL; } else if (isExt(path, ext)) { int l = strlen(path) - strlen(ext); if (l > 0) { path[l] = '\0'; } } return path; }
static data_entry_t *mydata_entry_new(const char *path, cue_entry_t * entry, struct stat *st) { data_entry_t *e = (data_entry_t *) mc_malloc(sizeof(data_entry_t)); e->path = mc_strdup(path); e->entry = entry; e->open_count = 0; if (st != NULL) { struct stat *stn = (struct stat *)mc_malloc(sizeof(struct stat)); memcpy((void *)stn, (void *)st, sizeof(struct stat)); e->st = stn; } else { e->st = NULL; } }
static void web_set_url_cover_art(GtkClipboard* board, const gchar* uri, gpointer p) { library_view_t* view = (library_view_t* ) p; if (uri != NULL) { char* image_uri = mc_strdup(uri); hre_trim(image_uri); log_debug3("got uri %s, view = %p", image_uri, view); if ((strncasecmp(image_uri, "http://", 7) == 0) || (strncasecmp(image_uri, "https://", 8) == 0)) { GtkTreeSelection* sel = gtk_tree_view_get_selection(view->tview); GtkTreeModel* model; GtkTreeIter iter; log_debug2("tree selection: %p", sel); if (gtk_tree_selection_get_selected(sel, &model, &iter)) { log_debug("ok"); int row = gtk_list_model_iter_to_row(GTK_LIST_MODEL(model), iter); track_t* track = playlist_model_get_track(view->playlist_model, row); log_debug2("track = %p", track); const char* artid = track_get_artid(track); log_debug3("fetch image %s, %s", image_uri, artid); fetch_image(image_uri, artid, image_fetched, view); } else { GtkMessageDialog* dialog = GTK_MESSAGE_DIALOG( gtk_message_dialog_new(btb_main_window(view->btb), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Please select a track to set the cover art for") ) ); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET(dialog)); } } else { GtkMessageDialog* dialog = GTK_MESSAGE_DIALOG( gtk_message_dialog_new (btb_main_window(view->btb), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Copy an http URL for an image to the clipboard") ) ); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET(dialog)); } mc_free(image_uri); } }
segmenter_t *segmenter_new() { segmenter_t *s = (segmenter_t *) mc_malloc(sizeof(segmenter_t)); s->memory_block = NULL; s->size = -1; s->last_result = SEGMENTER_NONE; s->segment.filename = mc_strdup(""); s->segment.artist = mc_strdup(""); s->segment.album = mc_strdup(""); s->segment.album_artist = mc_strdup(""); s->segment.title = mc_strdup(""); s->segment.composer = mc_strdup(""); s->segment.comment = mc_strdup(""); s->segment.genre = mc_strdup(""); s->segment.track = -1; s->stream = NULL; return s; }
void read_in_sizes(const char *from_file) { FILE *f = fopen(from_file, "rt"); if (f==NULL) { return; } char *line = (char *) mc_malloc(10240*sizeof(char)); if (fgets(line, 10240, f) != NULL) { char *ln = trim(line); if (strcmp(ln, VFILESIZE_FILE_TYPE) == 0) { if (fgets(line, 10240, f) != NULL) { char *ln1 = trim(line); if (strcmp(ln1, VFILESIZE_FILE_VERSION) == 0) { while (fgets(line, 10240, f) != NULL) { char *ln2 = trim(line); char *vfile = mc_strdup( ln2 ); fgets(line, 10240, f); char *ln3 = trim( line ); size_t size = (size_t) strtoul(ln3, NULL, 10); fgets(line, 10240, f); char *ln4 = trim (line); time_t mtime = (time_t) strtoul(ln4, NULL, 10); put_size( vfile, size, mtime ); mc_free( vfile); mc_free( ln4 ); mc_free( ln3 ); mc_free( ln2 ); } } mc_free( ln1 ); } } mc_free( ln ); } mc_free(line); fclose(f); }
char *readln(const char *prompt, playlist_player_t* player) { hre_t re_empty_line = hre_compile("^\\s*$",""); char* line; el_bool stop = el_false; while (!stop && (line = readline(prompt)) != NULL) { if (hre_has_match(re_empty_line, line)) { // do nothing } else { stop = el_true; } p_player(player); } if (line != NULL) { add_history(line); mc_take_control(line, strlen(line)+1); } else { line = mc_strdup(""); } return line; }
static gboolean library_view_update_info(library_view_t* view) { if (view->run_timeout) { // update play buttons playlist_player_t* player = backtobasics_player(view->btb); if (view->btn_play == NULL) { view->btn_play = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_play")); } if (view->btn_pause == NULL) { view->btn_pause = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_library_pause")); } GtkWidget* btn_play = view->btn_play; GtkWidget* btn_pause = view->btn_pause; if (!playlist_player_is_playing(player)) { if (!gtk_widget_get_visible(btn_play)) gtk_widget_show_all(btn_play); if (gtk_widget_get_visible(btn_pause)) gtk_widget_hide(btn_pause); } else if (playlist_player_is_playing(player)) { if (gtk_widget_get_visible(btn_play)) gtk_widget_hide(btn_play); if (!gtk_widget_get_visible(btn_pause)) gtk_widget_show_all(btn_pause); } // update slider and time long tr_tm = playlist_player_get_track_position_in_ms(player); track_t* track = playlist_player_get_track(player); int index = playlist_player_get_track_index(player); int a = tr_tm / 1000; int b = view->time_in_ms / 1000; if (a != b) { view->time_in_ms = tr_tm; int min = tr_tm / 1000 / 60; int sec = (tr_tm / 1000) % 60; { char s[200]; sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_time")); gtk_label_set_markup(lbl, s); // update presets reflect_presets(view->btb); } GtkScale* sc_playback = GTK_SCALE(gtk_builder_get_object(view->builder, "sc_library_playback")); double perc = 0.0; if (track != NULL) { int len_in_ms = track_get_length_in_ms(track); if (len_in_ms != view->len_in_ms) { view->len_in_ms = len_in_ms; int min = len_in_ms / 1000 / 60; int sec = (len_in_ms / 1000) % 60; { char s[200]; sprintf(s,"<span size=\"x-small\"><b><i>%02d:%02d</i></b></span>", min, sec); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_total")); gtk_label_set_markup(lbl, s); } } perc = (((double) tr_tm) / ((double) len_in_ms)) * 100.0; if (!view->sliding) { gtk_range_set_value(GTK_RANGE(sc_playback), perc); } } // update track info if (index != view->track_index || (track != NULL && track_get_id(track) != view->track_id)) { log_debug3("updating track info, index = %d, %p", index, track); view->track_index = index; if (track != NULL) { // fetch lyric if possible if (strcmp(track_get_lyric(track),"") == 0) { struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb)); cb->track_id = mc_strdup(track_get_id(track)); cb->view = view; fetch_lyric(track, library_view_process_lyric, cb); } else { struct lyric_cb* cb = (struct lyric_cb*) mc_malloc(sizeof(struct lyric_cb)); cb->track_id = mc_strdup(track_get_id(track)); cb->view = view; library_view_process_lyric(mc_strdup(track_get_lyric(track)), cb); } // Print artist info view->track_id = track_get_id(track); log_debug2("artid = %s", track_get_artid(track)); char s[200]; char c = ','; char c1 = ','; char *artist = text_to_html(track_get_artist(track)); char *title = text_to_html(track_get_title(track)); char *piece = text_to_html(track_get_piece(track)); if (strcmp(track_get_artist(track), "") == 0) { c = ' '; } if (strcmp(track_get_piece(track), "") == 0) { c1 = ' '; } snprintf(s, 125, "%s%c %s%c %s", artist, c, piece, c1, title ); mc_free(artist); mc_free(title); mc_free(piece); char ss[400]; log_debug2("s = %s", s); sprintf(ss,"<span size=\"x-small\"><i><b>%s</b></i></span>",s); GtkLabel* lbl = GTK_LABEL(gtk_builder_get_object(view->builder, "lbl_song_info")); gtk_label_set_markup(lbl, ss); log_debug2("artid = %s", track_get_artid(track)); file_info_t* info = file_info_new(track_get_artid(track)); if (!file_info_is_file(info)) { file_info_destroy(info); char *path = backtobasics_logo(view->btb); info = file_info_new(path); mc_free(path); //info = file_info_new(backtobasics_logo(view->btb)); } if (file_info_is_file(info)) { GError *err = NULL; GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_scale(file_info_path(info), view->img_w, view->img_h, TRUE, &err ); if (pb != NULL) { GtkImage* img = GTK_IMAGE(gtk_builder_get_object(view->builder, "img_art")); gtk_image_set_from_pixbuf(img, pb); g_object_unref(pb); } else { log_error3("error loading image art: %d, %s", err->code, err->message); //g_free(err); } } file_info_destroy(info); } log_debug("track hash"); // Select the track in the librarylist if the librarylist is still // the same if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) { GtkTreeView* tview = view->tview; GtkTreePath* path = gtk_tree_path_new(); gtk_tree_path_append_index(path, index); gtk_tree_view_set_cursor(tview, path, NULL, FALSE); gtk_tree_path_free(path); } log_debug("track hash 2"); } //log_debug3("lib hash = %lld, pl hash = %lld", view->library_list_hash, playlist_player_get_hash(player)); // TODO if (playlist_model_tracks_hash(view->playlist_model) == playlist_player_get_hash(player)) { //view->track_index = -1; } else { GtkTreeView* tview = view->tview; GtkTreeSelection* sel = gtk_tree_view_get_selection(tview); gtk_tree_selection_unselect_all(sel); } } // update repeat info playlist_player_repeat_t repeat = playlist_player_get_repeat(player); if (view->repeat != repeat) { log_debug3("repeat = %d, view repeat = %d", repeat, view->repeat); view->repeat = repeat; GtkWidget* r_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat")); GtkWidget* r1_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_one")); GtkWidget* rlist_btn = GTK_WIDGET(gtk_builder_get_object(view->builder, "tbtn_repeat_all")); log_debug4("r = %p, r1 = %p, rall = %p", r_btn, r1_btn, rlist_btn); switch (repeat) { case PLP_NO_REPEAT: { gtk_widget_show_all(r_btn); gtk_widget_hide(rlist_btn); gtk_widget_hide(r1_btn); } break; case PLP_TRACK_REPEAT: { gtk_widget_hide(r_btn); gtk_widget_show_all(r1_btn); gtk_widget_hide(rlist_btn); } break; case PLP_LIST_REPEAT: { gtk_widget_hide(r1_btn); gtk_widget_show_all(rlist_btn); gtk_widget_hide(r_btn); } break; } } return TRUE; } else { return FALSE; } }
static audio_result_t init(audio_worker_t* worker, const char* file_or_url, el_bool file) { static int mp3_initialized = 0; static int mp3_error = 0; if (!mp3_initialized) { mp3_initialized = 1; if (mpg123_init() != MPG123_OK) { mp3_error = 1; } else { atexit(mpg123_exit); } } if (mp3_error) { return AUDIO_CANNOT_INITIALIZE; } mp3_t* mp3=(mp3_t*) mc_malloc(sizeof(mp3_t)); worker->can_seek = can_seek; worker->play = play; worker->pause = mp3_pause; worker->seek = seek; worker->guard = guard; worker->destroy = destroy; worker->length_in_ms = length_in_ms; worker->load_file = load_file; worker->load_url = load_url; worker->set_volume = set_volume; worker->worker_data = (void*) mp3; int error; mp3->handle = mpg123_new(NULL, &error); mp3->buffer_size = mpg123_outblock(mp3->handle); mp3->buffer = mc_malloc(mp3->buffer_size * sizeof(char)); mpg123_volume(mp3->handle, 1.0); mp3->client_notification = worker->fifo; mp3->player_control = audio_event_fifo_new(); // http streams mp3->stream_fifo = mp3_stream_fifo_new(); mp3->continue_streaming = el_true; mp3->current_block = NULL; //sem_init(&mp3->stream_ready, 0, 0); mp3->stream_ready = psem_new(0); mp3->streaming = el_false; // etc. mp3->is_open = el_false; mp3->length = -1; //sem_init(&mp3->length_set, 0, 0); mp3->length_set = psem_new(0); mp3->ao_handle = aodev_new(); if (file) { mp3->can_seek = el_true; mp3->is_file = el_true; mp3->file_or_url = mc_strdup(file_or_url); post_event(mp3->player_control, INTERNAL_CMD_LOAD_FILE, -1); } else { // URL mp3->can_seek = el_false; mp3->is_file = el_true; // we check this later mp3->file_or_url = mc_strdup(file_or_url); post_event(mp3->player_control, INTERNAL_CMD_LOAD_URL, -1); } int thread_id = pthread_create(&mp3->player_thread, NULL, player_thread, mp3); // wait until fully loaded (length is set) psem_wait(mp3->length_set); log_debug("INIT OK"); return AUDIO_OK; }
int main(char *argv[],int argc) { mc_init(); el_bool stop = el_false; hre_t re_load = hre_compile("^load(&play)?\\s+(.*)$","i"); hre_t re_play = hre_compile("^play$","i"); hre_t re_pause = hre_compile("^pause$","i"); hre_t re_next = hre_compile("^next$","i"); hre_t re_previous = hre_compile("^prev(ious)?$","i"); hre_t re_track = hre_compile("^track\\s+([0-9]+)$","i"); hre_t re_quhit = hre_compile("^quit$","i"); hre_t re_seek = hre_compile("^seek\\s([0-9]+([.][0-9]+)?)$","i"); hre_t re_quit = hre_compile("^quit$","i"); hre_t re_repeat = hre_compile("^repeat\\s+(off|list|track)$","i"); hre_t re_again = hre_compile("^again$","i"); hre_t re_scan = hre_compile("^scan\\s+(.*)$","i"); file_info_t *history_file = mc_take_over(file_info_new_home(".btb_playlist")); printf("history file: %s\n", file_info_absolute_path(history_file)); printf("history file: %s\n", file_info_path(history_file)); if (file_info_exists(history_file)) { read_history(file_info_absolute_path(history_file)); } i18n_set_language("nl"); printf(_("Starting btb_playlist\n")); playlist_player_t *player = playlist_player_new(); while (!stop) { char* line = readln(">", player); hre_trim(line); if (hre_has_match(re_quit, line)) { stop = el_true; } else if (hre_has_match(re_load, line)) { hre_matches m = hre_match(re_load, line); hre_match_t *mplay = hre_matches_get(m, 1); hre_match_t *match = hre_matches_get(m, 2); char* file = mc_strdup(hre_match_str(match)); char* play = mc_strdup(hre_match_str(mplay)); hre_matches_destroy(m); printf("loading '%s', '%s'\n", file, play); file_info_t *info = file_info_new(file); if (file_info_exists(info)) { if (file_info_is_file(info)) { if (file_info_can_read(info)) { const char *mediafile = NULL; track_array array; if (strcasecmp(file_info_ext(info),"cue") == 0) { array = tracks_from_cue(file_info_absolute_path(info)); track_t* t = track_array_get(array, 0); } else { array = tracks_from_media(file_info_absolute_path(info)); } playlist_t* pl = playlist_new("playlist"); int i; for(i=0; i < track_array_count(array); ++i) { playlist_append(pl, track_array_get(array, i)); } playlist_player_set_playlist(player, pl); track_array_destroy(array); } } } file_info_destroy(info); if (strcasecmp(play,"&play")==0) { playlist_player_play(player); } mc_free(file); mc_free(play); } else if (hre_has_match(re_play, line)) { playlist_player_play(player); } else if (hre_has_match(re_pause, line)) { playlist_player_pause(player); } else if (hre_has_match(re_seek, line)) { hre_matches m = hre_match(re_seek, line); hre_match_t* match = hre_matches_get(m, 1); char* position = mc_strdup(hre_match_str(match)); hre_matches_destroy(m); double s = atof(position); int ms = s * 1000; mc_free(position); playlist_player_seek(player, ms); } else if (hre_has_match(re_next, line)) { playlist_player_next(player); } else if (hre_has_match(re_previous, line)) { playlist_player_previous(player); } else if (hre_has_match(re_track, line)) { hre_matches m = hre_match(re_track, line); hre_match_t* match = hre_matches_get(m, 1); char* nr = mc_strdup(hre_match_str(match)); hre_matches_destroy(m); int index = atoi(nr); mc_free(nr); printf("setting track %d\n",index); playlist_player_set_track(player, index); } else if (hre_has_match(re_repeat, line)) { hre_matches m = hre_match(re_repeat, line); hre_match_t* match = hre_matches_get(m, 1); if (strcasecmp(hre_match_str(match),"track") == 0) { playlist_player_set_repeat(player, PLP_TRACK_REPEAT); } else if (strcasecmp(hre_match_str(match),"list") == 0) { playlist_player_set_repeat(player, PLP_LIST_REPEAT); } else { playlist_player_set_repeat(player, PLP_NO_REPEAT); } hre_matches_destroy(m); } else if (hre_has_match(re_again, line)) { playlist_player_again(player); } else if (hre_has_match(re_scan, line)) { hre_matches m = hre_match(re_scan, line); hre_match_t* match = hre_matches_get(m, 1); printf("scanning %s\n", hre_match_str(match)); library_t* library = library_new(); printf("calling scan_library\n"); //scan_library(library, hre_match_str(match), library_cb); printf("\n"); printf("library: %d tracks\n", library_count(library)); printf("done scanning, destroying library\n"); library_destroy(library); printf("library destroyed\n"); hre_matches_destroy(m); printf("matches destroyed\n"); } mc_free(line); } playlist_player_destroy(player); printf("%d\n",write_history(file_info_absolute_path(history_file))); file_info_destroy(history_file); hre_destroy(re_load); hre_destroy(re_play); hre_destroy(re_pause); hre_destroy(re_quit); hre_destroy(re_seek); hre_destroy(re_track); hre_destroy(re_next); hre_destroy(re_previous); hre_destroy(re_again); hre_destroy(re_repeat); hre_destroy(re_scan); return 0; }
cue_t *cue_new(const char *file) { cue_t *r = (cue_t *) mc_malloc(sizeof(cue_t)); r->audio_file = NULL; r->album_title = NULL; r->album_performer = NULL; r->album_composer = NULL; r->genre = NULL; r->cuefile = mystrdup(file); r->count = 0; r->entries = NULL; r->_errno = 0; FILE *f = fopen(file, "rt"); time_t _audio_mtime=0; if (f == NULL) { r->_errno = ENOFILECUE; } else { char *line; char *image = NULL; char *year = NULL; cue_entry_t *entry = NULL; int in_tracks = 0; while ((line = readline(f)) != NULL) { trim_replace(&line); if (strcmp(line, "") != 0) { if (!in_tracks) { if (eq(line, "performer")) { mc_free(r->album_performer); r->album_performer = unquote(line, "performer"); } else if (eq(line, "title")) { mc_free(r->album_title); r->album_title = unquote(line, "title"); } else if (eq(line, "file")) { mc_free(r->audio_file); char *fl = getFilePart(line); char *af = unquote(fl, ""); if (strlen(af) > 0) { if (af[0] == '/') { r->audio_file = af; } else { char *cf = mc_strdup(r->cuefile); int ii; for (ii = strlen(cf) - 1; ii >= 0 && cf[ii] != '/'; ii--) ; if (ii >= 0) { cf[ii] = '\0'; char *aaf = (char *)mc_malloc(strlen(cf) + strlen(af) + strlen("/") + 1); sprintf(aaf, "%s/%s", cf, af); r->audio_file = aaf; mc_free(cf); mc_free(af); } else { r->audio_file = af; } } } else { r->audio_file = af; } // We have a full path audio file now. // get the mtime. { struct stat st; stat(r->audio_file,&st); _audio_mtime=st.st_mtime; } mc_free(fl); } else if (eq(line, "rem")) { if (eq(&line[3], "date")) { mc_free(year); year = unquote(&line[3], "date"); } else if (eq(&line[3], "image")) { mc_free(image); image = unquote(&line[3], "image"); } else if (eq(&line[3], "composer")) { mc_free(r->album_composer); r->album_performer = unquote(&line[3], "composer"); } else if (eq(&line[3], "genre")) { mc_free(r->genre); r->genre = unquote(&line[3], "genre"); } } else if (eq(line, "track")) { in_tracks = 1; } } if (in_tracks) { if (eq(line, "track")) { log_debug2("track: entry=%p", entry); if (entry != NULL) { addEntry(r, entry); } entry = cue_entry_new(r); entry->audio_mtime=_audio_mtime; entry->year = mystrdup(year); entry->performer = mystrdup(r->album_performer); entry->composer = mystrdup(r->album_composer); entry->piece = NULL; log_debug2("track: created new entry %p", entry); } else if (eq(line, "title")) { mc_free(entry->title); entry->title = unquote(line, "title"); } else if (eq(line, "performer")) { mc_free(entry->performer); entry->performer = unquote(line, "performer"); } else if (eq(line, "index")) { char *index = unquote(line, "index"); entry->begin_offset_in_ms = calculateOffset(index); mc_free(index); } else if (eq(line, "rem")) { if (eq(&line[3], "composer")) { mc_free(entry->composer); entry->composer = unquote(&line[3], "composer"); } else if (eq(&line[3], "piece")) { mc_free(entry->piece); entry->piece = unquote(&line[3], "piece"); } else if (eq(&line[3], "year")) { mc_free(year); year = unquote(&line[3], "year"); mc_free(entry->year); entry->year = mystrdup(year); } } } } mc_free(line); } if (entry != NULL) { addEntry(r, entry); } mc_free(year); mc_free(image); { int i, N; for (i = 0, N = r->count; i < N - 1; i++) { r->entries[i]->end_offset_in_ms = r->entries[i + 1]->begin_offset_in_ms; r->entries[i]->tracknr = i + 1; } r->entries[i]->tracknr = i + 1; } fclose(f); } return r; }