void ActivityWebView::goToCallback(string text) { string url; remove_tag(text, "<", ">"); if (text.substr(0, 7) != "http://" && text.substr(0, 8) != "https://") url = "http://"; url += text; elm_web_uri_set(web, url.c_str()); elm_object_focus_set(web, true); }
static inline struct boundary_tag* absorb_right( struct boundary_tag *tag ) { struct boundary_tag *right = tag->split_right; remove_tag( right ); // Remove right from free pages. tag->real_size += right->real_size; tag->split_right = right->split_right; if ( right->split_right != NULL ) right->split_right->split_left = tag; return tag; }
void FileStore::operation(Operation* operation) { Selection* const selection = operation->get_selection(); if(operation->get_delete()) { //delete the selected files //TODO } else { //add/remove tags for(Tag tag: operation->get_add_tags()) add_tag(selection, tag); for(Tag tag: operation->get_remove_tags()) remove_tag(selection, tag); } delete operation; }
void free(void *ptr) { int index; struct boundary_tag *tag; if ( ptr == NULL ) return; liballoc_lock(); tag = (struct boundary_tag*)((unsigned int)ptr - sizeof( struct boundary_tag )); if ( tag->magic != LIBALLOC_MAGIC ) { liballoc_unlock(); // release the lock return; } // MELT LEFT... while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) ) { tag = melt_left( tag ); remove_tag( tag ); } // MELT RIGHT... while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) ) { tag = absorb_right( tag ); } // Where is it going back to? index = getexp( tag->real_size - sizeof(struct boundary_tag) ); if ( index < MINEXP ) index = MINEXP; // A whole, empty block? if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) { if ( l_completePages[ index ] == MAXCOMPLETE ) { // Too many standing by to keep. Free this one. unsigned int pages = tag->real_size / l_pageSize; if ( (tag->real_size % l_pageSize) != 0 ) pages += 1; if ( pages < l_pageCount ) pages = l_pageCount; liballoc_free( tag, pages ); liballoc_unlock(); return; } l_completePages[ index ] += 1; // Increase the count of complete pages. } // .......... insert_tag( tag, index ); liballoc_unlock(); }
void *malloc(uint64_t size) { int index; void *ptr; struct boundary_tag *tag = NULL; liballoc_lock(); if ( l_initialized == 0 ) { for ( index = 0; index < MAXEXP; index++ ) { l_freePages[index] = NULL; l_completePages[index] = 0; } l_initialized = 1; } index = getexp( size ) + MODE; if ( index < MINEXP ) index = MINEXP; // Find one big enough. tag = l_freePages[ index ]; // Start at the front of the list. while ( tag != NULL ) { // If there's enough space in this tag. if ( (tag->real_size - sizeof(struct boundary_tag)) >= (size + sizeof(struct boundary_tag) ) ) { break; } tag = tag->next; } // No page found. Make one. if ( tag == NULL ) { if ( (tag = allocate_new_tag( size )) == NULL ) { liballoc_unlock(); return NULL; } index = getexp( tag->real_size - sizeof(struct boundary_tag) ); } else { remove_tag( tag ); if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) l_completePages[ index ] -= 1; } // We have a free page. Remove it from the free pages list. tag->size = size; // Removed... see if we can re-use the excess space. unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ ) { int childIndex = getexp( remainder ); if ( childIndex >= 0 ) { struct boundary_tag *new_tag = split_tag( tag ); new_tag = new_tag; // Get around the compiler warning about unused variables. } } ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) ); liballoc_unlock(); return ptr; }
/** finds tags that have been added or removed or updated */ void update_tags( const comment_object& c )const { try { auto hot = calculate_hot(c); comment_metadata meta; if( c.json_metadata.size() ){ meta = fc::json::from_string( c.json_metadata ).as<comment_metadata>(); } set<string> lower_tags; for( const auto& tag : meta.tags ) lower_tags.insert(fc::to_lower( tag ) ); lower_tags.insert( fc::to_lower(c.category) ); /// the universal tag applies to everything safe for work or nsfw with a positive payout if( c.net_rshares >= 0 || (lower_tags.find( "spam" ) == lower_tags.end() && lower_tags.find( "nsfw" ) == lower_tags.end() && lower_tags.find( "test" ) == lower_tags.end() ) ) { lower_tags.insert( string() ); /// add it to the universal tag } meta.tags = lower_tags; /// TODO: std::move??? const auto& comment_idx = _db.get_index_type<tag_index>().indices().get<by_comment>(); auto citr = comment_idx.lower_bound( c.id ); map<string, const tag_object*> existing_tags; vector<const tag_object*> remove_queue; while( citr != comment_idx.end() && citr->comment == c.id ) { const tag_object* tag = &*citr; ++citr; if( meta.tags.find( tag->tag ) == meta.tags.end() ) { remove_queue.push_back(tag); } else { existing_tags[tag->tag] = tag; } } for( const auto& tag : meta.tags ) { auto existing = existing_tags.find(tag); if( existing == existing_tags.end() ) { create_tag( tag, c, hot ); } else { update_tag( *existing->second, c, hot ); } } for( const auto& item : remove_queue ) remove_tag(*item); if( c.parent_author.size() ) { update_tags( _db.get_comment( c.parent_author, c.parent_permlink ) ); } } FC_CAPTURE_LOG_AND_RETHROW( (c) ) }
void free(void *ptr) { int index; struct boundary_tag *tag; if ( ptr == NULL ) return; liballoc_lock(); tag = (struct boundary_tag*)((unsigned int)ptr - sizeof( struct boundary_tag )); if ( tag->magic != LIBALLOC_MAGIC ) { liballoc_unlock(); // release the lock return; } #ifdef DEBUG l_inuse -= tag->size; printf("free: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 ); #endif // MELT LEFT... while ( (tag->split_left != NULL) && (tag->split_left->index >= 0) ) { #ifdef DEBUG printf("Melting tag left into available memory. Left was %i, becomes %i (%i)\n", tag->split_left->real_size, tag->split_left->real_size + tag->real_size, tag->split_left->real_size ); #endif tag = melt_left( tag ); remove_tag( tag ); } // MELT RIGHT... while ( (tag->split_right != NULL) && (tag->split_right->index >= 0) ) { #ifdef DEBUG printf("Melting tag right into available memory. This was was %i, becomes %i (%i)\n", tag->real_size, tag->split_right->real_size + tag->real_size, tag->split_right->real_size ); #endif tag = absorb_right( tag ); } // Where is it going back to? index = getexp( tag->real_size - sizeof(struct boundary_tag) ); if ( index < MINEXP ) index = MINEXP; // A whole, empty block? if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) { if ( l_completePages[ index ] == MAXCOMPLETE ) { // Too many standing by to keep. Free this one. unsigned int pages = tag->real_size / l_pageSize; if ( (tag->real_size % l_pageSize) != 0 ) pages += 1; if ( pages < l_pageCount ) pages = l_pageCount; liballoc_free( tag, pages ); #ifdef DEBUG l_allocated -= pages * l_pageSize; printf("Resource freeing %x of %i pages\n", tag, pages ); dump_array(); #endif liballoc_unlock(); return; } l_completePages[ index ] += 1; // Increase the count of complete pages. } // .......... insert_tag( tag, index ); #ifdef DEBUG printf("Returning tag with %i bytes (requested %i bytes), which has exponent: %i\n", tag->real_size, tag->size, index ); dump_array(); #endif liballoc_unlock(); }
void *malloc(size_t size) { int index; void *ptr; struct boundary_tag *tag = NULL; liballoc_lock(); if ( l_initialized == 0 ) { #ifdef DEBUG printf("%s\n","liballoc initializing."); #endif for ( index = 0; index < MAXEXP; index++ ) { l_freePages[index] = NULL; l_completePages[index] = 0; } l_initialized = 1; } index = getexp( size ) + MODE; if ( index < MINEXP ) index = MINEXP; // Find one big enough. tag = l_freePages[ index ]; // Start at the front of the list. while ( tag != NULL ) { // If there's enough space in this tag. if ( (tag->real_size - sizeof(struct boundary_tag)) >= (size + sizeof(struct boundary_tag) ) ) { #ifdef DEBUG printf("Tag search found %i >= %i\n",(tag->real_size - sizeof(struct boundary_tag)), (size + sizeof(struct boundary_tag) ) ); #endif break; } tag = tag->next; } // No page found. Make one. if ( tag == NULL ) { if ( (tag = allocate_new_tag( size )) == NULL ) { liballoc_unlock(); return NULL; } index = getexp( tag->real_size - sizeof(struct boundary_tag) ); } else { remove_tag( tag ); if ( (tag->split_left == NULL) && (tag->split_right == NULL) ) l_completePages[ index ] -= 1; } // We have a free page. Remove it from the free pages list. tag->size = size; // Removed... see if we can re-use the excess space. #ifdef DEBUG printf("Found tag with %i bytes available (requested %i bytes, leaving %i), which has exponent: %i (%i bytes)\n", tag->real_size - sizeof(struct boundary_tag), size, tag->real_size - size - sizeof(struct boundary_tag), index, 1<<index ); #endif unsigned int remainder = tag->real_size - size - sizeof( struct boundary_tag ) * 2; // Support a new tag + remainder if ( ((int)(remainder) > 0) /*&& ( (tag->real_size - remainder) >= (1<<MINEXP))*/ ) { int childIndex = getexp( remainder ); if ( childIndex >= 0 ) { #ifdef DEBUG printf("Seems to be splittable: %i >= 2^%i .. %i\n", remainder, childIndex, (1<<childIndex) ); #endif struct boundary_tag *new_tag = split_tag( tag ); new_tag = new_tag; // Get around the compiler warning about unused variables. #ifdef DEBUG printf("Old tag has become %i bytes, new tag is now %i bytes (%i exp)\n", tag->real_size, new_tag->real_size, new_tag->index ); #endif } } ptr = (void*)((unsigned int)tag + sizeof( struct boundary_tag ) ); #ifdef DEBUG l_inuse += size; printf("malloc: %x, %i, %i\n", ptr, (int)l_inuse / 1024, (int)l_allocated / 1024 ); dump_array(); #endif liballoc_unlock(); return ptr; }
int main(int argc, char **argv) { const char *filename = "/system/build.prop"; const char *propname = "ro.build.fingerprint"; const char *tag = NULL; int do_remove = 0, do_number = 0; int opt; while ((opt = getopt(argc, argv, "f:p:rn")) != -1) { switch (opt) { case 'f': filename = optarg; break; case 'p': propname = optarg; break; case 'r': do_remove = 1; break; case 'n': do_number = 1; break; case '?': return 2; } } if (argc != optind + 1) { fprintf(stderr, "usage: add-property-tag [flags] tag-to-add\n" "flags: -f /dir/file.prop (default /system/build.prop)\n" " -p prop.name (default ro.build.fingerprint)\n" " -r (if set, remove the tag rather than adding it)\n" " -n (if set, add and increment a number after the tag)\n"); return 2; } tag = argv[optind]; FILE *input = fopen(filename, "r"); if (input == NULL) { fprintf(stderr, "can't read %s: %s\n", filename, strerror(errno)); return 1; } char tmpname[PATH_MAX]; snprintf(tmpname, sizeof(tmpname), "%s.tmp", filename); FILE *output = fopen(tmpname, "w"); if (output == NULL) { fprintf(stderr, "can't write %s: %s\n", tmpname, strerror(errno)); return 1; } int found = 0; char line[4096]; while (fgets(line, sizeof(line), input)) { if (!should_tag(line, propname)) { fputs(line, output); // Pass through unmodified } else { found = 1; int number = remove_tag(line, tag); if (do_remove) { fputs(line, output); // Remove the tag but don't re-add it } else { write_tagged(output, line, tag, number + do_number); } } } fclose(input); fclose(output); if (!found) { fprintf(stderr, "property %s not found in %s\n", propname, filename); remove(tmpname); return 1; } if (rename(tmpname, filename)) { fprintf(stderr, "can't rename %s to %s: %s\n", tmpname, filename, strerror(errno)); remove(tmpname); return 1; } return 0; }
/** finds tags that have been added or removed or updated */ void update_tags( const comment_object& c )const { try { auto hot = calculate_hot(c); comment_metadata meta; if( c.json_metadata.size() ) { try { meta = fc::json::from_string( c.json_metadata ).as<comment_metadata>(); } catch( const fc::exception& e ) { // Do nothing on malformed json_metadata } } set<string> lower_tags; for( const auto& tag : meta.tags ) lower_tags.insert(fc::to_lower( tag ) ); lower_tags.insert( fc::to_lower(c.category) ); bool safe_for_work = false; /// the universal tag applies to everything safe for work or nsfw with a positive payout if( c.net_rshares >= 0 || (lower_tags.find( "spam" ) == lower_tags.end() && lower_tags.find( "nsfw" ) == lower_tags.end() && lower_tags.find( "test" ) == lower_tags.end() ) ) { safe_for_work = true; lower_tags.insert( string() ); /// add it to the universal tag } meta.tags = lower_tags; /// TODO: std::move??? if( meta.tags.size() > 7 ) { //wlog( "ignoring post ${a} because it has ${n} tags",("a", c.author + "/"+c.permlink)("n",meta.tags.size())); if( safe_for_work ) meta.tags = set<string>({"", c.parent_permlink}); else meta.tags.clear(); } const auto& comment_idx = _db.get_index_type<tag_index>().indices().get<by_comment>(); auto citr = comment_idx.lower_bound( c.id ); map<string, const tag_object*> existing_tags; vector<const tag_object*> remove_queue; while( citr != comment_idx.end() && citr->comment == c.id ) { const tag_object* tag = &*citr; ++citr; if( meta.tags.find( tag->tag ) == meta.tags.end() ) { remove_queue.push_back(tag); } else { existing_tags[tag->tag] = tag; } } for( const auto& tag : meta.tags ) { auto existing = existing_tags.find(tag); if( existing == existing_tags.end() ) { create_tag( tag, c, hot ); } else { update_tag( *existing->second, c, hot ); } } for( const auto& item : remove_queue ) remove_tag(*item); if( c.parent_author.size() ) { update_tags( _db.get_comment( c.parent_author, c.parent_permlink ) ); } } FC_CAPTURE_LOG_AND_RETHROW( (c) ) }
int Sn_Syntax_Highlight(ClientData clientData, Tcl_Interp * interp, int argc, char **argv) { register TkText *textPtr = NULL; Tcl_CmdInfo infoPtr; int result = TCL_OK; int del = 0; char *argv0 = argv[0]; int wargc; char *wargv[10]; char *language; char *idx1; char *idx2; char *text_widget; char endpos[TK_POS_CHARS]; char begpos[TK_POS_CHARS]; int val; int (*high_func) () = NULL; void (*flush_lex_scanner) () = NULL; void (*high_init_func) (int ms, int lineno, int charno, void (**func) (), void *idx1, void *idx2) = NULL; Tcl_CmdProc *text_proc; int update = 0; TkTextIndex lex_index1; TkTextIndex lex_index2; TkTextIndex lex_end_index; char prev_begpos[TK_POS_CHARS]; int lex_buf_size = 0; eos_read = 0; while (argc > 1 && argv[1][0] == '-') { if(strncmp(argv[1], "-delete", 5) == 0) { del = 1; argc--; argv++; } else if(strncmp(argv[1], "-delall", 5) == 0) { del = -1; argc--; argv++; } else if(strncmp(argv[1], "-update", 4) == 0) { lex_buf_size = 256; /* It is probably not necessary to fill */ /* the complete lex buffer. */ update = 1; argc--; argv++; } else break; } if(argc != 4 && argc != 5) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv0, " ?-delete? ?-delall? language text_widget index1 ?index2?", NULL); return TCL_ERROR; } language = argv[1]; text_widget = argv[2]; idx1 = argv[3]; idx2 = argc == 5 ? argv[4] : idx1; LOGGER((LOGFP, "highlight lang: <%s> text: <%s> idx1: <%s> idx2: <%s>\n", language, text_widget, idx1, idx2)); if(strcmp(language, "tcl") == 0) { high_func = tcl_highlight_lex; high_init_func = tcl_highlight_init_func; } else if(strcmp(language, "c++") == 0) { high_func = c_highlight_lex; high_init_func = c_highlight_init_func; } else if(strcmp(language, "java") == 0) { high_func = java_highlight_lex; high_init_func = java_highlight_init_func; } else if(strcmp(language, "chill") == 0) { high_func = ch_highlight_lex; high_init_func = ch_highlight_init_func; } else if(strcmp(language, "verilog") == 0) { high_func = verilog_highlight_lex; high_init_func = verilog_highlight_init_func; } else if(strcmp(language, "python") == 0) { high_func = py_highlight_lex; high_init_func = py_highlight_init_func; } if(!high_func) { return TCL_OK; } if(!Tcl_GetCommandInfo(interp, text_widget, &infoPtr)) { Tcl_AppendResult(interp, "wrong # \"", text_widget, "\" does not exist", (char *) NULL); return TCL_ERROR; } textPtr = (TkText *) infoPtr.clientData; Tcl_Preserve((ClientData) textPtr); text_proc = (Tcl_CmdProc *) infoPtr.proc; if(del) { remove_tag(textPtr, interp, text_widget, del, idx1, idx2); } TkTextGetIndex(interp, textPtr, "end", &lex_end_index); if(TkTextGetIndex(interp, textPtr, idx1, &lex_index1) != TCL_OK || TkTextGetIndex(interp, textPtr, idx2, &lex_index2) != TCL_OK) { result = TCL_ERROR; goto done; } if(TkTextIndexCmp(&lex_index1, &lex_index2) >= 0) { result = TCL_OK; goto done; } high_init_func(lex_buf_size, TkBTreeLineIndex(lex_index1.linePtr) + 1, lex_index1.CHARINDEX, &flush_lex_scanner, (void *) &lex_index1, (void *) &lex_end_index); wargc = 0; wargv[wargc++] = text_widget; wargv[wargc++] = "tag"; wargv[wargc++] = "add"; wargv[wargc++] = NULL; wargv[wargc++] = begpos; wargv[wargc++] = endpos; strcpy(prev_begpos, idx1); while ((val = (*high_func) ()) != 0) { sprintf(begpos, "%d.%d", paf_high_pos.beg_lineno, paf_high_pos.beg_charno); sprintf(endpos, "%d.%d", paf_high_pos.end_lineno, paf_high_pos.end_charno); wargv[3] = high_tag_names[val]; if(update) { int tag_argc = 0; char *tag_argv[10]; char *p_end; int cou; int tag_off; tag_argv[tag_argc++] = text_widget; tag_argv[tag_argc++] = "tag"; tag_argv[tag_argc++] = "prevrange"; tag_off = tag_argc; tag_argv[tag_argc++] = NULL; tag_argv[tag_argc++] = endpos; for (cou = 1; cou <= PAF_HIGH_STRING; cou++) { tag_argv[tag_off] = high_tag_names[cou]; Tcl_ResetResult(interp); TkTextTagCmd(textPtr, interp, tag_argc, tag_argv); p_end = strchr(interp->result, ' '); /* Check whether it is synchronized ! */ if(p_end && strcmp(p_end + 1, endpos) == 0) { eos_read = 1; /* It will get flex recognized that no further * input is available. */ flush_lex_scanner(); break; } } LOGGER((LOGFP, "Add %s %d %s %s\n", high_tag_names[val], val, begpos, endpos)); } if(update) { int tag_argc = 0; char *tag_argv[10]; int cou; int tag_off; tag_argv[tag_argc++] = text_widget; tag_argv[tag_argc++] = "tag"; tag_argv[tag_argc++] = "remove"; tag_off = tag_argc; tag_argv[tag_argc++] = NULL; tag_argv[tag_argc++] = prev_begpos; tag_argv[tag_argc++] = endpos; for (cou = 1; cou <= PAF_HIGH_STRING; cou++) { tag_argv[tag_off] = high_tag_names[cou]; TkTextTagCmd(textPtr, interp, tag_argc, tag_argv); } strcpy(prev_begpos, endpos); } TkTextTagCmd(textPtr, interp, wargc, wargv); } done: Tcl_Release((ClientData) textPtr); return result; }
/* Gets a reply from the cache */ static int cache_daap_query_get(struct cache_command *cmd) { #define Q_TMPL "SELECT reply FROM replies WHERE query = ?;" sqlite3_stmt *stmt; char *query; int datalen; int ret; query = cmd->arg.query; remove_tag(query, "session-id"); remove_tag(query, "revision-number"); // Look in the DB ret = sqlite3_prepare_v2(g_db_hdl, Q_TMPL, -1, &stmt, 0); if (ret != SQLITE_OK) { DPRINTF(E_LOG, L_CACHE, "Error preparing query for cache update: %s\n", sqlite3_errmsg(g_db_hdl)); free(query); return -1; } sqlite3_bind_text(stmt, 1, query, -1, SQLITE_STATIC); ret = sqlite3_step(stmt); if (ret != SQLITE_ROW) { if (ret != SQLITE_DONE) DPRINTF(E_LOG, L_CACHE, "Error stepping query for cache update: %s\n", sqlite3_errmsg(g_db_hdl)); goto error_get; } datalen = sqlite3_column_bytes(stmt, 0); if (!cmd->arg.evbuf) { DPRINTF(E_LOG, L_CACHE, "Error: DAAP reply evbuffer is NULL\n"); goto error_get; } ret = evbuffer_add(cmd->arg.evbuf, sqlite3_column_blob(stmt, 0), datalen); if (ret < 0) { DPRINTF(E_LOG, L_CACHE, "Out of memory for DAAP reply evbuffer\n"); goto error_get; } ret = sqlite3_finalize(stmt); if (ret != SQLITE_OK) DPRINTF(E_LOG, L_CACHE, "Error finalizing query for getting cache: %s\n", sqlite3_errmsg(g_db_hdl)); DPRINTF(E_INFO, L_CACHE, "Cache hit: %s\n", query); free(query); return 0; error_get: sqlite3_finalize(stmt); free(query); return -1; #undef Q_TMPL }
/* Adds the query to the list of queries for which we will build and cache a reply */ static int cache_daap_query_add(struct cache_command *cmd) { #define Q_TMPL "INSERT OR REPLACE INTO queries (user_agent, query, msec, timestamp) VALUES ('%q', '%q', %d, %" PRIi64 ");" #define Q_CLEANUP "DELETE FROM queries WHERE id NOT IN (SELECT id FROM queries ORDER BY timestamp DESC LIMIT 20);" char *query; char *errmsg; int ret; if (!cmd->arg.ua) { DPRINTF(E_LOG, L_CACHE, "Couldn't add slow query to cache, unknown user-agent\n"); goto error_add; } // Currently we are only able to pre-build and cache these reply types if ( (strncmp(cmd->arg.query, "/databases/1/containers/", strlen("/databases/1/containers/")) != 0) && (strncmp(cmd->arg.query, "/databases/1/groups?", strlen("/databases/1/groups?")) != 0) && (strncmp(cmd->arg.query, "/databases/1/items?", strlen("/databases/1/items?")) != 0) && (strncmp(cmd->arg.query, "/databases/1/browse/", strlen("/databases/1/browse/")) != 0) ) goto error_add; remove_tag(cmd->arg.query, "session-id"); remove_tag(cmd->arg.query, "revision-number"); query = sqlite3_mprintf(Q_TMPL, cmd->arg.ua, cmd->arg.query, cmd->arg.msec, (int64_t)time(NULL)); if (!query) { DPRINTF(E_LOG, L_CACHE, "Out of memory making query string.\n"); goto error_add; } ret = sqlite3_exec(g_db_hdl, query, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { DPRINTF(E_LOG, L_CACHE, "Error adding query to query list: %s\n", errmsg); sqlite3_free(query); sqlite3_free(errmsg); goto error_add; } sqlite3_free(query); DPRINTF(E_INFO, L_CACHE, "Slow query (%d ms) added to cache: '%s' (user-agent: '%s')\n", cmd->arg.msec, cmd->arg.query, cmd->arg.ua); free(cmd->arg.ua); free(cmd->arg.query); // Limits the size of the cache to only contain replies for 20 most recent queries ret = sqlite3_exec(g_db_hdl, Q_CLEANUP, NULL, NULL, &errmsg); if (ret != SQLITE_OK) { DPRINTF(E_LOG, L_CACHE, "Error cleaning up query list before update: %s\n", errmsg); sqlite3_free(errmsg); return -1; } cache_daap_trigger(); return 0; error_add: if (cmd->arg.ua) free(cmd->arg.ua); if (cmd->arg.query) free(cmd->arg.query); return -1; #undef Q_CLEANUP #undef Q_TMPL }