Malcolm's github site Baby X Resource Compiler    Baby X RC banner

Baby X FileSystem

 
BabyX FS logo

The Baby X filesystem project, or BabyXFS is a project designed to allow Baby X user to mount directories in Baby X programs. However because of the highly portable nature of Baby X, it is also modular and can be used entirely independently, by non- Baby X or even non- Baby X resource compiler users. However I recommend these projects as they come to maturity and encourage you to get involved.


Baby X structure

IconBannerShort nameLong nameDescription
Baby X logoBaby X bannerBabyXBaby X A small GUI toolkit which ports between Linux X11 and MS Windows.
Baby X RC logoBaby X RC bannerBabyXRCBaby X Resource compiler A commandline program to convert resources to compileable C code.
Baby X FS logoBaby X FS bannerBabyXFSBaby X File system A suite of programs and code for supporting virtual filesystems.

This project, BabyXFS, is the filing system sub-component. You can use it on its own, or in combination with the rest of Baby X. It is designed to add power to the other components of Baby X.

FileSystem XML files

The FileSystem XML format was invented to meet the needs of hobby programmers. It is a very clean XML format which is easy to parse and robust, as text files are all human-readable. You can of course compress the files using general purpose text compreession if you need to save space.

FileSystem XML files were invented form Baby X, but they are not branded as Baby X, because it is intended as a general purpose format which should attract wide use.

The BBX_FileSystem library

The BabyXFS FileSystem library is a suite of functions for mounting FileSystem XML files virtual drives on your machine and thus reading the contents.

THe object BBX_FileSystem is documented here, and The functions in bbx_filesystem.c are documented here.

The BBX_Options parser

The Baby X options parser, BBX_Options is a lightweight single file options parser that greatly simplifies command line options handling and is an essential for every small or "baby" program which takes commandline options. And as with all of Baby X, it is free to anyone for any use.

The Baby X filesystem programs

BabyXFS has an entire suite of programs and sourse subroutines designed to allow users to use FileSystem files. There are of course programs to generate the XML files from directories, and to recreate the directories from the files. You can also list the files in a FileSystem file, or extract them.

babyxfs_dirtoxml

babyxfs_dirtoxml, crawls a C source directory for files and writes them as xml. You then have a big xml file which you can use for other purposes.

     
     babyxfs_dirtoxml <targetfolder>
    
     The program accepts a folder as an argument, traverses it,
     and spits out the results as XML to stdout.
     
     Example:
        babysfxs_dirtoxml  data/myfolder > myfolder.xml
        
 

babyxfs_dirtoxml is simple but very powerful, and produces clean XML with text files represented a plain text and binary files uuencoded. It produces XML in the <FileSystem> format.

babyxfs_xmltodir

babyxfs_xmltodir, takes a FileSystem XML file, and recreates the directory on disk.So it is to be used with babyxfs_xmltodir to create and extract archives.

      
      babyxfs_xmltodie <filesystem.xml> <targetfolder>
     
      The program accepts a FileSystem XML file as an argument,
      and writes it to the target directory.
      
      Example:
         babysfxs_xmlrodir  poems.xml /users/fred/Documents/poetrycollection
         
  

babyxfs_xmltodir is quite a simple program because the FileSystem XML format is so simple.

babyxfs_ls

babyxfs_ls, lists the files in a FileSystem XML file. It's a very, very basic implementation of the Unix program ls, and currently accepts no options, but only globs or wildcards..

       
       babyxfs_ls <filesystem.xml> <glob>
      
       The program accepts a FileSystem XML file as an argument,
       and a path, and lists the files to standard output.
       
       Example:
          babysfxs_ls  poems.xml "/poems/*"
          
        This will list all the files under theroot directory, which
        should be "poems", the same as the name of the XML file. However
        of course there is no way of enforcing that, and query with "/*"
        if you do not know the root. Remember to enclose globs in quotes
        under Unix, as otherwise the system will expand them for its own
        file system.
          
   

babyxfs_ls is currently very basic, but there are plans to add more options, like "ls". Directories can be recognised becuause they heave "/" appended tob their names.

babyxfs_extract

babyxfs_extract, writes out a single file in an FileSystem XML file to standard output. So bthis is in fact a very powerful practical use. In combination with babyxfs_ls, you have a portable archive that you can use, on any machine with a C compiler, even an embedded system, because babyxfs_ls and babysfs_extract are written in completely portable ANSI C with no dependencies other than the standard library.

        
        babyxfs_extract <filesystem.xml> <filename>
       
        The program accepts a FileSystem XML file as an argument, and
        a path, and extracts the file to standard output.
        
        Example:
           babysfxs_extract poems.xml "/poems/Blake/tyger.txt"
           
         This will extract the file "tyger.txt" from the filesystem.xml
         file and write it to standard output.
           
    

babyxfs_extract is a very powerful facility. It means that you can get files from your FileSystem MXL files on demand.

babyxfs_shell

babyxfs_shell, invokes a simple shell, mounting a FileSystem XML file as its backing store.

         
         babyxfs_shell <filesystem.xml> <filename> [options]
        
         The program accepts a FileSystem XML file as an argument, and
         a path, and runs the shell over it.
        
        options:
                -editor <editor program>
         
         Example:
            babysfxs_shell poems.xml
            
            babyxfs_shell poems.xml -editor vi
            
          This will run a shell and mount poems.xml.
          in the second case, the program "vi" is used to edit the
          files.
            
     

babyxfs_shell is a very powerful facility. It means you can do practically anything you want with yuor FileSystem XML file. Your regular prompt will be replaced by the BBX$ prompt, and you are in the world of Baby X.

Because of the way ANSI C works, it is very difficult to give the shell an internal text editor that is any good, so you specify which editor to use. Curently it defaults to "nano".

Baby X BBX_FileSystem subroutines

THe FileSystem format is mainly designed for embedding in programs, so that they don't need to ship with supporting files on disk. However they can still use routines designed to wotk with files on disk. So the BBX_FileSystem object is an archive which supports fopen(), and fclose(). It the returns a standard library FILE * which can be passed ton any routines written in C or C++ designed to operatec ob C streams.

Now you can toggle the BBX_FileSystem between using a FileSystem XML file, and using the regular file system on the host machine. ANd this is desigend to make Baby X programs or non- Baby X programs which take the BabyXFS subsystem, easy to develop. When you are developing the program, you set the archive to an external directory. And you have all the facilities of your desktop system to move files in and out and manipulate them, and practically unlimited storage. Then when the program is getting near release, you settle on a relatively small and stable set of data that you actually need, and you create a clean directory with everhing else emoved. Then you aim the BBX_FileSystem at that and give it a test to make sure that nothing esenntial has been accidentally removed.

And now we use babyxfs_dirtoxml to serialise thec target directory, and write out a FileSystem XML file. Which we add to our program as a string resource using the Baby X resource compiler. ANd then weretarget the BBX_FileSystem at that string. And now our program should work in exactly the same way. But it no longer relies on external files. Everything is packaged within the exexcutable.

It's also a very robust solution. The files are packaged as a C string. They can be compiled anywhere there is A C compiler available. And all the text files are in plain text. If thete is a bug, you can inspect the file in the XML, and you can easily see if that is the problem. And the format is sufficiently robust that you can edit it in the source, though of course you will lose the changes when you need to regenerate the XML, so this should be cinsidered hacking rather than bug fixing. When you find the problem, you go back to the files on disk.

BabyXRC script to import the xml files

     
 <BabyXRC>
 <comment> This folder contains the poetry collection.</comment>
    <string src="myfolder.xml"></string>
 </BabyXRC>

 

testbabyxfilesystem

This program tests out the BBX_FileSystem, and ensures that the FileSystem XML and the system on disk and in sych and there are no problems. Here's the current main function.


     int main(int argc, char **argv)
     {
         BBX_FileSystem *bbx_fs_xml = 0;
         BBX_FileSystem *bbx_fs_stdio = 0;
         FILE *fp;
         FILE *fp_stdio = 0;
         FILE *fp_xml = 0;
         int ch;
         char *xmlstring;
         int err;
         unsigned char *data_xml;
         unsigned char *data_stdio;
         int N_xml;
         int N_stdio;
         int i;
         
         if (argc != 4)
         {
             usage();
         }
         
         fp = fopen(argv[2], "r");
         if (!fp)
         {
             fprintf(stderr, "Can't open xml file\n");
             exit(EXIT_FAILURE);
         }
         xmlstring = fslurp(fp);
         if (!xmlstring)
         {
             fprintf(stderr, "Out of memory\n");
             exit(EXIT_FAILURE);
         }
         fclose(fp);
         fp = 0;
         
         bbx_fs_stdio = bbx_filesystem();
         /* no need to check in Baby X, Baby X functions never return out of memory */
         /* Comment one of these in and out to toggle between filesystems */
         err = bbx_filesystem_set(bbx_fs_stdio, argv[1], BBX_FS_STDIO);
         if (err)
         {
             fprintf(stderr, "Can't set up stdio filessystem\n");
             exit(EXIT_FAILURE);
         }
         bbx_fs_xml = bbx_filesystem();
         err = bbx_filesystem_set(bbx_fs_xml, xmlstring, BBX_FS_STRING);
         if (err)
         {
             fprintf(stderr, "Can't set up XML filessystem\n");
             exit(EXIT_FAILURE);
         }
        
         if (!strcmp(argv[3], "-getname"))
         {
             printf("stdio filesystem name %s\n", bbx_filesystem_getname(bbx_fs_stdio));
             printf("xml filesystem name %s\n", bbx_filesystem_getname(bbx_fs_xml));
         }
         else
         {
             data_xml = bbx_filesystem_slurp(bbx_fs_xml, argv[3], "r", &N_xml);
             data_stdio = bbx_filesystem_slurp(bbx_fs_stdio, argv[3], "r", &N_stdio);
             if (!data_stdio)
                 fprintf(stderr, "Can't slurp target file on stdio system\n");
             if (!data_xml)
                 fprintf(stderr, "Can't slurp target file on xml system\n");
             if (N_xml != N_stdio)
                 fprintf(stderr, "N_xml %d N_stdio %d\n", N_xml, N_stdio);
             else
             {
                 for (i = 0; i < N_xml; i++)
                     if (data_stdio[i] != data_xml[i])
                         break;
                 if (i != N_xml)
                     fprintf(stderr, "xml and stdio data differ at byte %d\n", i);
             }
             free(data_xml);
             free(data_stdio);
             data_xml = 0;
             data_stdio = 0;
             
             fp_stdio = bbx_filesystem_fopen(bbx_fs_stdio, argv[3], "r");
             if (!fp_stdio)
             {
                 fprintf(stderr, "Can't open target file on stdio system\n");
                 exit(EXIT_FAILURE);
             }
             fp_xml = bbx_filesystem_fopen(bbx_fs_xml, argv[3], "r");
             if (!fp_xml)
             {
                 fprintf(stderr, "Can't open target file on xml system\n");
                 exit(EXIT_FAILURE);
             }
             if (!streamsidentical(fp_stdio, fp_xml))
             {
                 fprintf(stderr, "Files differ\n");
             }
             fseek(fp_xml, 0, SEEK_SET);
             while ( (ch = fgetc(fp_xml)) != EOF)
                 putchar(ch);
             err = bbx_filesystem_fclose(bbx_fs_stdio, fp_stdio);
             if (err)
                 fprintf(stderr, "Error closing stdio file\n");
             err = bbx_filesystem_fclose(bbx_fs_xml, fp_xml);
             if (err)
                 fprintf(stderr, "error closing xml file\n");
             
             
         }
         
         bbx_filesystem_kill(bbx_fs_stdio);
         bbx_filesystem_kill(bbx_fs_xml);
         free(xmlstring);
         
         return 0;
     }