/** * @function ferite_register_ns_class * @declaration FeriteClass *ferite_register_ns_class( FeriteScript *script, FeriteNamespace *ns, FeriteClass *classt ) * @brief Register the class within the namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace in which to reigster the class * @param FeriteClass *classt The class to register * @return It simply returns the class that has been registered */ FeriteClass *ferite_register_ns_class( FeriteScript *script, FeriteNamespace *ns, FeriteClass *classt ) { FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && classt != NULL ); ferite_register_namespace_element( script, ns, classt->name, FENS_CLS, classt ); FE_LEAVE_FUNCTION( classt ); }
uint32 Execute(const char* szExec, int(*callback)(void*, int, char**, char**), void* userData) { FE_ASSERT(IsDbLoaded, "Db not loaded !"); char *zErrMsg = 0; int rc = sqlite3_exec(SqlDb, szExec, callback, userData, &zErrMsg); if (rc != SQLITE_OK) { FE_ASSERT(false, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); return FeEReturnCode::Failed; } return FeEReturnCode::Success; }
/** * @function ferite_register_ns_variable * @declaration FeriteVariable *ferite_register_ns_variable( FeriteScript *script, FeriteNamespace *ns, FeriteVariable *var ) * @brief Register a variable within a namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace in which to register the variable * @param char *name The name in the namespace that will reference the variable * @param FeriteVariable *v The variable to register * @return It simply returns the variable that has been registered */ FeriteVariable *ferite_register_ns_variable( FeriteScript *script, FeriteNamespace *ns, char *name, FeriteVariable *var ) { FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && var != NULL ); FUD(("NS: Adding variable %p\n", var)); UNMARK_VARIABLE_AS_DISPOSABLE(var); ferite_register_namespace_element( script, ns, name, FENS_VAR, var ); FE_LEAVE_FUNCTION( var ); }
FeriteNamespaceBucket *ferite_register_namespace_element( FeriteScript *script, FeriteNamespace *ns, char *name, int type, void *data ) { FeriteNamespaceBucket *nsb = NULL; FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && name != NULL ); FE_ASSERT( type > 0 && data != NULL ); nsb = fmalloc( sizeof( FeriteNamespaceBucket ) ); nsb->type = type; nsb->data = data; if( type == FENS_VAR ) ferite_hash_add( script, ns->data_fork, name, nsb ); else ferite_hash_add( script, ns->code_fork, name, nsb ); FE_LEAVE_FUNCTION( nsb ); }
/** * @function ferite_namespace_element_exists * @declaration FeriteNamespaceBucket *ferite_namespace_element_exists( FeriteScript *script, FeriteNamespace *ns, char *name ) * @brief See if an element exists within the namespace (not recursive) * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace to look into * @param char *name The name of the element to look for * @return The FeriteNamespaceBucket for the name or NULL if it does not exist */ FeriteNamespaceBucket *ferite_namespace_element_exists( FeriteScript *script, FeriteNamespace *ns, char *name ) { FeriteNamespaceBucket *nsb = NULL; FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && name != NULL ); nsb = ferite_hash_get( script, ns->code_fork, name ); if( nsb == NULL ) nsb = ferite_hash_get( script, ns->data_fork, name ); FE_LEAVE_FUNCTION( nsb ); }
/** * @function ferite_raise_script_error * @declaration void ferite_raise_script_error( FeriteScript *script, int err, char *fmt, ... ) * @brief Raise an exception within the ferite engine. * @param FeriteScript *script The running script * @param int err The error code * @param char *fmt The format of the error string * @description Use the same formating codes as printf with this function */ void ferite_raise_script_error( FeriteScript *script, int err, char *fmt, ... ) { FeriteNamespaceBucket *nsb = NULL; FeriteVariable *global_error_object = NULL, *new_error_object = NULL, *backtrace = NULL; FeriteVariable *error_object_str = NULL, *error_object_num = NULL, *error_object_backtrace = NULL; FeriteBuffer *error_buffer = NULL; char *msg; va_list ap; FE_ENTER_FUNCTION; va_start( ap, fmt ); error_buffer = ferite_buffer_new(script, 0); ferite_buffer_vprintf( script, error_buffer, fmt, &ap ); msg = ferite_buffer_get( script, script->error, NULL ); FUD(("ERROR RAISED: %s %d\n", msg, err )); nsb = ferite_namespace_element_exists( script, script->mainns, "err" ); FE_ASSERT( nsb && nsb->type == FENS_VAR ); global_error_object = nsb->data; script->error_state = FE_ERROR_THROWN; if( VAO(global_error_object) == NULL ) { nsb = ferite_namespace_element_exists( script, script->mainns, "Error" ); if( nsb == NULL ) { FE_LEAVE_FUNCTION( NOWT ); exit(1); } new_error_object = ferite_new_object( script, nsb->data, NULL ); VAO(global_error_object) = VAO(new_error_object); FINCREF(VAO(global_error_object)); ferite_variable_destroy( script, new_error_object ); } error_object_str = ferite_object_get_var( script, VAO(global_error_object), "str" ); ferite_str_set( script, VAS(error_object_str), msg, strlen(msg), FE_CHARSET_DEFAULT ); ffree( msg ); error_object_num = ferite_object_get_var( script, VAO(global_error_object), "num" ); VAI(error_object_num) = err; backtrace = ferite_generate_backtrace( script, FE_FALSE ); error_object_backtrace = ferite_object_get_var( script, VAO(global_error_object), "backtrace"); ferite_variable_fast_assign( script, error_object_backtrace, backtrace ); ferite_buffer_delete( script, error_buffer ); FE_LEAVE_FUNCTION( NOWT ); }
/** * @function ferite_delete_namespace_element_from_namespace * @declaration int ferite_delete_namespace_element_from_namespace( FeriteScript *script, FeriteNamespace *ns, char *name ) * @brief Delete an element from the namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace to look into * @param char *name The name of the element to delete * @return FE_TRUE if an element is deleted, FE_FALSE otherwise */ int ferite_delete_namespace_element_from_namespace( FeriteScript *script, FeriteNamespace *ns, char *name ) { FeriteNamespaceBucket *nsb = NULL; FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && name != NULL ); nsb = ferite_namespace_element_exists( script, ns, name ); if( nsb != NULL ) { if( nsb->type == FENS_VAR ) ferite_hash_delete( script, ns->data_fork, name ); else ferite_hash_delete( script, ns->code_fork, name ); ferite_delete_namespace_element( script, nsb ); FE_LEAVE_FUNCTION(FE_TRUE); } FE_LEAVE_FUNCTION(FE_FALSE); }
/** * @function ferite_find_namespace * @declaration FeriteNamespaceBucket *ferite_find_namespace( FeriteScript *script, FeriteNamespace *parent, char *obj, int type ) * @brief Recusively look in a namespace for an element * @param FeriteScript *script The script * @param FeriteNamespace *parent The namespace to look in * @param char *obj The name to locate * @param int type The type to look for * @return The namespace bucket if it is found otherwise NULL * @description The type dictates what is returned. No type is specified (0) then if any element is * found then it will be returned. If a type is specified then it is checked to see if * the bucket is of the correct type, if so it is returned, if not NULL is returned.<nl/> * <nl/> * The types are FENS_VAR, FENS_FNC, FENS_CLS, or FENS_NS. */ FeriteNamespaceBucket *ferite_find_namespace( FeriteScript *script, FeriteNamespace *parent, char *obj, int type ) { FeriteNamespaceBucket *nsb = NULL; char *buf; int i = 0; FE_ENTER_FUNCTION; FE_ASSERT( parent != NULL && obj != NULL ); if( ferite_find_string( obj, "." ) == -1 ) { /* we need not split the string up */ nsb = ferite_namespace_element_exists( script, parent, obj ); if( type > 0 ) { if( nsb == NULL || nsb->type != type ) { FE_LEAVE_FUNCTION( NULL ); } } FE_LEAVE_FUNCTION( nsb ); } else { /* we need to split the string up */ buf = memset( fmalloc( strlen(obj)+1 ), '\0', strlen(obj) ); for( i = 0; obj[i] != '.'; i++ ); strncpy( buf, obj, i ); nsb = ferite_namespace_element_exists( script, parent, buf ); ffree( buf ); if( nsb == NULL || nsb->type != FENS_NS ) { FE_LEAVE_FUNCTION( NULL ); } if( type == FENS_PARENT_NS && ferite_find_string( obj+i+1, "." ) == -1 ) { FE_LEAVE_FUNCTION( nsb ); } FE_LEAVE_FUNCTION( ferite_find_namespace( script, nsb->data, obj+i+1, type ) ); } FE_LEAVE_FUNCTION( NULL ); }
/** * @function ferite_set_error * @declaration void ferite_set_error( FeriteScript *script, int num, char *fmt, ... ) * @brief Same as ferite_error except this wont raise an exception at runtime */ void ferite_set_error( FeriteScript *script, int num, char *fmt, ... ) { FeriteNamespaceBucket *nsb = NULL; FeriteVariable *global_error_object = NULL, *new_error_object = NULL; FeriteVariable *errstr = NULL, *erno = NULL; va_list ap; char *buf = NULL; FE_ENTER_FUNCTION; if( !script->is_being_deleted && (script->parent == NULL || !script->parent->is_being_deleted) ) { buf = fmalloc( 4096 ); va_start( ap, fmt ); vsprintf( buf, fmt, ap ); nsb = ferite_namespace_element_exists( script, script->mainns, "err" ); FE_ASSERT( nsb && nsb->type == FENS_VAR ); global_error_object = nsb->data; if( VAO(global_error_object) == NULL ) { nsb = ferite_namespace_element_exists( script, script->mainns, "Error" ); new_error_object = ferite_new_object( script, nsb->data, NULL ); VAO(global_error_object) = VAO(new_error_object); FINCREF(VAO(global_error_object)); ferite_variable_destroy( script, new_error_object ); } errstr = ferite_object_get_var( script, VAO(global_error_object), "str" ); ferite_str_set( script, VAS(errstr), buf, strlen(buf), FE_CHARSET_DEFAULT ); erno = ferite_object_get_var( script, VAO(global_error_object), "num" ); VAI(erno) = num; ffree( buf ); va_end( ap ); } FE_LEAVE_FUNCTION( NOWT ); }
/** * @function ferite_namespace_dup * @declaration FeriteNamespace *ferite_namespace_dup( FeriteScript *script, FeriteNamespace *ns, FeriteNamespace *container ) * @brief Duplicate a namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace to duplicate * @param FeriteNamespace *container The container of the new namespace * @return The new namespace */ FeriteNamespace *ferite_namespace_dup( FeriteScript *script, FeriteNamespace *ns, FeriteNamespace *container ) { FeriteNamespace *ptr = NULL; FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL ); ptr = fmalloc(sizeof(FeriteNamespace)); ptr->num = ns->num; ptr->data_fork = ferite_hash_dup( script, ns->data_fork, (void *(*)(FeriteScript *,void *,void*))ferite_namespace_bucket_dup, ptr ); /* Use the same code fork reference */ ptr->code_fork = ns->code_fork; ptr->code_fork_ref = ns->code_fork_ref; *(ptr->code_fork_ref) += 1; ptr->container = container; if( ns->name != NULL ) ptr->name = fstrdup( ns->name ); else ptr->name = NULL; FE_LEAVE_FUNCTION(ptr); }
/** * @function ferite_delete_namespace * @declaration int ferite_delete_namespace( FeriteScript *script, FeriteNamespace *ns ) * @brief Completely free up all elements within the namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace to delete * @return Always 1 */ int ferite_delete_namespace( FeriteScript *script, FeriteNamespace *ns ) { FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL ); FUD(("Deleting namespace contents: %s (%s) [%p]\n", ferite_generate_namespace_fqn( script, ns ), ns->name, ns)); ferite_delete_hash( script, ns->data_fork, (void (*)(FeriteScript*,void *))ferite_delete_namespace_element ); /* Only delete the code fork if the ref count goes to zero */ *(ns->code_fork_ref) -= 1; if( *(ns->code_fork_ref) == 0 ) { ferite_delete_hash( script, ns->code_fork, (void (*)(FeriteScript*,void *))ferite_delete_namespace_element ); ffree( ns->code_fork_ref ); } if( ns->name != NULL ) ffree( ns->name ); ffree( ns ); FE_LEAVE_FUNCTION( 1 ); }
FeriteNamespaceBucket *ferite_namespace_bucket_dup( FeriteScript *script, FeriteNamespaceBucket *nsb, FeriteNamespace *parent ) { FeriteNamespaceBucket *ptr = NULL; FeriteClass *klass = NULL, *klass_dup = NULL; //FeriteStack *stack = script->odata; FE_ENTER_FUNCTION; FE_ASSERT( nsb != NULL ); ptr = fmalloc(sizeof(FeriteNamespaceBucket)); ptr->type = nsb->type; switch( nsb->type ) { /*REMOVE case FENS_NS: ptr->data = ferite_namespace_dup( script, nsb->data, parent ); break; */ case FENS_VAR: ptr->data = ferite_duplicate_variable( script, nsb->data, NULL ); break; /*REMOVE case FENS_FNC: ptr->data = ferite_function_dup( script, nsb->data, NULL ); break; */ case FENS_CLS: ptr->data = ferite_class_dup( script, nsb->data, parent ); /*REMOVE klass = ptr->data; klass_dup = nsb->data; if( klass_dup->parent != NULL ) { klass->parent = (void *)ferite_class_full_name( script, klass_dup->parent ); ferite_stack_push( stack, klass ); }*/ break; default: ferite_warning( script, "Trying to duplicate element of type '%d' from a namespace - Unknown Type", nsb->type ); } FE_LEAVE_FUNCTION(ptr); }
/** * @function ferite_rename_namespace_element * @declaration int ferite_rename_namespace_element( FeriteScript *script, FeriteNamespace *ns, char *from, char *to ) * @brief Delete an element from the namespace * @param FeriteScript *script The script * @param FeriteNamespace *ns The namespace to look into * @param char *from The name of the element to rename * @param char *to The name to rename to * @return FE_TRUE if an element is deleted, FE_FALSE otherwise */ int ferite_rename_namespace_element( FeriteScript *script, FeriteNamespace *ns, char *from, char *to ) { FeriteNamespaceBucket *nsb = NULL; FE_ENTER_FUNCTION; FE_ASSERT( ns != NULL && from != NULL ); nsb = ferite_hash_get( script, ns->data_fork, from ); if( nsb != NULL ) { ferite_hash_delete( script, ns->data_fork, from ); ferite_hash_add( script, ns->data_fork, to, nsb ); FE_LEAVE_FUNCTION(1); } else { nsb = ferite_hash_get( script, ns->code_fork, from ); if( nsb != NULL ) { switch( nsb->type ) { case FENS_FNC: ffree( ((FeriteFunction*)nsb->data)->name ); ((FeriteFunction*)nsb->data)->name = fstrdup(to); break; case FENS_CLS: ffree( ((FeriteClass*)nsb->data)->name ); ((FeriteClass*)nsb->data)->name = fstrdup(to); break; } ferite_hash_delete( script, ns->code_fork, from ); ferite_hash_add( script, ns->code_fork, to, nsb ); FE_LEAVE_FUNCTION(1); } } FE_LEAVE_FUNCTION(0); }