This is a guide on how to use Backup Manager's system calls.
Backup Manager uses several different functions, subroutines, and configuration variables for accomplishing its tasks. They can be used in shells and other programs to control Backup Manager.
All of Backup Manager's routines, backups, and configuration data are stored in the ωbman3 folder. Any program using them must set the current folder to ωbman3 in order for the routines to operate. Some routines use external variables to store or return data. Unless otherwise indicated, it should be assumed that all variables mentioned below are located in the ωbman3 folder.
More information about error messages generated by Backup Manager system routines can be found in the errors.html document.
"Opens", or prepares, the backup database for use
Usage: openbd()
Note: This routine must be called prior to using most of the other routines listed here. Otherwise, the other routines will fail with strange error messages, because they will not be able to access the backup database. Once openbd has been called, it is not necessary to call it again every time a routine is used. Only after closebd or revertbd are called must openbd be called again before using the routines.
"Closes" the backup database, writing all changes made to Flash Archive
Usage: closebd()
Note: This routine should always be called once the desired Backup Manager operations have been completed (probably just before your program exits). This is so that all modified backup information is written back to the Flash Archive and not lost if RAM is deleted. Failure to call this routine after changing the backup database can result in lost backup data if the RAM's contents are lost.
Errors: closebd performs a simple "sanity check" on the database files before accepting the changes and closing the database. All registered bd* and bg* variables must exist and must be lists. Otherwise, closebd will call revertbd and cause a special "Database Error" condition. This is done to help protect the database from being severely damaged by bugs in shells or hooks that write data to the database directly.
Tip: The sanity check closebd performs is somewhat slow. You can take a shortcut by skipping the closebd call if the database has not been modified since the openbd call. This is safe because the last closed state of the database is kept in Archive at all times. The recommended way to do this is by checking the bdmod variable. For example:
:If bdmod:closebd()
Caution: If your program alters the bd* or bg* files directly without manually setting bdmod to true, or if it calls external code that may do so, it is better to call closebd unconditionally to prevent changes from being lost from the database. All of Backup Manager's own routines automatically update bdmod appropriately, so if you stick with just using these routines, the above method should be safe.
Reverts the database to the state it was in when the last call to closebd was made. All changes made since the openbd call are erased.
Usage: revertbd()
Notes: This routine is used in place of closebd when reverting the database back to its previous state. The database is automatically closed, so there is no need to call closebd again.
This routine should be avoided if at all possible. Reverting the database could result in missing backup files that the system thinks are there (if they were deleted since the call to openbd) or orphaned backup files (backup files that are no longer assigned to a backup, and therefore are never deleted) that waste space.
Note: The parameter <backup_specifier> indicates either a string or integer representing a file that has been previously backed up with the newbu routine. This parameter can be one of the following:
Backs up a new file
Usage: newbu(<path_remembered>, <actual_path_to_back_up>, <store_away_backup?>)
Examples:
newbu("main\hiscores","",false)
Backs up the file main\hiscores
newbu("main\results","temp\test1",true)
Backs up the file temp\test1 as a stored-away backup, but remembers the backup as being stored as main\results. All other operations will act as though the original file were stored as main\results instead of test\test1.
Notes:
A complete path including folder and file names must be given for <path_remembered> and <actual_path_to_back_up>, with the exception of passing a null string to <actual_path_to_back_up>.
Files from Backup Manager's ωbman3 folder cannot be backed up unless <path_remembered> points to a different folder.
Errors: newbu will throw an error if:
Updates a backup
Usage: updbu(<backup_specifier>, <path_to_use_for_update>)
Normally, when specifying an original path for <backup_specifier>, the parameters for <backup_specifier> and <path_to_use_for_update> are the same. This causes the current backup for the file to be updated with the file's current contents. However, by specifying a different file for <path_to_use_for_update>, it is possible to update the backup with a different file. This may be useful for updating a backup whose original file has been renamed, for instance.
Examples:
updbu("main\hiscores","main\hiscores")
Updates the backup of main\hiscores with its current contents
updbu("main\hiscores","")
A shorter version of the above
updbu("main\hiscores","main\hiscoold")
Replaces the backup of main\hiscores with the contents of main\hiscoold, rather than with main\hiscores
Note: Stored-away backups cannot be updated. They must be first switched back to normal backups before being updated by using the storebu routine.
Errors: updbu will throw an error if:
Restores a backup
Usage: restbu(<backup_specifier>, <restore_path>, <version_index>, <overwrite?>)
Examples:
restbu("main\hiscores","main\hiscores",0,false)
Restores the backup of main\hiscores to its original location (main\hiscores), if it doesn't already exist there. Otherwise, causes an error.
restbu("main\hiscores","",0,false)
A shorter version of the above
restbu("main\hiscores","",0,true)
Restores the backup of main\hiscores to its original location, overwriting the file main\hiscores if it already exists
restbu("main\hiscores","foo\bar",0,false)
Restores the backup of main\hiscores to the location foo\bar
restbu("novel\draft1","novel\dr1v2",2,true)
Copies the second version stored for the file novel\draft1 to novel\dr1v2, overwriting novel\dr1v2 if it already exists
Errors: restbu will throw an error if:
Deletes a backup
Usage: delbu(<backup_specifier>, <delete_stored_away?>)
Examples:
delbu("old\badfile",false)
Deletes the backup of old\badfile only if it is not a stored-away backup. Otherwise, an error is generated.
delbu("old\badfile",true)
Deletes the backup of old\badfile unconditionally, even if it is a stored-away backup
Errors: delbu will throw an error if:
Changes a backup's status from normal to stored-away or vice-versa
Usage: storebu(<backup_specifier>)
Notes:
storebu toggles a backup between being a normal backup and being a stored-away backup.
When a backup is stored away, it is updated with its original file. If this is successful, the original file is then deleted. Switching a backup back to normal reverses this process, restoring the backup to its original location.
When a backup's stored-away status is changed, data stored about that backup, including versions, is preserved.
In order for a stored-away backup to be returned to a normal backup, the original file must not exist in the original location, because the backup copy must be restored there. If a file with the original name and path already exists, an error will occur when storebu is called, and the backup's status will not change.
Example:
storebu("agenda\20050715")
If agenda\20050715 is a normal backup, it will now be stored away. If it is already a stored-away backup, it will be returned to a normal backup.
Errors:
storebu will throw an error if:
A function that returns information about one or more backups
Usage: infobu(<backups>, <data_to_return>)
Notes:
For <data_to_return> values of 1, 5, and 6, the backup type (normal or stored-away) is given as a boolean value. False means the backup is a regular backup; true means that the backup is stored away.
Determining the groups a backup belongs to (<data_to_return> values of 3, 4, and 6) is a very time-consuming process. This data should only be requested when absolutely necessary.
For a single backup, infobu returns a boolean value for backup type, an integer for the number of versions or groups a backup has, or a list for the list of groups a backup belongs to. It returns a list also for <data_to_return> values of 5 and 6, which contain more than one piece of data.
For a list of backups, infobu returns a list for the backup type and the number of versions or groups a backup has, with each item in the list representing a backup. For a list of groups a backup belongs to, or for <data_to_return> values of 5 and 6, infobu returns a list of strings. The strings themselves contain nested lists converted to strings using AMS's string() function. To extract the lists from these strings, use the expr() function. In this way, infobu actually returns the equivalent of nested lists under these circumstances.
If any of <backups> refers to a file that was not backed up, then infobu will return the value undef for those invalid backup specifiers.
Examples:
Pause infobu("test\foo",1)
If test\foo is a stored-away backup, true is displayed. If it is not, false is displayed.
infobu("games\hiscores",4)→grps
If games\hiscores is in backup groups data and games, the list {"data","games"}
will be stored to the variable grps.
A function that checks for the existence of a backup's backup file, its original file, and its version files (if it has any versions), and returns a list that indicates whether there are problems due to missing files. This function is mainly used to perform a basic check of the integrity of a backup and detect if there are any problems with missing files.
Usage: testbu(<backups>)
Notes:
For a single backup, testbu returns a list of the following format. False means a file is okay; true means something is missing. The format of the list is as follows:
{<orig_file_problem?>, <backup_file_problem?>, <version_file_problem?>, <no_of_missing_ver_file>, <no_of_missing_ver_file>, . . .}
For a list of backups, testbu generates a list with the above format for each backup and encodes each one into a string, placing it into a larger list of one element per backup. The string-encoded-lists inside this larger list can be converted to a regular list by using the expr() function on the string.
If any of <backups> refers to a file that was not backed up, then testbu will return the value undef for those invalid backup specifiers.
Examples:
Pause testbu("test\foo")
If test\foo does not exist, but its backup and all its version files are present, and test\foo is not a stored-away backup, displays {true,false,false}
Pause testbu("test\foobar")
If test\foobar and its backup file exist, but versions 3 and 4 are missing for some reason, displays {false,false,true,3,4}
Backup Manager has versioning capabilities that allow multiple versions of one file to be stored in addition to the file's regular backup. These routines allow access to this functionality.
Stores a version for a file that was backed up
Usage: veradd(<backup_specifier>, <file_to_capture>, <version_comment>)
Examples:
veradd("text\chap1","","1st draft")
Captures the current contents of text\chap1 as a version named 1st draft
veradd("text\chap1","text\chap1new","3rd draft")
Captures the current contents of text\chap1new and stores it as a version of text\chap1 with the name 3rd draft
Note: The version number is automatically chosen by veradd. For each backup, version numbers start at 1 for the first version stored, and they increase by 1 for each version stored. If a version is deleted, all version numbers higher than the deleted version shift down to fill in the gap in the numbering. These version numbers are used for referencing a version with the restbu, vercom, verdel, etc. routines.
Errors: veradd will throw an error if <backup_specifier> does not refer to a valid backup.
Changes a version's comment
Usage: vercom(<backup_specifier>, <version_index>, <new_comment>)
Example:
vercom("text\chap1",3,"Rev. 5A")
Changes the comment of version 3 of text\chap1 to Rev. 5A
Errors: vercom will throw an error if:
Deletes a version
Usage: verdel(<backup_specifier>, <version-index>)
Note: When a version is deleted, the numbers of all versions that had higher numbers than the deleted version will shift down by one to fill the gap that would otherwise be created in the numbering.
Example:
verdel("text\chap1",5)
Deletes version 5 of text\chap1
Errors: verdel will throw an error if:
Backup Manager utilizes groups as a mechanism for organizing backups. It is possible for any given backup to belong to zero, one, or more groups. The following routines allow groups to be manipulated.
Creates a new backup group
Usage: grpadd(<group_name>)
Example:
grpadd("Programs")
Creates a new group named Programs
Notes:
Newly created groups contain no backups. Backups are added to groups using the grpaddbu routine.
Group names are limited to 18 characters. If a longer name is given, it will be truncated to 18 characters first, then the group will be created with the truncated name.
All characters are legal in a group name. However, each group created must have a unique name; no duplicate names are allowed.
Errors: grpadd will throw an error if <group_name> matches the name of a group that already exists.
Tip: The file ωbman3\bg1 contains a list of all defined groups, in alphabetical order.
Deletes a backup group
Usage: grpdel(<group_name_or_index>)
Examples:
grpdel("-junk-")
Deletes the group named -junk-
grpdel(3)
Deletes whatever group that appears in element 3 of list ωbman3\bg1
dim(bg1)→n:For i,1,n:grpdel(1):EndFor:DelVar i,n
Deletes all backup groups
Errors: grpdel will throw an error if <group_name_or_index> does not match the name of any existing group, or if the index value found is not valid for list ωbman3\bg1.
Renames a group
Usage: grpren(<group_name_or_index>,<new_name>)
Example:
grpren("Misc. stuff","Utilities")
Renames the group named Misc. stuff to Utilities
Notes:
Group names are limited to 18 characters. If a longer name is given, it will be truncated to 18 characters first, then the group will be created with the truncated name.
All characters are legal in a group name. However, each group created must have a unique name; no duplicate names are allowed.
Errors: grpren will throw an error if:
Adds all backups belonging to the specified group to another group. If the group that the backups are to be added to does not exist, it is automatically created.
Usage: grpcpy(<source_group>,<destination-group>)
Example:
grpcpy("Programs[1]","All programs")
Adds all backups contained in group Programs[1] to group All programs. If group All programs does not exist, it is automatically created.
Notes:
grpcpy only adds backups to the destination group. It does not affect any backups already belonging to the destination group.
No action is taken for backups that already belong to both the source and the destination groups. Groups cannot contain the same backup more than once.
Adds a backup to a group. The group can be created automatically if it does not already exist.
Usage: grpaddbu(<backup_specifier>, <group_name_or_index>, <create_group_if_needed?>)
Example:
grpaddbu("text\important","Important stuff",true)
Adds backup text\important to group Important stuff. If Important stuff does not exist, it is created.
grpaddbu(3,1,false)
Adds backup 3 (third element of bd* lists) to group 1 (first element of bg* lists)
Notes:
For a new group to be created when <create_group_if_needed?> is true, <group_name_or_index> must be a group name. The <create_group_if_needed?> parameter does not apply if <group_name_or_index> is a group index.
Errors:
grpaddbu will throw an error if:
Removes a backup from a group
Usage: grprembu(<backup_specifier>, <group_name_or_index>, <delete_empty_gropus?>)
Examples:
grprembu("text\important","Important stuff",true)
Removes backup text\important from group Important stuff. If Important stuff no longer contains any backups, deletes the group Important stuff.
grprembu("test\test12","Junk",false)
Removes backup test\test12 from group Junk. Junk remains defined, even if test\test12 was the last backup it contained.
Errors: grprembu will throw an error if:
In some situations it may be necessary to access data in the backup database directly. These routines are designed to make this task easier. These routines can also allow your program or shell to expand Backup Manager by keeping custom information about backups in the database.
A function that returns the index value of a backup. This value can be used to access the backup's information directly via the bd* lists.
Usage: idxof(<backup_specifier>)
Notes:
idxof returns the index of the bd* lists where information about the given backup can be found. If the given file does not exist or is not backed up, or if the given index is not valid, idxof returns an integer less than or equal to zero.
Although idxof returns an index, an index can be passed to it. If that index is positive and is valid for the bd* lists, the same index value is returned; otherwise, 0 is returned. (If a negative index is passed, the same negative value is returned.)
Examples:
Disp idxof("math\equ1")
Displays the index of backup math\equ1 (or a value less than or equal to zero if the file is not backed up). For instance, if 5 is displayed, then information about backup math\equ1 can be read directly from the backup database using the expressions bd1[5], bd2[5], etc.
Disp bd1[idxof("x396")]
For the given backup specifier (in this case, the backup kept in file ωbman3\x396), displays the path of the original file. Note that if the backup does not exist or is invalid, this expression causes an error.
idxof("math\equ1")→x:Disp when(x≤0,0,bd1[x])
If math\equ1 is backed up, returns the string "math\equ1"; otherwise, returns the value 0. A method similar to this is used frequently in Backup Manager's backup-handling routines, both to obtain the original file path regardless of whether the user passes the original name, the backup file's name, or a backup index as the input parameter; and to validate the backup specifier, making sure it corresponds to an actual backup.
idxof("math\equ1")→x:Disp when(x≤0,0,bd2[x])
Same as above, except this version returns the backup's actual file (i.e., the file in the ωbman3 folder where the backup is actually stored).
gidxof is similar to idxof, except that it works for groups. It returns the index of a group in the bg* lists for the given group name or index.
Usage: gidxof(<group_name_or_index>)
Notes:
If the given group does not exist, or if the given index is not valid, gidxof returns an integer less than or equal to zero.
Although gidxof returns an index, an index can be passed to it. If that index is positive and is valid for the bg* lists, the same index value is returned; otherwise, 0 is returned. (If a negative index is passed, the same negative value is returned.)
Example:
Disp gidxof("New Group")
Displays the index of group New Group (or a value less than or equal to zero if no group by this name exists)
Generates a unique variable name for a variable in the ωbman3 folder by appending numerals to a prefix name, without returning a name that is already used by an existing variable. This routine is primarily used internally in Backup Manager to generate new variable names to use for backup files.
Usage: getbuname(<variable_prefix>)
Notes:
getbuname returns the variable name in the file ωbman3\bkvar (getbuname is not technically a function). The variable name is one that is not used by any other variable in the ωbman3 folder.
<variable_prefix> is limited to no more than three characters.
Certain values for <variable_prefix> are not allowed by AMS, notably, "c", "q", and "z".
The standard prefixes used by Backup Manager are "a" (for stored-away backups), "b" (for versions), and "x" (for regular backups).
Example:
getbuname("zz")
Returns a variable with the prefix zz and a numerical suffix, that does not match any variable already existing in folder ωbman3.
Returns the name of the list variable (in folder ωbman3) that stores data for a given field of the backup database. This routine is normally used to locate custom data that was stored in the backup database.
Usage: getbd(<field_ID>, <database_type>)
Notes:
The following reserved fields always exist in their respective lists shown below. You may access these lists directly; it is not necessary to call getbd to determine the lists' variable names.
Field ID | Description | List variable |
---|---|---|
OP | Original file path | bd1 |
BF | Backup file name | bd2 |
SA | Is backup stored away? | bd3 |
VC | List of version comments for backup | bd4 |
VF | List of version files for backup | bd5 |
For custom lists that are added using the regbd routine, however, the getbd routine should always be used to determine the list variable first. Never assume that the data will be stored in a particular list variable; this variable could change if another program uses the regbd or unregbd routines. getbd will always return the appropriate list name.
Errors: getbd will return an error if a field with the specified <field_ID> does not exist in database type <database_type>.
A function that returns a list of the names of all the list variables that make up a particular portion of the backup database
Usage: listbd(<base_name>)
Note: listbd only works for lists that make up the backup database. As of Backup Manager 3.0, the base names for these lists are "bd" and "bg".
Examples:
Disp listbd("bd")
In a fresh installation of Backup Manager, this will return the list {"bd","bd1","bd2","bd3","bd4","bd5"}. This is a list of all the variable names that make up the backup data portion of the backup database. If more lists were added by the regbd routine, these lists would also show up in the list.
Disp listbd("bg")
This returns the list of all the variable names making up the group data portion of the backup database. In a fresh installation, this returns {"bg","bg1","bg2"}.
"Registers" a new field (list variable) to be included in the backup database
Usage: regbd(<field_ID>, <database_type>)
Notes:
The fields created with regbd act like the reserved, built-in fields in the backup database. A field is stored in the form of a list. After regbd is called, the newly created list's name is stored to ωbman3\bfvar. This list can be modified directly using standard TI-BASIC expressions.
Each element in the list represents one backup. New lists created by regbd must always contain the same number of elements as all the other lists. Here is an example to clarify how data should be stored in the database lists:
Backup data | ||||||
---|---|---|---|---|---|---|
bd1 | bd2 | bd3 | bd4 | bd5 | bd6 | |
Element index | OP | BF | SA | VC | VF | TDS |
Original path | Backup file | Stored away? | Version comments | Version files | Custom: Date/time stamp | |
1 | main\hiscores | x1 | false | "{}" | "{}" | "2005/03/15 22:11" |
2 | proj\prog1 | x2 | false | "{""test1"",""draft1""}" | "{""b1"",""b2""}" | "2005/01/05 11:05" |
3 | proj\prog2 | x5 | false | "{}" | "{}" | "2005/01/11 14:23" |
4 | proj\test | a1 | true | "{}" | "{}" | "----/--/-- --:--" |
5 | proj\testb | a4 | true | "{}" | "{}" | "-----/--/-- --:--" |
The first five lists shown here (bd1 through bd5) are part of the standard backup database. The column shaded in yellow shows a custom list (bd6) that was added with regbd.
Each element index in a list corresponds to the same backup as the same element indeces in the other lists. Therefore, all lists must be the same length at all times and element indeces of the same value should all correspond to the same backup. Otherwise, the results will be very confusing and even dangerous. Normally, Backup Manager keeps all lists in sync with one another when a backup is added or deleted. There should be no reason for a program to manually resize any of the backup database lists, even those that it created itself.
Lists bd4 and bd5 hold lists of data for the versions of the backup. The lists are actually stored as strings inside the list variable (since AMS does not allow lists to be defined inside lists), hence the quotation marks around them. Double quotation marks ("") indicate a quotation mark (") inside a string that is surrounded by quotation marks. bd4 holds a list of version comments for the versions, and bd5 holds a list of the file names that the versions are stored as. Elements from these lists can be accessed by using AMS's expr() function to convert them from their string-encoded format to a list.
The group database stores data about backup groups in a similar manner:
Group data | ||
---|---|---|
bg1 | bg2 | |
Element index | GN | FL |
Group names | File lists | |
1 | "Misc" | "{""main\hiscores""}" |
2 | "Projects" | "{""proj\prog1"",""proj\prog2""}" |
3 | "Testing" | "{""proj\test"",""proj\testb""}" |
Extra group field lists can be added in the same way by using the "g" database type rather than the "d" type.
The default fields in the group database are as follows: the group names field, which stores the user-defined names of the groups; and the file list field, which lists all the backups that belong to each group. The file list is stored in a string-encoded list, like the version comment and version file lists in the backup data database.
Again, the data found in a particular element index of each group list must collectively refer to the same group. Backup Manager will automatically keep these lists in sync with one another as long as their lengths are not manipulated directly.
Example:
regbd("TDS","d")
This will register the new backup data field shown in the shaded yellow column of the Backup Data table above. The list name that contains this data is stored as a string in the variable ωbman3\bfvar. You may obtain this list name and store entries directly to the individual elements in the list. Remember, the list variable will not necessarily be bd6 in every case. This is why checking the bfvar variable after calling regbd is important.
Errors: regbd will throw an error if <field_ID> is the same as that of a field already existing in a database for the given <database_type>.
Removes a custom field that was previously added to the backup database using the regbd routine.
Usage: unregbd(<field_ID>, <database_type>)
Notes:
When a field is removed, all data held in that field for all backups is deleted and cannot be recovered.
The following fields are reserved for proper Backup Manager operation and cannot be removed: for backup data, the first five fields OP, BF, SA, VC, and VF; for group data, the first two fields GN and FL.
When a field is removed, the variable names used to store any other custom database fields may change. Therefore, after you delete a field in your program, you should call the getbd routine again to get the updated names of any other custom fields you're currently using, in case their variable names have changed. Failure to do so may result in a program error or corruption of the backup database.
Errors: unregbd will throw an error if:
The following routines are utility routines used throughout Backup Manager. You may also find them useful in your Backup Manager-based programs or shells.
Searches list <search_list> for an element equal to <search_item>. If found, returns the index of the item; if not found, returns zero.
Usage: inlist(<search_list>, <search_item>)
Notes:
inlist uses a simple sequential search algorithm. It first checks whether item 1 of <search_list> matches <search_item>, then item 2, then item 3, and so forth. Once the item is found, it exits immediately and returns that item number. If it searches the entire list and doesn't find the item, it returns zero.
For a faster search algorithm, see the inlistb function, which uses a binary search algorithm.
Examples:
Disp inlist({3,5,7.5,9,10},9)
Displays the value 4 (the item 9 was found in element 4 of the list).
Disp inlist({3,5,7.5,9,10},4)
Displays the value 0 (the item 4 does not appear in the list).
Disp inlist({"apple","banana","grapefruit","strawberry"},"apple")
Displays the value 1 (the item "apple" was found in element 1 of the list).
Using a binary search algorithm, searches list <search_list> for an element equal to <search_item>. If found, returns the index of the item; if not found, returns a negative value representing the index of the list before which that item would have appeared if it had been found.
Usage: inlistb(<search_list>, <search_item>)
Notes:
inlistb is generally much faster than inlist, especially when searching very large lists in which items searched for may frequently occur in the middle or near the end of the list. The disadvantage of inlistb is that the list to search must be sorted in ascending order already. If the list is not sorted, inlistb will usually fail to locate a given item, even if it appears in the list. For searching lists that are not sorted, inlist can be used.
If <search_item> is not found in <search_list>, then inlistb will return a negative value. This value represents the position before which <search_item> would have appeared in the list had it been found.
Examples:
Disp inlistb({1,3,4,7,8,9,11},7)
Displays 4 (item 7 found in element 4 of list).
Disp inlistb({1,3,4,7,8,9,11},10)
Displays -7 (item 10 not found, but would appear before element 7 if it were present)
If inlistb({"af","bc","hl"},"de")>0 Then:Disp "Item 'de' found":Else:Disp "Item 'de' not found":EndIf
Displays Item 'de' not found.
Tip: inlistb can be used to quickly determine if a single item exists in an ascending-sorted list, and insert it at the appropriate position if necessary. This seems to be faster than simply appending the new item to the end of the list, then using SortA to sort it. Here is how to do this:
:©Insert item 'dgf' into list 'bcodes' if it does not already exist
:Local result
:setFold(ωbman3)
:{"aaa","abc","ccc","fss"}→bcodes
:inlistb(bcodes,"dgf")→result
:If result>0 Then
: Disp "Item already exists in list."
:Else
: insl("dgf",-result,bcodes)→bcodes
:EndIf
:©Do whatever with 'bcodes' here
:DelVar bcodes
Note the negate symbol (-) before the result variable in the insl function. This is necessary to transform the negative value returned by inlistb into a positive number so that it is a valid list index.
Executes program code contained in a string for each item in a given list.
Usage: forall(<list>,<code>)
Examples:
forall({"One","Two","Three","Four"},"Disp i")
Displays:
One
Two
Three
Four
forall({"test\a","test\b","test\c","junk\aaa","junk\bbb","junk\ccc"},"del(i)")
Deletes all of the variables listed in <list>
errh is an error handler for errors that occur while executing Backup Manager system routines. This is most useful in shells, where it's often desirable to handle a failure in a graceful way rather than crash out of the shell and dump the user back to the Home Screen.
errh checks the value of the system variable errornum and tries to return an appropriate message for the particular error that occurred. That message is returned as a string so that the calling program can display it. Optionally, errh can display the message in a dialog box automatically.
Usage: errh(<path>,<display_error_dialog?>,<pass_unknown_errors?>)
Notes:
errh is intended to be used as an error handler, rather than being called directly. The backup routines to be trapped are placed in the Try section of a Try...Else...EndTry block. A call to errh is placed in the Else section of the block.
errh places the error message for the last error that occurred in the berrmsg variable. This will be the same message that is displayed in the dialog box when <display_error_dialog?> is true. By setting <display_error_dialog> to false, the calling program can use berrmsg to show the error message to the user using some other method.
Examples:
Try:newbu("main\y1","",false):Else:errh("main\y1",true,false):EndTry
Tries to back up the file main\y1. If the attempt fails (for instance, because the file is already backed up), an error dialog appears, then the calling program continues running.
Try:newbu("main\y1","",false):Else:errh("main\y1",false,false):Pause berrmsg:EndTry
Tries to back up the file main\y1. If the attempt fails, the error message is displayed on the I/O Screen rather than appearing in a dialog box.
Used internally to call system hooks
Usage: hookexec(<hook_ID>, <input>)
Note: This routine is used internally by Backup Manager. Under normal circumstances, it is not necessary to use this routine directly. When this routine is called, it looks up the routine for the given <hook_ID>, and if one is defined, it is called. The contents of <input> are stored to the variable bhin, which the hook routine can access. bhin is deleted once the hook routine returns.
For more information on Backup Manager hooks, see the hooks document.
The following utility functions are used to manipulate certain types of variables. Most of these routines are simple and are designed for convenience.
Permanently deletes a variable, even if it is archived or locked
Usage: del(<variable_name>)
Note: AMS appears to have a bug with the redirection (#) operator. If a program has local variables defined, and redirection is used to access an external variable that happens to have the same name as a local variable, the external variable is not recognized, even if the full path to the external variable is given. del and other Backup Manager routines work around this problem by using the expr() function instead of redirection.
Example:
del("main\delme")
Deletes the variable main\delme.
Inserts an item into the given position of a list and returns the result
Usage: insl(<item>,<position>,<list>)
Examples:
Disp insl(3,3,{1,2,5,7})
Displays {1,2,3,5,7}
{"A","B","D","F"}→l:insl("C",3,l)→l
Stores the list {"A","B","C","D","F"} to variable l.
Removes an item from a given list and returns the result
Usage: del(<index>,<list>)
Examples:
Disp dell(3,{1,2,3,5,7})
Displays {1,2,5,7}
{"A","B","C","D","F"}→l:dell(1,l)→l
Stores the list {"B","C","D","F"} to variable l.
Converts all uppercase letters in a string to lowercase and returns the result.
Usage: tolower(<string>)
Notes:
Only the letters A-Z (ASCII 64 to 91) are converted to lowercase. Uppercase accented or Greek characters are not converted.
This routine is quite slow. If it must be used, try not to use it more times than necessary.
Example:
Disp tolower("Hello, WORLD!")
Displays hello, world!
Truncates a string with the ellipsis character (...) if it is longer than the specified length
Usage: trunc(<string>,<max_length>)
Notes:
If the length of <string> is equal to or less than <length>, then this function returns <string>. If <string> is greater than length <length>, the first <length>-1 characters of the string is returned, plus the ellipsis character (...).
This function is mainly intended for user-interface programming. If you want to display a string whose length cannot be known ahead of time (such as a file name or a user-entered string), you can use this function to ensure that the string is never longer than the space allocated to it on the display. The ellipses character will automatically display to indicate that not all of the string fits on the screen.
Examples:
Output 0,0,"File name: "&trunc("programs\testprog",15)
Displays File name: progarms\testp... across the top of the screen
Output 0,0,"File name: "&trunc("main\x",15)
Displays File name: main\x on the top line of the screen
The following routines are designed to assist shells in providing user-friendly interfaces.
The menu routines allow a shell to display a multi-selection menu. This menu allows the user to select multiple items in the same menu and perform an operation on them, much like AMS's VAR-LINK menu. The menu can be customized in various ways by setting several menu parameters.
Initializes a menu
Usage: menuinit(<menu_items>,<parameter_list>)
The <parameter_list> can contain the following items. Any number of the first items may be specified; the default values shown are used for parameters that are not specified.
Notes:
After menuinit is run, the menu routine is called to actually display and handle the menu.
menuinit defines several variables that are used by the menu routine. (See the explanation of the menu routine for more information about these variables.) When a program is finished with a menu, it should call menuterm to clean up these variables.
Examples:
See the menu examples found in the doc/devel directory of the Backup Manager 3.0 archive.
Displays and handles keys for a multi-selection menu
Usage: menu()
Notes:
menu is designed to be placed in a special loop. This loop allows your program to respond to keypresses while the menu is displayed, while the menu routine responds to special menu keys. This allows for a flexible menu interface.
When menu is called, it displays or updates the menu if necessary and waits for a key. If the key is a menu key (such as for selecting an item, moving the cursor, or paging up or down the menu), the routine performs the appropriate action and waits for another key. If any key other than one that menu recognizes is pressed, menu returns and leaves the keypress in the variable key, allowing the calling program to respond to the keypress before returning control to menu.
The keys that menu recognizes are:
[Up], [Down] | Move the cursor up or down |
[Left]/[2nd+Up], [Right]/[2nd+Down] | Move the cursor one full screen up or down |
[Diamond+Up], [Dimaond+Down] | Move the cursor to the beginning or end of the menu list |
Selection key defined in menuinit | Selects menu items |
The following variables are used by the menu routine, and some can be set by the calling program to change the menu behavior while the menu is displayed. The variables are described below.
Examples:
See the menu examples found in the doc/devel directory of the Backup Manager 3.0 archive.
Tip:
The menu routine seems to perform a bit faster and more responsively when AMS's Exact/Approx mode setting is set to Auto or Exact.
Performs clean-up (by deleting all the menu temporary variables). This should be called after a menu selection is complete.
Usage: menuterm()