Routines for accessing the variable allocation table

 #define $(s) (SYMSTR (#s)) Defines a constant VAT string. This macro constructor has been superseded by the function-like macro SYMSTR. ### AddSymToFolder  HSym AddSymToFolder (SYM_STR SymName, SYM_STR FolderName); Adds a symbol in a given folder. AddSymToFolder acts like SymAdd, but adds the VAT entry in the folder given by FolderName. See SymAdd and SYMSTR for more info and rules about SymName and FolderName. Note: This routine is a bit buggy: if the folder FolderName does not exist, the behavior of this routine is very uncertain, and may result with a crash. ### checkCurrent  HSym checkCurrent (SYM_STR SymName, ESQ Type); Check for the existence of a symbol. checkCurrent makes sure the given symbol exists and matches the requested tag Type. SymName is the symbol name (see SYMSTR for rules about SymName), and Type is the requested tag type (see VarNew for a list of valid tags). checkCurrent returns the HSym of the VAT entry if it exists and matches the requested tag type, otherwise it returns HS_NULL. For example, the text editor uses checkCurrent when it is told to edit the current text variable, to make sure the previous name entered by the user still exists and is a text variable. If it is not then it executes the code to prompt the user for a new text variable to edit. ### CheckLinkLockFlag  void CheckLinkLockFlag (const SYM_ENTRY *FuncSymEntry); Prevents a variable to be overwritten through link transfer if this is not allowed. If FuncSymEntry is a pointer to the VAT entry of TI-Basic program or function variable, then this function sets or clears the link lock flag which is embedded in the program or function variable itself, according to the 'archived' and 'locked' bits in the VAT entry. This prevents the variable to be overwritten through link transfer if this is not permitted. Otherwise this function does nothing. ### CheckReservedName  short CheckReservedName (SYM_STR SymName); Checks for graph functions and other special variable names. CheckReservedName checks whether SymName is a graph function or another special variable name. It returns zero if this is not the case, otherwise it returns the type of the variable. This routine works in the same way as CheckSysFunc; the only differences are that SymName is a tokenized name, and that the function may also return R_SYSVAR. Precisely, this function returns values from either GraphModes or ExtendedSysTypes, in addition to zero:  GR_FUNC "y1".."y99" GR_PAR "xt1".."xt99", "yt1".."yt99" GR_POL "r1".."r99" GR_SEQ "u1".."u99" GR_3D "z1".."z99" GR_DE "y'1".."y'99" SEQ_INITC "ui1".."ui99" DE_INITC "yi1".."yi99" DR_FLDPIC "FldPic" SOLVER_SYS_VARS "Exp", "Eqn" UNIT_VAR name with a leading underscore C_COL "c1".."c99" R_REGEQ "RegEq" R_SYSVAR another system variable (see EXT_SYSTEM_TAG) This function calls TokToStrN and CheckSysFunc. See also: CheckSysFunc, SymSysVar ### CheckSysFunc  short CheckSysFunc (const char *VarName, unsigned short *Index); Checks for graph functions and other special variable names. CheckSysFunc checks whether VarName (an ordinary C string) is a graph function or another special variable name. It returns zero if this is not the case, otherwise it returns the type of the variable. Precisely, this function returns values from either GraphModes or ExtendedSysTypes, in addition to zero:  GR_FUNC "y1".."y99" GR_PAR "xt1".."xt99", "yt1".."yt99" GR_POL "r1".."r99" GR_SEQ "u1".."u99" GR_3D "z1".."z99" GR_DE "y'1".."y'99" SEQ_INITC "ui1".."ui99" DE_INITC "yi1".."yi99" DR_FLDPIC "FldPic" SOLVER_SYS_VARS "Exp", "Eqn" UNIT_VAR name with a leading underscore C_COL "c1".."c99" R_REGEQ "RegEq" Note that ExtendedSysTypes also contains R_SYSVAR, which may be returned only by CheckReservedName. In fact, this function cannot check for system variable names like "xmin". Also, if VarName is a valid graph function name or column name ("y1", "c1", etc.), CheckSysFunc stores the function/column index at the word pointed to by Index. See also: SymSysVar, CheckReservedName ### ClearUserDef  void ClearUserDef (HANDLE hFuncVar); Clears TI-Basic program/function status flags. This function assumes that hFuncVar is the handle of a TI-Basic program or function variable (otherwise the behavior is unpredicted). It clears various status flags which are embedded in the program or function variable itself, which include the link lock flag (see CheckLinkLockFlag), the entry counter (which counts the depth of recursive calls of a function or program), and some flags used in the "Graph" application. ### DataTypeNames AMS 2.00 or higher  unsigned char *DataTypeNames (unsigned char); Returns a pointer to a static string representing the type of the tag passed. On AMS 2.xx, the string is localized for the current language; on AMS 1.xx, the string is in English, because no language localizations are available. Valid values for tag are a subset of Tags and InstructionTags: EXT_SYSTEM_TAG (0x1C) STR_TAG (0x2D) EQ_TAG (0x87) DATA_TAG (0xDD) GDB_TAG (0xDE) PIC_TAG (0xDF) TEXT_TAG (0xE0) FIG_TAG (0xE1) MAC_TAG (0xE2) ASM_TAG (0xF3) OTH_TAG (0xF8) FUNC_ITAG (0x17) PRGM_ITAG (0x19)  If the tag is not allowed, the address of the string containing "?" is returned. ### DerefSym  SYM_ENTRY *DerefSym (HSym Sym); Dereferences a symbol. DerefSym dereferences the symbol by converting Sym (which is return value from many TIOS VAT functions) into the actual VAT entry. DerefSym returns a pointer to the entry, which is a pointer to the structure of type SYM_ENTRY, which represents a VAT entry. Returns NULL in a case of error. Beware that VAT entries may moved during the heap compression, so SYM_ENTRY pointers may become invalid after the heap compession. DerefSym may be simulated using HeapDeref. For example, the statement SymPtr = DerefSym (hsym);  is equal to the statement SymPtr = (SYM_ENTRY*)((char*)HeapDeref(hsym.folder) + hsym.offset);  I don't know what the best way to find the handle of the main folder is, but one method which is certainly legal is the following: MainHandle = DerefSym(SymFindHome(SYMSTR("main")))->handle;  Note: SYM_ENTRY structures are usually not locked, which means that pointers to them will become invalid if a heap compression occurs. Basically, this means that you can only operate on them for a short time in which you know that no heap compression can occur. ### EM_moveSymFromExtMem  short EM_moveSymFromExtMem (SYM_STR SymName, HSym Sym); Moves a symbol from the archive memory to the RAM. EM_moveSymFromExtMem unarchives an archived symbol. The symbol may be described either by symbol name SymName (in this case, parameter Sym should be set to HS_NULL) or by HSym structure Sym (in this case, SymName must be NULL). See SYMSTR for rules about SymName. EM_moveSymFromExtMem returns TRUE if the operation was successful, else returns FALSE. ### EM_moveSymToExtMem  short EM_moveSymToExtMem (SYM_STR SymName, HSym Sym); Moves a symbol from the RAM to the archive memory. EM_moveSymToExtMem archives a symbol. The symbol may be described either by symbol name SymName (in this case, parameter Sym should be set to HS_NULL) or by HSym structure Sym (in this case, SymName must be NULL). See SYMSTR for rules about SymName. EM_moveSymToExtMem returns TRUE if the operation was successful, else returns FALSE. ### EM_twinSymFromExtMem  HSym EM_twinSymFromExtMem (SYM_STR SymName, HSym Sym); Creates a twin symbol, then copies a symbol from the archive memory to it. EM_twinSymFromExtMem first calls SymAddTwin to create a twin symbol, then copies the archived symbol to it. The symbol may be described either by symbol name SymName (in this case, parameter Sym should be set to HS_NULL) or by Hsym structure Sym (in this case, SymName must be NULL). See SYMSTR for rules about SymName. TIOS uses EM_twinSymFromExtMem when it need to execute archived program. EM_twinSymFromExtMem returns a HSym structure which represents a newly created symbol (or HS_NULL in a case of error). EM_twinSymFromExtMem returns Sym itself if the symbol is not archived. ### EX_stoBCD  void EX_stoBCD (unsigned char *VarName, float *Src); Stores a floating point value into a variable. EX_stoBCD stores the floating point value pointed to by src into the TI-Basic variable whose name is pointed to by VarName (an ordinary C string). ### FindProgramVar  SYM_ENTRY *FindProgramVar (void); Finds the running program's variable. FindProgramVar returns a pointer to the SYM_ENTRY structure of the running program, or NULL in case it is not found (e.g. if the program was compressed). Note: Do not call anything which may cause a heap compression between when this function is called and when the pointer to it is used. Otherwise, the pointer may become invalid, causing a crash or other random, unexpected behavior. You can also use FolderOp to avoid this problem. ### FindSymInFolder  HSym FindSymInFolder (SYM_STR SymName, const char *FolderName); Finds a symbol in a given folder. FindSymInFolder acts like SymFind, but searches for a symbol in the folder given by FolderName. See SYMSTR for more info and rules about SymName and FolderName. As far as I know, the statement hsym = FindSymInFolder (SYMSTR ("tetris"), SYMSTR ("games"));  acts exactly the same as the statement hsym = SymFind (SYMSTR ("games\\tetris"));  ### FolderAdd  HANDLE FolderAdd (SYM_STR SymName); Creates a folder. FolderAdd creates a new folder with name SymName. See SYMSTR for rules about SymName. FolderAdd returns a handle to the created folder (more precise, to the VAT variable list which belongs to the created folder). Returns H_NULL in a case of error (for example, the folder already exists, or there is not enough memory). Note that reserved names are not valid folder names and that this routine does not check for reserved names. It is up to the caller to validate the folder name before calling this routine. This routine may cause heap compression. This routine also can be used to create temporary folders (see also FolderAddTemp) whose names begin with a number and are not displayed in VAR-LINK dialog. Temporary folder numbers '0001'...'8192' are reserved for keeping TI-BASIC local symbols, folder number '9998' is used in Data/Matrix Editor, and folder number '9999' is reserved for various temporary storage. See also: FolderAddTemp, SymAdd ### FolderAddTemp  SYM_STR FolderAddTemp (void); Creates a temporary folder. FolderAddTemp creates a temporary folder whose name will consist of four digits (see TempFolderName). The first call of FolderAddTemp will create a folder named "0001", the next call will create a folder named "0002", etc. FolderAddTemp returns the name of the created folder, with the same convention as used in function TempFolderName. The created folder will be marked as the "current temporary folder" (see FolderCurTemp). FolderAddTemp throws a "Memory" error if there is not enough space for a new folder. ### FolderClear  short FolderClear (SYM_STR SymName); Deletes all files in the folder. FolderClear deletes all files in the folder SymName, but does not remove the folder itself. Returns TRUE if the operation was successful, else returns FALSE (e.g. if the folder is not found). See SYMSTR for rules about SymName. Beware that this routine will delete all symbols in the folder even if they are locked, in use, or archived! Note: This function calls original TIOS entry called "FolderDel", but passes an extra Boolean parameter set to TRUE. See also note given with FolderDel function. See also: FolderDel ### FolderCount  unsigned short FolderCount (const SYM_ENTRY *SymPtr); Determines a number of symbols in a folder. FolderCount returns the number of symbols in the folder whose VAT entry is SymPtr. For example, to determine the number of symbols in the "main" folder, do the following: number = FolderCount (DerefSym (SymFindHome (SYMSTR ("main"))));  See SYMSTR, SymFindHome, and DerefSym for more info. ### FolderCur  short FolderCur (SYM_STR SymName, short nonSys); Sets the currently active folder. FolderCur sets the currently active folder to SymName (see SYMSTR for rules about SymName). It returns TRUE if the operation was successful, else returns FALSE (e.g. if the folder name is invalid). nonSys is a boolean flag which normally needs to be TRUE. If it is set to TRUE, FolderCur calls SymFindNext repeatedly until the first non-system variable in this folder is reached. This is necessary, else the current graph may become invalid. In particular, if the graph references a variable defined in a folder which previously was the current folder, it is not redrawn if nonSys is set to FALSE. Note: The folder name in the status line will not be changed automatically using this command. You must change it manually using the function ST_folder from statline.h. This routine may cause heap compression. See also: FolderGetCur, FolderCurTemp ### FolderCurTemp  short FolderCurTemp (SYM_STR SymName); Sets the current temporary folder for storing local symbols. FolderCurTemp sets the current temporary folder for storing local symbols to SymName. SymName must be a "numeric" symbol name as functions like TempFolderName or FolderAddTemp returns. FolderCurTemp returns TRUE if the operation was successful, else returns FALSE. See also: FolderCur ### FolderDel  short FolderDel (SYM_STR SymName); Deletes a folder, including all files in it. FolderDel deletes the folder SymName including all files in it, and returns TRUE if the operation was successful, else returns FALSE (e.g. if the folder is not found). See SYMSTR for rules about SymName. If the folder SymName is the current folder, the new current folder after deleting will become the "main" folder. If the folder SymName is "main", then all symbols from it will be deleted, but the folder itself will remain intact. Beware that this routine will delete all symbols in the folder even if they are locked, in use, or archived! Note: This function was buggy in TIGCCLIB releases prior to 2.3. I didn't know that the original TIOS entry called "FolderDel" requires in fact two parameters: another one is a Boolean flag. As this parameter was not passed before, the behaviour of this routine was random (see also FolderClear). Now, to keep the compatibility with already written programs, I modified FolderDel to always pass FALSE as an extra parameter (in this case, FolderDel behaves as described above; when it is TRUE, FolderDel behaves as FolderClear). See also: FolderClear ### FolderDelAllTemp  void FolderDelAllTemp (short StartTempNum); Deletes a block of temporary folders. FolderDelAllTemp deletes all temporary folders whose names are series of consequent numbers starting from StartTempNum up to the first unused number, like in following algorithm: current=StartTempNum; while (FolderFind ((name = TempFolderName (current++))) == 3) FolderDel (name);  The intention of this routine was very probably to delete all temporary folders when called with StartTempNum equals to 1. But, there is a problem. This routine does not reset the system variable which tells which is last used temporary folder number (I think that this is a bug in TIOS). So, a next call of FolderAddTemp will not start again from folder named "0001". This may cause various problems later. That's why I strongly recommend avoiding this routine, and using repeated call to FolderDelTemp instead. ### FolderDelTemp  void FolderDelTemp (void); Deletes a temporary folder. FolderDelTemp deletes the last created temporary folder and selects the previous temporary folder as current temporary folder (see FolderCurTemp). Nothing bad will happen if the temporary folder does not exist, or in case of any eventual error. ### FolderFind  short FolderFind (SYM_STR SymName); Checks whether a folder exists. FolderFind searches for a folder SymName through the folder table in the VAT, and returns the following result: • MAIN_FOLDER, if SymName is the "main" folder; • FOLDER_TABLE, if a folder with name SymName exists; • NOT_FOUND, if a folder with name SymName does not exists; • BAD_FOLDER, if a symbol with name SymName is really present in the folder table, but does not represents a folder (i.e. folder bit is not set); this return value probably represents an invalid entry. These constants are defined in enum FolderStats. See SYM_ENTRY for more info about structure of VAT entry, and SYMSTR for rules about SymName. ### FolderGetCur  void FolderGetCur (char *buffer); Determines the current active folder. FolderGetCur fills buffer with a name of the current active folder. The buffer must be at least 9 bytes long, and it will be filled with a standard C zero-terminated string. See also: FolderCur ### FolderOp  short FolderOp (SYM_STR SymName, short Flags); Locks or unlocks a folder table. FolderOp locks or unlocks a folder table which name is determined by SymName. Returns TRUE if the operation was successful, else returns FALSE. Parameter Flags may have following values (these constants are defined in enum FolderOpFlags):  FOP_UNLOCK Unlocks a folder table FOP_LOCK Locks a folder table FOP_ALL_FOLDERS Locks/unlocks all folder tables (SymName is ignored); this value should be ORed with one of FOP_UNLOCK or FOP_LOCK By locking the folder table, you may be sure that a dereferenced pointer to the table will remain valid even after a lot of heap memory allocations (i.e. a garbage collection will not move the table through memory). Note: To lock the "home" folder (this is a pseudo-folder which contains all other folders in itself, i.e. this is the table of folders), you need to know that its name consists only of the character with code 0x7F (diamond). So, you can use FolderOp (SYMSTR ("\x7F"), FOP_LOCK);  to do this. ### FolderRename  short FolderRename (const char *SrcName, const char *DestName); Renames a folder. FolderRename renames the folder SrcName to the name DestName. Returns TRUE if the operation was successful (SrcName must exist and must be a folder, and DestName must not exist), else returns FALSE. See SYMSTR for rules about folder names. Note that this routine does not check for reserved names, and may throw an error if renaming to or from a reserved name (e.g. "main"), or if any variable in the given folder is in-use. ### GetDataType AMS 1.01 or higher  short GetDataType (CESI tagptr); Returns the data type for a given tag pointed to by tagptr. Valid values for the tag pointed to by tagptr are defined in the enum SystemDataTypes. See also: SmapTypeStrings, handleVarLinkKey ### GetFuncPrgmBodyPtr  ESI GetFuncPrgmBodyPtr (ESI ptr); Returns a pointer to a TI-Basic function/program body. GetFuncPrgmBodyPtr returns the pointer to the function or program body of the TI-Basic function or program pointed to by ptr. ptr must point to the FUNC_TAG quantum, i.e. to the last byte of the variable. The parameters and flags are skipped. See Tags for more info on tags. ### GetTagStr AMS 2.00 or higher  char *GetTagStr (ESI tag, char * buf); Returns the address of the string representing the special tag pointed to by tag. tag needs to point to one of EXT_SYSTEM_TAG (0x1C), EXT_TAG (0xE3) or EXT_INSTR_TAG (0xE4), otherwise garbage is returned. Also, if you pass GetTagStr a tag unrecognized by the AMS version, it returns a pointer to 'ERROR'. Example: The TI-BASIC command ShowStat prints the string name for each statistical variable it finds using GetTagStr to print the name of the variable as shown in this example. unsigned char tag[2]; char buf[24]; char buf2[11]; tag[0] = X_BAR_TAG; // in fact, any tag defined in SysvarTags. tag[1] = EXT_SYSTEM_TAG; // Defined in Tags sprintf(buf,"%-7s",GetTagStr(tag+1,buf2));  You can use HToESI to get a pointer to the tag stored in tag. ### HSymDel  short HSymDel (HSym Sym); Deletes a symbol pointed to by HSym. HSymDel acts exactly like SymDel, except it takes a structure of type HSym as an input parameter instead of the symbol name (see SYMSTR). Note: This routine assumes that Sym is valid; if it is not, it may throw an error (for example, if Sym represents a reserved symbol like "main", or if the referenced symbol is in-use). If HSymDel is called to delete a folder than that folder must be empty! Also do not use HSymDel to delete twin or archived variables. This routine modifies the VAT table, so it invalidates any other existing HSyms. The caller must be sure that the VAT table has not been changed since Sym was obtained. See also: SymFind ### HSYMtoName  short HSYMtoName (HSym Sym, char *buffer); Determines a full path of a symbol. HSYMtoName fills buffer with a full-path name (i.e. "folder\name") of the symbol given by HSym structure Sym. See SYMSTR for more info about HSym names. The buffer must be at least 18 bytes long, and it will be filled with a standard C zero-terminated string. HSYMtoName returns TRUE if the operation was successful, else returns FALSE. ### is_pathname AMS 1.01 or higher  short is_pathname (CESI name); Checks if argument points to a pathname. name must be a valid SYM_STR constructed with SYMSTR or equivalent. This function first checks if name is pointing to the last byte of a SYM_STR (it must be 0x00), and searches backwards for character 0x5C ('\'). If is_pathname finds one such character, it immediately retuns TRUE. If name doesn't point to a 0x00, or there is no '\' in the string, it returns FALSE. Note: this function is flawed, as it doesn't check if there is only one '\'. Indeed, a string such as SYMSTR("main\foo\bar"), while it is a pathname (it contains '\'), is NOT a valid pathname... ### IsMainFolderStr  short IsMainFolderStr (const char *Name); Checks whether a name is the name of the main folder. IsMainFolderStr returns TRUE if Name is the string "main", else returns FALSE. ### MakeHSym  HSym MakeHSym (HANDLE FldHandle, const SYM_ENTRY *SymPtr); Makes a HSym structure. MakeHSym is an internal function, used very often in other TIOS routines. It converts the VAT symbol entry pointed to by SymPtr which belongs to the folder associated with handle FldHandle to the HSym structure. As HSym-s are basically a combination of the folder’s handle and the offset of a symbol into that folder, they are valid until a symbol is added or removed from the folder they belong to. Dereferencing them with DerefSym produces a direct pointer to the symbol entry, but such pointer are not valid after a heap compression is done. The main usage of MakeHSym is when you need to preserve a pointer to the symbol entry after a heap compression, like in following example: hsym = MakeHsym (FldHandle, SymPtr); // Something that may cause heap compression... SymPtr = DerefSym (hsym);  In this example, an eventual heap compression would cause the pointer to be invalid since it is a direct pointer into memory. So the SymPtr is converted to a HSym structure with MakeHsym (along with the handle of the folder that the symbol belongs to). After the code that may cause heap compression is executed, the HSym is converted back into a SYM_ENTRY pointer with DerefSym. Deprecated alias: MakeHsym ### partial_len  unsigned long partial_len (const char *VarName, unsigned char *MaxList); Queries information about the Data Editor. partial_len is used to query information about the temporary folder of the Data Editor ("9998", see FolderAdd), which contains three variables for each column:  "tc1".."tc99" A STR variable containing the title for the column. "hc1".."hc99" An EXPR variable containing the formula for the column. "c1".."c99" A LIST variable containing the (fixed or calculated) cell values. VarName must be "tc", "hc", or "c", and partial_len returns the size of all files matching VarName. It stores the last column which is used into the byte pointed to by MaxList. ### QSysProtected  short QSysProtected (ESQ Tag); Checks if a given tag represents a system-protected variable type. QSysProtected returns TRUE if the given tag (see Tags for more info) is the tag of a system protected data type, i.e. a program/function (FUNC_TAG), assembly program (ASM_TAG), text file (TEXT_TAG), graph database (GDB_TAG), picture (PIC_TAG), data variable (DATA_TAG), or custom file (OTH_TAG). Otherwise, QSysProtected returns FALSE. See also: VarStore ### ResetSymFlags  void ResetSymFlags (unsigned short Flags); Clears all VAT symbols flags. Clears all VAT symbol flags (i.e. flags defined in the enum SymFlags) which are set in the Flags parameter, for all entries in the VAT table (i.e. in all folders). ### SetOK  void SetOK (short value); Changes the system variable 'OK'. If value is TRUE, 'OK' is set to 1; if it is FALSE, 'OK' is set to 0. ### SmapTypeStrings AMS 2.00 or higher  const char *SmapTypeStrings (short type); Returns the 3-4 character description of a variable type. SmapTypeStrings returns a string of three characters for the variable type represented by type. Valid values for type are defined in the enum SystemDataTypes; you can use GetDataType to convert a tag to such a type value. NULL is returned if type is incorrect. The value returned is the string displayed in the VAR-LINK dialog. This string is localized for the current language and can be up to four characters long. Note that files of type SDT_OTH will return a pointer to the string "OTH", and not to the true extension of the file. See also: GetDataType, handleVarLinkKey ### StrToTokN  ESI StrToTokN (const char *src, unsigned char *dest); Converts a C string to a token. StrToTokN converts a symbol name pointed to by src, which is an ordinary ANSI C string, into a tokenized symbol name. See SYMSTR for more info about symbol names. dest must point to a buffer of 20 bytes (which is the maximum length of the expanded file name). The tokenized name is stored there starting at the end of the buffer. StrToTokN returns a pointer to the terminating zero byte of the converted name, exactly as expected in most routines from vat.h. Note: This routine merely converts a name into tokenized format; it does not handle reserved names or check for the validity of the name passed to it. For this reason, TokenizeSymName should be used in general to tokenize symbol names. See also: TokToStrN, SYMSTR ### SymAdd  HSym SymAdd (SYM_STR SymName); Adds a symbol. SymAdd creates a new entry in the variable allocation table (VAT) for a symbol called SymName, and returns the same type of result as the SymFind function. If the symbol SymName already exists, SymAdd deletes the old symbol before creating a new one (except if SymName is a folder name; this case is considered an error). In case of an error, SymAdd returns HS_NULL. This function may throw an error if the symbol already exists and it is locked. See SymFind and DerefSym for more info. SymName may also contain a folder name together with the symbol name (separated by "\"). In this case, the symbol will be added in the given folder. If the given folder does not exist, a dialog will appear which asks the user whether a new folder will be created. If the answer is "NO", a "Folder" error will be thrown (beware that opening a dialog may change the system font, so the use of SaveScrState and RestoreScrState is highly recommended in all cases when you expect that a folder creation dialog might appear). If SymName does not contain a folder name, the symbol entry will be created in the current active folder. This routine does not check for reserved symbol names, so caution must be used when using this routine. Note that SymAdd adds only an entry in the VAT with an empty handle; it does not allocate any space for the actual variable. To actually create a variable named "example", do the following (assuming that there were no errors in intermediate steps): HSym hsym = SymAdd (SYMSTR ("example")); // HeapAlloc must be executed before DerefSym // because of possible garbage collection. HANDLE handle = HeapAlloc (100); SYM_ENTRY *SymPtr = (DerefSym (hsym)); MULTI_EXPR *VarPtr = HeapDeref (SymPtr->handle = handle);  Now, 100 bytes of space for the variable (together with the valid handle in the VAT entry) is created, and VarPtr points to it (see HeapAlloc and HeapDeref for more info). It does not mean that the actual length of the variable must be 100 bytes: it is only the allocated amount of memory. To create a concrete variable, you must fill the space pointed to by VarPtr with valid data which depends on the wanted type of the variable. The format of some variable types (STR, PIC, TEXT etc.) may be found on doors.ticalc.org. For example, to create a one-character long string variable with content "A", do the following: VarPtr->Size = 4; // length of the variable data VarPtr->Expr[0] = 0; // zero marks the beginning of the actual variable data VarPtr->Expr[1] = 'A'; // actual data VarPtr->Expr[2] = 0; // end-of-string marker VarPtr->Expr[3] = STR_TAG; // the last byte is the type (see STR_TAG)  Note: It is very dangerous to add a new entry in the VAT without allocating a memory space, and without assigning the handle in the entry. I didn't check whether a real TI-89 crashes after this, but the debugger in VTI crashes!? Rusty, this is a bug... See also: SymAddMain, FolderAdd, MULTI_EXPR ### SymAddMain  HSym SymAddMain (SYM_STR SymName); Adds a symbol in the main folder. SymAddMain acts like SymAdd, but adds the VAT entry in the main folder list, regardless of the current active folder, even if SymName contains the folder name together with the symbol name. See SymAdd for more info. See also: SymAdd ### SymAddTwin  HSym SymAddTwin (SYM_STR SymName); Creates a twin symbol. SymAddTwin creates a twin entry in the variable allocation table (VAT) for an existing symbol SymName. A twin symbol is, in fact, another entry in the VAT with the same variable name, but with a different handle. The TIOS creates twin symbols during execution of archived programs, just in front of the normal symbol in the VAT table (see EM_twinSymFromExtMem). A twin symbol is "stronger" that a normal symbol, i.e. existence of a twin symbol temporary hides the symbol with the same name, until the twin symbol is deleted. Twin symbols have the "twin" bit set in the VAT entry (see SYM_ENTRY for the structure of a VAT entry), but in the VAR-LINK menu, it is shown as "archived". SymAddTwin returns the same result as SymAdd (HS_NULL in case of an error). If the symbol SymName does not exist, this is also an error. ### SymCmp  short SymCmp (const char *s1, const char *s2); Compares two symbol names. SymCmp compares two symbol names by comparing at most 8 characters starting from addresses pointed to by s1 and s2. It returns the same result as strcmp. It seems that calling this function is equal to strncmp (s1, s2, 8);  See strncmp for more info. ### SymCpy0  void SymCpy0 (char *dest, const char *src); Copies a symbol name with putting zero byte at the end. SymCpy0 first performs SymCpy, then puts the zero byte in ninth byte of the string pointed to by dest (i.e. in dest[8]). So, dest must be at least 9 bytes long. ### SymCpy  void SymCpy (char *dest, const char *src); Copies a symbol name. SymCpy copies at most 8 characters from string src to dest, then fills rest of the dest up to 8 bytes, so dest must be at least 8 bytes long. It seems that calling this function is equal to strncpy (dest, src, 8);  except in the fact that function SymCpy is void. See strncpy for more info. ### SymDel  short SymDel (SYM_STR SymName); Deletes a symbol. SymDel deletes the symbol SymName and returns TRUE if the operation was successful, else returns FALSE. See SYMSTR for rules about SymName. Note that this routine will delete symbols even if they are locked or in use! Do not call SymDel to delete a folder, or twin or archived symbols (for these purposes, see FolderDel and SymDelTwin). Note: Do not call SymDel to delete twin symbols. Instead, use the SymDelTwin function. ### SymDelTwin  short SymDelTwin (SYM_ENTRY *SymPtr); Deletes a twin symbol. SymDelTwin deletes a twin symbol (see SymAddTwin for more info about twin symbols) whose VAT entry is SymPtr. Returns TRUE if the operation was successful, else returns FALSE. When the TIOS deletes a twin symbol, the current value of the flags SF_GREF1, SF_GREF2, and SF_STATVAR are copied from the twin symbol to the original symbol. Note: Since the TIOS is not able to get the folder handle with only the SYM_ENTRY structure, it reads the folder address, the number of files in this folder, and the maximum number of files in the folder from the global variables used by SymFindFirst and related functions. If the program changes these variables (for example by simply using SymFindFirst) or if it adds or deletes a symbol in the VAT by itself without using SymAdd and SymDel, SymDelTwin will cause severe data corruption. The solution is simple: Always call SymFindPtr with the complete name of the twin symbol before calling SymDelTwin; passing 0 to its Flags parameter. Samuel Stearley says that calling LoadSymFromFindHandle after finding the symbol with SymFindFirst and SymFindNext works as well. (However, do not call SymDel to delete twin symbols.) ### SymFind  HSym SymFind (SYM_STR SymName); Finds a symbol. SymFind searches the variable allocation table (VAT) for a symbol (i.e. variable) SymName. SymName may also contain a folder name together with the symbol name (separated by "\"), else only the currently active folder will be searched. SymFind returns a structure of type HSym, which contains the handle of the variable table list belonging to the folder (current, or folder given in the name), and the offset from the beginning of the list to the actual VAT symbol entry. Use DerefSym to get a pointer to the actual VAT symbol entry instead. In case of an error (for example, if the symbol does not exist), SymFind returns HS_NULL. Note that most reserved symbols (i.e. system variables) are not stored in the VAT table, so you cannot locate them using SymFind. Note: SymName is not an ordinary C string. Instead, this is a sequence of characters which starts with the zero character ('\0') and terminates with the zero character as well, and all TIOS routines for VAT handling need a pointer to the terminating zero byte as the input argument, which is a little twisty. So, to search for a symbol named "tetris", instead of hsym = SymFind ("tetris");  you must do the following: hsym = SymFind ("\0tetris"+7);  To make this job easier, the macro SYMSTR is implemented, so you may simply do hsym = SymFind (SYMSTR ("tetris"));  You may use the older$ macro constructor as well.

Note also that all legal TIOS symbol names must be in lowercase!

### SymFindFirst

 SYM_ENTRY *SymFindFirst (SYM_STR SymName, unsigned short Flags);

Begins looping through the VAT.

SymFindFirst searches for the first symbol entry in the variable allocation table which satisfies the requirements given by the parameters Flags and SymName (see SYMSTR for information about symbol names), and sets some internal pointers so that SymFindNext and SymFindPrev may be called to traverse the VAT. SymName is required only for some values of Flags (you can set it to NULL otherwise). Flags is a collection of binary flags defined in the enum FindOptions. These flags also determine how subsequent calls of SymFindNext and SymFindPrev will be interpreted.

If Flags is 0 (i.e. no flags are given), SymFindFirst and subsequent calls to SymFindNext and SymFindPrev loop only through the list of folders. In this case, SymName is ignored.

The following flags are defined:

 FO_RECURSE Loop through all folders including their symbols. Naturally, SymName is still ignored. Subsequent calls to SymFindNext will continue searching through the whole variable allocation table, including both the folder table and the variable tables associated with each folder. More precisely, after each folder, the complete variable table for this folder will be browsed before the next folder is reached. This flag can be used together with all other flags except FO_SINGLE_FOLDER and FO_RETURN_FOLDER. FO_SKIP_TEMPS Skip temporary folders when looping through the folder table. See FolderAddTemp for more information about temporary folders. This flag cannot be used together with FO_SINGLE_FOLDER, obviously. FO_SKIP_COLLAPSE Skip variables in collapsed folders. Folders can be collapsed only since AMS 2.00; therefore this flag has no effect if the AMS version is lower than 2.00 (but it is still defined). This flag can only be used if FO_RECURSE is set as well. FO_RETURN_TWINS Return the temporarily hidden equivalents of twin entries in the archive as well, which is normally not the case. See SymAddTwin for more information about twin entries. Of course, this does not have any effect if neither FO_RECURSE nor FO_SINGLE_FOLDER are included in Flags (i.e. if only folder names are returned). FO_SINGLE_FOLDER Loop through all symbols in the folder identified by SymName, but do not return the folder name itself. This flag may be used together with FO_RETURN_FOLDER and FO_RETURN_TWINS, but not with any other flag. FO_RETURN_FOLDER This flag can only be set if FO_SINGLE_FOLDER is set as well. It slightly alters the meaning of FO_SINGLE_FOLDER so that SymFindFirst returns the SYM_ENTRY structure of the folder identified by SymName, and subsequent calls to SymFindNext will return all symbols in that folder.

SymFindFirst returns the pointer to the symbol entry in the VAT, or NULL if there are no symbols which satisfy the given requirements. Here is an example how to (legally) create a list of all variable names in the main folder:

counter = 0;
SymPtr = SymFindFirst (SYMSTR ("main"), FO_SINGLE_FOLDER);
while (SymPtr)
{
strcpy (names[counter++], SymPtr->name);
SymPtr = SymFindNext ();
}


If you want to create a list of all folder names, simply change

SymPtr = SymFindFirst (SYMSTR ("main"), FO_SINGLE_FOLDER);


in the previous example to

SymPtr = SymFindFirst (NULL, 0);


Note: Since this routine and subsequent calls to SymFindNext and SymFindPrev return direct pointers to the symbol table, heap compression will cause subsequent results to be invalid or may crash the system. In other words, heap compression will invalidate all pointers returned necessitating another call to SymFindFirst. Therefore locking the folder table (using FolderOp) during the complete operation is highly recommended.

### SymFindFolderName

 char *SymFindFolderName (void);

Returns an actual folder name during browsing through the VAT table.

This routine is used only when you search the complete VAT table using functions SymFindFirst, SymFindNext and SymFindPrev with FO_RECURSE in Flags set. Each time when a folder is encountered in the VAT table, the TIOS stores its name in an internal buffer. Later, when you go through the variable part of the VAT table, you can call this routine to retrieve the stored folder name, i.e. to get the name of the folder for the symbol just returned. Under any other conditions, SymFindFolderName just returns a pointer to the string "main".

See HeapWalk for an example using this function.

Deprecated alias: SymFindFoldername

### SymFindHome

 HSym SymFindHome (SYM_STR SymName);

Finds a folder.

SymFindHome searches the folder table part of variable allocation table (VAT) for a folder named SymName (in fact, it searches through a pseudo-folder called "home", which contains all other folders). SymFindHome returns a structure of type HSym, which contains the handle of the folder table list of the VAT, and the offset from the beginning of the list to the actual VAT symbol entry. Use DerefSym to get a pointer to the actual VAT symbol entry instead. In case of an error (for example, if the folder does not exist), SymFindHome returns HS_NULL.

Note: I don't know what kernels do to find the handle of the folder list, but as far as I know, the only legal method is the following:

FolderListHandle = SymFindHome(SYMSTR("main")).folder;


### SymFindMain

 HSym SymFindMain (SYM_STR SymName);

Finds a symbol in the main folder.

SymFindMain acts like SymFind, but searches only the main folder, regardless of the currently active folder, even if SymName contains a folder name together with the symbol name. See SymFind for more info. It is useful for searching some symbols such as the system reserved equations ("Y1"..."Y99", "RegEq", etc.) which are always stored in the "main" folder and cannot be moved to a different folder.

### SymFindNext

 SYM_ENTRY *SymFindNext (void);

Finds the next entry in the VAT table.

SymFindNext searches for the next symbol entry in the VAT table after calling SymFindFirst. The exact behavior of SymFindNext depends on the parameters passed to SymFindFirst. See the description of SymFindFirst for more information and examples of usage.

SymFindNext returns a pointer to the symbol entry in the VAT, or NULL if there are no more entries in the VAT which satisfy the given requirements.

### SymFindPrev

 SYM_ENTRY *SymFindPrev (void);

Finds the previous entry in the VAT table.

SymFindPrev is very similar to SymFindNext, but instead of the next entry in the VAT, SymFindPrev searches for the previous entry in the VAT.

Normally the only routine used with SymFindFirst is SymFindNext, but this routine allows a program to traverse the symbol table in both directions. For example, the VAR-LINK dialog uses this routine to present a scrollable list of all symbols without having to maintain a separate list in memory.

### SymFindPtr

 SYM_ENTRY *SymFindPtr (SYM_STR SymName, unsigned short Flags);

Finds a symbol and returns a pointer to the VAT entry.

SymFindPtr acts like SymFind and related functions, but instead of a HSym structure, it returns a pointer to the actual VAT entry. SymFindPtr returns NULL in case of an error. So, it acts somewhat as a combination of SymFind and DerefSym.

Flags is an additional argument which determines the searching method. It is a set of binary flags. The exact meaning of these flags are still unknown for me, but at the moment, I know the following for sure:

• If Flags = 0, the search is performed like using the SymFind function (i.e. through current or given folder);

• If Flags = 4, the search is performed like using the SymFindMain function (i.e. through main folder only).

What I also know is that if b15 in Flags is set, the search is somewhat related to the folder list, and it is possible to search for folders as well. But I still can't conclude the exact meaning of these flags. So, instead of giving uncertain information, I will stop here. Everything about this function presented so far is certainly true. Fortunately, the TIOS set of VAT functions is rich enough so that eventual additional possibilities of this function may be simulated using other known functions. Any additional information will be welcomed, if someone knows more than me.

As an example of usage, this is a legal method how to lock a variable named "tetris":

SymFindPtr(SYMSTR("tetris"),0)->flags.bits.locked = 1;


See SYMSTR for info about symbol names.

### SymMove

 short SymMove (SYM_STR SrcName, SYM_STR DestName);

Moves a symbol.

SymMove moves the symbol SrcName to the symbol DestName (see SymFind for rules about SrcName and DestName). Both SrcName and DestName may also contain a folder name together with the symbol name (separated by "\"). If none of the names does not contain a folder name, moving will be simply reduced to renaming. If the destination folder does not exist, a dialog will appear which asks the user whether a new folder will be created. If the answer is "NO", a "Folder" error will be thrown. Destination symbol will be deleted before moving, if such symbol exists. SymMove returns TRUE if the operation was successful, else returns FALSE. This function will even move and rename locked and archived files; however, upon a reset, they will return to the original name and/or folder.

Note: Check whether SrcName exists before applying this command, because the destination symbol DestName (if exists) will be deleted even in a case of an error!

### SYMSTR

 SYM_STR SYMSTR (const char *s);

Defines a VAT string.

Most of the TIOS functions which take symbol names as parameters do not accept ordinary C strings. Instead, the symbol name is either a variable tag or a sequence of characters which starts with the zero character ('\0') and terminates with the zero character as well, and the TIOS routines for VAT handling need a pointer to the terminating zero byte as the input argument, which is a little twisty. For example, to search for a symbol named "tetris", instead of

hsym = SymFind ("tetris");


you have to do the following:

hsym = SymFind ("\0tetris"+7);


To make this job easier, the SYMSTR macro is implemented, so you may simply do

hsym = SymFind (SYMSTR ("tetris"));


If the argument passed to SYMSTR is a string literal as in this case, SYMSTR simply expands to the sequence in the second example. This is an optimization done by the preprocessor. In all other cases, space for a temporary string is allocated on the stack using alloca, and the string is copied to this location on the stack. Strictly speaking, SYMSTR does not return a pointer of type SYM_STR in this case, but rather a pointer to non-constant data. This means that you may write to it if you wish.

Note that this macro doesn't check whether s is valid or not. If you need to tokenize a variable string and want to be sure that s is valid, you can use the TokenizeSymName routine.

Note: You cannot create tokens for system variables using this macro. See EXT_SYSTEM_TAG for more information. And if you want to use a single-character variable name, you can usually use one of the variable tags from the enum Tags. Note also that all legal TIOS symbol names must be in lowercase.

### SymSysVar

 short SymSysVar (const char *VarName);

Checks for a system-reserved variable name.

SymSysVar checks if a variable pointed to by VarName (an ordinary C string) is a system-reserved variable stored in the symbol table (in the main folder). It returns the same values as CheckSysFunc. Additionally, it returns R_SYSVAR if the variable name is "SysData" or "RegCoef". In fact, this function calls CheckSysFunc with additional checks for "SysData" and "RegCoef".

### TempFolderName

 SYM_STR TempFolderName (unsigned short TempNum);

Creates a temporary folder name.

TempFolderName converts the number TempNum in a four-digit string which corresponds to the given number (i.e. 12 will be converted into "0012"). This string will begin with '\0' character, and TempFolderName will return a pointer to the terminating '\0' character, as expected by many TIOS VAT routines (see SymAdd for more info about symbol names). TIOS will accept such "numeric" folder names, but they are invisible for the TI-Basic system, VAR-LINK menu, etc. TIOS creates and uses such folders for storing local variables during execution of TI-Basic programs.

### TokToStrN

 short TokToStrN (unsigned char *dest, SYM_STR src);

Converts a token to a C string.

TokToStrN converts the VAT symbol name pointed to by src into an ordinary ANSI C string. See SYMSTR for more info about symbol names. src should point to the terminating zero byte of the name (or to a one-letter variable tag), and the result will be stored in the buffer pointed to by dest. The buffer has to be at least 20 bytes long. TokToStrN returns TRUE if the symbol could be converted, and FALSE if src does not point to a tag that represents a variable or is a reserved variable name.

### ValidateSymName

 short ValidateSymName (const char *VarName);

Checks for a valid VAT name symbol.

Checks whether the ANSI C string pointed to by VarName may be a valid name of a VAT symbol (i.e. a TI-Basic variable), and returns TRUE if it can, or FALSE otherwise. This function checks for valid characters, and for a maximum length of eight characters.

### VarRecall

 HSym VarRecall (SYM_STR SymName, unsigned short Flags);

A higher-level variant of SymFind.

VarRecall works like SymFind, but it is able to handle system variables which do not have an entry in the variable allocation table. SymName is a pointer to the terminating zero byte of the VAT variable name (see SYMSTR for more info about symbol names). Flags is a collection of flags defined in the enum VarRecallFlags:

 VR_NO_SYS_VARS Do not return system variables. VR_FUNC_NAME Accept strings terminating with an opening parenthesis (like "y1(") for SymName. VR_LINK Used only internally by the link code.

Note that you cannot create the necessary token for system variables with the SYMSTR or $macro. Instead, system variables have their own tags. For example, to recall the system variable called "xmin", you have to use the following code: hsym = VarRecall ((const ESQ []){XMIN_TAG, EXT_SYSTEM_TAG} + 1, 0);  You may use the TokenizeSymName function if you need a generic way to access variables, like this: TokenizeSymName ("xmin", TSF_ALLOW_RESERVED); hsym = VarRecall (top_estack, 0);  To make the handling of system variables consistent with normal variables even though system variables do not have an entry in the variable allocation table, VarRecall returns a reference to a dummy SYM_ENTRY if a system variable is requested. It actually copies the contents of the system variable into an internal buffer and adds the appropriate tag. Since one dummy entry is used for many system variables, you have to store the contents of each variable in your program if you need to access more than one value at a time. In other words, a dummy HSym descriptor which is created for system variabes is shared by all variables not in the VAT. Thus the next call to VarRecall for such a variable will return the same descriptor, but with a different value (and the previous descriptor will be invalid). So if VarRecall is used for system variables, it is best to keep a copy of the value pointed to by the HSym if it is needed. It might be useful to know (but it is not reliable) that internally, the folder field of the returned HSym contains a handle to the following type of structure: struct SysVarSym { unsigned short DataSize; ESQ Data[60]; SYM_ENTRY sysVar; SYM_ENTRY tblInput; SYM_ENTRY unit; };  The offset field is then either 62 for system variables (offset to the sysVar field), 76 for the "tblInput" variable (offset to the tblInput field), or 90 for units (offset to the unit field). The reason that three different SYM_ENTRY type fields are used is that they contain different flags and handles. sysVar and unit both contain the same handle as the folder field of the HSym, whereas tblInput contains a handle to an external memory location. The compatibility flag is CF_NONE for system variables (including "tblInput"), but CF_NEW for units. All three fields contain the SF_LOCKED flag. If the SYM_ENTRY structures use the same handle as the folder field of the HSym returned by VarRecall, they use in fact the first 62 bytes of this internal structure. This saves a handle in the operating system. When dealing with system variables and units, it is not reliable to use the name field of the SYM_ENTRY structure whose address is obtained with DerefSym (which is, of course, one of the three structures mentioned above). It is blank for all system variables and units except "tblInput". Note: This function may throw different errors. Especially, most system variables cannot be used in a function that is being graphed, either because they change too often or because they are used by the graph routines themselves (for example, "xmin" or "xc"). If these variables are accessed while graphing, VarRecall throws an error. However, locked variables may be looked up with VarRecall. ### VarStore  HSym VarStore (SYM_STR SymName, unsigned short Flags, unsigned short Size, ...); High-level function to store values into variables. VarStore performs many storing operations, from basic file saving to list/matrix element access. Although some of its operations appear to be quite trivial, it provides a consistent interface to all storing operations, even for system variables. So, this is the general system routine for storing to TI-Basic variables. VarStore can perform different types of operations. It can store values into TI-Basic variables (it will create a new VAT entry if needed), prepare variables to be stored to, or store individual values to elements of a list or matrix. The data type and domain of system variables are verified to be correct. SymName is the symbol name of the variable in which the value will be stored (see SYMSTR for more info about symbol names). VarStore returns the HSym descriptor of the TI-Basic variable, or HS_NULL if the variable is a system variable (which is not stored in the VAT). Note that you cannot create the necessary token for system variables with the SYMSTR or$ macro. Instead, system variables have their own tags. For example, to store something in the system variable xmin, you have to use the following code:

VarStore ((const ESQ []){XMIN_TAG, EXT_SYSTEM_TAG} + 1, ...);


You may use the TokenizeSymName function if you need a generic way to access variables.

The parameter Flags determines the meaning of the remaining parameters:

 STOF_ESI An extra parameter of type ESI is needed, which points to an expression which will be stored into the variable. Basically, this parameter may point to an arbitrary locked block of memory, not necessarily on the expression stack. On a side note, this variant is used internally if RETURN_VALUE  is defined. STOF_HESI Like STOF_ESI, but the extra parameter has the type HANDLE. It must be a handle to a block of memory containing the data to be stored. The handle will be locked during the operation. STOF_ELEMENT Three extra parameters are needed. The first extra parameter has the type ESI; it should point to an expression which will be stored into an element of a list or matrix variable determined by the SymName parameter. The second and third parameters have the type unsigned short. For matrices, they determine the column and the row of the element, respectively. For lists, the second extra parameter is the index and the third parameter must be zero. Indices for both matrices and lists start at one. STOF_NONE Nothing is assumed about the source, so no copying is done (it is left to the caller). Only the VAT entry will be created. The name and flags and other conditions will be verified.

Additionally, the parameter Flags may contain some tag values (see Tags for more info). The allowed tags are USERFUNC_TAG (in this case an extra parameter of type ESI should point to the user function which will be stored; note that this is not FUNC_TAG), TEXT_TAG (for text variables), GDB_TAG (for Graph Database variables), PIC_TAG (for picture variables), DATA_TAG (for data variables), and OTH_TAG (for custom type variables). In all of these cases except USERFUNC_TAG, the destination is verified to have the same type as the source, but the copy operation is not done. There are more possible values for Flags, but they are used only for internal purposes in the TIOS.

The parameter Size is the size of the source data including the tag but not the size word stored in the heap. If Size is zero, then the size of the expression pointed to by the first extra parameter will be used (this is allowed if Flags is STOF_ESI, STOF_HESI, or STOF_ELEMENT). Otherwise, the new variable is not allocated, but the folder field in the returned HSym descriptor may still not be H_NULL if previous data existed in that variable).

Note: VarStore may throw various errors, and may cause heap compression (garbage collection). For example, some VAT variables are system protected (see QSysProtected). These include programs and functions (TI-Basic or ASM), data variables, graph databases, custom type files, pictures, and text variables. Only variables of the same type can be copied to a system-protected variable. If the variable name already exists, the lock flag is checked (a variable that is locked or archived cannot be overwritten; VarStore throws an error in this case). System variables cannot be locked and some system variables cannot be changed by the user. VarStore also checks the SF_HIDDEN flag in the VAT entry (see the SYM_ENTRY structure for more info), which is actually an "in-use" flag. Any variable being used by an application cannot be overwritten except by that application (it cannot be deleted, renamed, or linked, either). The in-use count is verified to be 0 for functions and programs.

If the variable is not a system variable, locked, system protected, or in use, a value can be stored to it no matter what it contained before. However, there are type restrictions on individual elements of lists or matrices. Usually, VarStore makes sure there is enough memory left to store the new contents to the variable before deleting the current contents of the variable. When storing to an existing variable, both graph reference flags are tested (SF_GREF1 and SF_GREF2). If one or both is set, the corresponding dirty graph and dirty table flag(s) are set to indicate the graph and table are no longer valid. Storing to an individual element or submatrix of a matrix or list does the same checks as for an existing variable, and updates the length. In addition, the data type of the element needs to be correct (expression, relation, string).

Only functions with the correct function arguments can be stored in the variables reserved as system functions. These are y1(x)...y99(x), xt1(t)...xt99(t), yt1(t)...yt99(t), r1(q)...r99(q), u1(n)...u99(n), y1'(t)...y99'(t), and z1(x,y)...z99(x,y). They can be single-line or multi-line functions, but an error is returned if the user tries to create any other data type with those names or if the number of arguments is incorrect. Since they are system functions, they cannot be locked and must be in the main folder. Empty functions are not valid and should not be added to the symbol table. This is true for user functions as well.

### HS_NULL

 #define HS_NULL ((HSym) {0, 0})

A null symbol constant.

HS_NULL is a null symbol. Many TIOS functions returns such a symbol in case of an error. Note that you can't check whether a some variable is HS_NULL using the "==" operator because HS_NULL is not scalar, i.e. you can't write something like

if (hs == HS_NULL) ...


Instead, check the folder field of HSym structure: if it is zero, the whole structure is HS_NULL, because TIOS never creates HSym structures in which the folder field is zero and the offset field is nonzero.

### CompatFlags

 enum CompatFlags {CF_NONE = 0, CF_CONVERT = 1, CF_ENHANCED = 2, CF_NEW = 3};

An enumeration for describing possible compatibility flags in the SYM_ENTRY structure.

### ExtendedSysTypes

 enum ExtendedSysTypes {SEQ_INITC = 7, DE_INITC = 8, DE_FLDPIC = 9, SOLVER_SYS_VARS = 10, UNIT_VAR = 11, C_COL = 12, R_REGEQ = 13, R_SYSVAR = 14};

Describes system variable types.

This is an enumeration describing system variables which are not included in the types described in GraphModes from gdraw.h. It is currently used only in CheckReservedName.

### FindOptions

 enum FindOptions {FO_SINGLE_FOLDER = 0x01, FO_RECURSE = 0x02, FO_SKIP_TEMPS = 0x04, FO_NOTEMPS = 0x04, FO_RETURN_TWINS = 0x08, FO_CKTWINS = 0x08, FO_RETURN_FOLDER = 0x10, FO_SKIP_COLLAPSE = 0x20};

Describes options for SymFindFirst and FFindFirst.

FindOptions is an enumeration describing flags for SymFindFirst and FFindFirst. They can be combined with the '|' operator.

### FolderOpFlags

 enum FolderOpFlags {FOP_UNLOCK = 0, FOP_LOCK = 1, FOP_ALL_FOLDERS = 0x80};

An enumeration for describing possible options for the FolderOp function.

### FolderStats

 enum FolderStats {MAIN_FOLDER = 2, FOLDER_TABLE = 3, NOT_FOUND = 4, BAD_FOLDER = 5};

An enumeration for describing possible results of the FolderFind function.

### HSym

typedef struct {
 HANDLE folder; unsigned short offset;
} HSym;

A structure representing a symbol reference.

HSym is a structure which contains the handle of the variable table list belonging to the folder in which the symbol is located, and the offset from the beginning of the list to the actual VAT symbol entry of type SYM_ENTRY. These symbol references are used as a safe and efficient method to pass variable references around in the system, so that there are no probems after garbage collection (i.e. the heap compression). In other words, symbol references stay valid even after the heap compression. Note, however, that the references may become invalid whenever a symbol in the same folder is added, removed, or even renamed, since the actual offset of the SYM_ENTRY structure may change during this operation.

You can use the DerefSym function to get a pointer to the actual SYM_ENTRY structure.

### HSYM

 #define HSYM HSym

An alias for HSym.

HSYM is an alias for HSym, to achieve compatibility between different programs.

### SYM_ENTRY

typedef struct {
char name[8];
unsigned short compat;
union {
unsigned short flags_n;
struct {
 unsigned int busy : 1, local : 1, flag1_5 : 1, flag1_4 : 1, collapsed : 1, twin : 1, archived : 1, in_view : 1; unsigned int folder : 1, overwritten : 1, checked : 1, hidden : 1, locked : 1, statvar : 1, graph_ref_1 : 1, graph_ref_0 : 1;
} bits;
} flags;
HANDLE handle;
} SYM_ENTRY;

A structure representing a VAT symbol entry.

Principally, SYM_ENTRY consists of the symbol name, the flags, and the handle associated with the symbol. The flags are defined as a union, so you can access to all flags together using the field flags_n (in such case, constants defined in the enum SymFlags may be useful for bit masking), or access to individual flags (which are defined as bit fields) using the field bits. Some flags are unused, and some flags have an unknown meaning. At the moment, the known flags are: locked (set for locked symbols), hidden (set for symbols which are hidden for the TI-Basic; in fact, "hidden" files are files which are currently opened, i.e. in-use files), checked (set for symbols which are checked in VAR-LINK dialog), folder (set for folder entries), collapsed (set for collapsed folders; this makes sense only on AMS 2.xx), archived (set for archived symbols), twin (set for twin symols, see SymAddTwin), and local (set for local symbols). For example, if "SymPtr" is the pointer to the VAT symbol entry, the following command makes this symbol invisible for TIOS:

SymPtr->flags.bits.hidden = 1;


Note that the twin bit may only be set if the symbol is really a twin symbol, i.e. an entry with the same name exists. Otherwise, the system will crash upon the next call to SymAdd.

The handle field always contains a handle to a MULTI_EXPR structure. It must contain valid data for the operating system to operate properly.

Each symbol has also associated compatibility flag (field compat). It determines how the symbol will behave during sending to unexpanded (non-Plus) TI-92. There are four possible values of the compatibility flag (these constants are defined in enum CompatFlags):

 CF_NONE Sends immediately CF_CONVERT Converts and sends CF_ENHANCED An enhanced token - may or may not work CF_NEW Will not be sent

A compatibilty number of CF_CONVERT or CF_NEW is determined from symbols context. CF_ENHANCED is related mainly for internal tokens, which does not appear in final results and programs.

Here is the list of token tags (see Tags) which belong to CF_CONVERT, CF_ENHANCED and CF_NEW categories:

 Convert: LOCALVAR_TAG Enhanced: _VAR_Q_TAG, PN_INFINITY_TAG, tag 0x5F (internal), START_TAG, ISTORE_TAG, ANS_TAG, ENTRY_TAG, MATRIX_TAG, ERROR_MSG_TAG, tags 0xF5, 0xF6 and 0xF7 (internal) New: PART_TAG, PN1_TAG, PN2_TAG, EIGVC_TAG, EIGVL_TAG, DASH_TAG, DESOLVE_TAG, FDASH_TAG, ASM_TAG, ISPRIME_TAG, OTH_TAG, ROTATE_TAG, PARENTH_START_TAG, PARENTH_END_TAG, MAT_START_TAG, MAT_END_TAG, LIST_START_TAG, LIST_END_TAG, COMMA_TAG, SEMICOLON_TAG, COMPLEX_ANGLE_TAG, SINGLE_QUOTE_TAG, QUOTE_TAG, POLCPLX_TAG, TMPCNV_TAG, DELTA_TMPCNV_TAG, GETUNITS_TAG, SETUNITS_TAG, BIN_TAG, HEX_TAG, INT2BIN_TAG, INT2DEC_TAG, INT2HEX_TAG, DET_TOL_TAG, REF_TOL_TAG, RREF_TOL_TAG, SIMULT_TOL_TAG, GETCONFG_TAG, V_AUGMENT_TAG, EYE_PSI_TAG, TPLOT_TAG, DIFTOL_TAG, ZEYE_PSI_TAG, T0_TAG, DTIME_TAG, NCURVES_TAG, FLDRES_TAG, ESTEP_TAG, ZT0DE_TAG, ZTMAXDE_TAG, ZTSTEPDE_TAG, ZTPLOTDE_TAG, NCONTOUR_TAG, DISPHOME_ITAG, EXEC_ITAG, ARCHIVE_ITAG, UNARCHIV_ITAG, LU_ITAG, QR_ITAG, BLDDATA_ITAG, DRWCTOUR_ITAG, NEWPROB_ITAG, SINREG_ITAG, LOGISTIC_ITAG, CUSTMON_ITAG, CUSTMOFF_ITAG, SENDCHAT_ITAG

Note: SYM_ENTRY structures are usually not locked, which means that pointers to them will become invalid if a heap compression occurs. Basically, this means that you can only operate on them for a short time in which you know that no heap compression can occur.

### SymFlags

 enum SymFlags {SF_GREF1 = 0x0001, SF_GREF2 = 0x0002, SF_STATVAR = 0x0004, SF_LOCKED = 0x0008, SF_HIDDEN = 0x0010, SF_OPEN = 0x0010, SF_CHECKED = 0x0020, SF_OVERWRITTEN = 0x0040, SF_FOLDER = 0x0080, SF_INVIEW = 0x0100, SF_ARCHIVED = 0x0200, SF_TWIN = 0x0400, SF_COLLAPSED = 0x0800, SF_LOCAL = 0x4000, SF_BUSY = 0x8000};

SymFlags is an enumeration for easy access to flags in VAT symbol entries represented by the SYM_ENTRY structure.

### SystemDataTypes

 enum SystemDataTypes {SDT_EXPR = 0, SDT_LIST = 1, SDT_MAT = 2, SDT_FUNC = 3, SDT_PRGM = 4, SDT_PIC = 5, SDT_STR = 6, SDT_TEXT = 7, SDT_GDB = 8, SDT_DATA = 9, SDT_FIG = 10, SDT_MAC = 11, SDT_OTH = 12, SDT_SYS = 13, SDT_ALL = 14, SDT_ASM = 15};

Describes valid variable types in the "Var-Link" dialog, and for the GetDataType and SmapTypeStrings functions.

### VarRecallFlags

 enum VarRecallFlags {VR_NO_SYS_VARS = 0x01, VR_FUNC_NAME = 0x02, VR_LINK = 0x04};

A collection of flags used in VarRecall.

VarRecallFlags is an enumeration describing possible flags used in the VarRecall function.

### VarStoreFlags

 enum VarStoreFlags {STOF_ESI = 0x4000, STOF_ELEMENT = 0x4001, STOF_NONE = 0x4002, STOF_HESI = 0x4003};

Describes possible flags for VarStore.

VarStoreFlags is an enumeration describing flags used in the VarStore function. Only one of these flags may be used at a time.