// // XREF-C.VDM // Christian Ziemski 10.03.1999 // 25.08.1999 unlimited size (for Clint) // 15.08.2000 f. 5.20 (HOME->USER_MACRO) // 18.09.2002 f. 6.x // 19.09.2002 some fixes with navigation etc, // Ctrl-F11/12 added // 20.09.2002 help window // // // Analyses a C program and creates a function cross reference. // // // (Some ideas adapted from CFUNC.VDM and CONDC.VDM.) // //---------------------------------------------------------------------- // // -- Inline documentation -- (could be displayed with Shft-F1) // // After the creation of the reference lists you can toggle between // a line in the cross reference buffer and the appropriate location // in the source code buffer with the following keys: // // Always: // // Shift-F1 toggle a little help window on/off // // In the cross reference: // // F10 switch window to source text (without any special positioning) // F11 jump to the appropriate function call (=line number in the reference) in the source text // F12 jump to the appropriate function definition in the source text // // Ctrl-F11 jump to the previous occurance of the current function in the cross reference // Ctrl-F12 jump to the next occurance of the current function in the cross reference // // In the source text: // // F10 jump to the appropriate line in the cross reference // Shift-F11 jump to the previous function // Shift-F12 jump to the next function // // //---------------------------------------------------------------------- // // Usage: Load the C source code into a buffer and then // load/execute the macro XREF-C.VDM. // // It uses two additional buffers for the reference lists and some // registers as documented below. // //---------------------------------------------------------------------- // // Requirements: The function definition must begin in column one. // // Known problems: - C macros and // forward declarations with parameter prototypes // are not evaluated correctly. // - some C comments with fuction names in it // can irritate XREF-C // // To do: - windows resizing of the cross reference list // (Awaiting an answer from Ted ...) 20.09.2002: I can't remember what that means. CZ // - solve known problems // //---------------------------------------------------------------------- // // used resources: // --------------- // // buffer[#93] : original C source program // buffer[#94] : condensation of functions // buffer[#95] : cross reference of functions // // // T-Reg 90 : temp. for building the condensed list // T-Reg 91 : temp. for storing function call ... // // // #90 : line# // #91 : line# // #92 : line# // #93 : buffer number source text // #94 : buffer number condensed list // #95 : buffer number cross-reference list // #98 : temp. // #99 : temp. // // // Marker 9 // ///////////////////////////////////////////////////////////////////////// // Config( U_AUTO_CFG, "Auto-save config", 0 ) Config( PG_E_SYNTAX, "Enable syntax highlighting (*)", 1 ) Syntax_Load("C.SYN") Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", 0, ALL ) // Buffer-Switch-Event-Macro: // Make the cursor line highlighted in the condensed function list only RS(114,'if(BN==#95){Config(D_H_CR_LINE,"HCL",2)} else {Config(D_H_CR_LINE,"HCL",0)}') // --------- the key assignments: --------------------------- Key_Add("Shft-F1", "[VISUAL EXIT] Call(100,'HELP')",NOCONFIRM) Key_Add("F10", "[VISUAL EXIT] Call(100,'SWITCHXREF')",NOCONFIRM) Key_Add("F11", "[VISUAL EXIT] Call(100,'GOTOFCALL')",NOCONFIRM) Key_Add("F12", "[VISUAL EXIT] Call(100,'GOTOFDEF')",NOCONFIRM) Key_Add("Shft-F11", "[VISUAL EXIT] Call(100,'PREVFUNC')",NOCONFIRM) Key_Add("Shft-F12", "[VISUAL EXIT] Call(100,'NEXTFUNC')",NOCONFIRM) Key_Add("Ctrl-F11", "[VISUAL EXIT] Call(100,'PREVOCC')",NOCONFIRM) Key_Add("Ctrl-F12", "[VISUAL EXIT] Call(100,'NEXTOCC')",NOCONFIRM) //------------------------------------------------------------- #93=Buf_Num // current buffer with source text if(#94==0){ // if not already assigned #94=Buf_Free // buffer for condensed list if(#94==-1){ alert() Statline_Message("No free buffer available!") return } } BS(#94) BY(OK) FSA("|(VEDIT_TEMP)\XRC-COND.TMP", NOMSG+OK) // save file for unlimited size if(#95==0){ // if not already assigned #95=Buf_Free // buffer for cross reference if(#95==-1){ alert() Statline_Message("No free buffer available!") return } } BS(#95) BY(OK) FSA("|(VEDIT_TEMP)\XRC-CROS.TMP", NOMSG+OK) // save file for unlimited size // ---------- Creation of the condensed function list BS(#93) // back to the source code BoF Reg_Empty(90) repeat(ALL){ //Search(")|[|P,|W|P,|W|M*|M*|?]|L",ADVANCE+ERRBREAK) Search(")|[|P,|W|P,|W|M*|M*|?]|L",ERRBREAK) // Search for ){}, // ) {}, // ) {} /* */ // Line(-1) // Backup to beginning of function declaration BoL // Backup to beginning of function declaration // // Skip this occurrence if 1st char is not alphanumeric. // if ((Cur_Char < 65 || Cur_Char > 122)) { Line(1,NOERR) Continue } //Out_Reg(90, APPEND) //Num_Type(CL,NOCR) // put located line# into T-Reg //Out_Reg(CLEAR) //Reg_Set(90," : ", APPEND) //Reg_Copy(90,1, APPEND) // put located line into T-Reg // new version for Clint's jillion functions C-program ... Reg_Copy(90,1) // just this line #98=CL BS(#94) // condensed function list Num_Ins(#98,NOCR) // put located line# into IT(" : ") Reg_Ins(90) BS(#93) // back to the source code Line(1) // next line } BS(#94) FS(NOMSG) // save it // Reg_Ins(90) // condensed function list // ---------- Creation of the cross reference //BS(#95) //WS(3,ATTACH) //BS(#95,ATTACH) if (Win_Status(#95) == -1){ Win_Split(#95, 40, RIGHT) } BS(#95,ATTACH) //Win_Move(#95,WINX+WINW-FONTW*40,WINY,FONTW*40,WINH) // Reg_Ins(90) // another copy of the condensed list Ins_File("|(VEDIT_TEMP)\XRC-COND.TMP") BOF while(!At_EoF) { #90=Num_Eval(ADVANCE) // line# in C program S("(",ADVANCE) DoV("\PW\") BB(CP) S("|{|W,(}") // end of function name BE(CP) RCB(11,BB,BE) // => function name Line(1) Set_Marker(9,CP) // remember the actual position BS(#93) // C program BoF // search for all occurences of the function name repeat(ALL) { S("|@(11)|[|W](", ERRBREAK) if(CL == #90){ // check if it's the function itself S("{") // >> } << just for parentheses-pairing in VDM Match_Paren() // Line(1) // continue // if yes: ignore } #98=CP // begin of function name S("(",ADVANCE) // check if forward declaration // testweise 20.09.2002 // if(Match("|[|X])")==0) { // (attention: no param. prototypes here!) // Line(1) // // continue // if yes: ignore // } #91=CL // line# RCB(91,#98,EoL_Pos) // function call BS(#95) // search the correct location in cross reference BoF // where the actual function is, repeat(ALL){ // using the line numbers #92=Num_Eval() if(#92 >= #91){ Break } Line(1,NOERR) } if(#92 != #91){ Num_Ins(#91, NOCR) // put located line# into T-Reg IT(" : -- ") // RI(91) // insert function call IN(1) // and CR/LF } BS(#93) // back to C source } BS(#95) // to cross reference and GP(Marker(9)) // next function here Update } // --------- just a little bit beautifying (some additional line feeds) BS(#95) BoF while(! AT_EoF) { S(":", ADVANCE) if(Match("|[|W]--")==0){ Line(1) Continue } BoL IN(1) Line(1) } BB(CLEAR) FS(NOMSG) BS(#93) BoF BS(#94) BoF BS(#95) BoF Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", 2 ) Visual_Macro(NOMSG) return //============================================================================= :HELPM: if(Win_Reserved_Bottom_ID != 0) { Win_Delete('H') Return } #99=Win_Num Win_Delete('H') Win_Reserved('H',3,BOTTOM+NOBORDER) Win_Switch('H') Win_Color(15) Win_Clear() M(" | | CF11 << XREF-entry | CF12 XREF-entry >> SF1 Help | | SF11 << function | SF12 function >> | F10 to crossreference | F11 to fnct call | F12 to fnct def ") Win_Color(112) WS(#99) return //============================================================================ :HELP: Key_Purge() #120=Config( PG_E_SYNTAX, "Enable syntax highlighting (*)", 0 ) #121=Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", 0 ) // Config( S_E_MORE, "Enable -MORE- operation", 0 ) // Config( S_TOP_MARG, "Top margin for cursor", 2 ) #103=Buf_Num Buf_Switch(Buf_Free, ATTACH) Reg_Ins(Macro_Num) BoF Search("|H3CDOC>", NOERR) // the leading "<" is masked out intentionally! if(EM){ Message("\n\n No inline help found.") }else{ Line(1) Del_Block(0,Cur_Pos) Search("|H3C/DOC>", NOERR) if(!EM){ BoL Del_Block(Cur_Pos, File_Size) } Replace("^/+", BEGIN+ALL+REGEXP+NOERR) // remove leading comment characters BoF while(! At_EoF){ // shorten lines longer than window width (not perfect, but ...) Goto_Col(Win_Cols) Del_Block(Cur_Pos, EoL_Pos) Line(1, NOERR+ERRBREAK) } EoF //#105=Win_Lines - 1 -2 // number of lines displayable in the window ??? wieso -2 ??? sonst fehlen oben Zeilen ?!? #105=Screen_Lines - 1 -2// number of lines displayable in the window ??? wieso -2 ??? sonst fehlen oben Zeilen ?!? #106=Cur_Line - 1 // number of lines to display // RS(55, "Win_Lines:") // ItoA(Win_Lines,55, APPEND) // RS(55, " Screen_Lines:", APPEND) // ItoA(Screen_Lines,55, APPEND) // // Dialog_Input_1(1,"`info`, // `|@(55)`", // WORKAREA+TOP+LEFT,20,20) BoF repeat(ALL){ Win_Clear Type(#105, NORESTORE) if(Cur_Line >= #106){ break } Update #104=Get_Key("\nPress any key to continue or to quit ...", STATLINE+RAW) if(#104==27){ break } } } Update Visual_Macro(NOMSG) if(#104 != 27){ Get_Key("\nPress any key to close help...", STATLINE+RAW) } Buf_Quit(OK+DELETE) Buf_Switch(#103) Config( PG_E_SYNTAX, "Enable syntax highlighting (*)", #120 ) Config( D_H_CR_LINE, "Highlight cursor line (1=Full, 2=Partial)", #121 ) return //--------------------------------------------------------- // // // *** F10 *** :SWITCHXREF: if(BN!=#93) { if(BN==#95) { BS(#93,EVENT) } Return } #98=Cur_Line BS(#95,EVENT) // search the actual location in cross reference BoF // repeat(ALL){ // using the line numbers #92=Num_Eval() if(#92 >= #98){ Break } Line(1,NOERR) if(At_EoF){ Break } } return //--------------------------------------------------------- // // // *** F11 *** // :GOTOFCALL: if(BN==#93) { BS(#95,EVENT) Return } BoL #98=Num_Eval() // line# from the source code BS(#93,EVENT) if(#98>0) { // if not have been on empty line Goto_Line(#98) SVL(5) } return // //-------------------------------- // // // *** F12 *** // :GOTOFDEF: if(BN==#93) { BS(#95,EVENT) Return } BoL if(Match('|[|W]|N')==0) { // if on empty line BS(#93,EVENT) Return } S(':',ADVANCE+NOERR) if(EM) { return } // if on definition line if(Match(' -- ',ADVANCE)!=0) { // behave like F11 BoL #98=Num_Eval() // line# of C source BS(#93,EVENT) Goto_Line(#98) SVL(5) return } // if on function call BB(CP) S('|{|W,(}') // o.k. ?????? BE(CP) RCB(91,BB,BE) // the function name BB(CLEAR) Save_Pos() BoF S(' : |!-|Y |[|Y]|@(91)') // search the definition of that function BoL #98=Num_Eval() // line# of C source Restore_Pos() BS(#93,EVENT) Goto_Line(#98) SVL(5) return //-------------------------------- // // // *** Shift-F11 *** // :PREVFUNC: if(BN==#95){ Return } do{ L(-1,NOERR) S(')|[|H7b,|W|H7b,|W|M*|M*|?]|L',REVERSE+NOERR+ERRBREAK) BoL } while(CC<65||CC>122) return //-------------------------------- // // // *** Shift-F12 *** // :NEXTFUNC: if(BN==#95){ Return } do{ L(1,NOERR) S(')|[|H7b,|W|H7b,|W|M*|M*|?]|L',NOERR+ERRBREAK) BoL } while(CC<65||CC>122) return //-------------------------------- // // // *** Ctrl-F11 *** // :PREVOCC: if(BN!=#95){ Return } BoL if(Match('|[|W]|N')==0){ return } S(':',ADVANCE+NOERR) if(EM){ return } if(Match(' -- ',ADVANCE)!=0){ S('|[|W](') DOV('\PW\') } BB(CP) S('|[|W](') BE(CP) RCB(91,BB,BE) BB(CLEAR) BoL S('|@(91)', REVERSE+NOERR) if(!EM){ SVL(Win_Lines/2) } return //-------------------------------- // // // *** Ctrl-F12 *** // :NEXTOCC: if(BN!=#95){ Return } BoL if(Match('|[|W]|N')==0){ return } S(':',ADVANCE+NOERR) if(EM){ return } if(Match(' -- ',ADVANCE)!=0){ S('|[|W](') DOV('\PW\') } BB(CP) S('|[|W](') BE(CP) RCB(91,BB,BE) BB(CLEAR) Line(1) S('|@(91)', NOERR) if(!EM){ SVL(Win_Lines/2) }else{ Line(-1) } return // --- end ---