void linked_list_destroy(llnode *node) { // We don't want elements get lost in memory if (node->next != NULL) { linked_list_destroy(node->next); } free(node); }
/*=========================================================================== FUNCTION: msg_q_init ===========================================================================*/ msq_q_err_type msg_q_init(void** msg_q_data) { if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_PARAMETER; } msg_q* tmp_msg_q; tmp_msg_q = (msg_q*)calloc(1, sizeof(msg_q)); if( tmp_msg_q == NULL ) { LOC_LOGE("%s: Unable to allocate space for message queue!\n", __FUNCTION__); return eMSG_Q_FAILURE_GENERAL; } if( linked_list_init(&tmp_msg_q->msg_list) != 0 ) { LOC_LOGE("%s: Unable to initialize storage list!\n", __FUNCTION__); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_mutex_init(&tmp_msg_q->list_mutex, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize list mutex!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } if( pthread_cond_init(&tmp_msg_q->list_cond, NULL) != 0 ) { LOC_LOGE("%s: Unable to initialize msg q cond var!\n", __FUNCTION__); linked_list_destroy(&tmp_msg_q->msg_list); pthread_mutex_destroy(&tmp_msg_q->list_mutex); free(tmp_msg_q); return eMSG_Q_FAILURE_GENERAL; } tmp_msg_q->unblocked = 0; *msg_q_data = tmp_msg_q; return eMSG_Q_SUCCESS; }
/*=========================================================================== FUNCTION: msg_q_destroy ===========================================================================*/ msq_q_err_type msg_q_destroy(void** msg_q_data) { if( msg_q_data == NULL ) { LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__); return eMSG_Q_INVALID_HANDLE; } msg_q* p_msg_q = (msg_q*)*msg_q_data; linked_list_destroy(&p_msg_q->msg_list); pthread_mutex_destroy(&p_msg_q->list_mutex); pthread_cond_destroy(&p_msg_q->list_cond); p_msg_q->unblocked = 0; free(*msg_q_data); *msg_q_data = NULL; return eMSG_Q_SUCCESS; }
AgpsStateMachine::~AgpsStateMachine() { dropAllSubscribers(); // free the 3 states. We must read out all 3 pointers first. // Otherwise we run the risk of getting pointers from already // freed memory. AgpsState* acquiredState = mStatePtr->mAcquiredState; AgpsState* releasedState = mStatePtr->mReleasedState; AgpsState* pendindState = mStatePtr->mPendingState; AgpsState* releasingState = mStatePtr->mReleasingState; delete acquiredState; delete releasedState; delete pendindState; delete releasingState; linked_list_destroy(&mSubscribers); if (NULL != mAPN) { delete[] mAPN; mAPN = NULL; } }
static void action_paste_files_free_data(paste_files_data* data) { task_clear_files(&data->contents); linked_list_destroy(&data->contents); free(data); }
static void task_populate_titledb_thread(void* arg) { populate_titledb_data* data = (populate_titledb_data*) arg; Result res = 0; linked_list titles; linked_list_init(&titles); json_t* root = NULL; if(R_SUCCEEDED(res = http_download_json("https://api.titledb.com/v1/entry?nested=true" "&only=id&only=name&only=author&only=headline&only=category" "&only=cia.id&only=cia.mtime&only=cia.version&only=cia.size&only=cia.titleid" "&only=tdsx.id&only=tdsx.mtime&only=tdsx.version&only=tdsx.size&only=tdsx.smdh.id", &root, 1024 * 1024))) { if(json_is_array(root)) { for(u32 i = 0; i < json_array_size(root) && R_SUCCEEDED(res); i++) { svcWaitSynchronization(task_get_pause_event(), U64_MAX); if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) { break; } json_t* entry = json_array_get(root, i); if(json_is_object(entry)) { list_item* item = (list_item*) calloc(1, sizeof(list_item)); if(item != NULL) { titledb_info* titledbInfo = (titledb_info*) calloc(1, sizeof(titledb_info)); if(titledbInfo != NULL) { titledbInfo->id = (u32) json_object_get_integer(entry, "id", 0); string_copy(titledbInfo->category, json_object_get_string(entry, "category", "Unknown"), sizeof(titledbInfo->category)); string_copy(titledbInfo->meta.shortDescription, json_object_get_string(entry, "name", ""), sizeof(titledbInfo->meta.shortDescription)); string_copy(titledbInfo->meta.publisher, json_object_get_string(entry, "author", ""), sizeof(titledbInfo->meta.publisher)); json_t* headline = json_object_get(entry, "headline"); if(json_is_string(headline)) { const char* val = json_string_value(headline); if(json_string_length(headline) > sizeof(titledbInfo->headline) - 1) { snprintf(titledbInfo->headline, sizeof(titledbInfo->headline), "%.508s...", val); } else { string_copy(titledbInfo->headline, val, sizeof(titledbInfo->headline)); } } else { titledbInfo->headline[0] = '\0'; } json_t* cias = json_object_get(entry, "cia"); if(json_is_array(cias)) { for(u32 j = 0; j < json_array_size(cias); j++) { json_t* cia = json_array_get(cias, j); if(json_is_object(cia)) { const char* mtime = json_object_get_string(cia, "mtime", "Unknown"); if(!titledbInfo->cia.exists || task_populate_titledb_compare_dates(mtime, titledbInfo->cia.mtime, sizeof(titledbInfo->cia.mtime)) >= 0) { titledbInfo->cia.exists = true; titledbInfo->cia.id = (u32) json_object_get_integer(cia, "id", 0); string_copy(titledbInfo->cia.mtime, mtime, sizeof(titledbInfo->cia.mtime)); string_copy(titledbInfo->cia.version, json_object_get_string(cia, "version", "Unknown"), sizeof(titledbInfo->cia.version)); titledbInfo->cia.size = (u32) json_object_get_integer(cia, "size", 0); titledbInfo->cia.titleId = strtoull(json_object_get_string(cia, "titleid", "0"), NULL, 16); } } } } json_t* tdsxs = json_object_get(entry, "tdsx"); if(json_is_array(tdsxs)) { for(u32 j = 0; j < json_array_size(tdsxs); j++) { json_t* tdsx = json_array_get(tdsxs, j); if(json_is_object(tdsx)) { const char* mtime = json_object_get_string(tdsx, "mtime", "Unknown"); if(!titledbInfo->tdsx.exists || task_populate_titledb_compare_dates(mtime, titledbInfo->tdsx.mtime, sizeof(titledbInfo->tdsx.mtime)) >= 0) { titledbInfo->tdsx.exists = true; titledbInfo->tdsx.id = (u32) json_object_get_integer(tdsx, "id", 0); string_copy(titledbInfo->tdsx.mtime, mtime, sizeof(titledbInfo->tdsx.mtime)); string_copy(titledbInfo->tdsx.version, json_object_get_string(tdsx, "version", "Unknown"), sizeof(titledbInfo->tdsx.version)); titledbInfo->tdsx.size = (u32) json_object_get_integer(tdsx, "size", 0); json_t* smdh = json_object_get(tdsx, "smdh"); if(json_is_object(smdh)) { titledbInfo->tdsx.smdh.exists = true; titledbInfo->tdsx.smdh.id = (u32) json_object_get_integer(smdh, "id", 0); } } } } } char* latestTime = "Unknown"; if(titledbInfo->cia.exists && titledbInfo->tdsx.exists) { if(task_populate_titledb_compare_dates(titledbInfo->cia.mtime, titledbInfo->tdsx.mtime, sizeof(titledbInfo->cia.mtime)) >= 0) { latestTime = titledbInfo->cia.mtime; } else { latestTime = titledbInfo->tdsx.mtime; } } else if(titledbInfo->cia.exists) { latestTime = titledbInfo->cia.mtime; } else if(titledbInfo->tdsx.exists) { latestTime = titledbInfo->tdsx.mtime; } string_copy(titledbInfo->mtime, latestTime, sizeof(titledbInfo->mtime)); if((titledbInfo->cia.exists || titledbInfo->tdsx.exists) && (data->filter == NULL || data->filter(data->userData, titledbInfo))) { string_copy(item->name, titledbInfo->meta.shortDescription, LIST_ITEM_NAME_MAX); item->data = titledbInfo; task_populate_titledb_update_status(item); linked_list_add_sorted(&titles, item, data->userData, data->compare); } else { free(titledbInfo); free(item); } } else { free(item); res = R_APP_OUT_OF_MEMORY; } } else { res = R_APP_OUT_OF_MEMORY; } } } linked_list_iter iter; linked_list_iterate(&titles, &iter); while(linked_list_iter_has_next(&iter)) { list_item* item = linked_list_iter_next(&iter); if(R_SUCCEEDED(res)) { linked_list_add(data->items, item); } else { task_free_titledb(item); linked_list_iter_remove(&iter); } } } else { res = R_APP_BAD_DATA; } json_decref(root); } data->itemsListed = true; if(R_SUCCEEDED(res)) { linked_list_iter iter; linked_list_iterate(&titles, &iter); while(linked_list_iter_has_next(&iter)) { svcWaitSynchronization(task_get_pause_event(), U64_MAX); Handle events[2] = {data->resumeEvent, data->cancelEvent}; s32 index = 0; svcWaitSynchronizationN(&index, events, 2, false, U64_MAX); if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) { break; } list_item* item = (list_item*) linked_list_iter_next(&iter); titledb_info* titledbInfo = (titledb_info*) item->data; char url[128]; if(titledbInfo->cia.exists) { snprintf(url, sizeof(url), "https://3ds.titledb.com/v1/cia/%lu/icon_l.bin", titledbInfo->cia.id); } else if(titledbInfo->tdsx.exists && titledbInfo->tdsx.smdh.exists) { snprintf(url, sizeof(url), "https://3ds.titledb.com/v1/smdh/%lu/icon_l.bin", titledbInfo->tdsx.smdh.id); } else { continue; } u8 icon[0x1200]; u32 iconSize = 0; if(R_SUCCEEDED(http_download(url, &iconSize, &icon, sizeof(icon))) && iconSize == sizeof(icon)) { titledbInfo->meta.texture = screen_allocate_free_texture(); screen_load_texture_tiled(titledbInfo->meta.texture, icon, sizeof(icon), 48, 48, GPU_RGB565, false); } } } linked_list_destroy(&titles); svcCloseHandle(data->resumeEvent); svcCloseHandle(data->cancelEvent); data->result = res; data->finished = true; }
PUBLIC void ui_end() { linked_list_destroy(ui.linked_view); ui.linked_view = NULL; return; }
struct linked_list *ctache_parse(struct linked_list *tokens) { struct linked_list *parsed_rules; struct linked_list_node *token_node; struct ctache_token *token; enum ctache_token_type *token_type_ptr; int match; struct linked_list *stack; /* Set up the stack */ stack = linked_list_create(); push_token_onto_stack(stack, CTACHE_TOK_EOI); push_token_onto_stack(stack, CTACHE_TOK_TEMPLATE); /* Set up the parsed rule list */ parsed_rules = linked_list_create(); /* Parse */ token_node = tokens->first; while (token_node != NULL) { token = token_node->data; token_type_ptr = linked_list_peek(stack); match = parse_table_check_match(*token_type_ptr, token->tok_type); if (*token_type_ptr == token->tok_type) { pop_token_off_stack(stack); token_node = token_node->next; } else if (match >= 0) { pop_token_off_stack(stack); switch (match) { case 0: /* Rule 1: template -> text, template */ push_token_onto_stack(stack, CTACHE_TOK_TEMPLATE); push_token_onto_stack(stack, CTACHE_TOK_TEXT); break; case 1: /* Rule 2: template -> tag, template */ push_token_onto_stack(stack, CTACHE_TOK_TEMPLATE); push_token_onto_stack(stack, CTACHE_TOK_TAG); break; case 2: /* Rule 3: template -> "" */ break; case 3: /* Rule 4: text -> string */ push_token_onto_stack(stack, CTACHE_TOK_STRING); break; case 4: /* Rule 5: text -> "" */ break; case 5: /* Rule 6: tag -> tag start, string, tag end */ push_token_onto_stack(stack, CTACHE_TOK_TAG_END); push_token_onto_stack(stack, CTACHE_TOK_STRING); push_token_onto_stack(stack, CTACHE_TOK_TAG_START); break; case 6: /* Rule 7: tag start -> section tag start */ push_token_onto_stack(stack, CTACHE_TOK_SECTION_TAG_START); break; case 7: /* Rule 8: tag start -> close tag start */ push_token_onto_stack(stack, CTACHE_TOK_CLOSE_TAG_START); break; case 8: /* Rule 9: tag start -> value tag start */ push_token_onto_stack(stack, CTACHE_TOK_VALUE_TAG_START); break; case 9: /* Rule 10: tag start -> unescaped tag start */ push_token_onto_stack(stack, CTACHE_TOK_UNESC_VALUE_TAG_START); break; case 10: /* Rule 11: tag start -> partial tag */ push_token_onto_stack(stack, CTACHE_TOK_PARTIAL_TAG); break; default: break; } append_parsed_rule(parsed_rules, match); } else { int line = token->line; int col = token->character; fprintf(stderr, "Syntax error at line %d, col %d\n", line, col); enum ctache_token_type tok_type = token->tok_type; extern char *ctache_token_names[]; char *token_name = ctache_token_names[tok_type]; char *value = token->value; char *stack_token_name = ctache_token_names[*token_type_ptr]; struct linked_list_node *curr; fprintf(stderr, "token = (%s, \"%s\")\n", token_name, value); fprintf(stderr, "stack top = %s\n", stack_token_name); fprintf(stderr, "Parsed rules: "); for (curr = parsed_rules->first; curr != NULL; curr = curr->next) { fprintf(stderr, "%d", *((int*)curr->data)); if (curr->next != NULL) { fprintf(stderr, ", "); } } fprintf(stderr, "\n"); linked_list_destroy(parsed_rules); parsed_rules = NULL; goto cleanup; } } /* Cleanup */ cleanup: linked_list_destroy(stack); return parsed_rules; }