int main() { struct watch *root = inotify_watch_new(0, "/"); struct watch *ch1 = inotify_watch_new(1, "/var/"); struct watch *ch2 = inotify_watch_new(2, "/mnt/"); inotify_watch_add(root, ch1); inotify_watch_add(root, ch2); inotify_watch_add(ch1, inotify_watch_new(11, "/var/a/")); inotify_watch_add(ch1, inotify_watch_new(12, "/var/b/")); inotify_watch_add(ch2, inotify_watch_new(21, "/mnt/c/")); inotify_watch_add((struct watch*)ch2->tree.child, inotify_watch_new(234, "/mnt/c/a/")); tree_traverse((struct tree*)root, print_node, NULL); inotify_watch_rm(ch1); printf("---\n"); tree_traverse((struct tree*)root, print_node, NULL); inotify_watch_add(root, ch1); printf("---\n"); tree_traverse((struct tree*)root, print_node, NULL); inotify_watch_destroy(root, NULL); return 0; }
/* traverse the tree in order */ void tree_traverse (tree_node * leaf) { if (leaf) { tree_traverse (leaf->left); printf ("%d .", leaf->key); tree_traverse (leaf->right); } }
tree_init(device *root, psim *system) { TRACE(trace_device_tree, ("tree_init(root=0x%lx, system=0x%lx)\n", (long)root, (long)system)); /* remove the old, rebuild the new */ tree_traverse(root, device_clean, NULL, system); tree_traverse(root, device_init_static_properties, NULL, system); tree_traverse(root, device_init_address, NULL, system); tree_traverse(root, device_init_runtime_properties, NULL, system); tree_traverse(root, device_init_data, NULL, system); }
int main() { int choice = 0; void *root = NULL; while (1) { printf ("1. Add node\n"); printf ("2. Print tree in BFS\n"); printf ("3. Print tree in DFS\n"); printf ("4. Exit\n"); printf ("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: { int *data = NULL, parent; void *pnode = NULL, *n = NULL; printf ("Enter parent: "); scanf ("%d", &parent); pnode = tree_traverse(root, BFS, compare_data, &parent); if (!pnode) { assert(!root); } data = (int *)calloc (1, sizeof(*data)); printf ("Enter data: "); scanf ("%d", data); n = tree_add_node(pnode, data); if (!root) root = n; } break; case 2: tree_traverse(root, BFS, print_tree, NULL); printf ("\n"); break; case 3: tree_traverse(root, DFS, print_tree, NULL); printf ("\n"); break; case 4: exit(0); break; default: printf ("Invalid choice!\n"); break; } } }
size_t tr_tree_traverse(tr_tree* tree, dict_visit_func visit) { ASSERT(tree != NULL); ASSERT(visit != NULL); return tree_traverse(tree, visit); }
Expr *expr_copy(Expr *orig) { Expr *copy; if (orig == NULL) return NULL; copy = tree_copy(orig); tree_traverse(copy, expr_copy_helper); return copy; }
void tree_traverse (void *tree, TREE_PROCESS *process, int method) { if ((!tree) || (tree == TREE_NULL)) return; if (method == 1) { (process) (tree); tree_traverse (((TREE *) tree)-> left, process, method); tree_traverse (((TREE *) tree)-> right, process, method); } else if (method == 2) { tree_traverse (((TREE *) tree)-> left, process, method); tree_traverse (((TREE *) tree)-> right, process, method); (process) (tree); } else { tree_traverse (((TREE *) tree)-> left, process, method); (process) (tree); tree_traverse (((TREE *) tree)-> right, process, method); } }
tree_traverse(device *root, tree_traverse_function *prefix, tree_traverse_function *postfix, void *data) { device *child; if (prefix != NULL) prefix(root, data); for (child = device_child(root); child != NULL; child = device_sibling(child)) { tree_traverse(child, prefix, postfix, data); } if (postfix != NULL) postfix(root, data); }
/* Completely empty the job queue and signal the removal of underlying * runq work. Runq work will take longer to die, however, as their * processes may not have come to an end. */ void job_clear() { ITREE *keys; if (!job_tab) /* do nothing if not initialised */ return; /* for safty make a duplicate list */ keys = itree_create(); tree_traverse(job_tab) itree_add(keys, itree_getkey(job_tab), NULL); /* Traverse the job_tab list and delete the associated storage */ /* The loop below always resets to a known state */ elog_printf(DEBUG, "removing %d jobs", itree_n(job_tab)); itree_traverse(keys) { job_rm( itree_getkey(keys) ); } itree_destroy(keys); }
tree_print(device *root) { tree_traverse(root, print_device, NULL, NULL); }
void parse_program(char *filename) { printf("parsing file: %s\n", filename); yyfiles = list_new(NULL, &free); log_assert(yyfiles); list_push_back(yyfiles, filename); yyclibs = list_new(NULL, &free); log_assert(yyclibs); yyincludes = hasht_new(8, true, NULL, NULL, NULL); log_assert(yyincludes); /* open file for lexer */ yyin = fopen(filename, "r"); if (yyin == NULL) log_error("could not open input file: %s", filename); /* push buffer state for lexer */ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); /* setup yytypes table for lexer */ yytypes = hasht_new(8, true, NULL, NULL, &free_typename); log_assert(yytypes); /* reset library flags */ libs.usingstd = false; libs.cstdlib = false; libs.cmath = false; libs.ctime = false; libs.cstring = false; libs.fstream = false; libs.iostream = false; libs.string = false; libs.iomanip = false; log_debug("invoking Bison"); int result = yyparse(); if (result != 0) exit(2); /* print syntax tree */ if (arguments.tree) tree_traverse(yyprogram, 0, &print_tree, NULL, NULL); /* initialize scope stack */ log_debug("setting up for semantic analysis"); yyscopes = list_new(NULL, NULL); log_assert(yyscopes); struct hasht *global = hasht_new(32, true, NULL, NULL, &symbol_free); log_assert(global); list_push_back(yyscopes, global); /* build the symbol tables */ log_debug("populating symbol tables"); region = GLOBE_R; offset = 0; symbol_populate(yyprogram); log_debug("global scope had %zu symbols", hasht_used(global)); /* constant symbol table put in front of stack for known location */ struct hasht *constant = hasht_new(32, true, NULL, NULL, &symbol_free); log_assert(constant); list_push_front(yyscopes, constant); region = CONST_R; offset = 0; log_debug("type checking"); type_check(yyprogram); /* generating intermediate code */ log_debug("generating intermediate code"); yylabels = 0; /* reset label counter */ code_generate(yyprogram); struct list *code = ((struct node *)yyprogram->data)->code; /* iterate to get correct size of constant region */ size_t string_size = 0; for (size_t i = 0; i < constant->size; ++i) { struct hasht_node *slot = constant->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *v = slot->value; if (v->base == FLOAT_T) string_size += 8; else if (v->base == CHAR_T && v->pointer) string_size += v->token->ssize; } } /* print intermediate code file if debugging */ if (arguments.debug) { char *output_file; asprintf(&output_file, "%s.ic", filename); FILE *ic = fopen(output_file, "w"); if (ic == NULL) log_error("could not save to output file: %s", output_file); fprintf(ic, ".file \"%s\"\n", filename); /* print .string region */ fprintf(ic, ".string %zu\n", string_size); /* iterate to print everything but ints, chars, and bools */ for (size_t i = 0; i < constant->size; ++i) { struct hasht_node *slot = constant->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *v = slot->value; if (v->base == FLOAT_T || (v->base == CHAR_T && v->pointer)) { fprintf(ic, " "); print_typeinfo(ic, slot->key, v); fprintf(ic, "\n"); } } } /* print .data region */ fprintf(ic, ".data\n"); for (size_t i = 0; i < global->size; ++i) { struct hasht_node *slot = global->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *value = slot->value; if (value->base != FUNCTION_T) { fprintf(ic, " "); print_typeinfo(ic, slot->key, value); fprintf(ic, "\n"); } } } fprintf(ic, ".code\n"); print_code(ic, code); fclose(ic); free(output_file); } log_debug("generating final code"); /* copy because Wormulon */ char *copy = strdup(filename); char *base = basename(copy); free(copy); char *output_file; asprintf(&output_file, "%s.c", base); FILE *fc = fopen(output_file, "w"); if (fc == NULL) log_error("could not save to output file: %s", output_file); time_t t = time(NULL); struct tm *local = localtime(&t); char timestamp[60]; strftime(timestamp, sizeof(timestamp), "%F %T", local); fprintf(fc, "/*\n"); fprintf(fc, " * %s - 120++ Three-Address C Code\n", output_file); fprintf(fc, " * Generated @ %s\n", timestamp); fprintf(fc, " *\n"); fprintf(fc, " * Created by Andrew Schwartzmeyer's 120++ Compiler\n"); fprintf(fc, " * Project located @ https://github.com/andschwa/uidaho-cs445\n"); fprintf(fc, " */\n\n"); fprintf(fc, "/* Required includes for TAC-C */\n"); fprintf(fc, "#include <stdlib.h>\n"); fprintf(fc, "#include <stdbool.h>\n"); fprintf(fc, "#include <string.h>\n"); if (libs.usingstd && libs.iostream) fprintf(fc, "#include <stdio.h>\n"); fprintf(fc, "\n"); /* include passed-through C headers */ fprintf(fc, "/* Source-file C headers */\n"); struct list_node *iter = list_head(yyclibs); while (!list_end(iter)) { fprintf(fc, "#include %s\n", (char *)iter->data); iter = iter->next; } fprintf(fc, "\n"); /* get maximum param size for faux stack */ size_t max_param_size = 0; iter = list_head(code); while (!list_end(iter)) { struct op *op = iter->data; if (op->code == PROC_O) { size_t param_size = op->address[0].offset; if (param_size > max_param_size) max_param_size = param_size; } iter = iter->next; } fprintf(fc, "/* Memory regions */\n"); fprintf(fc, "char constant[%zu];\n", string_size); fprintf(fc, "char global[%zu];\n", global->size); fprintf(fc, "char stack[%zu];\n", max_param_size); fprintf(fc, "\n"); fprintf(fc, "/* Final Three-Address C Generated Code */\n"); final_code(fc, code); fclose(fc); /* remove TAC-C "assembler" code */ if (!arguments.assemble) { /* compile object files */ char *command; asprintf(&command, "gcc -c %s", output_file); int status = system(command); if (status != 0) log_error("command failed: %s", command); remove(output_file); } free(output_file); /* clean up */ log_debug("cleaning up"); tree_free(yyprogram); yylex_destroy(); hasht_free(yytypes); free(yyincludes); /* values all referenced elsewhere */ list_free(yyfiles); list_free(yyclibs); list_free(yyscopes); }