From b4d3db625e05f10c9f9ded6e433f12325774c43e Mon Sep 17 00:00:00 2001 From: Yatis Date: Mon, 1 Mar 2021 09:02:43 +0100 Subject: [PATCH] Gintracer: v0.6.3 - Graphgraph export. @update * callgraph: add "export ", to export callgraph information to the SMEM. * input: input_display(): add meta information (cursor mode) * input: input_read(): allow user to add prefix text. * input: add input_write_noint(): display and doesn't wait user interaction. --- TODO.txt | 5 +- gintrace.g3a | Bin 116704 -> 117984 bytes include/gintrace/gui/input.h | 9 +- include/gintrace/menu/callgraph.h | 1 - src/gui/input.c | 154 ++++++++++++++++----- src/gui/menu.c | 2 +- src/menu/callgraph.c | 221 ++++++++++++++++++++++-------- 7 files changed, 293 insertions(+), 99 deletions(-) diff --git a/TODO.txt b/TODO.txt index 833a266..0880960 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,10 +1,13 @@ @fix * fix fixed size 'space' character * fix tabulation +* fix destructor +* fix fx9860 support @update +* hexdump: search commands @feature -* call graph export for laptop * night mode (refacto gui and handle color template) * transform gintracer into a librairy +* handle session (send the session instead of ucontext !) diff --git a/gintrace.g3a b/gintrace.g3a index 93989d3aa9cc68163a4a8c10ac585538a5d734d3..c13b86de69ac63347168a27e1b4fd4d79ece79a1 100644 GIT binary patch delta 21539 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 delta 20264 zcmcKCe_T{`zWDLa45-5ob@)9Z>VRmN7-y6ei`^NMijoqPl3Uywl@yf>6^)AB!K8Ld z2z1b>$Vew6V}lJVwy;Q1QK^QOE!t(fXlQJ4cS+6MBIf)0%#3;V-haOTTzed!=Y4*B z&inJ@e9p`P>w9iYU*#CnfrdkkRrcpA{^TCvzc2YKWy)%y`txe+5{>4UShH-0X_n^r zj{67vOta@VXKB`rbyziHnp?+3u2_4w5Xv=uI(-y}YZPI+t3(Jtq0@(pvqo8h+;(@v zSy3nhAxz79&uXr&3nd{&D4JxJRH2Mc(di?Dg|aM@?S6|dkg+8~$#-$Of<4If^JU|v z=k#j~qT({``=>s(!6@7%x5HQ5(vQex7_ z=5Ie8R2-&@>Y6huIw`bkc3|{^pv~^HB5&WKprW7i_MH_)Ba4E*5#Nd|hiQLBrT67`>3p4OR7zYR{aTEtZK%z4}7&bXjNEJ+!o#HrFR77 zg*~P@J^jY0?V4iEx1#Z#M>V2PQ|_(3GkU=*w10+ddrv>m%JhYe&X_~f#HT0iUb8f5 z|JsGJffmPA_}MN`%c<0!GrSzsC;s|SPvKdyC@62+S+UB2`%Y^NuNcA}xX`sO?}B0H zf}kS*t~E=(TOMjMR%%zAPYRt9`^BoyR^RpAZ9#eGpMUqXCLy%8r7pOvZ2PRNtqVfL zjOBi1WeW@oG`15qCSih$L&-`*Nhq0I}ft1enlv^?+5F0;IJ<7*#3r2i;FlT%G`?h`0FxHs4E$a!*K`xqoN-rK4PYAczDgxxxAnyX^sw!^P zDxu7)656+J6G91K5}Roh${M+F@9G9DOjAadtg?-6Q(VR24Vp%W2zW}%1i>`@7R3A+$>`o858pH^%9*w40e~WvX&E`?qv`+0L>!+I~A(PHla^ zeSGxItwLcn-?qxTn&;@YottYalM@NGu`+cJQ8Q{ONBTKK((e3)J04ja=lYe|@aJFU zU9gZ|g1sWBZ^U(@W2iJ@)=G29;_2RIt(>~zLe{oe!&6hT!s+3dybG?RUD=#rv_w>f zue#t$bR=&zM|Jdx%rK+wsUz7>Sb`pK7{xR6*8 z6cR_vBqTj~T9dTfx+!V@i782MFBqG2EPr9rXX}nO2qQ0DVwH*C)l4F zZTnm9^1VyCOo?a0OxJABv>6spUw`SrOX{(6`o{uCM$C?V)*}|(e0{~_G4G$&SRE&( zEEpSGToJPD!c8HS<4y;CzDOIj{L>YVn{*qrlomKDT64`gac7W!^s)<&XjXEK`I{=g zn4OxTTlRfw>+-|JmdxM9K4!G(DxwoZ?V8VjRS{*^ex6zpZujHw5W7D`U$l?<{Dz7t z_R-q|mR*c}}Kj!n;(}4j|T~X)60&2E=FGIiM+R!N) z*96XpD_{`bT#5uWepSV znnIQ;7DnTmQtu?ZCWrN6q3CPSE|h7#e3;;*n|ZFTsiOc!?3#L(gB)*gWS3oM^W4K6 zqOXxpvo#EWwF_M#{RK&HuUnaPtYGQlIPN};QCBf8-!IS46?86#;dtcJz~$RESVGEy?UdCU!RcqQ%r;$~TP*3MW%WiYqO!sQD$SRSw~To!&# zPRfF@e%%D^1ix%Ye0s%<<@+{RmW4YWT)yGc8Irq*7tcDI<+=Qn@ z+>Nsn^EVayrzD=!RNZTwVE5Y|W(~7UI5FO$)4g#{%M?Ge;zoN=#f{dLc6X&=H3?ps z+IFTX#)^QAM#X5W{PxO8W8SD6ea`=Cbk5HeOEHyv7eE_+>_& z(J)L0vJ8za6T*hX_z?Gy+Y;pM+R!#3n#9h>Zwd`h@ZO)?ow4#^8boz6iQETy}jYOAkvwi=3#2g|b%163${|Nn}Z3;Zxb#OqN`h zd=~m^EkkK-ISb{ib+RrWM%SlEUxWl8DLupUKC1{h3)5M#T*&WoF69-mzxYOv^p{> zmjp&xyd@f3&GnTlG_mp!?{3dWzq?l5<(-#3A44*D6gg(@_&QV`HIat6T3B=Z&J~*5 z<=nnbu=ukC3nkcz@hqwGvnJ-qbFN%bD3h|;mfz*)oi9Jt${EwsCq)jIiW3u2JM@*tI`0*2M>VBVnnVXC(3= zKBCN#zx&tP2)mwEGTjbsI+wv$>7W$X_~~&)&{1 z8Oq(hT~wJ}{x#QXBRU*P&5FRNVvgvbQ(7IhHScP+JC;3nqvkP((KYqXKUj^P*PPQH@{iq!M1g$v8C8s4uRc#tm;Mn`7t?C2RZ z#xkq#I|U6gL#}h^vd0~@wKq&&J;Wp4&rZ=EiajLeqv zYfZoxqZY^AMr#`F+kd+9al=o@ia6Sx)3uRS$Ds2Dt^H7t&Y_D>w;U8~$572sKu`y7q?llVF+ zj~W(o>_%0~t^eFVF-{itADMjIYU=X)TD#jXFSJX$VCGpN`Z&U~&yo1*WbK@S=8RY8 zY69;mz$eA8h2_U<>B-1^PO^aU*R8a(N6Yk zzf#;U`-Evx4NHTg@DEYV-!?yVr3}jDa^6dOE?fB4`;mN{HZ5wChs)i+TsrOTn>1P` zTl+gFBW}v`e!!bg4|oret-rcuPNb)nvSzZDvbL1Ju-?(s5*L?d7ko725j@H^oU~%q z(m(rKf>vL!`E&a*c!ZK>cU)|Vi%zq1h(CvH{9n73Kd#l@oY`Fa$79<0o-8|^w+Vlt zEM_FHmP1v>I+jG|9lW7XR_mP^?p~p+Y7)v_cDB(42FDAne;u7!FZ-ssUDA z8@QNDEG}g^;3zmeJ#g_cR(G;E9kqv7Tqox&5*DJGw=EVdL>Gyn=P-GuljQ(QlOyp+ z+-Ug$CQ{#=ePo=x;L7$S{&uwAI(lihP_n}veeKgnt%#wM96?8a2+R^AqSPvstVBof zu@%}Z;V3-zsATZifoKl%v``jrY%&C`(j;30U5=*XzaE`M<8kE0;~S&18OK@Tta!+M z)@XLiX6Sdzp5c0>9rwk0kCa#H^8ZS#2t6GfXIh}I9Ny^feKTQjxI1K;NhjvWlutZ7 zDkDKQ_QjOaszn^Jo5~19Y;K)4rOx!gz((Ec; zcR9T`>@~^Efks+mh;3;sWjjyBO}?hcwQEIhZ@_IsY`rll5+NoUDm$!5uC;h3eREM+X^EVV41 zEW`ANQJAuIEW88EPG!mSj0RJ7q5PsK7Mijya)AbxHkLk?i(T5qamz#HS5^7gFvP^C zZx`K~E3Y3TmL#*t>9WeZ@47yZ>c32PDBgX`x_!EYl2glrC)v@|YjpJVI-)ntU{}J% zq6a*#-Lz3!Vl*0s<2Qec8Z&L>tXalso0{MI^4kzwLHLk-bL$@ODNQH^@k8U4U@`Pd ztPqb=#TMf6syNdvPH?{Wbk5Hm8gC3x?az0MkJS51-D3Nd_%>lv3d-H0^2!G8qJo+s zQ76WG3%rfkIph{oed%zU6f_O-ok6v~mHmFI{T*)c)Rpq&`MgiAP{)1T2noJ)g^dFS z*pPl@1Mv{CcNEBtO2K8fuwN;F_(2^lAg$pUlu zMigfBUCSp$oJl7|IHa4jGXnhZ{ zY80;@B-T+)nJx)G#Ojc$3m!5M2dVbU8V0Ij3-Ogcm*;1a;2o6ay*?Xq+3?`ij33G; z9;=FrDL|tt(9Zr}srJ{z#ca0@T6*m!2R>j;kmT}{+T%QEw7`RS#KsWKPRdFBj zovL_{_&!y9nRxxxxKKy@j4Cz|?@`4G#BYrE)t@FQOkuEzy2Tb530D@EuK+LTpOHjQLc^;4!LcX zwW<@^DexXuEXP2gD()waR>c>Iue};?6vV3XHU<+vs@iWLep(gB582$7=T#eIlN?aR zsl@N9;&kFws+haRag7* z>{rE?iQm2&Z_+U}r+6m~Id5#zGli&T(oHrVw-)t=lp)baANh(2IU z>cdS1Zox}>O7L7n*;K{_R8#Y&8qQZe3pVjAu&SnF+ol$`Xj2#Ha*I-Rfddq%E?}64 zk18$-CRP<#6yp}hROJ;V4++t~5)k9Z3$2z5v{Ih>d>09-<38eF%H#Q8#OH^jsscCbhD6nsj3)?X zGc|fb)gqe}E}(kaZB8RW)x&Eu4=<}~s@|OE79Xn1FOfe?@^u;WpR&1{0@Vf3M@Dtr zLaZ*3PdLZb1@=;d8CM70X4z$`htuZEoUa;VTXe*}7MJs{vc*8gs;Ac$2BlT?^xBfl zC=TFA?;mAL3j0+T*plWJr&I}T$>aj+@^anc6ZL*>Q?bpHuxI{Pwv=$ yt!7CZ4Y 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 bpVA!CMwC5k?bK`uG<5T8>;Z!R`Q85mrIe6h diff --git a/include/gintrace/gui/input.h b/include/gintrace/gui/input.h index 5b754d0..a4e1bbc 100644 --- a/include/gintrace/gui/input.h +++ b/include/gintrace/gui/input.h @@ -4,10 +4,11 @@ #include #include -/* intput(): Handle user input */ -extern int input_read(char *buffer, size_t size); +/* intput_read(): Handle user input */ +extern int input_read(char *buffer, size_t size, const char *prefix, ...); -/* intput(): display message then wait user event */ +/* intput_write(): display message then wait user event */ extern int input_write(const char *format, ...); - +/* intput(): display message */ +extern int input_write_noint(const char *format, ...); #endif /*__GINTRACE_GUI_INPUT_H__*/ diff --git a/include/gintrace/menu/callgraph.h b/include/gintrace/menu/callgraph.h index c9897ab..f551ee5 100644 --- a/include/gintrace/menu/callgraph.h +++ b/include/gintrace/menu/callgraph.h @@ -30,7 +30,6 @@ struct callgraph { } cursor; struct callnode *root; struct callnode *parent; - int callnode_counter; }; /* extern menu information */ diff --git a/src/gui/input.c b/src/gui/input.c index 481a4cd..289bd1e 100644 --- a/src/gui/input.c +++ b/src/gui/input.c @@ -13,14 +13,16 @@ /* internal structure used to store many information */ struct { struct { - int visible; - } cursor; + uint8_t cursor :1; /* display cursor */ + uint8_t meta :1; /* display meta info */ + uint8_t const :6; + } config; struct { - uint8_t alpha: 1; - uint8_t shift: 1; - uint8_t ctrl: 1; - uint8_t exit: 1; - uint8_t const: 4; + uint8_t alpha :1; + uint8_t shift :1; + uint8_t ctrl :1; + uint8_t exit :1; + uint8_t const :4; } mode; struct { size_t max; @@ -28,41 +30,35 @@ struct { off_t cursor; char *data; } buffer; + struct { + size_t size; + char data[256]; + } prefix; } input_info; //--- // Display management //--- -/* input_display(): Display the input area */ -void input_display(void) +/* input_print(): Print line */ +static void input_print(int *cursor_x, int *cursor_y, const char *str) { - int cursor_x; - int cursor_y; uint16_t tmp; int cursor; + char c; int x; int y; - /* add cursor mark */ - if (input_info.cursor.visible == 1) - input_info.buffer.data[input_info.buffer.cursor] |= 0x80; - - /* display part */ - cursor_x = 0; - cursor_y = GUI_DISP_NB_ROW - 1; - cursor_y -= input_info.buffer.size / GUI_DISP_NB_COLUMN; - drect(0, cursor_y * (FHEIGHT + 1) - 1, DWIDTH, DHEIGHT, C_WHITE); - dhline(cursor_y * (FHEIGHT + 1) - 3, C_BLACK); - dhline(cursor_y * (FHEIGHT + 1) - 2, C_BLACK); - for (size_t i = 0; i < input_info.buffer.size; ++i) { + if (str == NULL) + return; + for (size_t i = 0; str[i] != '\0'; ++i) { /* get the cursor and remove the potential cursor marker */ - cursor = ((input_info.buffer.data[i] & 0x80) != 0); - input_info.buffer.data[i] &= 0x7f; + cursor = ((str[i] & 0x80) != 0); + c = str[i] & 0x7f; /* display part (character + cursor if needed) */ - x = cursor_x * (FWIDTH + 1); - y = cursor_y * (FHEIGHT + 1); - tmp = input_info.buffer.data[i] << 8; + x = (*cursor_x) * (FWIDTH + 1); + y = (*cursor_y) * (FHEIGHT + 1); + tmp = c << 8; dtext(x, y, C_BLACK, (void*)&tmp); if (cursor != 0) { dline(x, y + (FHEIGHT + 1), x + (FWIDTH + 1) - 2, @@ -70,16 +66,53 @@ void input_display(void) } /* update cursor if needed */ - cursor_x += 1; - if (cursor_x >= GUI_DISP_NB_COLUMN) { - cursor_x = 0; - cursor_y += 1; + *cursor_x += 1; + if (*cursor_x >= GUI_DISP_NB_COLUMN) { + *cursor_x = 0; + *cursor_y += 1; } } +} + +/* input_display(): Display the input area */ +static void input_display(void) +{ + int cursor_x; + int cursor_y; + size_t bytes; + + /* add cursor mark */ + if (input_info.config.cursor == 1) + input_info.buffer.data[input_info.buffer.cursor] |= 0x80; + + /* calculate the number of bytes to display */ + /* TODO: remove me, check line discipline */ + bytes = input_info.buffer.size + input_info.prefix.size; + if (input_info.config.meta == 1) + bytes += 4; + + /* calculate the X/Y position */ + cursor_x = 0; + cursor_y = (GUI_DISP_NB_ROW - 1) - (bytes / GUI_DISP_NB_COLUMN); + + /* display information */ + drect(0, cursor_y * (FHEIGHT + 1) - 1, DWIDTH, DHEIGHT, C_WHITE); + dhline(cursor_y * (FHEIGHT + 1) - 3, C_BLACK); + dhline(cursor_y * (FHEIGHT + 1) - 2, C_BLACK); + if (input_info.config.meta == 1) { + char meta[] = "[l]:"; + if (input_info.mode.alpha == 1) + meta[1] = 'L'; + if (input_info.mode.shift == 1) + meta[1] = 'n'; + input_print(&cursor_x, &cursor_y, meta); + } + input_print(&cursor_x, &cursor_y, input_info.prefix.data); + input_print(&cursor_x, &cursor_y, input_info.buffer.data); dupdate(); /* remove cursor mark */ - if (input_info.cursor.visible == 1) + if (input_info.config.cursor == 1) input_info.buffer.data[input_info.buffer.cursor] &= ~0x80; } @@ -210,7 +243,7 @@ static int input_key_buffer_update(key_event_t key_event) } /* input_read(): Handle user input */ -int input_read(char *buffer, size_t size) +int input_read(char *buffer, size_t size, const char *prefix, ...) { key_event_t key; uint16_t *secondary; @@ -226,10 +259,17 @@ int input_read(char *buffer, size_t size) memset(&input_info, 0x00, sizeof(input_info)); memset(buffer, 0x00, size); - /* save terminal information */ + /* setup internal information */ input_info.buffer.data = buffer; input_info.buffer.size = 1; input_info.buffer.max = size; + if (prefix != NULL) { + va_list _args; + va_start(_args, prefix); + input_info.prefix.size = vsnprintf(input_info.prefix.data, + 32, prefix, _args); + va_end(_args); + } /* Gint workaround to freeze the current display */ dgetvram(&main, &secondary); @@ -240,8 +280,10 @@ int input_read(char *buffer, size_t size) } memcpy(secondary, main, 2*396*224); + /* keyboard handling */ - input_info.cursor.visible = 1; + input_info.config.cursor = 1; + input_info.config.meta = 1; while (input_info.mode.exit == 0) { input_display(); key = getkey_opt(GETKEY_REP_ALL | GETKEY_MENU, NULL); @@ -289,8 +331,46 @@ int input_write(const char *format, ...) memcpy(secondary, main, 2*396*224); /* display and wait user event */ - input_info.cursor.visible = 0; + input_info.config.cursor = 0; + input_info.config.meta = 0; input_display(); getkey(); return (0); } +/* TODO: merge with input_write*/ +int input_write_noint(const char *format, ...) +{ + char buffer[512]; + va_list _args; + uint16_t *secondary; + uint16_t *main; + size_t size; + void *tmp; + + va_start(_args, format); + size = vsnprintf(buffer, 512, format, _args); + va_end(_args); + + /* initialize internal data */ + memset(&input_info, 0x00, sizeof(input_info)); + + /* save terminal information */ + input_info.buffer.data = buffer; + input_info.buffer.size = size; + input_info.buffer.max = 512; + + /* Gint workaround to freeze the current display */ + dgetvram(&main, &secondary); + if (gint_vram == main) { + tmp = main; + main = secondary; + secondary = tmp; + } + memcpy(secondary, main, 2*396*224); + + /* display and wait user event */ + input_info.config.cursor = 0; + input_info.config.meta = 0; + input_display(); + return (0); +} diff --git a/src/gui/menu.c b/src/gui/menu.c index caa0a5b..eef885d 100644 --- a/src/gui/menu.c +++ b/src/gui/menu.c @@ -154,7 +154,7 @@ int menu_keyboard(struct menu_group *gmenu) goto check_fkeys; } char buf[256]; - if (input_read(buf, 256) <= 0) + if (input_read(buf, 256, NULL) <= 0) goto check_fkeys; int ac; char **av; diff --git a/src/menu/callgraph.c b/src/menu/callgraph.c index c513bd1..ace6d3e 100644 --- a/src/menu/callgraph.c +++ b/src/menu/callgraph.c @@ -2,12 +2,15 @@ #include "gintrace/ubc.h" #include "gintrace/gui/menu.h" #include "gintrace/gui/display.h" +#include "gintrace/gui/input.h" #include #include #include #include #include +#include +#include #include "./src/menu/internal/dictionary.h" @@ -15,13 +18,15 @@ /* TODO: find a way to have local information (session) */ struct callgraph callgraph; +/* internal buffer */ +static char line[256]; + //--- // callode management //--- /* callnode_create(): create a new callnode */ static struct callnode *callnode_create(struct callnode *parent, - struct ucontext *context, - int type, uintptr_t address) + struct ucontext *context, int type, uintptr_t address) { struct callnode *node; @@ -31,7 +36,6 @@ static struct callnode *callnode_create(struct callnode *parent, node->type = type; node->parent = parent; node->address = address; - callgraph.callnode_counter += 1; } return (node); } @@ -47,12 +51,70 @@ static void callnode_add_child(struct callnode *parent, struct callnode *child) *sibling = child; } +/* callnode_generate_info(): Genera information about a node */ +static size_t callnode_generate_info(char *buf, + size_t max, struct callnode *node) +{ + const char *addrname; + const char *type; + + /* generate the line */ + type = "(err)"; + if (node->type == callnode_type_root) + type = "(root)"; + if (node->type == callnode_type_bsr) + type = "(bsr)"; + if (node->type == callnode_type_bsrf) + type = "(bsrf)"; + if (node->type == callnode_type_jsr) + type = "(jsr)"; + if (node->type == callnode_type_jmp) + type = "(jmp)"; + if (node->type == callnode_type_rte) + type = "(rte)"; + if (node->type == callnode_type_rts) + type = "(rts)"; + + /* check special address */ + addrname = dictionary_syscalls_check((void*)node->address); + if (addrname == NULL) + addrname = dictionary_notes_check((void*)node->address); + if (addrname == NULL) + return(snprintf(buf, max, "%s %p", type, (void*)node->address)); + return (snprintf(buf, max, "%s %p - %s", + type, (void*)node->address, addrname)); +} + +/* callnode_get_size(): Count the number of bytes that the callgraph take */ +static size_t callnode_export(int fd, struct callnode *node) +{ + if (node == NULL) + return (0); + + size_t size = 0; + size += sizeof(size_t); + size += sizeof(uintptr_t); + size += sizeof(struct callnode); + size += callnode_generate_info(line, 256, node); + if (fd >= 0) { + BFile_Write(fd, &size, sizeof(size)); + BFile_Write(fd, &node, sizeof(&node)); + BFile_Write(fd, node, sizeof(struct callnode)); + BFile_Write(fd, line, size); + } + + /* check other node */ + size += callnode_export(fd, node->child); + size += callnode_export(fd, node->sibling); + return (size); +} + /* callnode_display(): Display callnode information */ static void callnode_display(struct callnode *node, uint32_t bitmap[4], int *row, int depth) { - static char line[256]; char shift; + char pipe; int idx; int i; @@ -76,61 +138,28 @@ static void callnode_display(struct callnode *node, uint32_t bitmap[4], } /* generate the line */ - char pipe = '|'; - const char *type = "(err)"; + pipe = '|'; bitmap[idx] |= 1 << (depth & 0x1f); - if (node->type == callnode_type_root) - type = "(root)"; - if (node->type == callnode_type_bsr) - type = "(bsr)"; - if (node->type == callnode_type_bsrf) - type = "(bsrf)"; - if (node->type == callnode_type_jsr) - type = "(jsr)"; - if (node->type == callnode_type_jmp) { + if (node->type == callnode_type_jmp + || node->type == callnode_type_rte + || node->type == callnode_type_rts) { bitmap[idx] &= ~(1 << (depth & 0x1f)); - type = "(jmp)"; pipe = '`'; } - if (node->type == callnode_type_rte) { - bitmap[idx] &= ~(1 << (depth & 0x1f)); - type = "(rte)"; - pipe = '`'; - } - if (node->type == callnode_type_rts) { - bitmap[idx] &= ~(1 << (depth & 0x1f)); - type = "(rts)"; - pipe = '`'; - } - - /* skip display part */ - if (*row + callgraph.cursor.voffset < 0) { - *row = *row + 1; - callnode_display(node->child, bitmap, row, depth + 1); - callnode_display(node->sibling, bitmap, row, depth); - return; - } - - - const char *addrname = dictionary_syscalls_check((void*)node->address); - if (addrname == NULL) - addrname = dictionary_notes_check((void*)node->address); - if (addrname == NULL) { - snprintf(line, 256, "%s %p", type, (void*)node->address); - } else { - snprintf(line, 256, "%s %p - %s", - type, (void*)node->address, addrname); - } /* display the line then check child and siblig */ - if (depth < 0) { - dtext((callgraph.cursor.hoffset + (i << 2)) * (FWIDTH + 1), - (*row + callgraph.cursor.voffset) * (FHEIGHT + 1), - C_BLACK, line); - } else { - dprint((2 + callgraph.cursor.hoffset + (i << 2)) * (FWIDTH + 1), - (*row + callgraph.cursor.voffset) * (FHEIGHT + 1), C_BLACK, - "%c-- %s", pipe, line); + if (*row + callgraph.cursor.voffset >= 0) { + callnode_generate_info(line, 256, node); + if (depth < 0) { + int a = callgraph.cursor.hoffset + (i << 2); + int b = callgraph.cursor.voffset + (*row); + dtext(a * (FWIDTH + 1), b * (FHEIGHT + 1), C_BLACK, line); + } else { + int a = callgraph.cursor.hoffset + (i << 2) + 2; + int b = callgraph.cursor.voffset + (*row); + dprint(a * (FWIDTH + 1), b * (FHEIGHT + 1), + C_BLACK, "%c-- %s", pipe, line); + } } *row = *row + 1; callnode_display(node->child, bitmap, row, depth + 1); @@ -246,7 +275,6 @@ static void callgraph_display(struct ucontext *context) } /* callgraph_keyboard(): Handle one key event */ -/* TODO: remove the cursor, handle node selection ! */ static int callgraph_keyboard(struct ucontext *context, int key) { (void)context; @@ -263,6 +291,89 @@ static int callgraph_keyboard(struct ucontext *context, int key) return (0); } +/* callgraph_command(): handle user command */ +static void callgraph_command(struct ucontext *context, int argc, char **argv) +{ + /* check useless export */ + (void)context; + if (callgraph.root == NULL) { + input_write("nothing to export"); + return; + } + + /* check argument validity */ + if (argc != 2) { + input_write("argument missing"); + return; + } + if (strcmp(argv[0], "export") != 0) { + input_write("'%s': command unknown", argv[0]); + return; + } + + /* convert the filename (arg2) into Bfile pathname */ + /* TODO: handle special extention */ + int i = -1; + uint16_t pathname[14 + strlen(argv[1]) + 1]; + memcpy(pathname, u"\\\\fls0\\", 14); + while (argv[1][++i] != '\0') + pathname[7 + i] = argv[1][i]; + pathname[7 + i] = 0x0000; + + /* check if the file exist */ + input_write_noint("Check if the file exist"); + gint_switch_to_casio(); + int fd = BFile_Open(pathname, BFile_ReadOnly); + if (fd >= 0) { + gint_switch_to_gint(); + while (1) { + if (input_read(line, 3, "'%s' exist, erase ? [n/Y]:", + argv[1]) <= 0) { + input_write("export aborded"); + return; + } + if (line[0] == 'n') { + input_write("export aborded"); + return; + } + if (line[0] != 'Y') + continue; + gint_switch_to_casio(); + BFile_Remove(pathname); + break; + } + } + + /* create the file then dump information */ + gint_switch_to_gint(); + int size = callnode_export(-1, callgraph.root); + input_write_noint("Create the file (%d)", size); + gint_switch_to_casio(); + fd = BFile_Create(pathname, BFile_File, &size); + if (fd != 0) { + gint_switch_to_gint(); + input_write("Bfile_Create: error %d", fd); + return; + } + gint_switch_to_gint(); + input_write_noint("Create success"); + gint_switch_to_casio(); + fd = BFile_Open(pathname, BFile_ReadWrite); + if (fd < 0) { + BFile_Remove(pathname); + gint_switch_to_gint(); + input_write("BFile_Open: error %d", fd); + return; + } + gint_switch_to_gint(); + input_write_noint("Open success, now write..."); + gint_switch_to_casio(); + callnode_export(fd, callgraph.root); + BFile_Close(fd); + gint_switch_to_gint(); + input_write("success"); +} + //--- // Define the menu //--- @@ -271,6 +382,6 @@ struct menu menu_callgraph = { .init = &callgraph_init, .display = &callgraph_display, .keyboard = &callgraph_keyboard, - .command = NULL, + .command = &callgraph_command, .dtor = NULL };