void make_wallchart_info (void) { struct info_buffer * wc = find_or_make_info ("unexpanded_wallchart"); struct info_buffer * wc_expanded = find_or_make_info ("wallchart"); if (wc->len == 0) { char ** txt = forminfo_text ("keybindings-wallchart"); if (!txt) io_error_msg ("<bug> Wallchart is missing!"); wc->len = parray_len (txt); wc->text = txt; } clear_info (wc_expanded); expand_help_msg (wc_expanded, wc); }
void describe_function (char * name) { int vector; struct cmd_func * cmd; if (!( !find_function (&vector, &cmd, name, strlen(name)) && cmd->func_doc)) io_error_msg ("%s is not a function.", name); /* no return */ { struct info_buffer * ib_disp = find_or_make_info ("help-buffer"); clear_info (ib_disp); print_info (ib_disp, ""); print_info (ib_disp, "%s", name); { struct info_buffer ib; /* FIXME: * Something is screwed up here. ib.len is wrongly identified * for help texts defined through name-macro-string. Looks * like it should always be 1. I _really_ don't know what I am * doing here. This is a hack. And probably stoopid. But for * now it's better than the current core-dump-on-help behaviour. * * * for (ib.len = 0; cmd->func_doc[ib.len]; ++ib.len) ; */ ib.len = 1; ib.text = cmd->func_doc; ib.name = name; expand_help_msg (ib_disp, &ib); } } { static char buf[] = "{view-info help-buffer}"; run_string_as_macro (buf); } }
void builtin_help (char * name) { char info_name[100]; struct info_buffer * ib; if (strlen (name) > sizeof (info_name) - 20) io_error_msg ("No built in help for %s.", name); sprintf (info_name, "_info_%s", name); ib = find_info (info_name); if (!ib) { char ** msg = forminfo_text (name); if (!msg) { msg = (char **)ck_malloc (sizeof (char *) * 2); msg[0] = mk_sprintf ("No built in help for %s.", name); msg[1] = 0; } ib = find_or_make_info (info_name); ib->len = parray_len (msg); ib->text = msg; } { char exp_name[200]; char command[250]; struct info_buffer * expanded; sprintf (exp_name, "_expanded_%s", info_name); expanded = find_or_make_info (exp_name); clear_info (expanded); expand_help_msg (expanded, ib); sprintf (command, "{set-info %s}", exp_name); run_string_as_macro (command); } }
/* * spi write data * Input: hign: hign 8 bit data * low: low 8 bit data * Output: read u16 data * */ static u16 spi_send16(u8 hign, u8 low) { u32 i = 0; u8 save_data = 0; u32 count = 0; u16 data = 0; u8 line; SPI_TXRX_ON; SPI_CS_LOW; Delay(5); //延时时间参考814x数据手册的要求 clear_info(); write_byte(hign); udelay(10); write_byte(low); if ((hign & 0xc0) == 0x80) { line = (hign >> 3) & 0x03; udelay(g_spi_send_delay[line]); }
int main(int argc, char *argv[]) { size_t path_len, total_files; off_t bytes_wasted, total_wasted; char path_buffer[PATH_MAX_LEN], *hash_value; struct file_entry_t *file_entry, *trie_entry; SListIterator slist_iterator; SetIterator set_iterator; /* Step 0: Session data */ struct file_info_t file_info; clear_info(&file_info); /* Step 1: Parse arguments */ while (--argc) { /* Being unable to record implies insufficient resources */ if (!record(argv[argc], &file_info)){ fprintf(stderr, "[FATAL] out of memory\n"); destroy_info(&file_info); return (EXIT_FAILURE); } } /* Step 2: Fully explore any directories specified */ #ifndef NDEBUG printf("[DEBUG] Creating file list...\n"); #endif while (slist_length(file_info.file_stack) > 0) { /* Pick off the top of the file stack */ file_entry = (struct file_entry_t *)(slist_data(file_info.file_stack)); slist_remove_entry(&file_info.file_stack, file_info.file_stack); assert(file_entry->type == DIRECTORY); /* Copy the basename to a buffer */ memset(path_buffer, '\0', PATH_MAX_LEN); path_len = strnlen(file_entry->path, PATH_MAX_LEN); memcpy(path_buffer, file_entry->path, path_len); /* Ignore cases that would cause overflow */ if (path_len < PATH_MAX_LEN) { /* Append a trailing slash */ path_buffer[path_len] = '/'; /* Record all contents (may push onto file stack or one of the lists) */ DIR *directory = opendir(file_entry->path); if (traverse(&file_info, directory, path_buffer, ++path_len)) { fprintf(stderr, "[FATAL] out of memory\n"); destroy_info(&file_info); return (EXIT_FAILURE); } else if (closedir(directory)) { fprintf(stderr, "[WARNING] '%s' (close failed)\n", file_entry->path); } } /* Discard this entry */ destroy_entry(file_entry); } /* Step 3: Warn about any ignored files */ if (slist_length(file_info.bad_files) > 0) { slist_iterate(&file_info.bad_files, &slist_iterator); while (slist_iter_has_more(&slist_iterator)) { file_entry = slist_iter_next(&slist_iterator); fprintf(stderr, "[WARNING] '%s' ", file_entry->path); switch (file_entry->type) { case INVALID: ++file_info.invalid_files; fprintf(stderr, "(invalid file)\n"); break; case INACCESSIBLE: ++file_info.protected_files; fprintf(stderr, "(protected file)\n"); break; default: ++file_info.irregular_files; fprintf(stderr, "(irregular file)\n"); break; } } fprintf(stderr, "[WARNING] %lu file(s) ignored\n", (long unsigned)(num_errors(&file_info))); } #ifndef NDEBUG if (num_errors(&file_info) > 0) { fprintf(stderr, "[FATAL] cannot parse entire file tree\n"); destroy_info(&file_info); return (EXIT_FAILURE); } printf("[DEBUG] Found %lu / %lu valid files\n", (unsigned long)(num_files(&file_info)), (unsigned long)(file_info.total_files)); #endif /* Step 4: Begin the filtering process */ #ifndef NDEBUG printf("[DEBUG] Creating file table...\n"); #endif if (slist_length(file_info.good_files) > 0) { file_info.hash_trie = trie_new(); file_info.shash_trie = trie_new(); optimize_filter(&file_info); /* Extract each file from the list (they should all be regular) */ slist_iterate(&file_info.good_files, &slist_iterator); while (slist_iter_has_more(&slist_iterator)) { file_entry = slist_iter_next(&slist_iterator); assert(file_entry->type == REGULAR); /* Perform a "shallow" hash of the file */ hash_value = hash_entry(file_entry, SHALLOW); #ifndef NDEBUG printf("[SHASH] %s\t*%s\n", file_entry->path, hash_value); #endif /* Check to see if we might have seen this file before */ if (bloom_filter_query(file_info.shash_filter, hash_value)) { /* Get the full hash of the new file */ hash_value = hash_entry(file_entry, FULL); #ifndef NDEBUG printf("[+HASH] %s\t*%s\n", file_entry->path, hash_value); #endif archive(&file_info, file_entry); /* Check to see if bloom failed us */ trie_entry = trie_lookup(file_info.shash_trie, file_entry->shash); if (trie_entry == TRIE_NULL) { #ifndef NDEBUG printf("[DEBUG] '%s' (false positive)\n", file_entry->path); #endif trie_insert(file_info.shash_trie, file_entry->shash, file_entry); } else { /* Get the full hash of the old file */ hash_value = hash_entry(trie_entry, FULL); #ifndef NDEBUG if (hash_value) { printf("[-HASH] %s\t*%s\n", trie_entry->path, hash_value); } #endif archive(&file_info, trie_entry); } } else { /* Add a record of this shash to the filter */ bloom_filter_insert(file_info.shash_filter, hash_value); trie_insert(file_info.shash_trie, hash_value, file_entry); } } persist("bloom_store", &file_info); } /* Step 5: Output results and cleanup before exit */ printf("[EXTRA] Found %lu sets of duplicates...\n", (unsigned long)(slist_length(file_info.duplicates))); slist_iterate(&file_info.duplicates, &slist_iterator); for (total_files = total_wasted = bytes_wasted = 0; slist_iter_has_more(&slist_iterator); total_wasted += bytes_wasted) { Set *set = slist_iter_next(&slist_iterator); int size = set_num_entries(set); if (size < 2) { continue; } printf("[EXTRA] %lu files (w/ same hash):\n", (unsigned long)(size)); set_iterate(set, &set_iterator); for (bytes_wasted = 0; set_iter_has_more(&set_iterator); bytes_wasted += file_entry->size, ++total_files) { file_entry = set_iter_next(&set_iterator); printf("\t%s (%lu bytes)\n", file_entry->path, (unsigned long)(file_entry->size)); } } printf("[EXTRA] %lu bytes in %lu files (wasted)\n", (unsigned long)(total_wasted), (unsigned long)(total_files)); destroy_info(&file_info); return (EXIT_SUCCESS); }