Introduce COVERAGE_ON/OFF macros, rename shell functions to shell_*.

Coverage collection slowdown is ~75x now.
This commit is contained in:
Ivan Baravy 2020-03-10 00:03:57 +03:00
parent 70fc19fc5e
commit 7d3dea91c0
7 changed files with 250 additions and 142 deletions

View File

@ -60,38 +60,38 @@ size_t count_block_bytes(FILE *f) {
int is_cond_jump(const char *s) { int is_cond_jump(const char *s) {
s += strspn(s, " \t"); s += strspn(s, " \t");
int found = !strncasecmp(s, "jo", 2) int found = !strncmp(s, "jo", 2)
|| !strncasecmp(s, "jno", 3) || !strncmp(s, "jno", 3)
|| !strncasecmp(s, "js", 2) || !strncmp(s, "js", 2)
|| !strncasecmp(s, "jns", 3) || !strncmp(s, "jns", 3)
|| !strncasecmp(s, "je", 2) || !strncmp(s, "je", 2)
|| !strncasecmp(s, "jne", 3) || !strncmp(s, "jne", 3)
|| !strncasecmp(s, "jz", 2) || !strncmp(s, "jz", 2)
|| !strncasecmp(s, "jnz", 3) || !strncmp(s, "jnz", 3)
|| !strncasecmp(s, "jb", 2) || !strncmp(s, "jb", 2)
|| !strncasecmp(s, "jnb", 3) || !strncmp(s, "jnb", 3)
|| !strncasecmp(s, "jc", 2) || !strncmp(s, "jc", 2)
|| !strncasecmp(s, "jnc", 3) || !strncmp(s, "jnc", 3)
|| !strncasecmp(s, "jae", 3) || !strncmp(s, "jae", 3)
|| !strncasecmp(s, "jnae", 4) || !strncmp(s, "jnae", 4)
|| !strncasecmp(s, "jbe", 3) || !strncmp(s, "jbe", 3)
|| !strncasecmp(s, "jna", 3) || !strncmp(s, "jna", 3)
|| !strncasecmp(s, "ja", 2) || !strncmp(s, "ja", 2)
|| !strncasecmp(s, "jnbe", 4) || !strncmp(s, "jnbe", 4)
|| !strncasecmp(s, "jl", 2) || !strncmp(s, "jl", 2)
|| !strncasecmp(s, "jnge", 4) || !strncmp(s, "jnge", 4)
|| !strncasecmp(s, "jge", 3) || !strncmp(s, "jge", 3)
|| !strncasecmp(s, "jnl", 3) || !strncmp(s, "jnl", 3)
|| !strncasecmp(s, "jle", 3) || !strncmp(s, "jle", 3)
|| !strncasecmp(s, "jng", 3) || !strncmp(s, "jng", 3)
|| !strncasecmp(s, "jg",2) || !strncmp(s, "jg",2)
|| !strncasecmp(s, "jnle", 4) || !strncmp(s, "jnle", 4)
|| !strncasecmp(s, "jp", 2) || !strncmp(s, "jp", 2)
|| !strncasecmp(s, "jpe", 3) || !strncmp(s, "jpe", 3)
|| !strncasecmp(s, "jnp", 3) || !strncmp(s, "jnp", 3)
|| !strncasecmp(s, "jpo", 3) || !strncmp(s, "jpo", 3)
|| !strncasecmp(s, "jcxz", 4) || !strncmp(s, "jcxz", 4)
|| !strncasecmp(s, "jecxz", 5); || !strncmp(s, "jecxz", 5);
return found; return found;
} }

View File

@ -1,7 +1,7 @@
FASM=fasm FASM=fasm
CC=gcc CC=gcc
WARNINGS=-Wall -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wjump-misses-init -Wshadow -Wformat=2 -Wswitch -Wswitch-enum #-Wconversion -Wsign-conversion WARNINGS=-Wall -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wjump-misses-init -Wshadow -Wformat=2 -Wswitch -Wswitch-enum #-Wconversion -Wsign-conversion
CFLAGS=$(WARNINGS) -g -O0 -D_FILE_OFFSET_BITS=64 -Wno-address-of-packed-member -DNDEBUG -masm=intel CFLAGS=$(WARNINGS) -std=c99 -g -O0 -D_FILE_OFFSET_BITS=64 -Wno-address-of-packed-member -DNDEBUG -masm=intel -D_POSIX_C_SOURCE=200809L
CFLAGS_32=$(CFLAGS) -m32 CFLAGS_32=$(CFLAGS) -m32
LDFLAGS= LDFLAGS=
LDFLAGS_32=$(LDFLAGS) -m32 LDFLAGS_32=$(LDFLAGS) -m32
@ -51,10 +51,10 @@ vdisk.o: vdisk.c
$(CC) $(CFLAGS_32) -c $< $(CC) $(CFLAGS_32) -c $<
umka_shell.o: umka_shell.c kolibri.h trace.h syscalls.h umka_shell.o: umka_shell.c kolibri.h trace.h syscalls.h
$(CC) $(CFLAGS_32) -c $< -std=c99 -D_POSIX_C_SOURCE=2 $(CC) $(CFLAGS_32) -c $<
umka_fuse.o: umka_fuse.c kolibri.h umka_fuse.o: umka_fuse.c kolibri.h
$(CC) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $< -std=gnu99 $(CC) $(CFLAGS_32) `pkg-config fuse3 --cflags` -c $<
tools/mkdirrange: tools/mkdirrange.c tools/mkdirrange: tools/mkdirrange.c
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@

View File

@ -8,3 +8,11 @@ void trace_begin() {
void trace_end() { void trace_end() {
trace_lbr_end(); trace_lbr_end();
} }
uint32_t trace_pause(void) {
return trace_lbr_pause();
}
void trace_resume(uint32_t value) {
trace_lbr_resume(value);
}

View File

@ -1,7 +1,13 @@
#ifndef TRACE_H_INCLUDED #ifndef TRACE_H_INCLUDED
#define TRACE_H_INCLUDED #define TRACE_H_INCLUDED
#define COVERAGE_ON() do { trace_resume(coverage); } while (0)
#define COVERAGE_OFF() do { coverage = trace_pause(); } while (0)
void trace_begin(void); void trace_begin(void);
void trace_end(void); void trace_end(void);
uint32_t trace_pause(void);
void trace_resume(uint32_t value);
#endif #endif

View File

@ -59,18 +59,23 @@ void handle_sigtrap() {
wrmsr(MSR_IA32_DEBUGCTLMSR, 3); wrmsr(MSR_IA32_DEBUGCTLMSR, 3);
} }
void set_eflags_tf(uint32_t tf) { uint32_t set_eflags_tf(uint32_t tf) {
uint32_t prev;
__asm__ __inline__ __volatile__ ( __asm__ __inline__ __volatile__ (
"pushfd;" "pushfd;"
"pop eax;" "pop eax;"
"shl ecx, 8;" // TF "ror eax, 8;"
"and eax, ~(1 << 8);" "mov edx, eax;"
"and edx, 1;"
"and eax, ~1;"
"or eax, ecx;" "or eax, ecx;"
"rol eax, 8;"
"push eax;" "push eax;"
"popfd" "popfd"
: : "=d"(prev)
: "c"(tf) : "c"(tf)
: "eax", "memory"); : "eax", "memory");
return prev;
} }
void trace_lbr_begin() { void trace_lbr_begin() {
@ -92,12 +97,18 @@ void trace_lbr_begin() {
void *coverage_end_addr = &coverage_end; void *coverage_end_addr = &coverage_end;
write(covfd, &coverage_begin_addr, 4); write(covfd, &coverage_begin_addr, 4);
write(covfd, &coverage_end_addr, 4); write(covfd, &coverage_end_addr, 4);
set_eflags_tf(1);
} }
void trace_lbr_end() { void trace_lbr_end() {
set_eflags_tf(0);
wrmsr(MSR_IA32_DEBUGCTLMSR, 0); wrmsr(MSR_IA32_DEBUGCTLMSR, 0);
close(msrfd); close(msrfd);
close(covfd); close(covfd);
} }
uint32_t trace_lbr_pause(void) {
return set_eflags_tf(0u);
}
void trace_lbr_resume(uint32_t value) {
set_eflags_tf(value);
}

View File

@ -1,7 +1,11 @@
#ifndef TRACE_LBR_H_INCLUDED #ifndef TRACE_LBR_H_INCLUDED
#define TRACE_LBR_H_INCLUDED #define TRACE_LBR_H_INCLUDED
#include <inttypes.h>
void trace_lbr_begin(void); void trace_lbr_begin(void);
void trace_lbr_end(void); void trace_lbr_end(void);
uint32_t trace_lbr_pause(void);
void trace_lbr_resume(uint32_t value);
#endif #endif

View File

@ -61,7 +61,7 @@ const char *last_dir = cur_dir;
bool cur_dir_changed = true; bool cur_dir_changed = true;
char cmd_buf[FGETS_BUF_LEN]; char cmd_buf[FGETS_BUF_LEN];
int trace = 0; uint32_t coverage = 0;
const char *f70_status_name[] = { const char *f70_status_name[] = {
"success", "success",
@ -177,7 +177,9 @@ const char *get_last_dir(const char *path) {
void prompt() { void prompt() {
if (cur_dir_changed) { if (cur_dir_changed) {
COVERAGE_ON();
umka_sys_get_cwd(cur_dir, PATH_MAX); umka_sys_get_cwd(cur_dir, PATH_MAX);
COVERAGE_OFF();
last_dir = get_last_dir(cur_dir); last_dir = get_last_dir(cur_dir);
cur_dir_changed = false; cur_dir_changed = false;
} }
@ -198,7 +200,7 @@ int split_args(char *s, char **argv) {
return argc; return argc;
} }
void umka_disk_list_partitions(disk_t *d) { void shell_disk_list_partitions(disk_t *d) {
for (size_t i = 0; i < d->num_partitions; i++) { for (size_t i = 0; i < d->num_partitions; i++) {
printf("/%s/%d: ", d->name, i+1); printf("/%s/%d: ", d->name, i+1);
if (d->partitions[i]->fs_user_functions == xfs_user_functions) { if (d->partitions[i]->fs_user_functions == xfs_user_functions) {
@ -215,7 +217,7 @@ void umka_disk_list_partitions(disk_t *d) {
} }
} }
void umka_disk_add(int argc, char **argv) { void shell_disk_add(int argc, char **argv) {
const char *usage = \ const char *usage = \
"usage: disk_add <file> <name> [option]...\n" "usage: disk_add <file> <name> [option]...\n"
" <file> absolute or relative path\n" " <file> absolute or relative path\n"
@ -244,10 +246,14 @@ void umka_disk_add(int argc, char **argv) {
void *userdata = vdisk_init(file_name, cache_size); void *userdata = vdisk_init(file_name, cache_size);
if (userdata) { if (userdata) {
COVERAGE_ON();
void *vdisk = disk_add(&vdisk_functions, disk_name, userdata, 0); void *vdisk = disk_add(&vdisk_functions, disk_name, userdata, 0);
COVERAGE_OFF();
if (vdisk) { if (vdisk) {
COVERAGE_ON();
disk_media_changed(vdisk, 1); disk_media_changed(vdisk, 1);
umka_disk_list_partitions(vdisk); COVERAGE_OFF();
shell_disk_list_partitions(vdisk);
return; return;
} }
} }
@ -255,20 +261,22 @@ void umka_disk_add(int argc, char **argv) {
return; return;
} }
void umka_disk_del_by_name(const char *name) { void shell_disk_del_by_name(const char *name) {
for(disk_t *d = disk_list.next; d != &disk_list; d = d->next) { for(disk_t *d = disk_list.next; d != &disk_list; d = d->next) {
if (!strcmp(d->name, name)) { if (!strcmp(d->name, name)) {
COVERAGE_ON();
disk_del(d); disk_del(d);
COVERAGE_OFF();
return; return;
} }
} }
printf("umka: can't find disk '%s'\n", name); printf("umka: can't find disk '%s'\n", name);
} }
void umka_disk_del(int argc, char **argv) { void shell_disk_del(int argc, char **argv) {
(void)argc; (void)argc;
const char *name = argv[1]; const char *name = argv[1];
umka_disk_del_by_name(name); shell_disk_del_by_name(name);
return; return;
} }
@ -277,19 +285,23 @@ void shell_pwd(int argc, char **argv) {
(void)argv; (void)argv;
bool quoted = false; bool quoted = false;
const char *quote = quoted ? "'" : ""; const char *quote = quoted ? "'" : "";
COVERAGE_ON();
umka_sys_get_cwd(cur_dir, PATH_MAX); umka_sys_get_cwd(cur_dir, PATH_MAX);
COVERAGE_OFF();
printf("%s%s%s\n", quote, cur_dir, quote); printf("%s%s%s\n", quote, cur_dir, quote);
} }
void umka_set_pixel(int argc, char **argv) { void shell_set_pixel(int argc, char **argv) {
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t y = strtoul(argv[2], NULL, 0); size_t y = strtoul(argv[2], NULL, 0);
uint32_t color = strtoul(argv[3], NULL, 16); uint32_t color = strtoul(argv[3], NULL, 16);
int invert = (argc == 5) && !strcmp(argv[4], "-i"); int invert = (argc == 5) && !strcmp(argv[4], "-i");
COVERAGE_ON();
umka_sys_set_pixel(x, y, color, invert); umka_sys_set_pixel(x, y, color, invert);
COVERAGE_OFF();
} }
void umka_write_text(int argc, char **argv) { void shell_write_text(int argc, char **argv) {
(void)argc; (void)argc;
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t y = strtoul(argv[2], NULL, 0); size_t y = strtoul(argv[2], NULL, 0);
@ -302,10 +314,12 @@ void umka_write_text(int argc, char **argv) {
int scale_factor = strtoul(argv[9], NULL, 0); int scale_factor = strtoul(argv[9], NULL, 0);
int length = strtoul(argv[10], NULL, 0); int length = strtoul(argv[10], NULL, 0);
int background_color_or_buffer = strtoul(argv[11], NULL, 0); int background_color_or_buffer = strtoul(argv[11], NULL, 0);
COVERAGE_ON();
umka_sys_write_text(x, y, color, asciiz, fill_background, font_and_encoding, draw_to_buffer, scale_factor, string, length, background_color_or_buffer); umka_sys_write_text(x, y, color, asciiz, fill_background, font_and_encoding, draw_to_buffer, scale_factor, string, length, background_color_or_buffer);
COVERAGE_OFF();
} }
void umka_dump_win_stack(int argc, char **argv) { void shell_dump_win_stack(int argc, char **argv) {
int depth = 5; int depth = 5;
if (argc > 1) { if (argc > 1) {
depth = strtol(argv[1], NULL, 0); depth = strtol(argv[1], NULL, 0);
@ -315,7 +329,7 @@ void umka_dump_win_stack(int argc, char **argv) {
} }
} }
void umka_dump_win_pos(int argc, char **argv) { void shell_dump_win_pos(int argc, char **argv) {
int depth = 5; int depth = 5;
if (argc > 1) { if (argc > 1) {
depth = strtol(argv[1], NULL, 0); depth = strtol(argv[1], NULL, 0);
@ -325,11 +339,13 @@ void umka_dump_win_pos(int argc, char **argv) {
} }
} }
void umka_process_info(int argc, char **argv) { void shell_process_info(int argc, char **argv) {
(void)argc; (void)argc;
process_information_t info; process_information_t info;
int32_t pid = strtol(argv[1], NULL, 0); int32_t pid = strtol(argv[1], NULL, 0);
COVERAGE_ON();
umka_sys_process_info(pid, &info); umka_sys_process_info(pid, &info);
COVERAGE_OFF();
printf("cpu_usage: %u\n", info.cpu_usage); printf("cpu_usage: %u\n", info.cpu_usage);
printf("window_stack_position: %u\n", info.window_stack_position); printf("window_stack_position: %u\n", info.window_stack_position);
printf("window_stack_value: %u\n", info.window_stack_value); printf("window_stack_value: %u\n", info.window_stack_value);
@ -343,7 +359,7 @@ void umka_process_info(int argc, char **argv) {
printf("wnd_state: 0x%.2" PRIx8 "\n", info.wnd_state); printf("wnd_state: 0x%.2" PRIx8 "\n", info.wnd_state);
} }
void umka_display_number(int argc, char **argv) { void shell_display_number(int argc, char **argv) {
(void)argc; (void)argc;
int is_pointer = strtoul(argv[1], NULL, 0); int is_pointer = strtoul(argv[1], NULL, 0);
int base = strtoul(argv[2], NULL, 0); int base = strtoul(argv[2], NULL, 0);
@ -363,10 +379,12 @@ void umka_display_number(int argc, char **argv) {
int draw_to_buffer = strtoul(argv[12], NULL, 0); int draw_to_buffer = strtoul(argv[12], NULL, 0);
int scale_factor = strtoul(argv[13], NULL, 0); int scale_factor = strtoul(argv[13], NULL, 0);
uintptr_t background_color_or_buffer = strtoul(argv[14], NULL, 16); uintptr_t background_color_or_buffer = strtoul(argv[14], NULL, 16);
COVERAGE_ON();
umka_sys_display_number(is_pointer, base, digits_to_display, is_qword, show_leading_zeros, number_or_pointer, x, y, color, fill_background, font, draw_to_buffer, scale_factor, background_color_or_buffer); umka_sys_display_number(is_pointer, base, digits_to_display, is_qword, show_leading_zeros, number_or_pointer, x, y, color, fill_background, font, draw_to_buffer, scale_factor, background_color_or_buffer);
COVERAGE_OFF();
} }
void umka_set_window_colors(int argc, char **argv) { void shell_set_window_colors(int argc, char **argv) {
if (argc != (1 + sizeof(system_colors_t)/4)) { if (argc != (1 + sizeof(system_colors_t)/4)) {
printf("10 colors required\n"); printf("10 colors required\n");
return; return;
@ -382,14 +400,18 @@ void umka_set_window_colors(int argc, char **argv) {
colors.work_button_text = strtoul(argv[8], NULL, 16); colors.work_button_text = strtoul(argv[8], NULL, 16);
colors.work_text = strtoul(argv[9], NULL, 16); colors.work_text = strtoul(argv[9], NULL, 16);
colors.work_graph = strtoul(argv[10], NULL, 16); colors.work_graph = strtoul(argv[10], NULL, 16);
COVERAGE_ON();
umka_sys_set_window_colors(&colors); umka_sys_set_window_colors(&colors);
COVERAGE_OFF();
} }
void umka_get_window_colors(int argc, char **argv) { void shell_get_window_colors(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
system_colors_t colors; system_colors_t colors;
COVERAGE_ON();
umka_sys_get_window_colors(&colors); umka_sys_get_window_colors(&colors);
COVERAGE_OFF();
printf("0x%.8" PRIx32 " frame\n", colors.frame); printf("0x%.8" PRIx32 " frame\n", colors.frame);
printf("0x%.8" PRIx32 " grab\n", colors.grab); printf("0x%.8" PRIx32 " grab\n", colors.grab);
printf("0x%.8" PRIx32 " work_3d_dark\n", colors.work_3d_dark); printf("0x%.8" PRIx32 " work_3d_dark\n", colors.work_3d_dark);
@ -402,25 +424,29 @@ void umka_get_window_colors(int argc, char **argv) {
printf("0x%.8" PRIx32 " work_graph\n", colors.work_graph); printf("0x%.8" PRIx32 " work_graph\n", colors.work_graph);
} }
void umka_get_skin_height(int argc, char **argv) { void shell_get_skin_height(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
COVERAGE_ON();
uint32_t skin_height = umka_sys_get_skin_height(); uint32_t skin_height = umka_sys_get_skin_height();
COVERAGE_OFF();
printf("%" PRIu32 "\n", skin_height); printf("%" PRIu32 "\n", skin_height);
} }
void umka_get_screen_area(int argc, char **argv) { void shell_get_screen_area(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
rect_t wa; rect_t wa;
COVERAGE_ON();
umka_sys_get_screen_area(&wa); umka_sys_get_screen_area(&wa);
COVERAGE_OFF();
printf("%" PRIu32 " left\n", wa.left); printf("%" PRIu32 " left\n", wa.left);
printf("%" PRIu32 " top\n", wa.top); printf("%" PRIu32 " top\n", wa.top);
printf("%" PRIu32 " right\n", wa.right); printf("%" PRIu32 " right\n", wa.right);
printf("%" PRIu32 " bottom\n", wa.bottom); printf("%" PRIu32 " bottom\n", wa.bottom);
} }
void umka_set_screen_area(int argc, char **argv) { void shell_set_screen_area(int argc, char **argv) {
if (argc != 5) { if (argc != 5) {
printf("left top right bottom\n"); printf("left top right bottom\n");
return; return;
@ -430,61 +456,77 @@ void umka_set_screen_area(int argc, char **argv) {
wa.top = strtoul(argv[2], NULL, 0); wa.top = strtoul(argv[2], NULL, 0);
wa.right = strtoul(argv[3], NULL, 0); wa.right = strtoul(argv[3], NULL, 0);
wa.bottom = strtoul(argv[4], NULL, 0); wa.bottom = strtoul(argv[4], NULL, 0);
COVERAGE_ON();
umka_sys_set_screen_area(&wa); umka_sys_set_screen_area(&wa);
COVERAGE_OFF();
} }
void umka_get_skin_margins(int argc, char **argv) { void shell_get_skin_margins(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
rect_t wa; rect_t wa;
COVERAGE_ON();
umka_sys_get_skin_margins(&wa); umka_sys_get_skin_margins(&wa);
COVERAGE_OFF();
printf("%" PRIu32 " left\n", wa.left); printf("%" PRIu32 " left\n", wa.left);
printf("%" PRIu32 " top\n", wa.top); printf("%" PRIu32 " top\n", wa.top);
printf("%" PRIu32 " right\n", wa.right); printf("%" PRIu32 " right\n", wa.right);
printf("%" PRIu32 " bottom\n", wa.bottom); printf("%" PRIu32 " bottom\n", wa.bottom);
} }
void umka_set_button_style(int argc, char **argv) { void shell_set_button_style(int argc, char **argv) {
(void)argc; (void)argc;
uint32_t style = strtoul(argv[1], NULL, 0); uint32_t style = strtoul(argv[1], NULL, 0);
COVERAGE_ON();
umka_sys_set_button_style(style); umka_sys_set_button_style(style);
COVERAGE_OFF();
} }
void umka_set_skin(int argc, char **argv) { void shell_set_skin(int argc, char **argv) {
(void)argc; (void)argc;
const char *path = argv[1]; const char *path = argv[1];
COVERAGE_ON();
int32_t status = umka_sys_set_skin(path); int32_t status = umka_sys_set_skin(path);
COVERAGE_OFF();
printf("status: %" PRIi32 "\n", status); printf("status: %" PRIi32 "\n", status);
} }
void umka_get_font_smoothing(int argc, char **argv) { void shell_get_font_smoothing(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
const char *names[] = {"off", "anti-aliasing", "subpixel"}; const char *names[] = {"off", "anti-aliasing", "subpixel"};
COVERAGE_ON();
int type = umka_sys_get_font_smoothing(); int type = umka_sys_get_font_smoothing();
COVERAGE_OFF();
printf("font smoothing: %i - %s\n", type, names[type]); printf("font smoothing: %i - %s\n", type, names[type]);
} }
void umka_set_font_smoothing(int argc, char **argv) { void shell_set_font_smoothing(int argc, char **argv) {
(void)argc; (void)argc;
int type = strtol(argv[1], NULL, 0); int type = strtol(argv[1], NULL, 0);
COVERAGE_ON();
umka_sys_set_font_smoothing(type); umka_sys_set_font_smoothing(type);
COVERAGE_OFF();
} }
void umka_get_font_size(int argc, char **argv) { void shell_get_font_size(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
COVERAGE_ON();
size_t size = umka_sys_get_font_size(); size_t size = umka_sys_get_font_size();
COVERAGE_OFF();
printf("%upx\n", size); printf("%upx\n", size);
} }
void umka_set_font_size(int argc, char **argv) { void shell_set_font_size(int argc, char **argv) {
(void)argc; (void)argc;
uint32_t size = strtoul(argv[1], NULL, 0); uint32_t size = strtoul(argv[1], NULL, 0);
COVERAGE_ON();
umka_sys_set_font_size(size); umka_sys_set_font_size(size);
COVERAGE_OFF();
} }
void umka_button(int argc, char **argv) { void shell_button(int argc, char **argv) {
(void)argc; (void)argc;
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t xsize = strtoul(argv[2], NULL, 0); size_t xsize = strtoul(argv[2], NULL, 0);
@ -494,10 +536,12 @@ void umka_button(int argc, char **argv) {
uint32_t color = strtoul(argv[6], NULL, 16); uint32_t color = strtoul(argv[6], NULL, 16);
int draw_button = strtoul(argv[7], NULL, 0); int draw_button = strtoul(argv[7], NULL, 0);
int draw_frame = strtoul(argv[8], NULL, 0); int draw_frame = strtoul(argv[8], NULL, 0);
COVERAGE_ON();
umka_sys_button(x, xsize, y, ysize, button_id, draw_button, draw_frame, color); umka_sys_button(x, xsize, y, ysize, button_id, draw_button, draw_frame, color);
COVERAGE_OFF();
} }
void umka_put_image(int argc, char **argv) { void shell_put_image(int argc, char **argv) {
(void)argc; (void)argc;
FILE *f = fopen(argv[1], "r"); FILE *f = fopen(argv[1], "r");
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -510,11 +554,13 @@ void umka_put_image(int argc, char **argv) {
size_t ysize = strtoul(argv[3], NULL, 0); size_t ysize = strtoul(argv[3], NULL, 0);
size_t x = strtoul(argv[4], NULL, 0); size_t x = strtoul(argv[4], NULL, 0);
size_t y = strtoul(argv[5], NULL, 0); size_t y = strtoul(argv[5], NULL, 0);
COVERAGE_ON();
umka_sys_put_image(image, xsize, ysize, x, y); umka_sys_put_image(image, xsize, ysize, x, y);
COVERAGE_OFF();
free(image); free(image);
} }
void umka_put_image_palette(int argc, char **argv) { void shell_put_image_palette(int argc, char **argv) {
(void)argc; (void)argc;
FILE *f = fopen(argv[1], "r"); FILE *f = fopen(argv[1], "r");
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -530,47 +576,57 @@ void umka_put_image_palette(int argc, char **argv) {
size_t bpp = strtoul(argv[6], NULL, 0); size_t bpp = strtoul(argv[6], NULL, 0);
void *palette = NULL; void *palette = NULL;
size_t row_offset = strtoul(argv[7], NULL, 0); size_t row_offset = strtoul(argv[7], NULL, 0);
COVERAGE_ON();
umka_sys_put_image_palette(image, xsize, ysize, x, y, bpp, palette, row_offset); umka_sys_put_image_palette(image, xsize, ysize, x, y, bpp, palette, row_offset);
COVERAGE_OFF();
free(image); free(image);
} }
void umka_draw_rect(int argc, char **argv) { void shell_draw_rect(int argc, char **argv) {
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t xsize = strtoul(argv[2], NULL, 0); size_t xsize = strtoul(argv[2], NULL, 0);
size_t y = strtoul(argv[3], NULL, 0); size_t y = strtoul(argv[3], NULL, 0);
size_t ysize = strtoul(argv[4], NULL, 0); size_t ysize = strtoul(argv[4], NULL, 0);
uint32_t color = strtoul(argv[5], NULL, 16); uint32_t color = strtoul(argv[5], NULL, 16);
int gradient = (argc == 7) && !strcmp(argv[6], "-g"); int gradient = (argc == 7) && !strcmp(argv[6], "-g");
COVERAGE_ON();
umka_sys_draw_rect(x, xsize, y, ysize, color, gradient); umka_sys_draw_rect(x, xsize, y, ysize, color, gradient);
COVERAGE_OFF();
} }
void umka_get_screen_size(int argc, char **argv) { void shell_get_screen_size(int argc, char **argv) {
(void)argc; (void)argc;
(void)argv; (void)argv;
uint32_t xsize, ysize; uint32_t xsize, ysize;
COVERAGE_ON();
umka_sys_get_screen_size(&xsize, &ysize); umka_sys_get_screen_size(&xsize, &ysize);
COVERAGE_OFF();
printf("%" PRIu32 "x%" PRIu32 "\n", xsize, ysize); printf("%" PRIu32 "x%" PRIu32 "\n", xsize, ysize);
} }
void umka_draw_line(int argc, char **argv) { void shell_draw_line(int argc, char **argv) {
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t xend = strtoul(argv[2], NULL, 0); size_t xend = strtoul(argv[2], NULL, 0);
size_t y = strtoul(argv[3], NULL, 0); size_t y = strtoul(argv[3], NULL, 0);
size_t yend = strtoul(argv[4], NULL, 0); size_t yend = strtoul(argv[4], NULL, 0);
uint32_t color = strtoul(argv[5], NULL, 16); uint32_t color = strtoul(argv[5], NULL, 16);
int invert = (argc == 7) && !strcmp(argv[6], "-i"); int invert = (argc == 7) && !strcmp(argv[6], "-i");
COVERAGE_ON();
umka_sys_draw_line(x, xend, y, yend, color, invert); umka_sys_draw_line(x, xend, y, yend, color, invert);
COVERAGE_OFF();
} }
void umka_set_window_caption(int argc, char **argv) { void shell_set_window_caption(int argc, char **argv) {
(void)argc; (void)argc;
const char *caption = argv[1]; const char *caption = argv[1];
int encoding = strtoul(argv[2], NULL, 0); int encoding = strtoul(argv[2], NULL, 0);
COVERAGE_ON();
umka_sys_set_window_caption(caption, encoding); umka_sys_set_window_caption(caption, encoding);
COVERAGE_OFF();
} }
void umka_draw_window(int argc, char **argv) { void shell_draw_window(int argc, char **argv) {
(void)argc; (void)argc;
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t xsize = strtoul(argv[2], NULL, 0); size_t xsize = strtoul(argv[2], NULL, 0);
@ -584,25 +640,31 @@ void umka_draw_window(int argc, char **argv) {
int movable = strtoul(argv[10], NULL, 0); int movable = strtoul(argv[10], NULL, 0);
int style = strtoul(argv[11], NULL, 0); int style = strtoul(argv[11], NULL, 0);
const char *caption = argv[12]; const char *caption = argv[12];
COVERAGE_ON();
umka_sys_draw_window(x, xsize, y, ysize, color, has_caption, client_relative, fill_workarea, gradient_fill, movable, style, caption); umka_sys_draw_window(x, xsize, y, ysize, color, has_caption, client_relative, fill_workarea, gradient_fill, movable, style, caption);
COVERAGE_OFF();
} }
void umka_window_redraw(int argc, char **argv) { void shell_window_redraw(int argc, char **argv) {
(void)argc; (void)argc;
int begin_end = strtoul(argv[1], NULL, 0); int begin_end = strtoul(argv[1], NULL, 0);
COVERAGE_ON();
umka_sys_window_redraw(begin_end); umka_sys_window_redraw(begin_end);
COVERAGE_OFF();
} }
void umka_move_window(int argc, char **argv) { void shell_move_window(int argc, char **argv) {
(void)argc; (void)argc;
size_t x = strtoul(argv[1], NULL, 0); size_t x = strtoul(argv[1], NULL, 0);
size_t y = strtoul(argv[2], NULL, 0); size_t y = strtoul(argv[2], NULL, 0);
ssize_t xsize = strtol(argv[3], NULL, 0); ssize_t xsize = strtol(argv[3], NULL, 0);
ssize_t ysize = strtol(argv[4], NULL, 0); ssize_t ysize = strtol(argv[4], NULL, 0);
COVERAGE_ON();
umka_sys_move_window(x, y, xsize, ysize); umka_sys_move_window(x, y, xsize, ysize);
COVERAGE_OFF();
} }
void umka_blit_bitmap(int argc, char **argv) { void shell_blit_bitmap(int argc, char **argv) {
(void)argc; (void)argc;
FILE *f = fopen(argv[1], "r"); FILE *f = fopen(argv[1], "r");
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -625,14 +687,18 @@ void umka_blit_bitmap(int argc, char **argv) {
int client_relative = strtoul(argv[13], NULL, 0); int client_relative = strtoul(argv[13], NULL, 0);
int row_length = strtoul(argv[14], NULL, 0); int row_length = strtoul(argv[14], NULL, 0);
uint32_t params[] = {dstx, dsty, dstxsize, dstysize, srcx, srcy, srcxsize, srcysize, (uintptr_t)image, row_length}; uint32_t params[] = {dstx, dsty, dstxsize, dstysize, srcx, srcy, srcxsize, srcysize, (uintptr_t)image, row_length};
COVERAGE_ON();
umka_sys_blit_bitmap(operation, background, transparent, client_relative, params); umka_sys_blit_bitmap(operation, background, transparent, client_relative, params);
COVERAGE_OFF();
free(image); free(image);
} }
void umka_scrot(int argc, char **argv) { void shell_scrot(int argc, char **argv) {
(void)argc; (void)argc;
uint32_t xsize, ysize; uint32_t xsize, ysize;
COVERAGE_ON();
umka_sys_get_screen_size(&xsize, &ysize); umka_sys_get_screen_size(&xsize, &ysize);
COVERAGE_OFF();
uint32_t *lfb = kos_lfb_base; uint32_t *lfb = kos_lfb_base;
for (size_t y = 0; y < ysize; y++) { for (size_t y = 0; y < ysize; y++) {
@ -647,7 +713,9 @@ void umka_scrot(int argc, char **argv) {
void shell_cd(int argc, char **argv) { void shell_cd(int argc, char **argv) {
(void)argc; (void)argc;
COVERAGE_ON();
umka_sys_set_cwd(argv[1]); umka_sys_set_cwd(argv[1]);
COVERAGE_OFF();
cur_dir_changed = true; cur_dir_changed = true;
} }
@ -662,7 +730,9 @@ void ls_range(f7080s1arg_t *fX0, f70or80_t f70or80) {
if (fX0->size > requested) { if (fX0->size > requested) {
fX0->size = requested; fX0->size = requested;
} }
COVERAGE_ON();
umka_sys_lfn(fX0, &r, f70or80); umka_sys_lfn(fX0, &r, f70or80);
COVERAGE_OFF();
fX0->offset += fX0->size; fX0->offset += fX0->size;
print_f70_status(&r, 1); print_f70_status(&r, 1);
f7080s1info_t *dir = fX0->buf; f7080s1info_t *dir = fX0->buf;
@ -690,7 +760,9 @@ void ls_all(f7080s1arg_t *fX0, f70or80_t f70or80) {
f7080ret_t r; f7080ret_t r;
size_t bdfe_len = (fX0->encoding == CP866) ? BDFE_LEN_CP866 : BDFE_LEN_UNICODE; size_t bdfe_len = (fX0->encoding == CP866) ? BDFE_LEN_CP866 : BDFE_LEN_UNICODE;
while (true) { while (true) {
COVERAGE_ON();
umka_sys_lfn(fX0, &r, f70or80); umka_sys_lfn(fX0, &r, f70or80);
COVERAGE_OFF();
print_f70_status(&r, 1); print_f70_status(&r, 1);
assert((r.status == ERROR_SUCCESS && r.count == fX0->size) assert((r.status == ERROR_SUCCESS && r.count == fX0->size)
|| (r.status == ERROR_END_OF_FILE && r.count < fX0->size)); || (r.status == ERROR_END_OF_FILE && r.count < fX0->size));
@ -733,7 +805,7 @@ fs_enc_t parse_encoding(const char *str) {
return enc; return enc;
} }
void umka_ls(int argc, char **argv, const char *usage, f70or80_t f70or80) { void shell_ls(int argc, char **argv, const char *usage, f70or80_t f70or80) {
int opt; int opt;
optind = 1; optind = 1;
const char *optstring = (f70or80 == F70) ? "f:c:e:" : "f:c:e:p:"; const char *optstring = (f70or80 == F70) ? "f:c:e:" : "f:c:e:p:";
@ -783,17 +855,17 @@ void umka_ls(int argc, char **argv, const char *usage, f70or80_t f70or80) {
return; return;
} }
void umka_ls70(int argc, char **argv) { void shell_ls70(int argc, char **argv) {
const char *usage = \ const char *usage = \
"usage: ls70 [dir] [option]...\n" "usage: ls70 [dir] [option]...\n"
" -f number index of the first dir entry to read\n" " -f number index of the first dir entry to read\n"
" -c number number of dir entries to read\n" " -c number number of dir entries to read\n"
" -e encoding cp866|utf16|utf8\n" " -e encoding cp866|utf16|utf8\n"
" return directory listing in this encoding"; " return directory listing in this encoding";
umka_ls(argc, argv, usage, F70); shell_ls(argc, argv, usage, F70);
} }
void umka_ls80(int argc, char **argv) { void shell_ls80(int argc, char **argv) {
const char *usage = \ const char *usage = \
"usage: ls80 [dir] [option]...\n" "usage: ls80 [dir] [option]...\n"
" -f number index of the first dir entry to read\n" " -f number index of the first dir entry to read\n"
@ -802,10 +874,10 @@ void umka_ls80(int argc, char **argv) {
" return directory listing in this encoding\n" " return directory listing in this encoding\n"
" -p encoding cp866|utf16|utf8\n" " -p encoding cp866|utf16|utf8\n"
" path to dir is specified in this encoding"; " path to dir is specified in this encoding";
umka_ls(argc, argv, usage, F80); shell_ls(argc, argv, usage, F80);
} }
void umka_stat(int argc, char **argv, f70or80_t f70or80) { void shell_stat(int argc, char **argv, f70or80_t f70or80) {
(void)argc; (void)argc;
f7080s5arg_t fX0 = {.sf = 5, .flags = 0}; f7080s5arg_t fX0 = {.sf = 5, .flags = 0};
f7080ret_t r; f7080ret_t r;
@ -818,7 +890,9 @@ void umka_stat(int argc, char **argv, f70or80_t f70or80) {
fX0.u.f80.path_encoding = DEFAULT_PATH_ENCODING; fX0.u.f80.path_encoding = DEFAULT_PATH_ENCODING;
fX0.u.f80.path = argv[1]; fX0.u.f80.path = argv[1];
} }
COVERAGE_ON();
umka_sys_lfn(&fX0, &r, f70or80); umka_sys_lfn(&fX0, &r, f70or80);
COVERAGE_OFF();
print_f70_status(&r, 0); print_f70_status(&r, 0);
if (r.status != ERROR_SUCCESS) if (r.status != ERROR_SUCCESS)
return; return;
@ -851,15 +925,15 @@ void umka_stat(int argc, char **argv, f70or80_t f70or80) {
return; return;
} }
void umka_stat70(int argc, char **argv) { void shell_stat70(int argc, char **argv) {
umka_stat(argc, argv, F70); shell_stat(argc, argv, F70);
} }
void umka_stat80(int argc, char **argv) { void shell_stat80(int argc, char **argv) {
umka_stat(argc, argv, F80); shell_stat(argc, argv, F80);
} }
void umka_read(int argc, char **argv, f70or80_t f70or80) { void shell_read(int argc, char **argv, f70or80_t f70or80) {
(void)argc; (void)argc;
f7080s0arg_t fX0 = {.sf = 0}; f7080s0arg_t fX0 = {.sf = 0};
f7080ret_t r; f7080ret_t r;
@ -897,7 +971,9 @@ void umka_read(int argc, char **argv, f70or80_t f70or80) {
} }
fX0.buf = (uint8_t*)malloc(fX0.count); fX0.buf = (uint8_t*)malloc(fX0.count);
COVERAGE_ON();
umka_sys_lfn(&fX0, &r, f70or80); umka_sys_lfn(&fX0, &r, f70or80);
COVERAGE_OFF();
print_f70_status(&r, 1); print_f70_status(&r, 1);
if (r.status == ERROR_SUCCESS || r.status == ERROR_END_OF_FILE) { if (r.status == ERROR_SUCCESS || r.status == ERROR_END_OF_FILE) {
@ -911,12 +987,12 @@ void umka_read(int argc, char **argv, f70or80_t f70or80) {
return; return;
} }
void umka_read70(int argc, char **argv) { void shell_read70(int argc, char **argv) {
umka_read(argc, argv, F70); shell_read(argc, argv, F70);
} }
void umka_read80(int argc, char **argv) { void shell_read80(int argc, char **argv) {
umka_read(argc, argv, F80); shell_read(argc, argv, F80);
} }
typedef struct { typedef struct {
@ -925,47 +1001,47 @@ typedef struct {
} func_table_t; } func_table_t;
func_table_t funcs[] = { func_table_t funcs[] = {
{ "disk_add", umka_disk_add }, { "disk_add", shell_disk_add },
{ "disk_del", umka_disk_del }, { "disk_del", shell_disk_del },
{ "ls70", umka_ls70 }, { "ls70", shell_ls70 },
{ "ls80", umka_ls80 }, { "ls80", shell_ls80 },
{ "stat70", umka_stat70 }, { "stat70", shell_stat70 },
{ "stat80", umka_stat80 }, { "stat80", shell_stat80 },
{ "read70", umka_read70 }, { "read70", shell_read70 },
{ "read80", umka_read80 }, { "read80", shell_read80 },
{ "pwd", shell_pwd }, { "pwd", shell_pwd },
{ "cd", shell_cd }, { "cd", shell_cd },
{ "set_cwd", shell_cd }, { "set_cwd", shell_cd },
{ "draw_window", umka_draw_window }, { "draw_window", shell_draw_window },
{ "set_pixel", umka_set_pixel }, { "set_pixel", shell_set_pixel },
{ "write_text", umka_write_text }, { "write_text", shell_write_text },
{ "put_image", umka_put_image }, { "put_image", shell_put_image },
{ "button", umka_button }, { "button", shell_button },
{ "process_info", umka_process_info }, { "process_info", shell_process_info },
{ "window_redraw", umka_window_redraw }, { "window_redraw", shell_window_redraw },
{ "draw_rect", umka_draw_rect }, { "draw_rect", shell_draw_rect },
{ "get_screen_size", umka_get_screen_size }, { "get_screen_size", shell_get_screen_size },
{ "draw_line", umka_draw_line }, { "draw_line", shell_draw_line },
{ "display_number", umka_display_number }, { "display_number", shell_display_number },
{ "set_button_style", umka_set_button_style }, { "set_button_style", shell_set_button_style },
{ "set_window_colors", umka_set_window_colors }, { "set_window_colors", shell_set_window_colors },
{ "get_window_colors", umka_get_window_colors }, { "get_window_colors", shell_get_window_colors },
{ "get_skin_height", umka_get_skin_height }, { "get_skin_height", shell_get_skin_height },
{ "get_screen_area", umka_get_screen_area }, { "get_screen_area", shell_get_screen_area },
{ "set_screen_area", umka_set_screen_area }, { "set_screen_area", shell_set_screen_area },
{ "get_skin_margins", umka_get_skin_margins }, { "get_skin_margins", shell_get_skin_margins },
{ "set_skin", umka_set_skin }, { "set_skin", shell_set_skin },
{ "get_font_smoothing", umka_get_font_smoothing }, { "get_font_smoothing", shell_get_font_smoothing },
{ "set_font_smoothing", umka_set_font_smoothing }, { "set_font_smoothing", shell_set_font_smoothing },
{ "get_font_size", umka_get_font_size }, { "get_font_size", shell_get_font_size },
{ "set_font_size", umka_set_font_size }, { "set_font_size", shell_set_font_size },
{ "put_image_palette", umka_put_image_palette }, { "put_image_palette", shell_put_image_palette },
{ "move_window", umka_move_window }, { "move_window", shell_move_window },
{ "set_window_caption", umka_set_window_caption }, { "set_window_caption", shell_set_window_caption },
{ "blit_bitmap", umka_blit_bitmap }, { "blit_bitmap", shell_blit_bitmap },
{ "scrot", umka_scrot }, { "scrot", shell_scrot },
{ "dump_win_stack", umka_dump_win_stack }, { "dump_win_stack", shell_dump_win_stack },
{ "dump_win_pos", umka_dump_win_pos }, { "dump_win_pos", shell_dump_win_pos },
{ NULL, NULL }, { NULL, NULL },
}; };
@ -977,7 +1053,7 @@ void *run_test(const char *infile_name) {
outfile = stdout; outfile = stdout;
} else { } else {
char outfile_name[PATH_MAX]; char outfile_name[PATH_MAX];
strncpy(outfile_name, infile_name, PATH_MAX-2); // ".t" is shorter that ".out" strncpy(outfile_name, infile_name, PATH_MAX-2); // ".t" is shorter than ".out"
char *last_dot = strrchr(outfile_name, '.'); char *last_dot = strrchr(outfile_name, '.');
if (!last_dot) { if (!last_dot) {
printf("test file must have '.t' suffix\n"); printf("test file must have '.t' suffix\n");
@ -993,7 +1069,7 @@ void *run_test(const char *infile_name) {
} }
int is_tty = isatty(fileno(infile)); int is_tty = isatty(fileno(infile));
char **cargv = (char**)malloc(sizeof(char*) * (MAX_COMMAND_ARGS + 1)); char **argv = (char**)malloc(sizeof(char*) * (MAX_COMMAND_ARGS + 1));
while(next_line(infile, is_tty)) { while(next_line(infile, is_tty)) {
if (cmd_buf[0] == '#' || cmd_buf[0] == '\n') { if (cmd_buf[0] == '#' || cmd_buf[0] == '\n') {
printf("%s", cmd_buf); printf("%s", cmd_buf);
@ -1005,20 +1081,20 @@ void *run_test(const char *infile_name) {
printf("%s", cmd_buf); printf("%s", cmd_buf);
fflush(outfile); fflush(outfile);
} }
int cargc = split_args(cmd_buf, cargv); int argc = split_args(cmd_buf, argv);
func_table_t *ft; func_table_t *ft;
for (ft = funcs; ft->name != NULL; ft++) { for (ft = funcs; ft->name != NULL; ft++) {
if (!strcmp(cargv[0], ft->name)) { if (!strcmp(argv[0], ft->name)) {
break; break;
} }
} }
if (ft->name) { if (ft->name) {
ft->func(cargc, cargv); ft->func(argc, argv);
} else { } else {
printf("unknown command: %s\n", cargv[0]); printf("unknown command: %s\n", argv[0]);
} }
} }
free(cargv); free(argv);
return NULL; return NULL;
} }
@ -1026,7 +1102,7 @@ void *run_test(const char *infile_name) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
const char *usage = \ const char *usage = \
"usage: umka_shell [test_file.t] [-c]\n" "usage: umka_shell [test_file.t] [-c]\n"
" -c trace branches to collect coverage"; " -c collect coverage";
const char *test_file = NULL; const char *test_file = NULL;
int opt; int opt;
@ -1037,7 +1113,7 @@ int main(int argc, char **argv) {
while ((opt = getopt(argc, argv, "c")) != -1) { while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) { switch (opt) {
case 'c': case 'c':
trace = 1; coverage = 1;
break; break;
default: default:
puts(usage); puts(usage);
@ -1045,13 +1121,16 @@ int main(int argc, char **argv) {
} }
} }
if (trace) if (coverage)
trace_begin(); trace_begin();
COVERAGE_ON();
kos_init(); kos_init();
COVERAGE_OFF();
run_test(test_file); run_test(test_file);
if (trace) if (coverage)
trace_end(); trace_end();
return 0; return 0;