I want to create a variable without using functions from stdio.h.

Previous TI Variables and the Variable Allocation Table (VAT) Next

Q: I want to avoid standard ANSI C functions for file handling like fopen etc. and to use low-level functions from vat.h (to make my program shorter), but I am not very sure what I need exactly to do to create a new file, and how I can manipulate with it.
A: Basically, to create a file you need to do the following:
  1. Create a new VAT symbol using SymAdd;
  2. Allocate a space for the variable using HeapAlloc;
  3. Dereference the symbol to get a pointer to the VAT entry, then store the handle returned by HeapAlloc to it;
  4. Put the actual file length in first two bytes of allocated space.
To be more concrete, I will show here a simple demo program (called "Create Variable") which creates a string file (I use this internally), but it is easy to adapt to any file type:
// Create a variable using functions from vat.h

#define USE_TI89              // Compile for TI-89
#define USE_TI92PLUS          // Compile for TI-92 Plus
#define USE_V200              // Compile for V200

#define OPTIMIZE_ROM_CALLS    // Use ROM Call Optimization
#define MIN_AMS 100           // Compile for AMS 1.00 or higher
#define SAVE_SCREEN           // Save/Restore LCD Contents

#include <tigcclib.h>         // Include All Header Files

HANDLE CreateFile (const char *FileName)
// Returns a handle, H_NULL in case of error
{
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if (!(h = HeapAlloc (HeapMax ()))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;
  return h;
}

void AppendCharToFile (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h) - 10) return;
  *(unsigned short*)base = len + 1;
  base[len+2] = c;
}

void AppendBlockToFile (HANDLE h, void *addr, unsigned short len)
{
  unsigned short i;
  for (i = len; i; i--) AppendCharToFile (h, *((char*)addr)++);
}

void CloseFile (HANDLE h)
{
  AppendCharToFile (h,0); AppendCharToFile (h,0x2D);
  HeapUnlock (h);
  HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
}

void _main(void)
{
  static char s[] = "Hello world!";
  HANDLE h;
  h = CreateFile ("example");
  AppendBlockToFile (h, s, 12);
  CloseFile (h);
}
Note that the used method is not the best: it initially allocates as much space as avaliable, then reallocates the space to the necessary size on closing, but it is worth to look at it. Note also that the CreateFile function may be even simpler if you want to use it like CreateFile(SYMSTR("example")) instead of CreateFile("example"), i.e. if you avoid the use of ANSI strings.