current stable:
0.99.6
unstable:
cvs (0.99.7)
General
  Home / News
  About
  Contact
  The Team

Obtaining
  Download
  Source Tarball
  CVS Web View
  Misc. Files

Documentation
  Introduction
The Manual
  Download [html]
  Download [pdf]
  View Online
API
  Download [html]
  View Online
Resources
  Script Examples

Developer
  Introduction
Developer Guide
  Download [html]
  Download [pdf]
  View Online
Ferite C API
  Download [html]
  View Online




Open Source Approved

SourceForge Logo
KwMap.net - browse the Keyword Map of ferite.org

[previous] The Rest[up][toc]Fake Native Modules [next]


Chapter 6. Embedding Ferite

This chapter is split into three sections. The first deals with getting the engine up and running within your application so that scripts can be executed. The second section deals with the most effcient way of exporting the application's interface into a script so that useful things can then be done. The third is how to cheat with builder and applications.

Getting The Engine Purring

Ferite is designed to be placed in pretty much anywhere. Therefore it is pretty easy to get the engine up and running, scripts compiled and then executed, and to clean everything up afterwards. To explain how to do this, an example is listed below and afterwards each line is discussed. It is a simple program that shows most of the functionality of the ferite command line program.

    #include <stdio.h>
    #include <stdlib.h>
    #include <ferite.h>
                
    int main( int argc, char **argv )
    {
        FeriteScript *script;
        char *errmsg = NULL, *scriptfile = "test.fe";
    
        if( ferite_init( 0, NULL ) )
        {
            ferite_add_library_search_path( LIBRARY_DIR );
            ferite_set_library_native_path( NATIVE_LIBRARY_DIR );
    	
            script = ferite_script_compile( scriptfile );
            if( ferite_has_compile_error( script ) )
            {
                errmsg = ferite_get_error_log( script );
                fprintf( stderr, "[ferite: compile]\n%s", errmsg );
            }
            else
            {
                ferite_script_execute( script );
                if( ferite_has_runtime_error( script ) )
                {
                    errmsg = ferite_get_error_log( script );
                    fprintf( stderr, "[ferite: execution]\n%s", errmsg );
                }
            }
            if( errmsg )
              ffree( errmsg );
            ferite_script_delete( script );
            ferite_deinit( );
        }
        exit( 0 );
    }
    			

And now, the explanation. It should be noted that only the lines that are critical to the operation of ferite will be dicussed, anything that is standard C will be left out.

    #include <stdio.h>
    #include <stdlib.h>
    #include <ferite.h>
                            

The above is all pretty standard issue. You dont need the stdio.h or stdlib.h headers to be honest. But with any program they are good practice. The one you do need is ferite.h. This will pull all the function prototypes and defines into the program so that the magic may begin.

    if( ferite_init( 0, NULL ) )
                            

This line initialises the engine. You must do this before you do anything ferite related. This is because this call will initialise the ferite memory system, the module system, the regex engine and potentially more things. If you dont call this then what happens is all your own fault. You may call this multiple times and it wont cause issues. It takes two arguments, the first is the number of arguments, the second is an array of strings. This is how options are passed into the engine. For a full list look at the command line program's help option.

    ferite_add_library_search_path( LIBRARY_DIR );
    ferite_set_library_native_path( NATIVE_LIBRARY_DIR );
                            

Ferite does what it is told. One of the things that makes it very useful is the ability to control what modules are availible to be loaded. You can obtain the system wide defaults using the ferite-config shell script. If you do not call these then the ferite engine will be unable to load any modules and will only have the api that the application exports. This is useful for both controlling what the scripters can do and stoping people loading rogue modules into the system.

    script = ferite_script_compile( scriptfile );
                            

This line will compile the script that is in the file in the scriptfile variable. It will always return a script object. The return will either contain the error information or will be an executable script. It is also possible to compile a string into script. For this you call ferite_compile_string, it takes one argument which is the script to compile. There are also two more functions, ferite_script_compile_with_path and ferite_compile_string_with_path, they both take the same arguments as their respective counterparts, with the exception of an added argument. This is a null terminated array of search paths to add to the module system for the duration of the compilation. For more in depth information about these two functions please refer to the C api.

    if( ferite_has_compile_error( script ) )
    {
    	errmsg = ferite_get_error_log( script );
    	fprintf( stderr, "[ferite: compile]\n%s", errmsg );
    }
    			

This is how we check that everything is working. Or not. ferite_has_compile_error will return true if there was a compile error and false if not. If there is an error, the script will not be executable but you will be able to get the error logs from the script as shown above. You will need to, when finished, delete the script - this is dicussed later. You will also need to free the string returned using ffree.

    ferite_script_execute( script );
    			

Well, if you have got this far you will be wanting to run the script. This is easy. You simply pass it to ferite_script_execute which will execute the script. The return value is the return value from the script's main function. To find out whether a runtime error occured you will need to use the code below. NOTE: you can run scripts multiple times but it is not recommended, as the state of the script can not be guaranteed. The way to run a script multiple times is to use ferite_duplicate_script and execute each duplicate - for more information please see the C api.

    if( ferite_has_runtime_error( script ) )
    {
    	errmsg = ferite_get_error_log( script );
    	fprintf( stderr, "[ferite: execution]\n%s", errmsg );
    }
    			

ferite_has_runtime_error will return true if there has been a runtime error on the script. To get the messages about the error you will need to use ferite_get_error_log. This will return the error log as a C string. You will need to free the string returned with ffree.

    if( errmsg )
    	ffree( errmsg );
    			

Remember to free things!

    ferite_script_delete( script );
    			

Once you have finished with your script object you must delete it. Once again this is a simple and straight forward call to ferite_script_delete.

    ferite_deinit( );
    			

It's been a long day, you've been running scripts and it's now time to pack your bags and go home. There is one last thing to be done - tell ferite to deinitialise. This is done doing ferite_deinit. This will cause all allocated memory via fmalloc/fcalloc/frealloc to be deallocated, shutdown the module system and anything else that needs to be done. Once this has been called you can re-initialise the system with ferite_init and start all over again.

So there you have it. Thats how easy it is to get things up and running. It is suggest that you have a look at the command line program in the ferite distribution for more options availible or a more concrete example.



[previous] The Rest[up][toc]Fake Native Modules [next]
ferite et al © 2000-2004, Chris Ross