DWORD WINAPI UpdateThread(void *param) { if(!TryEnterCriticalSection(&cs_update)) { return 1; } stack_update(); LeaveCriticalSection(&cs_update); return 0; }
Node* reduce_graph(Node* root, int r) { Node* aux, *rec; int check = 1; char num1, num2, debug; int n1, n2, res; rec = (Node*) malloc(sizeof(Node)); rec->type = 'r'; if (r == 1){ stack[stack_point] = rec; stack_point++; } aux = root; while (aux != NULL) { stack[stack_point] = aux; aux = aux->left; stack_point = stack_point + 1; } stack_point = stack_point - 1; while (check != 0) { switch (stack[stack_point]->type) { case 'K': if (stack_point - 2 >= 0) { aux = K_reduction(stack[stack_point - 2]); /* It points the rest of graph to the K reducted sub-graph */ if ((stack_point - 3) >= 0 && stack[stack_point - 3]->type != 'r'){ stack[stack_point - 3]->left = aux; } else root = aux; if (stack_point < 3) stack_point = 3; if (stack[stack_point - 3]->type == 'r') stack_point = stack_point - 3; else stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // printf("KOPERATORRRRR\n"); // print_graph(root); // printf("\n\n"); break; case 'S': if (stack_point - 3 >= 0) { // scanf("%c", &debug); aux = S_reduction(stack[stack_point - 3]); if ((stack_point - 4) >= 0 && stack[stack_point - 4]->type != 'r') stack[stack_point - 4]->left = aux; else root = aux; if (stack_point < 4) stack_point = 4; if (stack[stack_point - 4]->type == 'r') stack_point = stack_point - 4; else stack_point = stack_point - 3; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else{ check = 0; } // print_graph(root); // printf("\n\n"); break; case 's': if (stack_point - 4 >= 0) { aux = Sl_reduction(stack[stack_point - 4]); if ((stack_point - 5) >= 0) stack[stack_point - 5]->left = aux; else root = aux; stack_point = stack_point - 4; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'B': if (stack_point - 3 >= 0) { aux = B_reduction(stack[stack_point - 3]); if ((stack_point - 4) >= 0) stack[stack_point - 4]->left = aux; else root = aux; stack_point = stack_point - 3; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'b': if (stack_point - 4 >= 0) { aux = Bl_reduction(stack[stack_point - 4]); if ((stack_point - 5) >= 0) stack[stack_point - 5]->left = aux; else root = aux; stack_point = stack_point - 4; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'C': if (stack_point - 3 >= 0) { aux = C_reduction(stack[stack_point - 3]); if ((stack_point - 4) >= 0) stack[stack_point - 4]->left = aux; else root = aux; stack_point = stack_point - 3; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'c': if (stack_point - 4 >= 0) { aux = Cl_reduction(stack[stack_point - 4]); if ((stack_point - 5) >= 0) stack[stack_point - 5]->left = aux; else root = aux; stack_point = stack_point - 4; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'I': if (stack_point - 1 >= 0) { aux = I_reduction(stack[stack_point - 1]); if ((stack_point - 2) >= 0 && stack[stack_point - 2]->type != 'r'){ stack[stack_point - 2]->left = aux; // stack[stack_point - 2]->type = '@'; } else root = aux; if (stack_point < 2) stack_point = 2; if (stack[stack_point - 2]->type == 'r') stack_point = stack_point - 2; else stack_point = stack_point - 1; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else{ check = 0; } // print_graph(root); // printf("\n\n"); break; case ':': if (stack_point - 2 >= 0) { aux = list_reduction(stack[stack_point]); if (stack[stack_point - 3] >= 0) stack[stack_point - 3]->left = aux; else root = aux; stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case 'h': if (stack_point - 1 >= 0){ if (stack[stack_point - 1]->right->left->type == ':' || stack[stack_point - 1]->right->left->type == 't'){ if (stack[stack_point - 1]->right->left->type == ':'){ aux = head_reduction(stack[stack_point - 1]->right->right); } else if (stack[stack_point - 1]->right->left->type == 't'){ aux = tail_reduction(stack[stack_point - 1]->right->right); aux = head_reduction(aux->right); } }else { printf("Head de nao lista.\n"); } if (stack_point - 2 >= 0) stack[stack_point - 2]->left = aux; else root = aux; stack_point = stack_point - 1; stack[stack_point] = aux; stack_point = stack_update(stack_point); check = 0; // TIRAR ISSO AQUI || SEM ISSO NAO FUNCIONA! } else check = 0; // print_graph(root); // printf("\n\n"); break; case 't': if (stack_point - 1 >= 0){ if (stack[stack_point - 1]->right->left->type == ':' || stack[stack_point - 1]->right->left->type == 't') aux = tail_reduction(stack[stack_point - 1]->right); else printf("Head de nao lista.\n"); if ((stack_point - 2) >= 0) stack[stack_point - 2]->left = aux; else root = aux; stack_point = stack_point - 1; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // print_graph(root); // printf("\n\n"); break; case '=': // printf("\ncomparacao\n"); // print_graph(stack[stack_point-4]); // scanf("%c", &debug); if (stack_point - 2 >= 0){ aux = comp_reduction(stack[stack_point - 2], '='); root = aux; stack_point = 0; print_graph(aux); while (aux->left != NULL){ stack[stack_point] = aux; aux = aux->left; stack_point = stack_point + 1; } stack[stack_point] = aux; // printf("Saiu comparacao\n"); } else check = 0; // print_graph(root); // printf("\n\n"); break; case '>': if (stack_point - 2 >= 0){ aux = comp_reduction(stack[stack_point - 2], '>'); root = aux; stack_point = 0; while (aux->left != NULL){ stack[stack_point] = aux; aux = aux->left; stack_point = stack_point + 1; } stack[stack_point] = aux; // printf("Saiu gt\n"); } else check = 0; break; case '<': if (stack_point - 2 >= 0){ aux = comp_reduction(stack[stack_point - 2], '<'); root = aux; stack_point = 0; while (aux->left != NULL){ stack[stack_point] = aux; aux = aux->left; stack_point = stack_point + 1; } stack[stack_point] = aux; // printf("Saiu lt\n"); } else check = 0; break; case '+': if (stack_point - 2 >= 0){ aux = add_reduction(stack[stack_point - 2]); if ((stack_point - 3) >= 0 && stack[stack_point - 3]->type != 'r'){ stack[stack_point - 3]->left = aux; } else root = aux; if (stack_point < 3) stack_point = 3; if (stack[stack_point - 3]->type == 'r') stack_point = stack_point - 3; else stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // printf("operador +\n"); // print_graph(root); // printf("\n\n"); break; case '-': if (stack_point - 2 >= 0){ aux = sub_reduction(stack[stack_point - 2]); if ((stack_point - 3) >= 0 && stack[stack_point - 3]->type != 'r'){ stack[stack_point - 3]->left = aux; } else root = aux; if (stack_point < 3) stack_point = 3; if (stack[stack_point - 3]->type == 'r') stack_point = stack_point - 3; else stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // printf("\noperador -\n"); // print_graph(root); // printf("\n\n"); break; case '*': if (stack_point - 2 >= 0){ aux = mul_reduction(stack[stack_point - 2]); if ((stack_point - 3) >= 0 && stack[stack_point - 3]->type != 'r'){ stack[stack_point - 3]->left = aux; } else root = aux; if (stack_point < 3) stack_point = 3; if (stack[stack_point - 3]->type == 'r') stack_point = stack_point - 3; else stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // printf("\noperador -\n"); // print_graph(root); // printf("\n\n"); break; case '/': if (stack_point - 2 >= 0){ aux = div_reduction(stack[stack_point - 2]); if ((stack_point - 3) >= 0 && stack[stack_point - 3]->type != 'r'){ stack[stack_point - 3]->left = aux; } else root = aux; if (stack_point < 3) stack_point = 3; if (stack[stack_point - 3]->type == 'r') stack_point = stack_point - 3; else stack_point = stack_point - 2; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else check = 0; // printf("\noperador -\n"); // print_graph(root); // printf("\n\n"); break; case 'Y': if (stack_point - 1 >= 0) { // scanf("%c", &debug); aux = Y_reduction(stack[stack_point - 1]); if ((stack_point - 2) >= 0 && stack[stack_point - 2]->type != 'r') stack[stack_point - 2]->left = aux; else root = aux; if (stack_point < 2) stack_point = 2; if (stack[stack_point - 2]->type == 'r') stack_point = stack_point - 2; else stack_point = stack_point - 1; stack[stack_point] = aux; stack_point = stack_update(stack_point); } else{ check = 0; } // print_graph(root); // printf("\n\n"); break; case 'n': // printf("\nn case!!!!\n"); aux = stack[stack_point]; root = aux; // print_graph(aux); // printf("\n"); check = 0; break; default: // printf("\n"); // printf("\nEntrou no default\n"); // printf("STACK[STACK_POINT]"); // print_graph(stack[stack_point]); // printf("%c\n", stack[stack_point]->type); // printf("\n\n"); if (r == 0) root = stack[stack_point]; check = 0; break; } } return root; }
int __cdecl wmain(int argc, wchar_t *wargv[]) { int ret = 0; // Global URL cache to not download anything twice json_t *url_cache = json_object(); // Repository ID cache to prioritize the most local repository if more // than one repository with the same name is discovered in the network json_t *id_cache = json_object(); json_t *repo_list = NULL; const char *start_repo = "http://thcrap.nmlgc.net/repos/nmlgc/"; json_t *sel_stack = NULL; json_t *new_cfg = json_pack("{s[]}", "patches"); size_t cur_dir_len = GetCurrentDirectory(0, NULL) + 1; VLA(char, cur_dir, cur_dir_len); json_t *games = NULL; const char *run_cfg_fn = NULL; const char *run_cfg_fn_js = NULL; char *run_cfg_str = NULL; json_t *args = json_array_from_wchar_array(argc, wargv); wine_flag = GetProcAddress( GetModuleHandleA("kernel32.dll"), "wine_get_unix_file_name" ) != 0; strings_mod_init(); log_init(1); // Necessary to correctly process *any* input of non-ASCII characters // in the console subsystem w32u8_set_fallback_codepage(GetOEMCP()); GetCurrentDirectory(cur_dir_len, cur_dir); PathAddBackslashA(cur_dir); str_slash_normalize(cur_dir); // Maximize the height of the console window... unless we're running under // Wine, where this 1) doesn't work and 2) messes up the console buffer if(!wine_flag) { CONSOLE_SCREEN_BUFFER_INFO sbi = {0}; HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); COORD largest = GetLargestConsoleWindowSize(console); HWND console_wnd = GetConsoleWindow(); RECT console_rect; GetWindowRect(console_wnd, &console_rect); SetWindowPos(console_wnd, NULL, console_rect.left, 0, 0, 0, SWP_NOSIZE); GetConsoleScreenBufferInfo(console, &sbi); sbi.srWindow.Bottom = largest.Y - 4; SetConsoleWindowInfo(console, TRUE, &sbi.srWindow); } http_init(); if(json_array_size(args) > 1) { start_repo = json_array_get_string(args, 1); } log_printf( "==========================================\n" "Touhou Community Reliant Automatic Patcher - Patch configuration tool\n" "==========================================\n" "\n" "\n" "This tool will create a new patch configuration for the\n" "Touhou Community Reliant Automatic Patcher.\n" "\n" "\n" "The configuration process has two steps:\n" "\n" "\t\t1. Selecting patches\n" "\t\t2. Download game-independent data\n" "\t\t3. Locating game installations\n" "\t\t4. Download game-specific data\n" "\n" "\n" "\n" "Patch repository discovery will start at\n" "\n" "\t%s\n" "\n" "You can specify a different URL as a command-line parameter.\n" "Additionally, all patches from previously discovered repositories, stored in\n" "subdirectories of the current directory, will be available for selection.\n" "\n" "\n", start_repo ); pause(); if(RepoDiscoverAtURL(start_repo, id_cache, url_cache)) { goto end; } if(RepoDiscoverFromLocal(id_cache, url_cache)) { goto end; } repo_list = RepoLoad(); if(!json_object_size(repo_list)) { log_printf("No patch repositories available...\n"); pause(); goto end; } sel_stack = SelectPatchStack(repo_list); if(json_array_size(sel_stack)) { json_t *new_cfg_patches = json_object_get(new_cfg, "patches"); size_t i; json_t *sel; log_printf("Downloading game-independent data...\n"); stack_update(update_filter_global, NULL); /// Build the new run configuration json_array_foreach(sel_stack, i, sel) { json_array_append_new(new_cfg_patches, patch_build(sel)); } }
/*---------------------------------------------------------------------------- * rumavl_delete - deletes a node. Beware! this function is the worst part of * the library. Think (and draw pictures) when you edit this function. *--------------------------------------------------------------------------*/ int rumavl_delete (RUMAVL *tree, const void *record) { RUMAVL_NODE **node, *tmpnode; RUMAVL_STACK *stack; int dir, ln; if (tree->root == NULL) /* tree is empty */ return RUMAVL_ERR_NOENT; stack = NULL; node = &tree->root; /* Find desired node */ while ((dir = rec_cmp(tree, record, NODE_REC(*node))) != 0){ if (stack_push(tree, &stack, node, dir) != 0) goto nomemout; if ((*node)->thread[LINK_NO(dir)] > 0){ /* desired node does not exist */ stack_destroy(tree, stack); return RUMAVL_ERR_NOENT; } node = &(*node)->link[LINK_NO(dir)]; } /* OK, we got the node to be deleted, now get confirmation from user */ if (tree->delcb != NULL && (ln = tree->delcb(tree, *node, NODE_REC(*node), tree->udata)) != 0){ stack_destroy(tree, stack); return ln; } if ((*node)->thread[LEFT] > 0){ if ((*node)->thread[RIGHT] > 0){ /* ooh look, we're a leaf */ tmpnode = *node; if (stack != NULL){ /* This node has a parent, which will need to take over a * thread from the node being deleted. First we work out * which (left/right) child we are of parent, then give * parent the respective thread. If the thread destination * points back to us (edge of tree thread), update it to * point to our parent. */ ln = LINK_NO(stack->dir); (*stack->node)->link[ln] = tmpnode->link[ln]; (*stack->node)->thread[ln] = tmpnode->thread[ln]; if ((*stack->node)->thread[ln] == 2) (*stack->node)->link[ln]->link[OTHER_LINK(ln)] = *stack->node; }else{ /* * the only time stack will == NULL is when we are * deleting the root of the tree. We already know that * this is a leaf, so we will be leaving the tree empty. */ tree->root = NULL; } node_destroy(tree, tmpnode); }else{ /* *node has only one child, and can be pruned by replacing * *node with its only child. This block of code and the next * should be identical, except that all directions and link * numbers are opposite. * * Let node being deleted = DELNODE for this comment. * DELNODE only has one child (the right child). The left * most descendant of DELNODE will have a thread (left thread) * pointing to DELNODE. This thread must be updated to point * to the node currently pointed to by DELNODE's left thread. * * DELNODE's left thread may point to the opposite edge of the * BST. In this case, the destination of the thread will have * a thread back to DELNODE. This will need to be updated to * point back to the leftmost descendant of DELNODE. */ tmpnode = *node; /* node being deleted */ *node = (*node)->link[RIGHT]; /* right child */ /* find left most descendant */ while ((*node)->thread[LEFT] == 0) node = &(*node)->link[LEFT]; /* inherit thread from node being deleted */ (*node)->link[LEFT] = tmpnode->link[LEFT]; (*node)->thread[LEFT] = tmpnode->thread[LEFT]; /* update reverse thread if necessary */ if ((*node)->thread[LEFT] == 2) (*node)->link[LEFT]->link[RIGHT] = *node; node_destroy(tree, tmpnode); } }else if ((*node)->thread[RIGHT] > 0){ /* see above */ tmpnode = *node; *node = (*node)->link[LEFT]; while ((*node)->thread[RIGHT] == 0) node = &(*node)->link[RIGHT]; (*node)->link[RIGHT] = tmpnode->link[RIGHT]; (*node)->thread[RIGHT] = tmpnode->thread[RIGHT]; if ((*node)->thread[RIGHT] == 2) (*node)->link[RIGHT]->link[LEFT] = *node; node_destroy(tree, tmpnode); }else{ /* Delete a node with children on both sides. We do this by replacing * the node to be deleted (delnode) with its inner most child * on the heavier side (repnode). This in place replacement is quicker * than the previously used method of rotating delnode until it is a * (semi) leaf. * * At this point node points to delnode's parent's link to delnode. */ RUMAVL_NODE *repnode, *parent; int outdir, outln; /* find heaviest subtree */ if ((*node)->balance > 0){ outdir = +1; /* outter direction */ dir = -1; /* inner direction */ outln = 1; /* outer link number */ ln = 0; /* inner link number */ }else{ outdir = -1; /* same as above, but opposite subtree */ dir = +1; outln = 0; ln = 1; } /* Add node to be deleted to the list of nodes to be rebalanced. * Rememer that the replacement node will actually be acted apon, * and that the replacement node should feel the effect of its own * move */ if (stack_push(tree, &stack, node, outdir) != 0) goto nomemout; parent = *node; repnode = parent->link[outln]; if (repnode->thread[ln] != 0){ /* repnode inherits delnode's lighter tree, and balance, and gets * balance readjusted below */ repnode->link[ln] = (*node)->link[ln]; repnode->thread[ln] = (*node)->thread[ln]; repnode->balance = (*node)->balance; }else{ /* Now we add delnodes direct child to the list of "to update". * We pass a pointer to delnode's link to its direct child to * stack_push(), but that pointer is invalid, because when * stack_update() tries to access the link, delnode would have * been destroyed. So, we remember the stack position at which * we passed the faulty pointer to stack_push, and update its * node pointer when we find repnode to point to repnodes * link on the same side */ RUMAVL_STACK *tmpstack; if (stack_push(tree, &stack, &parent->link[outln], dir) != 0) goto nomemout; tmpstack = stack; parent = repnode; repnode = repnode->link[ln]; /* move towards the innermost child of delnode */ while (repnode->thread[ln] == 0){ if (stack_push(tree, &stack, &parent->link[ln], dir) != 0) goto nomemout; parent = repnode; repnode = repnode->link[ln]; } if (repnode->thread[outln] == 0){ /* repnode's parent inherits repnodes only child */ parent->link[ln] = repnode->link[outln]; }else{ /* parent already has a link to repnode, but it must now be * marked as a thread */ parent->thread[ln] = 1; } repnode->link[0] = (*node)->link[0]; repnode->thread[0] = (*node)->thread[0]; repnode->link[1] = (*node)->link[1]; repnode->thread[1] = (*node)->thread[1]; repnode->balance = (*node)->balance; /* see comment above */ tmpstack->node = &repnode->link[outln]; } node_destroy(tree, *node); *node = repnode; /* innermost child in lighter tree has an invalid thread to delnode, * update it to point to repnode */ repnode = seq_next(repnode, dir); repnode->link[outln] = *node; } /* update parents' balances */ stack_update(tree, stack, -1); return 0; nomemout: stack_destroy(tree, stack); return RUMAVL_ERR_NOMEM; }
/*---------------------------------------------------------------------------- * rumavl_set - set a node, overwriting if necessary, or creating if the node * does not exist *--------------------------------------------------------------------------*/ int rumavl_set (RUMAVL *tree, const void *record) { RUMAVL_NODE **node, *tmp; RUMAVL_STACK *stack; int ln; if (tree->root == NULL){ /* This is the first node in the tree */ if ((tree->root = node_new(tree, record)) == NULL) return RUMAVL_ERR_NOMEM; tree->root->link[LEFT] = tree->root; tree->root->link[RIGHT] = tree->root; tree->root->thread[LEFT] = 2; tree->root->thread[RIGHT] = 2; return 0; } /* Since the tree is not empty, we must descend towards the nodes ideal * possition, and we may even find an existing node with the same record. * We keep a list parents for the eventual node position, because these * parents may become inbalanced by a new insertion. */ stack = NULL; node = &tree->root; for (;;){ if ((ln = rec_cmp(tree, record, NODE_REC(*node))) == 0){ /* OK, we found the exact node we wish to set, and we now * overwrite it. No change happens to the tree structure */ stack_destroy(tree, stack); if (tree->owcb != NULL && (ln = tree->owcb(tree, *node, NODE_REC(*node), record, tree->udata)) != 0){ return ln; } memcpy(NODE_REC(*node), record, tree->reclen); return 0; } /* *node is not the node we seek */ if (stack_push(tree, &stack, node, ln)){ stack_destroy(tree, stack); return RUMAVL_ERR_NOMEM; } ln = LINK_NO(ln); if ((*node)->thread[ln] > 0){ /* This is as close to the correct node as we can get. We will * now break and add the new node as a leaf */ break; } node = &(*node)->link[ln]; } /* we have reached a leaf, add new node here */ if ((tmp = node_new(tree, record)) == NULL){ stack_destroy(tree, stack); return RUMAVL_ERR_NOMEM; } /* new child inherits parent thread */ tmp->link[ln] = (*node)->link[ln]; tmp->thread[ln] = (*node)->thread[ln]; if (tmp->thread[ln] == 2) tmp->link[ln]->link[OTHER_LINK(ln)] = tmp; tmp->link[OTHER_LINK(ln)] = *node; tmp->thread[OTHER_LINK(ln)] = 1; (*node)->link[ln] = tmp; (*node)->thread[ln] = 0; /* all parentage is now one level heavier - balance where necessary */ stack_update(tree, stack, +1); return 0; }