// Remove Studio Markers from Source Code // by Marcia Booth - Data Access Corporation // Created on October, 2005 // // Modified by Allan Kim Eriksen // This will also: // - Right trim lines // - Remove more studio markers. // - Correct an error that added an extra empty line for each source file. // - All ending blank lines are not written back to the source file. // - Added a business process that makes it possible to change all files for a complete workspace. // It will traverse recursively through all directories in the workspace. // - Removes any LOCAL statements Use dfClient.pkg Use Windows.pkg Use File_dlg.Pkg Use dirform.pkg Use BatchDD.pkg Use akefs.pkg Use dfSpnFrm.pkg Use vWin32fh.pkg Define CS_LF for (Character(10)) Define CS_CR for (Character(13)) Define CS_CRLF for (CS_CR+CS_LF) Define CI_SplitBySpaceSemiColumn for 0 Define CI_SplitBySemiColumn for 1 Define CI_SplitByBeginEnd for 2 Struct tCounters Integer iTrimmed Integer iRemoveMarker Integer iRemoveLocal Integer iRemoveFonts Integer iInlineIfElse Integer iRemovePublic Integer iRemovePrivate Integer iEndComments End_Struct Deferred_View Activate_oCleanMarkersView for ; ; Object oCleanMarkersView is a dbView Set Location to 11 21 Set Size to 263 340 Set Label to "Cleanup your DataFlex Source" Set pbAcceptDropFiles to True Property Boolean pbIssueWarning True Property Boolean pbSaveBackupFile True Property Boolean pbCleanMarkers True Property Boolean pbRTrimSource True Property Boolean pbRemoveLocal True Property Boolean pbRemoveFonts True Property Boolean pbInlineIfElse True Property Boolean pbPropertyPublic True Property Boolean pbPropertyPrivate False Property Boolean pbRemoveEndComments True Property Integer piChangedFileCount 0 Property Integer piFileCount 0 Property String[] pCommands Property tCounters pTotalCounters Object oActions_Grp is a Group Set Size to 136 292 Set Location to 16 34 Set Label to "Cleanup actions To Perform:" Object oRemoveMarkers_cb is a CheckBox Set Size to 10 177 Set Location to 15 12 Set Label to 'Remove Studio Markers' End_Object Object oRTrimLines_cb is a CheckBox Set Size to 10 50 Set Location to 30 12 Set Label to 'Remove trailing spaces' End_Object Object oLocalVariables_cb is a CheckBox Set Size to 10 50 Set Location to 45 12 Set Label to "Remove local keyword on variable declarations" End_Object Object oRemoveFonts_cb is a CheckBox Set Size to 10 50 Set Location to 60 12 Set Label to 'Remove Hardcoded Fonts' End_Object Object oIfElseSemicolumn_cb is a CheckBox Set Size to 10 50 Set Location to 75 12 Set Label to "Rewrite single line if/else to use to multiple lines" End_Object Object oPropertyPublic_cb is a CheckBox Set Size to 10 50 Set Location to 90 12 Set Label to "Remove Property keyword 'public'" End_Object Object oPropertyPrivate_cb is a CheckBox Set Size to 10 50 Set Location to 105 12 Set Label to "Remove Property keyword 'private'" End_Object Object oEndComments_cb is a CheckBox Set Size to 10 50 Set Location to 120 12 Set Label to "Remove comments after end_class/end_object/end_function/end_procedure" End_Object Object oSplitBy is a RadioGroup Set Location to 65 182 Set Size to 26 98 Set Label to "Use:" Object oRadio1 is a Radio Set Label to "' ;'" Set Size to 10 20 Set Location to 10 5 Set psToolTip to "Break the line with a space followed by a semi column" End_Object Object oRadio2 is a Radio Set Label to "';'" Set Size to 10 20 Set Location to 10 25 Set psToolTip to "Break the line with a semi column" End_Object Object oRadio3 is a Radio Set Label to "Begin/End" Set Size to 10 48 Set Location to 10 49 Set psToolTip to "Break the line by adding a begin / end block" End_Object End_Object Object oTabSize is a SpinForm Set Size to 13 49 Set Location to 15 231 Set Label to "Tab Size:" Set Label_Col_Offset to 3 Set Label_Justification_Mode to JMode_Right Set psToolTip to "Select the indent size you want to use when breaking a line on rewriting a single line to multiple lines" End_Object End_Object Object oSelectFileOrDirectory is a RadioGroup Set Location to 154 34 Set Size to 30 100 Set Label to "Select" Object oRadio1 is a Radio Set Label to "Directory" Set Size to 10 45 Set Location to 15 12 End_Object Object oRadio2 is a Radio Set Label to "File" Set Size to 10 29 Set Location to 15 61 End_Object Procedure Notify_Select_State Integer iToItem Integer iFromItem Boolean bIsFile Boolean bIsFolder Forward Send Notify_Select_State iToItem iFromItem Move (iToItem = 1) to bIsFile Move (iToItem = 0) to bIsFolder // Set Enabled_State of oSourceFile to bIsFile Set Visible_State of oSourceFile to bIsFile Set Enabled_State of oCompareBtn to bIsFile Set Visible_State of oCompareBtn to bIsFile Set Enabled_State of oDirFormPath to bIsFolder Set Visible_State of oDirFormPath to bIsFolder End_Procedure // If you set Current_Radio, you must set it AFTER the // radio objects have been created AND AFTER Notify_Select_State has been // created. i.e. Set in bottom-code of object at the end!! // Set Current_Radio to 0 End_Object Object oSourceFile is a Form Set Label to "Enter the name of the source file to be parsed:" Set Size to 13 292 Set Location to 198 34 Set Label_Col_Offset to 0 Set Label_Justification_Mode to jMode_Top Set Prompt_Button_Mode to pb_PromptOn Procedure Prompt Integer bOpen bReadOnly String sFileName Get Show_Dialog of oOpenDialog1 to bOpen If bOpen Begin Get File_Name of oOpenDialog1 to sFileName Set value to sFileName // check if user is opening file as read_only Get TickReadOnly_State of oOpenDialog1 to bReadOnly If bReadOnly Begin Send info_box ("Files should not be opened as ReadOnly.") "Clean Markers" End End End_Procedure End_Object Object oOpenDialog1 is a OpenDialog Set Dialog_Caption to "Select a source file" Set Filter_String to "Programs|*.src|Views|*.vw|Dialogs|*.dg|Data Dictionaries|*.dd|Include files|*.inc|Report Views|*.rv|Selection Lists|*.sl|Web Object|*.wo|Packages|*.pkg|Business Processes|*.bp|Menus|*.mn|Header Files|*.h|Sture's Files|*.nui;*.utl|Any file|*.*" End_Object Object oDirFormPath is a DirForm Set Size to 13 292 Set Location to 198 34 Set Label_Justification_Mode to JMode_Top Set Label to "Enter the name of the main folder that contains the files:" Set Label_Col_Offset to 0 Set Prompt_Button_Mode to PB_PromptOn End_Object Object oCreateBackupFiles_cb is a CheckBox Set Size to 14 50 Set Location to 221 43 Set Label to "Create backup files (*.cmbak)" End_Object Object oFormParsedExt is a Form Set Size to 14 185 Set Location to 167 141 Set value to ".src;.vw;.sl;.dg;.rv;.pkg;.wo;.dd;.inc;.nui;.utl;.bp;.h;.mn;" Set Label to "Parsed file extensions:" Set Label_Col_Offset to 0 Set Label_Justification_Mode to JMode_Top Set psToolTip to "File extensions of files to cleanup, must end with ;" End_Object // // Reads the settings from the checkboxes and applies those by writing them out // to our properties // Procedure ReadSettings Boolean bChecked Get checked_state of oCreateBackupFiles_cb to bChecked Set pbSaveBackupFile to bChecked Get Checked_state of oRemoveMarkers_cb to bChecked Set pbCleanMarkers to bChecked Get Checked_State of oRTrimLines_cb to bChecked Set pbRTrimSource to bChecked Get Checked_State of oLocalVariables_cb to bChecked Set pbRemoveLocal to bChecked Get Checked_State of oRemoveFonts_cb to bChecked Set pbRemoveFonts to bChecked Get Checked_State of oIfElseSemiColumn_cb to bChecked Set pbInlineIfElse to bChecked Get Checked_State of oPropertyPublic_cb to bChecked Set pbPropertyPublic to bChecked Get Checked_State of oPropertyPrivate_cb to bChecked Set pbPropertyPrivate to bChecked Get Checked_State of oEndComments_cb to bChecked Set pbRemoveEndComments to bChecked End_Procedure // // At least one action should be selected. // Function ValidActions Returns Boolean Boolean bClean Boolean bRtrim Boolean bLocal Boolean bFonts Boolean bChecked Boolean bInlineIfElse Boolean bPublic Boolean bPrivate Boolean bEndComments Get pbCleanMarkers to bClean Get pbRTrimSource to bRTrim Get pbRemoveFonts to bFonts Get pbRemoveLocal to bLocal Get pbInlineIfElse to bInlineIfElse Get pbPropertyPublic to bPublic Get pbPropertyPrivate to bPrivate Get pbRemoveEndComments to bEndComments Move (bClean or bRTrim or bFonts or bLocal or bInlineIfElse or bPublic or bPrivate or bEndComments) to bChecked If (bChecked = False) ; Send Info_Box "You should at least check ONE action for the process to run." Function_Return bChecked End_Procedure Object oGenerateBtn is a Button Set Label to "Start Processing" Set Size to 14 123 Set Location to 239 99 Procedure OnClick String sDirName sFileName sText Integer iCurrent_Radio Boolean bFolderExists Boolean bFileExists Boolean bOK Send ReadSettings Get ValidActions to bOk If (bOk) Begin Send InitializeCounters Get Current_Radio of oSelectFileOrDirectory to iCurrent_Radio If (iCurrent_Radio = 0) Begin Set Value of oSourceFile to "" // This is required to have the file extension test work correctly at all times (a file might have been selected) Get value of oDirFormPath to sDirName // // PHvW 08/06/2018 Let see if the directory does exist.... // File_Exist sDirName bFolderExists If (bFolderExists = False) Begin Send Info_Box "Directory does not exists" "For your Information" Procedure_Return End Send DoProcess of oBPO Get pbOk of oBPO to bOk End Else Begin Get value of oSourceFile to sFileName File_Exist sFileName bFileExists If (bFileExists = False) Begin Send Info_Box "File does not exists" "For your Information" Procedure_Return End Get ProcessFile sFileName to bOK End If (bOK) Begin Get CleanupResult to sText Send info_box (sText+"\n\nParsing completed.") "Clean Markers" End Else Begin Send info_box "Parsed File could not be created. " "Clean Markers" End End End_Procedure End_Object Object oBPO is a BusinessProcess Property Boolean pbOk Procedure OnProcess String sDirName Boolean bOk Send SetProgressBarText Get value of oDirFormPath to sDirName Get RecursiveSearchDirectoryFiles sDirName to bOK Set pbOk to bOk End_Procedure Function RecursiveSearchDirectoryFiles String sSourceDirname Returns Boolean Boolean bOk bStop bFound Integer iCnt iMax iTmp String sFile sLine sEval sExt sSourceFile Handle hoDir Move 0 to iCnt Get value of oSourceFile to sSourceFile Get Create (RefClass(cDirectory)) to hoDir Move (sSourceDirname+"\*.*") to sFile Get SearchSingleDirectory of hoDir sFile DIRMODE_DIRECTORIES_ONLY to iMax Decrement iMax For iCnt from 0 to iMax Get Searchresult of hoDir item iCnt LIST_FILENAME to sLine If (sLine <> "." and sLine <> ".." and sLine <> ".svn" and sLine <> ".git" and sLine <> ".hg" and Lowercase(sLine) <> "apphtml") Begin Get RecursiveSearchDirectoryFiles (sSourceDirname + "\" + sLine) to bOk If (not(bOk)) Begin Send destroy of hoDir Function_Return False End Get Cancel_Check to bStop If bStop Begin Send destroy of hoDir Function_Return False End End Loop Get SearchSingleDirectory of hoDir sFile DIRMODE_FILES_ONLY to iMax Decrement iMax For iCnt from 0 to iMax Get Searchresult of hoDir item iCnt LIST_FILENAME to sLine Get ParseFileExtension sLine to sExt Move (Lowercase(sExt)) to sExt Get value of oFormParsedExt to sEval Move (Lowercase(sEval)) to sEval If ((Pos("."+sExt+";", sEval)) or sSourceFile<>"") Begin Send Update_status (sSourceDirname + "\" + sLine) Get ProcessFile (sSourceDirname + "\" + sLine) to bOK If (not(bOk)) Begin Send destroy of hoDir Function_Return False End End Get Cancel_Check to bStop If bStop Begin Send destroy of hoDir Function_Return False End Loop Send destroy of hoDir Move True to bOk Function_Return bOk End_Function Procedure Update_Status String sProgress Integer iRadio String sPath Get Current_Radio of oSelectFileOrDirectory to iRadio If (iRadio=0) Begin Get Value of oDirFormPath to sPath If (sPath<>"") Begin // Strip out the path Move (Replace(sPath,sProgress,"..")) to sProgress End End Forward Send Update_Status sProgress End_Procedure Procedure SetProgressBarText Boolean bCleanMarkers Boolean bRTrimSource Boolean bRemoveLocal Boolean bRemoveFonts Boolean bIsFontLine Boolean bInlineIfElse Boolean bPublic Boolean bPrivate Boolean bEndComments String sMessage Move "" to sMessage Get pbCleanMarkers to bCleanMarkers Get pbRTrimSource to bRTrimSource Get pbRemoveLocal to bRemoveLocal Get pbRemoveFonts to bRemoveFonts Get pbInlineIfElse to bInlineIfElse Get pbPropertyPublic to bPublic Get pbPropertyPrivate to bPrivate Get pbRemoveEndComments to bEndComments If (bCleanMarkers) ; Move "Removing Studio Markers\n" to sMessage If (bRTrimSource) ; Move (sMessage+"Removing end of line whitespace\n") to sMessage If (bRemoveLocal) ; Move (sMessage+"Removing local keyword from variables\n") to sMessage If (bRemoveFonts) ; Move (sMessage+"Removing typeface MS Sans Serif\n") to sMessage If (bInlineIfElse) ; Move (sMessage+"Rewriting if/else single line compound statement to multiple lines with ;\n") to sMessage If (bPublic or bPrivate) ; Move (sMessage+"Removing public/private keyword from properties\n") to sMessage If (bEndComments) ; Move (sMessage+"Removing end comments\n") to sMessage Move (sMessage+"...") to sMessage Move (Replaces("\n",sMessage,CS_LF)) to sMessage Set Process_Caption to "Clean Markers" Set Process_Message to sMessage Set Process_Title to "Code cleanup" End_Procedure Set Display_Error_State to True Set Allow_Cancel_State to True End_Object Object oCompareBtn is a Button Set Location to 221 276 Set Label to 'Compare' Set psToolTip to "Compare file changes after running cleanup" Set psImage to "Compare.bmp" Procedure OnClick Boolean bExist String sFile1 sFile2 String sCompareApp Get psFileCompareApp of ghoApplication to sCompareApp File_Exist sCompareApp bExist If (bExist) Begin Get Value of oSourceFile to sFile1 If (sFile1<>"") Begin Move (sFile1+".cmbak") to sFile2 File_Exist sFile1 bExist If (bExist) Begin File_Exist sFile2 bExist If (bExist) Begin Runprogram Wait ('"'+sCompareApp+'"') ('"'+sFile2+'" "'+sFile1+'"') End Else Begin Send Info_Box ("There is no .cmbak file, so there's nothing to compare with.\nDid you run the process already?") End End Else Begin Send Info_Box ("The file in the source file"*sFile1*"\nDoes not exist.") End End Else Begin Send Info_Box "You have to select a file first." End End Else Begin Send Info_Box "A file compare application is not set or not valid.\nPlease select a valid file comparison application from the menu." End End_Procedure End_Object Procedure AddCommand String sCommand String[] Commands Get pCommands to Commands Move (Lowercase(sCommand)) to sCommand Move sCommand to Commands[SizeOfArray(Commands)] Set pCommands to Commands End_Procedure // // Command line used for testing against inline if/else statements. // Note that it is not a complete command list and that we should be careful // about commands that might be used as functions or in functions! // For example, it is by intention that none of the variable declaration commands // are added as things like If (Convert(sVer,String)="ab") would complicate our testing // // All commands can be entered case insensitive // Standalone commands can end on a end of line, such as Abort. // Other commands need more parameters and in such case we can improve our success rate // by adding a space character. // Procedure AddAllCommands String[] Empty Set pCommands to Empty //Send AddCommand "Repeat" // nope it is a function too Send AddCommand "Abort" Send AddCommand "Abort_Transaction" Send AddCommand "Activate_View " Send AddCommand "Add " Send AddCommand "Address " Send AddCommand "Append " Send AddCommand "Append_Output " Send AddCommand "Attach " Send AddCommand "Begin_Constraints" Send AddCommand "Begin_Transaction" Send AddCommand "Broadcast " Send AddCommand "Broadcast_Focus " Send AddCommand "Calc " Send AddCommand "Calculate " Send AddCommand "Call_Driver " Send AddCommand "CallStackDump " Send AddCommand "Case " Send AddCommand "Clear " Send AddCommand "Close " Send AddCommand "Close_Input" Send AddCommand "Close_Output" Send AddCommand "Constrain " Send AddCommand "Constrained_Clear " Send AddCommand "Constrained_Find " Send AddCommand "Constraint_Set" Send AddCommand "Constraint_Validate" Send AddCommand "Copy_db " Send AddCommand "Copy_Records " Send AddCommand "Copyfile " Send AddCommand "Create_Field " Send AddCommand "Create_Index " Send AddCommand "Declare_DataFile " Send AddCommand "Decrement " Send AddCommand "Delegate " Send AddCommand "Delete " Send AddCommand "Delete_db " Send AddCommand "Delete_Field " Send AddCommand "Delete_Index " Send AddCommand "Direct_Input " Send AddCommand "Direct_Output " Send AddCommand "DiskFree " Send AddCommand "EraseFile " Send AddCommand "Error " Send AddCommand "Field_Map " Send AddCommand "File_Exist " Send AddCommand "Fill_Field " Send AddCommand "Find " Send AddCommand "For " Send AddCommand "For_All " Send AddCommand "Forward " Send AddCommand "Function_Return " // you might have code that does not return a value, I'd consider that a warning Send AddCommand "Get " Send AddCommand "Get_Argument_Size " Send AddCommand "Get_Attribute " Send AddCommand "Get_Channel_Position " Send AddCommand "Get_Channel_Size " Send AddCommand "Get_Current_Directory " Send AddCommand "Get_Current_Input_Channel " Send AddCommand "Get_Current_Output_Channel " Send AddCommand "Get_Current_User_Count " Send AddCommand "Get_Date_Attribute " Send AddCommand "Get_Directory " Send AddCommand "Get_Environment " Send AddCommand "Get_Field_Value " Send AddCommand "Get_FieldNumber " Send AddCommand "Get_File_Mod_Time " Send AddCommand "Get_File_Path " Send AddCommand "Get_FileNumber " Send AddCommand "Get_Licensed_Max_Users " Send AddCommand "Get_StrictEval " Send AddCommand "Get_Transaction_Retry " Send AddCommand "Get_Windows_Directory " Send AddCommand "GetAddress " Send AddCommand "GetBuff " Send AddCommand "GetBuff_String " Send AddCommand "GetDskInfo " Send AddCommand "Global_Variable " Send AddCommand "Include_Resource " Send AddCommand "Increment " Send AddCommand "Indicate " Send AddCommand "Indicator " Send AddCommand "Load_Def " Send AddCommand "Load_Driver " Send AddCommand "Lock" Send AddCommand "Login " Send AddCommand "Logout" Send AddCommand "Make_Directory " Send AddCommand "Make_File " Send AddCommand "Make_Temp_File " Send AddCommand "Move " Send AddCommand "Movedate " Send AddCommand "Moveint " Send AddCommand "Movenum " Send AddCommand "Movereal " Send AddCommand "Movestr " Send AddCommand "NewRecord " Send AddCommand "On_Item" Send AddCommand "On_key " Send AddCommand "Open " Send AddCommand "Output " Send AddCommand "Output_Aux_File " Send AddCommand "Output_Wrap" Send AddCommand "Playwave " Send AddCommand "Procedure_Return" Send AddCommand "Property " Send AddCommand "Put " Send AddCommand "Read " Send AddCommand "Read_Block " Send AddCommand "Read_hex " Send AddCommand "Readln " Send AddCommand "Reg_Close_Key " Send AddCommand "Reg_Enum_Key " Send AddCommand "Reg_Enum_Key_Info " Send AddCommand "Reg_Enum_Value " Send AddCommand "Relate " Send AddCommand "Remove_Directory " Send AddCommand "Renamefile " Send AddCommand "Report_Breaks " Send AddCommand "Reread" Send AddCommand "RunProgram " Send AddCommand "Save " Send AddCommand "SaveRecord " Send AddCommand "Send " Send AddCommand "Set " Send AddCommand "Set_Argument_Size " Send AddCommand "Set_Attribute " Send AddCommand "Set_Channel_Position " Send AddCommand "Set_Date_Attribute " Send AddCommand "Set_Directory " Send AddCommand "Set_Field_Value " Send AddCommand "Set_File_Mod_Time " Send AddCommand "Set_Foreign_Profile_String " Send AddCommand "set_registry_root " Send AddCommand "Set_Relate " Send AddCommand "Set_StrictEval " Send AddCommand "Set_Transaction_Retry " Send AddCommand "Shift_State " Send AddCommand "Show " Send AddCommand "Showln" Send AddCommand "Sleep " Send AddCommand "Sort " Send AddCommand "Start_UI" Send AddCommand "Structure_Abort " Send AddCommand "Structure_Copy " Send AddCommand "Structure_End " Send AddCommand "Structure_Start " Send AddCommand "Subtract " Send AddCommand "Sysdate " Send AddCommand "Sysdate4 " Send AddCommand "Unload_Driver " Send AddCommand "Unlock" Send AddCommand "Valid_Drive " Send AddCommand "ValueTreeDeserializeParameter " Send AddCommand "ValueTreeSerializeParameter " Send AddCommand "VConstrain " Send AddCommand "Version_Information " Send AddCommand "VFind " Send AddCommand "Virtual_Key " Send AddCommand "WebGet " Send AddCommand "WebPublishFunction " Send AddCommand "WebPublishProcedure " Send AddCommand "WebSet " Send AddCommand "WebSetResponsive " Send AddCommand "While " Send AddCommand "Write " Send AddCommand "Write_Hex " Send AddCommand "WriteLn" Send AddCommand "ZeroFile " Send AddCommand "ZeroString " Send AddCommand "ZeroType " End_Procedure // Set the default values for the checkboxes Procedure Entering_Scope Returns Integer Integer iRetval String sCmdLineFile Forward Get Msg_Entering_Scope to iRetval If (iRetval=0) Begin Set Checked_State of oRemoveMarkers_cb to True Set Checked_State of oRTrimLines_cb to True Set Checked_State of oLocalVariables_cb to True Set Checked_State of oRemoveFonts_cb to True Set Checked_State of oCreateBackupFiles_cb to True Set Checked_State of oIfElseSemiColumn_cb to True Set Checked_State of oPropertyPublic_cb to True Set Checked_State of oPropertyPrivate_cb to False // user should choose to enable this one Set Checked_State of oEndComments_cb to True Set Value of oTabSize to "4" Send AddAllCommands Get psCmdLineFile of ghoApplication to sCmdLineFile If (sCmdLineFile<>"") Begin Set Value of oSourceFile to sCmdLineFile Set Current_Radio of oSelectFileOrDirectory to 1 End End Procedure_Return iRetval End_Procedure Procedure CloseChannel Integer iChannel Close_Input channel iChannel Send Seq_Release_Channel iChannel End_Procedure Function FindStudioMarker String sLine Returns Boolean Boolean bFound Move False to bFound Move (Trim(sLine)) to sLine Case Begin Case (sLine = "//AB-IgnoreStart") Move True to bFound Case Break Case (sLine = "//AB-IgnoreEnd") Move True to bFound Case Break Case (sLine = "//AB-StoreStart") Move True to bFound Case Break Case (sLine = "//AB-StoreEnd") Move True to bFound Case Break Case (sLine = "//AB-StoreTopStart") Move True to bFound Case Break Case (sLine = "//AB-StoreTopEnd") Move True to bFound Case Break Case (sLine = "//AB-PanelStoreTopStart") Move True to bFound Case Break Case (sLine = "//AB-PanelStoreTopEnd") Move True to bFound Case Break Case (sLine = "//AB-PanelStoreStart") Move True to bFound Case Break Case (sLine = "//AB-PanelStoreEnd") Move True to bFound Case Break Case (sLine = "//AB-ClientStoreTopStart") Move True to bFound Case Break Case (sLine = "//AB-ClientStoreTopEnd") Move True to bFound Case Break Case (sLine = "//AB-ClientStoreStart") Move True to bFound Case Break Case (sLine = "//AB-ClientStoreEnd") Move True to bFound Case Break Case (sLine = "//AB-DDOStart") Move True to bFound Case Break Case (sLine = "//AB-DDOEnd") Move True to bFound Case Break Case (Left(sLine, 6) = "//AB/ ") Move True to bFound Case Break Case (sLine = "//AB-MenuPackage") Move True to bFound Case Break Case (sLine = "//AB-End") Move True to bFound Case Break Case (sLine = "//AB-ToolbarPackage") Move True to bFound Case Break Case (sLine = "//AB-ViewStart") Move True to bFound Case Break Case (sLine = "//AB-ViewEnd") Move True to bFound Case Break Case (sLine = "//AB-StatusBarPackage") Move True to bFound Case Break Case (sLine = "//IDE-FileType=ftApplication") Move True to bFound Case Break Case End Function_Return bFound End_Function // RTrim trailing spaces if present. Function RemoveTrailingSpaces String ByRef sLine Returns Boolean Integer iBefore iAfter Boolean bChanged Move False to bChanged Move (Length(sLine)) to iBefore Move (Rtrim(sLine)) to sLine Move (Length(sLine)) to iAfter If (iBefore<>iAfter) ; Move True to bChanged Function_Return bChanged End_Function // Removes local statement if present. Function RemoveLocal String ByRef sLine Returns Boolean Boolean bChanged String sTest Integer iPos Move False to bChanged Move (ltrim(sLine)) to sTest Move (Left(sTest, 6)) to sTest Move (lowercase(sTest)) to sTest If (sTest = "local ") Begin // local must be the first word in the line. // Now find the local statement in the line and remove it. Move (lowercase(sLine)) to sTest Move (pos("local ", sTest)) to iPos If (iPos>0) Begin Move (Remove(sLine, iPos, 6)) to sLine Move True to bChanged End End Function_Return bChanged End_Function Function RemovePropertyPublicPrivate String ByRef sLine String sPubPriv Returns Boolean Boolean bChanged String sTest Integer iPos Move False to bChanged Move (ltrim(sLine)) to sTest Move (Left(sTest, 9)) to sTest Move (lowercase(sTest)) to sTest If (sTest = "property ") Begin Move (lowercase(sLine)) to sTest Move (pos(sPubPriv, sTest)) to iPos If (iPos>0) Begin Move (Overstrike(Repeat(" ",Length(sPubPriv)),sLine, iPos)) to sLine Move True to bChanged End End Function_Return bChanged End_Function Function RemovePropertyPublic String ByRef sLine Returns Boolean Boolean bChanged Get RemovePropertyPublicPrivate (&sLine) " public " to bChanged Function_Return bChanged End_Function Function RemovePropertyPrivate String ByRef sLine Returns Boolean Boolean bChanged Get RemovePropertyPublicPrivate (&sLine) " private " to bChanged Function_Return bChanged End_Function Function RemoveComments String ByRef sLine Returns Boolean Boolean bRemoved Integer iPos Move False to bRemoved Move (Pos("//",sLine)) to iPos If (iPos>0) Begin Move (Left(sLine,iPos-1)) to sLine Move True to bRemoved End Function_Return bRemoved End_Function Function LineEndHasBeginOrSemicolumn String sLine Returns Boolean Boolean bRemoved Boolean bStop String sTest Move sLine to sLine // dummy line which appears to fix a runtime byref error (???) Get RemoveComments (&sLine) to bRemoved Move (Rtrim(sLine)) to sTest If (Right(sTest,1)=";") Begin Move True to bStop End If not bStop Begin Move (Lowercase(sTest)) to sTest If (Right(sTest,5)="begin") Begin Move True to bStop End End Function_Return bStop End_Function Function RemoveEndComments String ByRef sLine Returns Boolean Boolean bChanged Boolean bRemoved String sTestLine String sTest Integer iPos Move False to bChanged Move (ltrim(sLine)) to sTestLine Move (lowercase(sTestLine)) to sTestLine Move (Left(sTestLine, 10)) to sTest If (sTest = "end_class ") Begin Get RemoveComments (&sLine) to bRemoved If (bRemoved) ; Move True to bChanged End Move (Left(sTestLine, 11)) to sTest If (sTest = "end_object ") Begin Get RemoveComments (&sLine) to bRemoved If (bRemoved) ; Move True to bChanged End Move (Left(sTestLine, 13)) to sTest If (sTest = "end_function ") Begin Get RemoveComments (&sLine) to bRemoved If (bRemoved) ; Move True to bChanged End Move (Left(sTestLine, 14)) to sTest If (sTest = "end_procedure ") Begin Get RemoveComments (&sLine) to bRemoved If (bRemoved) ; Move True to bChanged End Function_Return bChanged End_Function Function TestCommands String sTest Returns Integer Boolean bRemoved Integer iCount Integer iPos Integer iItem Integer iTest String sCommand String[] Commands Move 0 to iPos Get RemoveComments (&sTest) to bRemoved Get pCommands to Commands Move (SizeOfArray(Commands)) to iCount For iItem from 0 to (iCount-1) Move Commands[iItem] to sCommand Move (Pos(" "+sCommand,sTest)) to iTest // The command MUST have a space before it, after it not always If (iTest<>0) Begin If (iPos=0) ; Move iTest to iPos Else Begin If (iTest0) Begin Move True to bChanged If (eSplitBy=CI_SplitBySpaceSemiColumn) Begin Move (Insert(" ;"+CS_CRLF+sLineIndent+sIndent,sLine,iPos)) to sLine End Else If (eSplitBy=CI_SplitBySemiColumn) Begin Move (Insert(";"+CS_CRLF+sLineIndent+sIndent,sLine,iPos)) to sLine End Else If (eSplitBy=CI_SplitByBeginEnd) Begin Move (Insert(" Begin"+CS_CRLF+sLineIndent+sIndent,sLine,iPos)) to sLine Move (sLine+CS_CRLF+sLineIndent+"End") to sLine End // Remove any spaces before the point on which we break the line Move (Left(sLine,iPos-1)) to sLine1 Move (Right(sLine,Length(sLine)-(iPos-1))) to sLine2 Move (Rtrim(sLine1)) to sLine1 Move (sLine1+sLine2) to sLine End Function_Return bChanged End_Function Function SplitInlineIfElseLine String ByRef sLine Integer eSplitBy Returns Boolean Boolean bHasIfElse Boolean bStop Boolean bChanged Integer iIndent Integer iPos String sTest Move False to bChanged Move (ltrim(sLine)) to sTest Move (Pos(sTest,sLine)-1) to iIndent Move (Left(sTest, 3)) to sTest Move (lowercase(sTest)) to sTest If (sTest = "if ") Begin Get LineEndHasBeginOrSemicolumn sLine to bStop If (bStop=False) Begin // It's one of those single line if statements, break it up Move (Lowercase(sLine)) to sTest Get BreakupCompoundStatement iIndent (&sLine) eSplitBy to bChanged End End Else Begin Move (ltrim(sLine)) to sTest Move (Left(sTest, 5)) to sTest Move (lowercase(sTest)) to sTest If (sTest = "else ") Begin Get LineEndHasBeginOrSemicolumn sLine to bStop If (bStop=False) Begin Get BreakupCompoundStatement iIndent (&sLine) eSplitBy to bChanged End End End Function_Return bChanged End_Function // Removes hardcoded MS Sans Serif fonts if present. Function IsSansSerifTypeFaceLine String sLine Returns Boolean String sTest Boolean bIsFontLine Move False to bIsFontLine Move (Trim(sLine)) to sTest Move (lowercase(sTest)) to sTest Move (replaces(" ",sTest,"")) to sTest Move (replaces("'",sTest,"*")) to sTest Move (replaces('"',sTest,"*")) to sTest If (sTest = 'settypefaceto*mssansserif*') Begin Move True to bIsFontLine End Function_Return bIsFontLine End_Function Function ParseFile String sParsedFile Integer iInChannel Integer iOutChannel tCounters ByRef Counters Returns Boolean Boolean bParseOK bMarkerFound bChanged Boolean bCleanMarkers Boolean bRTrimSource Boolean bRemoveLocal Boolean bRemoveFonts Boolean bIsFontLine Boolean bPublic Boolean bPrivate Boolean bInlineIfElse Boolean bEndComments Boolean bEndOfFile Boolean bReadAhead Integer iLine Integer eSplitBy String sLineBreak String sSourceFile String sLine String sNextLine Move False to bParseOK Move False to bEndOfFile Move False to bReadAhead Move "" to sLineBreak Move "" to sNextLine Move 0 to iLine Get pbCleanMarkers to bCleanMarkers Get pbRTrimSource to bRTrimSource Get pbRemoveLocal to bRemoveLocal Get pbRemoveFonts to bRemoveFonts Get pbPropertyPublic to bPublic Get pbPropertyPrivate to bPrivate Get pbInlineIfElse to bInlineIfElse Get pbRemoveEndComments to bEndComments Get BackupFileName sParsedFile to sSourceFile // Need to use binary read mode if we want to preserve tab characters and not have automatic tab replacement // filemode options don't seem to work as documented, not sure why, but I stop caring about that now. //Direct_Input channel iInChannel ("binary: "+"cr: 13: "+"eof: 26: "+sSourceFile) //Direct_Input channel iInChannel ("binary: "+"cr: 13:"+"eof: 26:"+sSourceFile) Direct_Input channel iInChannel ("binary:"+sSourceFile) Direct_Output channel iOutChannel (sParsedFile) Repeat If (bReadAhead=False) Begin Readln channel iInChannel sLine End Else Begin Move sNextLine to sLine Move False to bReadAhead Move "" to sNextLine End Move (SeqEof) to bEndOfFile Increment iLine Move False to bMarkerFound Move False to bIsFontLine // On line 1 we determine if the file has CRLF or LF line endings. If (iLine=1) Begin // The readline automatically reads Until LF, but does not report LF back in the string If (Length(sLine) >= 1 and Right(sLine,1)=CS_CR) Begin Move CS_CRLF to sLineBreak End Else Begin Move CS_LF to sLineBreak End End If (sLineBreak=CS_CRLF) Begin If (Right(sLine,1)=CS_CR) Begin Move (Left(sLine,Length(sLine)-1)) to sLine End Else Begin // if reading last line then bEndOfFile is still not set so can't test for that // unless we read ahead! Move True to bReadAhead Readln channel iInChannel sNextLine If (SeqEof) Begin Move "" to sLineBreak End End End If (Length(sLine)=0) Begin If (bEndOfFile=False) Begin // We only want this for lines that are actually not even having a space, so a test for sLine="" // doesn't work as sLine="" == sLine=" " == sLine=" " etcetera Write channel iOutChannel sLineBreak End End Else Begin If (bCleanMarkers) Begin Get FindStudioMarker sLine to bMarkerFound If (bMarkerFound) ; Increment Counters.iRemoveMarker End If (bMarkerFound=False) Begin If (bRemoveLocal) Begin Get RemoveLocal (&sLine) to bChanged If (bChanged) ; Increment Counters.iRemoveLocal End If (bRemoveFonts) Begin Get IsSansSerifTypeFaceLine sLine to bIsFontLine If (bIsFontLine) ; Increment Counters.iRemoveFonts End If (bPublic) Begin Get RemovePropertyPublic (&sLine) to bChanged If (bChanged) ; Increment Counters.iRemovePublic End If (bPrivate) Begin Get RemovePropertyPrivate (&sLine) to bChanged If (bChanged) ; Increment Counters.iRemovePrivate End If (bInlineIfElse) Begin Get Current_Radio of oSplitBy to eSplitBy Get SplitInlineIfElseLine (&sLine) eSplitBy to bChanged If (bChanged) ; Increment Counters.iInlineIfElse End If (bEndComments) Begin Get RemoveEndComments (&sLine) to bChanged If (bChanged) ; Increment Counters.iEndComments End If (bRTrimSource) Begin // should be after remove end comments Get RemoveTrailingSpaces (&sLine) to bChanged If (bChanged) ; Increment Counters.iTrimmed End If (bIsFontLine=False) Begin Write channel iOutChannel sLine sLineBreak End End End Until (bEndOfFile) If (not (err)) Begin Move True to bParseOK End Function_Return bParseOK End_Function Function AvailableChannel Returns Integer Integer iChannelAvailable Get Seq_New_Channel to iChannelAvailable Function_Return iChannelAvailable End_Function // Changed to use .cmbak instead of a normal .BAK as I don't want the // utility to overwrite the normal .BAK files. By using a unique // file extension, they are easy to select and delete all of them in one // go. Function BackupFileName String sFile Returns String String sBkupFile Boolean bFileExists Move (sFile - ".cmbak") to sBkupFile Function_Return sBkupFile End_Function Function SaveFileBackup String sFileName Returns Boolean Boolean bFileExists bOK String sBKFile Integer iRetval Move False to bOK Get BackupFileName sFileName to sBKFile Get FileCopy sFileName sBKFile to iRetVal Get FileExists sBKFile to bOK Function_Return bOK End_Function Procedure InitializeCounters tCounters EmptyTotals Set piChangedFileCount to 0 Set piFileCount to 0 Set pTotalCounters to EmptyTotals End_Procedure Procedure TallyCounters tCounters Counters tCounters Totals Get pTotalCounters to Totals Move (Counters.iTrimmed + Totals.iTrimmed ) to Totals.iTrimmed Move (Counters.iRemoveMarker + Totals.iRemoveMarker ) to Totals.iRemoveMarker Move (Counters.iRemoveLocal + Totals.iRemoveLocal ) to Totals.iRemoveLocal Move (Counters.iRemoveFonts + Totals.iRemoveFonts ) to Totals.iRemoveFonts Move (Counters.iRemovePublic + Totals.iRemovePublic ) to Totals.iRemovePublic Move (Counters.iRemovePrivate + Totals.iRemovePrivate) to Totals.iRemovePrivate Move (Counters.iInlineIfElse + Totals.iInlineIfElse ) to Totals.iInlineIfElse Move (Counters.iEndComments + Totals.iEndComments ) to Totals.iEndComments Set pTotalCounters to Totals End_Procedure Function CleanupResult Returns String String sText Integer iChangedFiles Integer iFileCount tCounters Totals Get pTotalCounters to Totals Get piChangedFileCount to iChangedFiles Get piFileCount to iFileCount Move ("Totals Files changed:"*Trim(iChangedFiles)*"out of"*Trim(iFileCount)*"Files.\n") to sText Move (sText+"\nStatistics:") to sText Move (sText+"\nRight trimmed"*Trim(Totals.iTrimmed)*"lines") to sText Move (sText+"\nMarkers removed"*Trim(Totals.iRemoveMarker)) to sText Move (sText+"\nLocal keywords removed"*Trim(Totals.iRemoveLocal)) to sText Move (sText+"\nStatic fonts removed"*Trim(Totals.iRemoveFonts)) to sText Move (sText+"\nPublic keywords removed"*Trim(Totals.iRemovePublic)) to sText Move (sText+"\nPrivate keywords removed"*Trim(Totals.iRemovePrivate)) to sText Move (sText+"\nIf/Else lines changed"*Trim(Totals.iInlineIfElse)) to sText Move (sText+"\nEnd Comments removed"*Trim(Totals.iEndComments)) to sText Function_Return sText End_Function // // Checks the counters to see if the file was changed // Function FileCountersChanged tCounters Counters Returns Boolean Boolean bChanged Move False to bChanged If (Counters.iTrimmed<>0) ; Move True to bChanged If (Counters.iRemoveMarker<>0) ; Move True to bChanged If (Counters.iRemoveLocal<>0) ; Move True to bChanged If (Counters.iRemoveFonts<>0) ; Move True to bChanged If (Counters.iRemovePublic<>0) ; Move True to bChanged If (Counters.iRemovePrivate<>0) ; Move True to bChanged If (Counters.iInlineIfElse<>0) ; Move True to bChanged If (Counters.iEndComments<>0) ; Move True to bChanged Function_Return bChanged End_Function Procedure IncrementChangedFiles Integer iCount Get piChangedFileCount to iCount Increment iCount Set piChangedFileCount to iCount End_Procedure Procedure IncrementFileCount Integer iCount Get piFileCount to iCount Increment iCount Set piFileCount to iCount End_Procedure // // Processes the file passed and performs the actions that have been chosen // This function will always create a backup file and then call parsefile // for the actual work. // After the work has been done, it will remove the backup file OR // rename it to .bak depending on if you wanted to save the backup file or not. // Function ProcessFile String sFileName Returns Boolean Boolean bSuccess Boolean bSaveBak Boolean bChanged Integer iInChannel iOutChannel iIgnored structFileTime ftLastWrite String sBKFile tCounters Counters // copy file to .CMBAK Get SaveFileBackup sFileName to bSuccess Get pbSaveBackupFile to bSaveBak If (bSuccess) Begin // open available channels Get AvailableChannel to iInChannel Get AvailableChannel to iOutChannel If ((iInChannel <> DF_SEQ_CHANNEL_NOT_AVAILABLE) and (iOutChannel <> DF_SEQ_CHANNEL_NOT_AVAILABLE)) Begin Get GetFileLastWriteTime sFileName to ftLastWrite // parse file Get ParseFile sFileName iInChannel iOutChannel (&Counters) to bSuccess // close channels Send CloseChannel iInChannel Send CloseChannel iOutChannel Send IncrementFileCount Get FileCountersChanged Counters to bChanged If (bChanged) Begin Send IncrementChangedFiles Send TallyCounters Counters End Else Begin // while the file was rewritten, it has not changed, so restore the file // modified date/time and get rid of the backup file. Send SetFileLastWriteTime sFileName ftLastWrite If (bSaveBak) Begin Get BackupFileName sFileName to sBKFile Get FileDelete sBKFile to iIgnored End End End End If (bSaveBak=False) Begin Get BackupFileName sFileName to sBKFile Get FileDelete sBKFile to iIgnored End Function_Return bSuccess End_Function Procedure OnFileDropped String sFilename Boolean bLast Forward Send OnFileDropped sFilename bLast Set Current_Radio of oSelectFileOrDirectory to 1 // File Set Value of oSourceFile to sFilename End_Procedure Cd_End_Object