Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Auto Backup
Author | Message | ||||
elk1984 Senior Member Joined: 11/07/2020 Location: United KingdomPosts: 227 |
After breaking my program (the dreaded line too long followed by a corrupted file), I've created an include that can be embedded in any program that will automatically create a copy every time it is run, and retain a set number of versions. Comments welcome - I hope people find it useful. OPTION BASE 0 OPTION EXPLICIT OPTION DEFAULT NONE '****************************************************************************************** ' Filename: sub-backup-program.inc ' Author : elk1984 ' Version : 1.0 ' Date : 22 October 2020 ' ' Description: ' Automatic Backup Routine to prevent file loss, the dreaded "line too long" error or ' to protect against bad edits. ' ' Usage: ' Add into your main program ' #Include "sub-backup-program.inc" ' DoBackup(<NumVersion>, <ShowDetail>) ' ' Where <NumVersion> is an integer of the number of versions to keep ' And <ShowDetail> is an integer; 0 = silent, 1+ = show increasing levels of debug information ' '****************************************************************************************** SUB DoBackup(versions As Integer, showDetail As Integer) LOCAL thisDate As String = IsoDate(date$) LOCAL thisTime As String = ReplaceText(time$,":","-") LOCAL fullPath As String = MM.INFO$(CURRENT) LOCAL directory As String = LEFT$(fullPath,LastIndexOf(fullPath,"/")) LOCAL fileName As String = RIGHT$(fullPath,LEN(fullPath)-LEN(directory)) LOCAL extension As String = RIGHT$(fileName,LEN(fileName)-LastIndexOf(fileName,".")) LOCAL fileOnly As String = LEFT$(fileName,LEN(fileName)-LEN(extension)-1) LOCAL backupFileName As String = fileOnly+"."+thisDate+"."+thisTime+"."+extension LOCAL cleanupSpec As String = directory + fileOnly+".*.*."+extension LOCAL currentWorking As String = CWD$ CHDIR directory IF ShowDetail>=1 THEN PRINT "Backing Up Program " PRINT "Full Path : " + fullPath PRINT "Directory : " + directory PRINT "File Name : " + fileName PRINT "File Only : " + fileOnly PRINT "Extension : " + extension PRINT "Backup Name : " + backupFileName PRINT "Date : " + thisDate PRINT "Time : " + thisTime PRINT "Versions To Keep : " + STR$(Versions) PRINT "Cleanup Spec : " + cleanupSpec END IF IF showDetail>=2 THEN PRINT "Creating backup of " + fileName + " called " + backupFileName IF versions > 0 THEN COPY fileName TO backupFileName END IF IF showDetail>=2 THEN PRINT "Clearing Up Old Versions. Retaining " + str$(versions) + " of files matching " + cleanupSpec ManageVersions(cleanupSpec, versions, showDetail) CHDIR currentWorking END SUB '****************************************************************************************** SUB ManageVersions(fileSpec As String, versionCount As Integer, showDetail as Integer) LOCAL backupFile As String = DIR$(fileSpec,FILE) LOCAL backupFilesFound As Integer = 0 LOCAL i As Integer = 0 LOCAL currentWorking As String = CWD$ 'Find the number of matching files to generate a correctly sized array DO WHILE backupFile <> "" backupFilesFound = backupFilesFound + 1 backupFile = DIR$() LOOP IF backupFilesFound > versionCount THEN 'Create and fill array of filenames LOCAL backupFiles(backupFilesFound) As String 'Change into the directory of the fileSpec CHDIR LEFT$(fileSpec,LastIndexOf(fileSpec,"/")) backupFile = DIR$(fileSpec,FILE) IF backupFile <> "" THEN DO backupFiles(i) = backupFile backupFile = DIR$() i = i + 1 LOOP UNTIL backupFile = "" END IF 'Sort array ascending SORT backupFiles() 'Loop backwards through the file collection to remove versions > version count i = backupFilesFound-1 DO IF backupFilesFound-i > versionCount-1 THEN IF showDetail>=2 THEN PRINT "Removing File " + backupFiles(i) IF backupFiles(i) <> "" THEN KILL backupFiles(i) END IF END IF IF showDetail>=3 THEN PRINT backupFilesFound-i,versionCount,backupFiles(i) END IF i=i-1 LOOP UNTIL i < 0 'Cleanup CHDIR currentWorking ERASE backupFiles END IF 'Cleanup ERASE backupFile ERASE backupFilesFound ERASE i END SUB '****************************************************************************************** FUNCTION IsoDate(inputDate As String) As String IsoDate = RIGHT$(inputDate,4) + "-" + MID$(inputDate,4,2) + "-" + LEFT$(inputDate,2) END FUNCTION '****************************************************************************************** FUNCTION ReplaceText(inputString As String, textToReplace As String, replacementString As String) As String LOCAL foundPosition As Integer = 1 LOCAL lastFoundPosition As Integer = 1 LOCAL newString As String = "" LOCAL preFindString As String = "" LOCAL postFindString As String = "" lastFoundPosition=foundPosition foundPosition=INSTR(inputString, textToReplace) IF foundPosition > 0 THEN 'Replace The Found Text preFindString=MID$(inputString,lastFoundPosition,foundPosition-1) postFindString = MID$(inputString,foundPosition+LEN(textToReplace),LEN(inputString)-foundPosition+LEN(textToReplace)) newString=preFindString + replacementString + postFindString 'Search for the next instance by recursing the string newString=ReplaceText(newString, textToReplace, replacementString) ELSE newString=inputString END IF ReplaceText=newString END FUNCTION '****************************************************************************************** FUNCTION LastIndexOf(inputString As String, textToFind As String) As Integer LOCAL foundPosition As Integer = 1 LOCAL lastFoundPosition As Integer = 1 DO lastFoundPosition=foundPosition foundPosition=INSTR(foundPosition+1,inputString, textToFind) LOOP UNTIL foundPosition=0 LastIndexOf=lastFoundPosition END FUNCTION '****************************************************************************************** |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3861 |
Hi "elk1984", That does look like a useful set of functionality. The editor does create a single backup now though anyway which I would have thought was sufficient protection against the dreaded line too long / file corruption ? Why are you bothering with those ERASE statements though? those LOCALs will be cleaned up automatically when the SUB ends. Tom. Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
elk1984 Senior Member Joined: 11/07/2020 Location: United KingdomPosts: 227 |
Yes, the editor creating a backup does cover line too long. I noticed editor has that feature in the newer versions of the Firmware than I'm running, but sometimes it's useful to have previous versions of the file in case of "user error" like messing up code when refactoring. Thanks - I didn't realise I got that for free Edited 2020-10-23 05:08 by elk1984 |
||||
thwill Guru Joined: 16/09/2019 Location: United KingdomPosts: 3861 |
Hmmm ... might be better if we could write a wrapper around EDIT that compared the current state of the file with the last "versioned" state and if they were different created a new version. Unfortunately even using EXECUTE we cannot run EDIT from within a program: Error in line X: Invalid in a program @matherp, if you see this, is there a good reason for this limitation or did you just think it was a nuts thing for us to want to do ? Best wishes Tom Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
elk1984 Senior Member Joined: 11/07/2020 Location: United KingdomPosts: 227 |
That's a good idea. I'll incorporate a hash check into the next version I'm currently wrestling (without much success) with MMEdit, but I'll start a different thread for that.... |
||||
elk1984 Senior Member Joined: 11/07/2020 Location: United KingdomPosts: 227 |
New version created - backups are now only created if the source file has been modified and no backup exists. sub-backup-program.zip |
||||
elk1984 Senior Member Joined: 11/07/2020 Location: United KingdomPosts: 227 |
And another quick update sub-backup-program.zip |
||||
Print this page |