/* * The following functions below implement printing / dumping of statistical * information. */ static void stat_dump_mem_contents(stat_mem_block_t *block, uint16_t cols) { unsigned char *buffer = (unsigned char *)mem_a(cols); unsigned char *memory = (unsigned char *)(block + 1); size_t i; for (i = 0; i < block->size; i++) { if (!(i % 16)) { if (i != 0) con_out(" %s\n", buffer); con_out(" 0x%08X: ", i); } con_out(" %02X", memory[i]); buffer[i % cols] = ((memory[i] < 0x20) || (memory[i] > 0x7E)) ? '.' : memory[i]; buffer[(i % cols) + 1] = '\0'; } while ((i % cols) != 0) { con_out(" "); i++; } con_out(" %s\n", buffer); mem_d(buffer); }
void vfu_redraw_status() /* redraw bottom status, total,free,selected... */ { VString s1; VString s2; VString tmp; /* first line here */ s1 = "Select:"; tmp = sel_count; str_comma(tmp); str_pad(tmp,14); s1 += tmp; s1 += " Free: "; tmp = fsize_fmt( fs_free ); str_pad(tmp,14); s1 += tmp; if (fs_total == 0 || fs_free > fs_total) tmp = " n/a%"; else sprintf( 64, tmp, "%5.1f%%", (double)100 * ((double)fs_free / (double)fs_total)); s1 += " " + tmp + " FSize:"; tmp = fsize_fmt( files_size ); str_pad(tmp,14); s1 += tmp; if (fs_total == 0 || files_size > fs_total) tmp = " n/a%"; else sprintf(tmp,"%4.1f%%", (double)100 * ((double)files_size / (double)fs_total)); s1 += " " + tmp; /* second line here */ s2 = "S.Size:"; tmp = fsize_fmt( sel_size ); str_pad(tmp,14); s2 += tmp; s2 += " Total:"; tmp = fsize_fmt( fs_total ); str_pad(tmp,14); s2 += tmp; tmp = fs_block_size; str_pad( tmp,5 ); s2 += " [" + tmp + "]"; sprintf( tmp," %s.%s@%s ", user_id_str.data(), group_id_str.data(), host_name_str.data() ); s2 += tmp; str_pad( s1, - con_max_x() ); str_pad( s2, - con_max_x() ); con_out( 1, con_max_y()-3, s1, cINFO2 ); con_out( 1, con_max_y()-2, s2, cINFO2 ); }
/* * Actual loading subsystem, this finds the ini or cfg file, and properly * loads it and executes it to set compiler options. */ void opts_ini_init(const char *file) { /* * Possible matches are: * gmqcc.ini * gmqcc.cfg */ char *error = NULL; char *parse_file = NULL; size_t line; fs_file_t *ini; if (!file) { /* try ini */ if (!(ini = fs_file_open((file = "gmqcc.ini"), "r"))) /* try cfg */ if (!(ini = fs_file_open((file = "gmqcc.cfg"), "r"))) return; } else if (!(ini = fs_file_open(file, "r"))) return; con_out("found ini file `%s`\n", file); parse_file = util_strdup(file); if ((line = opts_ini_parse(ini, &opts_ini_load, &error, &parse_file)) != 0) { /* there was a parse error with the ini file */ con_printmsg(LVL_ERROR, parse_file, line, 0 /*TODO: column for ini error*/, "error", error); vec_free(error); } mem_d(parse_file); fs_file_close(ini); }
static void stat_dump_mem_leaks(void) { stat_mem_block_t *info; /* we need access to the root for this */ VALGRIND_MAKE_MEM_DEFINED(stat_mem_block_root, sizeof(stat_mem_block_t)); for (info = stat_mem_block_root; info; info = info->next) { /* we need access to the block */ VALGRIND_MAKE_MEM_DEFINED(info, sizeof(stat_mem_block_t)); con_out("lost: %u (bytes) at %s:%u from expression `%s`\n", info->size, info->file, info->line, info->expr ); stat_dump_mem_contents(info, OPTS_OPTION_U16(OPTION_MEMDUMPCOLS)); /* * we're finished with the access, the redzone should be marked * inaccesible so that invalid read/writes that could 'step-into' * those redzones will show up as invalid read/writes in valgrind. */ VALGRIND_MAKE_MEM_NOACCESS(info, sizeof(stat_mem_block_t)); } VALGRIND_MAKE_MEM_NOACCESS(stat_mem_block_root, sizeof(stat_mem_block_t)); }
void vfu_draw( int n ) { VFU_CHECK_LIST_POS( n ); if ( n < FLP || n > FLP + PS ) return; /* we are out of screen -- don't draw */ TF* fi = files_list[n]; int c = fi->color(); /* color to be used */ VString view = fi->view(); if ( fi->sel ) { str_set_ch( view, sel_mark_pos, '#' ); c = CONCOLOR(cBLACK,cWHITE); } if ( n == FLI ) { str_set_ch( view, tag_mark_pos , TAGMARKS[opt.tag_mark_type][0] ); str_set_ch( view, tag_mark_pos+1, TAGMARKS[opt.tag_mark_type][1] ); c += cBOLD; /* this is a hack, can be removed w/o warning :) -- more visibility */ if ( c == 120 ) c = cTAG; // 116; // 123; // 63; // 123 } con_out( 1, n - FLP + 4, view, c ); // con_ce( c ); }
int con_full_box( int x, int y, const char *title, VArray *va, ConMenuInfo *menu_info ) { ScrollPos scroll; scroll.wrap = 0; scroll.set_min_max( 0, va->count()-1 ); scroll.set_pagesize( con_max_y() - 3 ); /* one title and two status */ scroll.go( 0 ); char pos_str[32]; con_xy( 1, 1 ); con_puts( title, menu_info->ti ); con_ce( menu_info->ti ); while(4) { VString str; int z; for( z = 0; z < scroll.pagesize(); z++ ) { if ( scroll.page() + z < va->count() ) str = va->get( scroll.page() + z ); else str = "~"; str = str_dot_reduce( str, con_max_x()-1 ); con_xy( 1, z + 2 ); int c = ( scroll.page() + z == scroll.pos() ) ? menu_info->ch : menu_info->cn; con_puts( str, c ); con_ce( c ); } sprintf( pos_str, " %5d of %5d", scroll.pos()+1, scroll.max()+1 ); con_out( con_max_x() - 15, 1, pos_str, menu_info->ti ); int ch; switch( (ch = con_getch()) ) { case 27 : menu_info->ec = 27; return -1; break; case 8 : menu_info->ec = 8; return -1; break; case KEY_BACKSPACE : menu_info->ec = KEY_BACKSPACE; return -1; break; case 13 : menu_info->ec = 13; return scroll.pos(); break; case KEY_UP : scroll.up(); break; case KEY_DOWN : scroll.down(); break; case KEY_NPAGE : scroll.npage(); break; case KEY_PPAGE : scroll.ppage(); break; case KEY_HOME : scroll.home(); break; case KEY_END : scroll.end(); break; default: if ( tolower(ch) == tolower(menu_info->ac) ) { menu_info->ec = menu_info->ac; return -2; } break; } } }
void stat_info() { if (OPTS_OPTION_BOOL(OPTION_MEMCHK) || OPTS_OPTION_BOOL(OPTION_STATISTICS)) { uint64_t mem = 0; con_out("Memory Statistics:\n\ Total vectors allocated: %llu\n\ Total string duplicates: %llu\n\ Total string duplicate memory: %f (MB)\n\ Total hashtables allocated: %llu\n\ Total unique vector sizes: %llu\n", stat_used_vectors, stat_used_strdups, (float)(stat_mem_strdups) / 1048576.0f, stat_used_hashtables, stat_type_vectors ); stat_dump_stats_table ( stat_size_vectors, " %2u| # of %5u byte vectors: %u\n", &mem ); con_out ( " Total unique hashtable sizes: %llu\n", stat_type_hashtables ); stat_dump_stats_table ( stat_size_hashtables, " %2u| # of %5u element hashtables: %u\n", NULL ); con_out ( " Total vector memory: %f (MB)\n\n", (float)(mem) / 1048576.0f ); }
void util_debug(const char *area, const char *ms, ...) { va_list va; if (!opts.debug) return; if (!strcmp(area, "MEM") && !opts.memchk) return; va_start(va, ms); con_out ("[%s] ", area); con_vout(ms, va); va_end (va); }
static void code_stats(const char *filename, const char *lnofile, code_t *code, prog_header_t *code_header) { if (OPTS_OPTION_BOOL(OPTION_QUIET) || OPTS_OPTION_BOOL(OPTION_PP_ONLY)) return; con_out("\nFile statistics:\n"); con_out(" dat:\n"); con_out(" name: %s\n", filename); con_out(" size: %u (bytes)\n", code_size_binary(code, code_header)); con_out(" crc: 0x%04X\n", code->crc); if (lnofile) { con_out(" lno:\n"); con_out(" name: %s\n", lnofile); con_out(" size: %u (bytes)\n", code_size_debug(code, code_header)); } con_out("\n"); }
bool fold_generate(fold_t *fold, ir_builder *ir) { /* generate globals for immediate folded values */ size_t i; ast_value *cur; for (i = 0; i < vec_size(fold->imm_float); ++i) if (!ast_global_codegen ((cur = fold->imm_float[i]), ir, false)) goto err; for (i = 0; i < vec_size(fold->imm_vector); ++i) if (!ast_global_codegen((cur = fold->imm_vector[i]), ir, false)) goto err; for (i = 0; i < vec_size(fold->imm_string); ++i) if (!ast_global_codegen((cur = fold->imm_string[i]), ir, false)) goto err; return true; err: con_out("failed to generate global %s\n", cur->name); ir_builder_delete(ir); return false; }
static void stat_dump_stats_table(stat_size_table_t table, const char *string, uint64_t *size) { size_t i,j; if (!table) return; for (i = 0, j = 1; i < ST_SIZE; i++) { stat_size_entry_t *entry; if (!(entry = table[i])) continue; con_out(string, (unsigned)j, (unsigned)entry->key, (unsigned)entry->value); j++; if (size) *size += entry->key * entry->value; } }
void tree_draw_page( ScrollPos &scroll ) { VString str = " "; str_mul( str, con_max_x() ); str = " SiZE DiRECTORY" + str; str_sleft( str, con_max_x()-16 ); con_out(1,3, str, cHEADER ); int z = 0; for(z = 0; z < scroll.pagesize(); z++) { if (scroll.page() + z <= scroll.max()) { tree_draw_item( scroll.page(), z ); } else { con_xy( 1, 3+1+z ); con_puts( "~", cCYAN ); con_ce( cCYAN ); } } }
/* * This is the heart of the whole test-suite process. This cleans up * any existing temporary files left behind as well as log files left * behind. Then it propagates a list of tests from `curdir` by scaning * it for template files and compiling them into tasks, in which it * schedualizes them (executes them) and actually reports errors and * what not. It then proceeds to destroy the tasks and return memory * it's the engine :) * * It returns true of tests could be propagated, otherwise it returns * false. * * It expects con_init() was called before hand. */ static GMQCC_WARN bool test_perform(const char *curdir, const char *defs) { size_t failed = false; static const char *default_defs = "defs.qh"; size_t pad[] = { /* test ### [succeed/fail]: `description` [tests/template.tmpl] [type] */ 0, 0, 0 }; /* * If the default definition file isn't set to anything. We will * use the default_defs here, which is "defs.qc" */ if (!defs) { defs = default_defs; } task_precleanup(curdir); if (!task_propagate(curdir, pad, defs)) { con_err("error: failed to propagate tasks\n"); task_destroy(); return false; } /* * If we made it here all tasks where propagated from their resultant * template file. So we can start the FILO scheduler, this has been * designed in the most thread-safe way possible for future threading * it's designed to prevent lock contention, and possible syncronization * issues. */ failed = task_schedualize(pad); if (failed) con_out("%u out of %u tests failed\n", failed, vec_size(task_tasks)); task_destroy(); return (failed) ? false : true; }
static void code_create_header(code_t *code, prog_header_t *code_header, const char *filename, const char *lnofile) { size_t i; code_header->statements.offset = sizeof(prog_header_t); code_header->statements.length = vec_size(code->statements); code_header->defs.offset = code_header->statements.offset + (sizeof(prog_section_statement_t) * vec_size(code->statements)); code_header->defs.length = vec_size(code->defs); code_header->fields.offset = code_header->defs.offset + (sizeof(prog_section_def_t) * vec_size(code->defs)); code_header->fields.length = vec_size(code->fields); code_header->functions.offset = code_header->fields.offset + (sizeof(prog_section_field_t) * vec_size(code->fields)); code_header->functions.length = vec_size(code->functions); code_header->globals.offset = code_header->functions.offset + (sizeof(prog_section_function_t) * vec_size(code->functions)); code_header->globals.length = vec_size(code->globals); code_header->strings.offset = code_header->globals.offset + (sizeof(int32_t) * vec_size(code->globals)); code_header->strings.length = vec_size(code->chars); code_header->version = 6; code_header->skip = 0; if (OPTS_OPTION_BOOL(OPTION_FORCECRC)) code_header->crc16 = OPTS_OPTION_U16(OPTION_FORCED_CRC); else code_header->crc16 = code->crc; code_header->entfield = code->entfields; if (OPTS_FLAG(DARKPLACES_STRING_TABLE_BUG)) { /* >= + P */ vec_push(code->chars, '\0'); /* > */ vec_push(code->chars, '\0'); /* = */ vec_push(code->chars, '\0'); /* P */ } /* ensure all data is in LE format */ util_swap_header(code_header); /* * These are not part of the header but we ensure LE format here to save on duplicated * code. */ util_swap_statements (code->statements); util_swap_defs_fields(code->defs); util_swap_defs_fields(code->fields); util_swap_functions (code->functions); util_swap_globals (code->globals); if (!OPTS_OPTION_BOOL(OPTION_QUIET)) { if (lnofile) con_out("writing '%s' and '%s'...\n", filename, lnofile); else con_out("writing '%s'\n", filename); } if (!OPTS_OPTION_BOOL(OPTION_QUIET) && !OPTS_OPTION_BOOL(OPTION_PP_ONLY)) { char buffer[1024]; con_out("\nOptimizations:\n"); for (i = 0; i < COUNT_OPTIMIZATIONS; ++i) { if (opts_optimizationcount[i]) { util_optimizationtostr(opts_opt_list[i].name, buffer, sizeof(buffer)); con_out( " %s: %u\n", buffer, (unsigned int)opts_optimizationcount[i] ); } } } }
static size_t task_schedualize(size_t *pad) { char space[2][64]; bool execute = false; char *data = NULL; char **match = NULL; size_t size = 0; size_t i = 0; size_t j = 0; size_t failed = 0; util_snprintf(space[0], sizeof(space[0]), "%d", (int)vec_size(task_tasks)); for (; i < vec_size(task_tasks); i++) { memset(space[1], 0, sizeof(space[1])); util_snprintf(space[1], sizeof(space[1]), "%d", (int)(i + 1)); con_out("test #%u %*s", i + 1, strlen(space[0]) - strlen(space[1]), ""); /* * Generate a task from thin air if it requires execution in * the QCVM. */ /* diagnostic is not executed, but compare tested instead, like preproessor */ execute = !! (!strcmp(task_tasks[i].tmpl->proceduretype, "-execute")) || (!strcmp(task_tasks[i].tmpl->proceduretype, "-pp")) || (!strcmp(task_tasks[i].tmpl->proceduretype, "-diagnostic")); /* * We assume it compiled before we actually compiled :). On error * we change the value */ task_tasks[i].compiled = true; /* * Read data from stdout first and pipe that stuff into a log file * then we do the same for stderr. */ while (fs_file_getline(&data, &size, task_tasks[i].runhandles[1]) != FS_FILE_EOF) { fs_file_puts(task_tasks[i].stdoutlog, data); if (strstr(data, "failed to open file")) { task_tasks[i].compiled = false; execute = false; } } while (fs_file_getline(&data, &size, task_tasks[i].runhandles[2]) != FS_FILE_EOF) { /* * If a string contains an error we just dissalow execution * of it in the vm. * * TODO: make this more percise, e.g if we print a warning * that refers to a variable named error, or something like * that .. then this will blowup :P */ if (strstr(data, "error") && strcmp(task_tasks[i].tmpl->proceduretype, "-diagnostic")) { execute = false; task_tasks[i].compiled = false; } fs_file_puts (task_tasks[i].stderrlog, data); fs_file_flush(task_tasks[i].stderrlog); /* fast flush for read */ } if (!task_tasks[i].compiled && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) { con_out("failure: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), task_tasks[i].tmpl->rulesfile, (pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen("(failed to compile)") - pad[2]), "(failed to compile)" ); failed++; continue; } if (task_pclose(task_tasks[i].runhandles) != EXIT_SUCCESS && strcmp(task_tasks[i].tmpl->proceduretype, "-fail")) { con_out("failure: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), task_tasks[i].tmpl->rulesfile, (pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen("(compiler didn't return exit success)") - pad[2]), "(compiler didn't return exit success)" ); failed++; continue; } if (!execute) { con_out("succeeded: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), task_tasks[i].tmpl->rulesfile, (pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen(task_type(task_tasks[i].tmpl)) - pad[2]), task_type(task_tasks[i].tmpl) ); continue; } /* * If we made it here that concludes the task is to be executed * in the virtual machine (or the preprocessor output needs to * be matched). */ if (!task_trymatch(i, &match)) { size_t d = 0; con_out("failure: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), task_tasks[i].tmpl->rulesfile, (pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen( (strcmp(task_tasks[i].tmpl->proceduretype, "-pp")) ? "(invalid results from execution)" : (strcmp(task_tasks[i].tmpl->proceduretype, "-diagnostic")) ? "(invalid results from preprocessing)" : "(invalid results from compiler diagnsotics)" ) - pad[2]), (strcmp(task_tasks[i].tmpl->proceduretype, "-pp")) ? "(invalid results from execution)" : (strcmp(task_tasks[i].tmpl->proceduretype, "-diagnostic")) ? "(invalid results from preprocessing)" : "(invalid results from compiler diagnsotics)" ); /* * Print nicely formatted expected match lists to console error * handler for the all the given matches in the template file and * what was actually returned from executing. */ con_out(" Expected From %u Matches: (got %u Matches)\n", vec_size(task_tasks[i].tmpl->comparematch), vec_size(match) ); for (; d < vec_size(task_tasks[i].tmpl->comparematch); d++) { char *select = task_tasks[i].tmpl->comparematch[d]; size_t length = 60 - strlen(select); con_out(" Expected: \"%s\"", select); while (length --) con_out(" "); con_out("| Got: \"%s\"\n", (d >= vec_size(match)) ? "<<nothing else to compare>>" : match[d]); } /* * Print the non-expected out (since we are simply not expecting it) * This will help track down bugs in template files that fail to match * something. */ if (vec_size(match) > vec_size(task_tasks[i].tmpl->comparematch)) { for (d = 0; d < vec_size(match) - vec_size(task_tasks[i].tmpl->comparematch); d++) { con_out(" Expected: Nothing | Got: \"%s\"\n", match[d + vec_size(task_tasks[i].tmpl->comparematch)] ); } } for (j = 0; j < vec_size(match); j++) mem_d(match[j]); vec_free(match); failed++; continue; } for (j = 0; j < vec_size(match); j++) mem_d(match[j]); vec_free(match); con_out("succeeded: `%s` %*s %*s\n", task_tasks[i].tmpl->description, (pad[0] + pad[1] - strlen(task_tasks[i].tmpl->description)) + (strlen(task_tasks[i].tmpl->rulesfile) - pad[1]), task_tasks[i].tmpl->rulesfile, (pad[1] + pad[2] - strlen(task_tasks[i].tmpl->rulesfile)) + (strlen(task_type(task_tasks[i].tmpl))- pad[2]), task_type(task_tasks[i].tmpl) ); } mem_d(data); return failed; }
int con_toggle_box( int x, int y, const char *title, ToggleEntry* toggles, ConMenuInfo *menu_info ) { ScrollPos scroll; int z; int w = -1; int h = -1; int maxlen = 0; int count = 0; while( toggles[count].key != -1 ) { int sl = strlen( toggles[count].name ); if (sl > maxlen) maxlen = sl; count++; } maxlen += 6+3; // 6 for state string and 3 for " key " string in the front if (w == -1) w = maxlen; if (h == -1) h = count; z = strlen(title); if (w < z) w = z; if (h > count) h = count; if (h == 0) h = 1; // FIXME: those should be fixed!!! if (x + w > con_max_x()) w = con_max_x() - x - 1; if (y + h > con_max_y()-4) h = con_max_y() - y - 5; VString str; VString str1; VString hots = ""; for(z = 0; z < count; z++) if (strncmp("--", toggles[z].name, 2)) str_add_ch( hots, toggles[z].key ); else str_add_ch( hots,' ' ); con_xy(x,y); int ch = 0; str = ""; str = title; str_pad( str,-w, menu_info->bo ? '-' : ' ' ); if (str_len(str) > w) str_sleft(str,w); if (menu_info->bo) str = ".-" + str + "-."; else str = " " + str + " "; con_out(x,y,str,menu_info->ti); y++; scroll.wrap = 1; scroll.set_min_max( 0, count-1 ); scroll.set_pagesize( h ); scroll.go( 0 ); while(1) { for( z = 0; z < scroll.pagesize(); z++ ) { if (scroll.page() + z >= count) { str = " ~"; str_pad( str, -(w+2), ' '); } else { int sep = (strncmp("--", toggles[scroll.page()+z].name, 2) == 0); if (sep) { str = ""; str += toggles[scroll.page()+z].name; str_pad( str, -w, '-'); str += "--"; } else { str = " "; str_add_ch( str, toggles[scroll.page()+z].key ); str += " "; str += toggles[scroll.page()+z].name; str_pad( str, -(w-6), ' '); str1 = toggles[scroll.page()+z].states[*(toggles[scroll.page()+z].data)]; str_pad( str1, 6, ' '); str1 += " "; str += " " + str1; } } if (menu_info->bo) str = "|" + str + "|"; else str = " " + str + " "; // if (str.len() > w) StrSLeft(str,w); // str = " " + str + " "; con_out( x, y+z, str, ( scroll.page()+z != scroll.pos() ) ? menu_info->cn : menu_info->ch ); } if (menu_info->bo) { str = ""; str_pad( str, w+2, '-' ); str = "`" + str + "'"; con_out( x, y+scroll.pagesize(), str, menu_info->cn ); } ch = con_getch(); menu_info->ec = ch; if ( ch == KEY_UP ) scroll.up(); if ( ch == KEY_DOWN ) scroll.down(); if ( ch == KEY_NPAGE ) scroll.npage(); if ( ch == KEY_PPAGE ) scroll.ppage(); if ( ch == KEY_HOME ) scroll.home(); if ( ch == KEY_END ) scroll.end(); if ( ch < 0 || ch > 255 ) continue; if ( ch == 27 ) return 0; if ( ch == 13 /* && strncmp("--", toggles[scroll.pos].name, 2) */ ) return 1; z = ( ch == ' ' ) ? scroll.pos() : z = str_find( hots, ch ); if (z > -1 && strncmp("--", toggles[z].name, 2) ) { int state = *(toggles[z].data) + 1; if (toggles[z].states[state] == NULL) state = 0; *(toggles[z].data) = state; } } return -1; }
int con_menu_box( int x, int y, const char *title, VArray *va, int hotkeys, ConMenuInfo *menu_info ) { ScrollPos scroll; int z; int w = -1; int h = -1; if (w == -1) w = va->max_len(); if (h == -1) h = va->count(); z = strlen(title); if (w < z) w = z; if (h > va->count()) h = va->count(); if (h == 0) h = 1; // FIXME: those should be fixed!!! if (x + w > con_max_x()) w = con_max_x() - x - 4; if (y + h > con_max_y()-4) h = con_max_y() - y - 4; VString str; VString hots = ""; if ( hotkeys > -1 ) { for(z = 0; z < va->count(); z++) if (strncmp("--", va->get(z), 2)) str_add_ch( hots, char(((const char*)(va->get(z)))[hotkeys]) ); else str_add_ch( hots,' ' ); str_up(hots); } con_xy(x,y); int ch = 0; str = " "; str += title; str += " "; str_pad( str,-(w), menu_info->bo ? '-' : ' ' ); if (str_len(str) > w) str_sleft(str,w); if (menu_info->bo) str = ".-" + str + "-."; else str = " " + str + " "; con_out(x,y,str,menu_info->ti); y++; scroll.wrap = 1; scroll.set_min_max( 0, va->count()-1 ); scroll.set_pagesize( h ); scroll.go( 0 ); while(1) { for( z = 0; z < scroll.pagesize(); z++ ) { str = (scroll.page()+z >= va->count())? "~" : va->get(scroll.page()+z); if ( menu_info->hide_magic[0] ) { int i = str_rfind( str, menu_info->hide_magic ); if ( i != -1) str_sleft( str, i ); } str_pad( str,-w , (strncmp("--", str, 2) == 0)?'-':' '); if (str_len(str) > w) str = str_dot_reduce( str, w ); if (menu_info->bo) str = "| " + str + " |"; else str = " " + str + " "; con_out( x, y+z, str, ( scroll.page()+z != scroll.pos() ) ? menu_info->cn : menu_info->ch ); } if (menu_info->bo) { str = ""; str_pad( str, w+2, '-' ); str = "`" + str + "'"; con_out( x, y+scroll.pagesize(), str, menu_info->cn ); } ch = con_getch(); menu_info->ec = ch; if ( ch == KEY_UP ) scroll.up(); if ( ch == KEY_DOWN ) scroll.down(); if ( ch == KEY_NPAGE ) scroll.npage(); if ( ch == KEY_PPAGE ) scroll.ppage(); if ( ch == KEY_HOME ) scroll.home(); if ( ch == KEY_END ) scroll.end(); if ( ch < 0 || ch > 255 ) continue; if ( ch == 27 ) { menu_info->ac = 0; return -1; } if ( ch == 13 ) { if (strncmp("--", va->get(scroll.pos()), 2) != 0) // ako e "--" e separator { menu_info->ec = hots[scroll.pos()]; menu_info->ac = -1; return scroll.pos(); } } if ( menu_info->ac > -1 && ch == menu_info->ac ) { if (strncmp("--", va->get(scroll.pos()), 2) != 0) // ako e "--" e separator { menu_info->ec = hots[scroll.pos()]; menu_info->ac = -2; return scroll.pos(); } } z = str_find( hots, toupper(ch) ); if (z > -1) { menu_info->ec = hots[z]; menu_info->ac = -1; return z; } } menu_info->ac = -1; return -1; };
int TextInput( int x, int y, const char *prompt, int maxlen, int fieldlen, VString *strres, void (*handlekey)( int key, VString &s, int &pos ) ) { int res = 0; int insert = 1; VString str = *strres; VString tmp; int ch; ScrollPos scroll; scroll.set_min_max( 0, str_len( str ) ); scroll.set_pagesize( fieldlen ); scroll.go( str_len(str) ); int show = 1; int firsthit = 1; int opage = -1; con_cshow(); while(1) { if (opage != scroll.page()) show = 1; if (show) { str_copy( tmp, str, scroll.page(), scroll.pagesize() ); str_pad( tmp, -scroll.pagesize() ); tmp = " " + tmp + " "; if ( scroll.page() > 0 ) str_set_ch( tmp, 0, '<' ); if ( scroll.page()+scroll.pagesize() < str_len(str) ) str_set_ch( tmp, str_len(tmp)-1, '>' ); con_out(x, y, tmp, firsthit ? EditStrFH : EditStrBF ); show = 0; opage = scroll.page(); } con_xy( x + scroll.pos() - scroll.page() + 1 , y ); ch = con_getch(); if( ch >= 32 && ch <= 255 && ch != KEY_BACKSPACE && str_len(str) < maxlen - 1 ) { if (firsthit) { str = ""; scroll.go(0); firsthit = 0; } if (!insert) str_del( str, scroll.pos(), 1 ); str_ins_ch( str, scroll.pos(), ch ); scroll.set_min_max( 0, str_len( str ) ); scroll.go( scroll.pos() ); scroll.down(); show = 1; }; if (firsthit) { show = 1; firsthit = 0; } if( ch == 27 ) { res = 0; break; } else if( ch == 13 ) { *strres = str; res = 1; break; } else if( ch == KEY_CTRL_U ) { scroll.go(0); str = ""; show = 1; } else if( (ch == KEY_BACKSPACE || ch == 8 ) && (scroll.pos() > 0) ) { scroll.up(); str_del( str, scroll.pos(), 1 ); show = 1; } else if ( ch == KEY_IC ) insert = !insert; else if ( ch == KEY_LEFT ) scroll.up(); else if ( ch == KEY_RIGHT ) scroll.down(); else /* if ( ch == KEY_PPAGE ) scroll.ppage(); else if ( ch == KEY_NPAGE ) scroll.npage(); else */ if ( ch == KEY_HOME || ch == KEY_CTRL_A ) scroll.go(0); else if ( ch == KEY_END || ch == KEY_CTRL_E ) scroll.go(str_len(str)); else if ( ( ch == KEY_DC || ch == KEY_CTRL_D ) && scroll.pos() < str_len(str) ) { str_del( str, scroll.pos(), 1 ); show = 1; } else if ( handlekey ) { int npos = scroll.pos(); handlekey( ch, str, npos ); scroll.set_min_max( 0, str_len( str ) ); scroll.go( scroll.pos() ); if (scroll.pos() != npos) scroll.go( npos ); show = 1; } scroll.set_min_max( 0, str_len( str ) ); scroll.go( scroll.pos() ); } con_chide(); return res; }
void show_pos( int curr, int all ) { char t[64]; sprintf( t, "%5d of %5d", curr, all ); con_out( con_max_x() - 13, 3, t, cHEADER ); }
void con_out( int x, int y, const char *s ) { con_out( x, y, s, __ta ); }
/*#######################################################################*/ extern const char *FTIMETYPE[]; /* in vfuopt.cpp */ void vfu_redraw() /* redraw file list and header */ { char t[MAX_PATH]; VString str; str = "Mask: "; str += files_mask; con_out(1,1,str,cINFO); con_ce(cINFO); if ( work_mode == WM_ARCHIVE ) con_out( con_max_x()-34, 1, " [-ARCHIVE-] ", cWARNING ); con_out(con_max_x()-17,1,"Press H for help",cINFO); con_out(con_max_x()-20,1,"VFU " VFU_VERSION " <H> for help",cINFO); str = "Path: "; str += work_path; if ( work_mode == WM_ARCHIVE ) { str += "["; str += archive_name; str += "]/"; /* NOTE: to simulate root dir visually */ str += archive_path; } str = str_dot_reduce( str, con_max_x()-1 ); con_out(1,2,str,cINFO); con_ce(cINFO); str = ""; if ( opt.sort_order == 'N' ) str = "NAME"; if ( opt.sort_order == 'M' ) str = "NAME#"; if ( opt.sort_order == 'E' ) str = "EXT"; if ( opt.sort_order == 'A' ) str = "MODE"; if ( opt.sort_order == 'O' ) str = "OWNER"; if ( opt.sort_order == 'G' ) str = "GROUP"; if ( opt.sort_order == 'T' ) str = "MTIME"; if ( opt.sort_order == 'H' ) str = "CTIME"; if ( opt.sort_order == 'C' ) str = "ATIME"; if ( opt.sort_order == 'S' ) str = "SIZE"; if ( opt.sort_order == 'Y' ) str = "TYPE"; str += opt.sort_direction == 'A' ? "+" : "-"; str = "(SORT:" + str + ")"; con_out( con_max_x() - str_len( str ) + 1, 2, str, cHEADER ); str = ""; t[0] = 0; char *spos = t; if (opt.sort_order == 'D') opt.sort_order = 'T'; /* hack anyway */ if (!opt.long_name_view) { if (opt.f_mode ) spos += sprintf( spos, "%10s ", MODE_STRING ); if (opt.f_owner ) spos += sprintf( spos, " OWNER " ); if (opt.f_group ) spos += sprintf( spos, " GROUP " ); if (opt.f_time ) spos += sprintf( spos, "%s TiME ", FTIMETYPE[opt.f_time_type] ); if (opt.f_size ) spos += sprintf( spos, filesize_fmt, "SiZE" ); }; if ( opt.f_mode + opt.f_owner + opt.f_group + opt.f_time + opt.f_size + opt.f_type == 0 ) opt.f_type = 1; /* a hack really :) if all fields are off -- turn on type one */ if (opt.f_type || opt.long_name_view) spos += sprintf( spos, "TP" ); tag_mark_pos = strlen( t ); sel_mark_pos = tag_mark_pos + 2; spos += sprintf( spos, " #NAME %s", opt.long_name_view ? "( long name view )" : "" ); str_pad( t, - con_max_x() ); str_sleft( t, con_max_x() ); con_out(1,3, t, cHEADER ); show_pos( FLI+1, files_count ); int z; for ( z = 0; z < PS; z++ ) { ASSERT( FLP + z >= 0 ); if ( FLP + z >= files_count ) { con_out( 1, z+4, "~", cPLAIN ); con_ce( cPLAIN ); } else if ( files_list[FLP+z] == NULL ) /* FIXME: if NULL?! */ { con_out( 1, z+4, "~", cPLAIN ); con_ce( cPLAIN ); } else vfu_draw( FLP + z ); } if ( files_count <= 0 ) con_out( ( con_max_x() - 20 ) / 2, 10, " *** No files found *** ", cHEADER); }