// WSEARCH-PL.VDM - Search text from entire groups of files. // // Pauli Lindgren // Last change: 21.11.1997 // // 22.02.2003: Renamed from WSEARCH to WSEARCH-PL due to naming conflicts: Ch. Ziemski // // Requires: VEDIT 5.03 or later. // // From VEDIT: Select {User, Wild search}. // // From OS: vedit -x wsearch.vdm // // Description: Perform a Search on an entire group of files, e.g. "*.txt", "*.c". // To search all files on drive C, enter "c:\*.* -s". // //////////////// // // Register Usage: // T-Regs Only empty T-Regs are used and then emptied on exit. // // #70 User's last choice // #74 -- [D]isplay or [V]isual mode flag // #75 Temp save window # // #76 Save original Zoom value // #77 Name of any bottom-reserved window // #78 Number of lines in any bottom-reserved window // #79 Border type in any bottom-reserved window // #80 T-Reg # containing this macro // #81 Value of parent's locked-in macro // #82 Original buffer # // #83 Original window # // #84 Save state of "Enable file open/close macro" // #85 Save state of "Enable -MORE- operation" // #86 Save state of Visual_Macro // #87 Save/restore file position // #88 State of SR_CASE_OPT and SR_MODE_OPT (Search Case,Mode) // #89 T-Reg # for holding locked-in macro // #90 Edit-buffer # for editing each file not already open // #91 1st time in flag, for #92's macro // #92 T-Reg # for holding macro executed for each file // During filename processing: "\" for DOS, "/" for UNIX // #93 T-Reg # for holding search string // During filename processing: full drive:pathname // #94 -- T-Reg # for holding replace string // During filename processing: filename // #95 T-Reg # for holding current filename during main execution // #96 T-Reg # for main processing macro // #97 T-Reg # to hold each macro line (file) to process // #98 Flag - break-out operation // #99 Flag - 0x57495C44 ("WILD") when macro is running // #100 Filename position marker; temp window # // // $34 Temp buffer is clobbered, as any macro is allowed to // ////////////////////////////////////////////////////////////////////////////// // // Init - 1) Save state // 2) Use configured search mode (Simple, Pattern, Reg-Exp) // 3) Determine free buffers/T-Regs // 4) Setup T-Reg #89 with Break-out/exit (locked-in) macro // if (#99==0x57495C44) { Goto LABEL1 } //Skip init if macro already running Num_Push(70,100) //Save numeric regs #80 = Macro_Num //#80 = T-Reg containing this macro #81 = Reg_Lock_Macro //#81 = parent's locked-in macro (0=none) #82 = Buf_Num //#82 = original buffer #83 = Win_Num //#83 = original window # (maybe status line!) #84 = Config(F_E_F_MACRO,0) //#84 = original Config value; disable #85 = Config(S_E_MORE,0) //#85 = original Config value; disable #86 = Visual_Macro //#86 = save state of Visual_Macro #88 = 0 //Assume pattern matching, not case sensitive if (Config(SR_MODE_OPT)==0) { #88 += SIMPLE } if (Config(SR_MODE_OPT)>=2) { #88 += REGEXP } if (Config(SR_MODE_OPT)==3) { #88 += MAX } if (Config(SR_CASE_OPT)) { #88 += CASE } // #76 = Zoom_Status //#76 = window zoom status #77 = 0 //Assume no reserved windows if (#102!=0x44454D4F) { //Only if demo macro not running... if (#77=Win_Reserved_Bottom_ID) { //If reserved bottom window... Win_Switch(#77) //Switch to it #78 = Win_Lines //#78 = lines in it #79 = Win_Border //#79 = # border lines in it Win_Delete() //Delete it Win_Switch(#83) //Switch back to original window } } Buf_Switch(#90=Buf_Free) //#90 = buffer for editing files Reg_Set(#89=Reg_Free," ") //#89 = Reserve T-reg for locked-in macro Reg_Set(#92=Reg_Free," ") //#92 = Reserve T-reg for operation macro Reg_Set(#93=Reg_Free," ") //#93 = Reserve T-Reg for search string //Reg_Set(#94=Reg_Free," ") //#94 = Reserve T-Reg for replace string Reg_Set(#95=Reg_Free," ") //#95 = Reserve T-Reg for filename Reg_Set(#96=Reg_Free," ") //#96 = Reserve T-Reg for processing macro Reg_Set(#97=Reg_Free," ") //#97 = Reserve T-Reg for processing macro // // "Locked-in" macro #89 catches break-outs and exits macro. // Reg_Set(#89,` Buf_Switch(34,LOCAL) Buf_Quit(OK) //Quit any temp file Buf_Switch(#82,LOCAL) //Return to original buffer Win_Delete('h') //Delete any 'h' window if (#102==0x44454D4F) { Goto EXIT } //Exit if demo macro is running Message("\n") if (#98==1) { Alert() Message("BREAK-OUT!") } Message(" Press any key to return to VEDIT: ") #70=Get_Key("") Char_Dump(#70) // // Exit - Restore state before returning. // :EXIT: Call(#80,"SAVELAST") //Save or abandon last file, if any //Switches to buffer #90 if (Config(WIN_AUTO_CRE)) { //Probably need to delete attached window Buf_Quit(DELETE) //Close buffer and window } else { Buf_Quit() } //Else just close buffer Win_Delete('*') // PL: delete window // Win_Delete('H') //Delete help window if (#77) { //Restore original reserved bottom window... if (#79==0) { Win_Reserved(#77,#78,BOTTOM+NOBORDER) } else { if (#79==1) { Win_Reserved(#77,#78,BOTTOM+MINBORDER) } else { Win_Reserved(#77,#78,BOTTOM) } } } Win_Zoom(#76) //Restore window zoom state Buf_Switch(34,LOCAL) Buf_Quit(OK) Buf_Switch(#82,LOCAL) //Return to original buffer Reg_Empty(#80,EXTRA) //Empty register with main macro Reg_Empty(#92) Reg_Empty(#93) //Reg_Empty(#94) Reg_Empty(#95) Reg_Empty(#96) Reg_Empty(#97) Config(F_E_F_MACRO,#84) //Restore original Config values Config(S_E_MORE,#85) if (#86) { Visual_Macro(SET+NOMSG) } //Return to Visual Mode; no Pause Reg_Lock_Macro(#81) //Restore any previous locked-in macro Num_Pop(70,100) //Restore numeric regs Reg_Empty(Macro_Num,EXTRA) //Empty this T-Reg; return Return //Just in case `) // // Main Body of Macro. // :LABEL1: Call("SAVELAST") //Save or abandon last file, if any //In case of restart following Break-out if (OS_Type >= 4) { //#92 = UNIX/DOS pathname char Reg_Set(#92,"/") } else { Reg_Set(#92,"\") } #74=0 #98=1 //Enable "BREAKOUT" message #99=0x57495C44 //Macro is now running ("WILD") Visual_Macro(CLEAR) //Don't return to Visual Mode on break-out Reg_Lock_Macro(#89,EXTRA) //Enable Break-out macro Buf_Switch(34,EXTRA) Buf_Empty(OK) //Build main macro in extra buffer 34 File_Delete("wildfile.tmp",OK+NOERR) File_Open("wildfile.tmp",FORCE+NOMSG) //Open temp file; force in temp buffer Config(F_F_TYPE,1,LOCAL) //Ensure not record-mode //Win_Zoom() //Max sized window Win_Create(*,1,10,22,68) // Create window Win_Switch(*) Win_Color(48) Win_Attach(*) // Attach special window Win_Clear() Message(` ***************************************** * * * WILD SEARCH * * Multi-file search * * * ***************************************** Enter the names of the files you want to process and . The wildcards "?" and "*" may be used. Append "-s" to include files in subdirectories. E.g., *.c or c:\\proj\\*.* -s or c:\\*.* -s Press again when all filenames have been entered. Press to cancel. Default directory is: `,TAB8) // Chdir("",NOMSG) Type_Newline() // // Prompt for filenames and expand wildcards; add complete pathname. // repeat (ALL) { Get_Input(#95,"Enter filename: ",NOCR) if (Reg_Size(#95)==0) { Break } Buf_Switch(Buf_Free(EXTRA)) Reg_Ins(#95) Search("|W-s",BEGIN+NOERR) // Check for subtree search option -s Buf_Quit(OK) Buf_Switch(34) if (Error_Match) { // Check file existence when not "-s" if (File_Exist(@#95)==0) { Message("File(s) not found. Try again.\n") Continue } } End_Of_File() //Goto end of buffer #87=#100=Cur_Pos() // and save position Out_Ins() //Re-route normal display into buffer 34 Directory(@#95,COUNT+NOERR,1) //Insert directory, one column Out_Ins(CLEAR) //Turn off re-routing repeat (ALL) { Goto_Pos(#87) //Restore position Search("|<|[|W]|LDirectory ",ADVANCE+ERRBREAK) //Search for "Directory" header Del_Char(-Chars_Matched) //Delete partial header and previous blank line #87=Cur_Pos() //Save current position End_Of_Line() //Advance to end of line Reg_Copy_Block(#93,#87,Cur_Pos) //Copy drive:pathname to T-Reg #93 Begin_Of_Line() Del_Line() //Delete rest of header if (Search("|<|[|W]|LDirectory ",NOERR)) { //Search for next "Directory" header Set_Marker(9,Cur_Pos) } else { Set_Marker(9,File_Size) } // // Cleanup filenames. // Goto_Pos(#87) repeat (ALL) { //Remove blank lines Search_Block("|L|L",#87,Marker(9),ERRBREAK) Del_Line() } Goto_Pos(#87) //Eliminate excess white space (in filenames) Replace_Block("|W","",#87,Marker(9),NOERR+ALL) Goto_Pos(#87) //Remove the ".." entry Replace_Block("|<..|L","",#87,Marker(9),NOERR+ALL) Goto_Pos(#87) //Remove the active temp file entry Replace_Block("|",#87,Marker(9),ERRBREAK) Begin_Of_Line() Del_Line() } Goto_Pos(#87) //Restore position if (#87==Marker(9)) { continue } // Handle empty directories //(May be empty after deleting garbage above) repeat (ALL) { //Precede each filename with ... Search_Block("|<|?",#87,Marker(9),ERRBREAK+NORESTORE) Reg_Ins(#93,ADVANCE) //... full drive:pathname Reg_Ins(#92,ADVANCE) //... "\" (DOS) or "/" (UNIX/QNX) } Goto_Pos(Marker(9)) //Goto end of subdirectory block #87 = Cur_Pos } Del_Char(ALL) // Belts & suspenders if (Cur_Pos == #100) { // Check for empty result set Message("File(s) not found. Try again.\n") } } // // Prompt for desired operation. // Buf_Switch(#82) Reg_Empty(#93) if ((BE-BB > 0) && (BE-BB<50)) { Reg_Copy_Block(#93,BB,BE) } Get_Input(#93,"\n\nEnter search string: ",@(#93),NOCR) // // Build desired operation macro executed for each file in buffer #90. // Because unmatched braces in strings confuse VEDIT, use "Ins_Char(n)" // to insert them. // "Search" uses the following options": // ERRBREAK - Breaks out of the "Repeat" loop when no more occurrences // CONFIRM - Sets temporary block markers just like {SEARCH, Search} // NORESTORE - Does not restore edit position - this is much faster! // #88 - Enables Regular Expressions if {SEARCH, Config, Default RE} // Buf_Switch(#90) Buf_Empty(OK) Ins_text("repeat(ALL)") Ins_Char(123) Ins_Text("Search(@#93,SET+ERRBREAK+CONFIRM+NORESTORE+#88)") Ins_Text("Visual_Macro(CLEAR) V Char()") Ins_Char(125) // // Copy operation-macro in buffer #90 to T-Reg #92 and empty buffer #90. // Reg_Copy(#92,-10) Buf_Empty(OK) Buf_Switch(34) // // Place the following macro into T-Reg #96: // // if ((#87=File_Check(@#95))==0) { Buf_Switch(#90) File_Open(@#95) // Message("\n...Processing ") Name_Write(EXTRA+NOMSG) Call(#92) // Buf_Switch(#90) File_Close(NOMSG) } // else { Buf_Switch(#87) Save_Pos() Message("\n...Processing ") // Name_Write(EXTRA+NOMSG) Begin_Of_File() Call(#92) Restore_Pos() } // Reg_Set(#96,`if((#87=File_Check(@#95))<=0){BS(#90) File_Open(@#95) Message("\n...Processing ") Name_Write(EXTRA+NOMSG) Call(#92) BS(#90) File_Close(NOMSG) } else { BS(#87) SPOS() Message("\n...Processing ") Name_Write(EXTRA+NOMSG) BOF Call(#92) RPOS()}`) // // Convert each line in buffer 34 consisting of a simple pathname into: // // Reg_Set(#95,'pathname') Call(#96) // Begin_Of_File() while ( !At_EOF ) { Ins_Text("RS(#95,`") End_Of_Line() Ins_Text("`) Call(#96)") Line() } Begin_Of_File() // // // //Get_Key("\nPress any key to begin operation...") if (#102==0x44454D4F) { //If demo macro, remove instruction window if (#77=Win_Reserved_Bottom_ID) { //If reserved bottom window... Win_Switch(#77) //Switch to it #78 = Win_Lines //#78 = lines in it #79 = Win_Border //#79 = # border lines in it Win_Delete() //Delete it Win_Switch(#83) //Switch back to original window } } //if (#74=='V') { Win_Zoom(#76) //Restore window zoom state #75 = Win_Num if (Win_Border>=2) { Win_Reserved('h',1,BOTTOM+NOBORDER) } else { Win_Reserved('h',1,BOTTOM) } Win_Switch('h') Win_Color(112) Win_Clear() Message(" Press [VISUAL EXIT] (<\>) to search for next occurrence.",EXTRA+TAB8) Win_Switch(#75) //} // // Copy each line (filename) from buffer into T-Reg #97 and execute it. // while (! At_EOF) { Buf_Switch(34) Reg_Copy(#97,1) //Copy next line into T-Reg #97 Buf_Switch(1) Call(#97) //Process next file Buf_Switch(34) Line(1,ERRBREAK) //Advance to next line; breakout at E-O-F } #98=0 //Disable "BREAK-OUT" message Chain(#89) //Chain to Break-out/exit macro // // SAVELAST - Save or abandon last file following Break-out. // Return: Switched to buffer #90. // :SAVELAST: Buf_Switch(#90) if (Is_Open_Write && Is_Altered) { //Save or abandon last file... #100 = Win_Num if ((#101=Buf_Status) > 1) { //Force buffer's window to the top Win_Switch(#101) Update() } File_Close(CONFIRM) Win_Switch(#100) } return