void output_printf( int type, char *format, ... ) { va_list arguments; va_start( arguments, format ); if( output_closure ) { char *msg = NULL; FeriteBuffer *output_buffer = NULL; FeriteVariable **params = NULL; FeriteFunction *function = ferite_object_get_function( output_script, output_closure, "invoke" ); FeriteVariable *return_value = NULL; output_buffer = ferite_buffer_new(output_script, 0); ferite_buffer_vprintf( output_script, output_buffer, format, &arguments ); msg = ferite_buffer_get( output_script, output_buffer, NULL ); params = ferite_create_parameter_list_from_data( output_script, "lc", type, msg, NULL ); return_value = ferite_call_function( output_script, output_closure, NULL, function, params ); if( return_value ) { ferite_variable_destroy( output_script, return_value ); } ferite_delete_parameter_list( output_script, params ); ferite_buffer_delete(output_script, output_buffer); ffree_ngc(msg); } else { vprintf(format, arguments); printf("\n"); } va_end(arguments); }
/** * @function ferite_get_warning_string * @declaration char *ferite_get_warning_string( FeriteScript *script ) * @brief Get a null terminated string containing the warning log * @param FeriteScript *script The script whose warnings are required * @return A null terminated string, you will need to ffree the string when done to prevent memory leak */ char *ferite_get_warning_string( FeriteScript *script ) { char *msg; FE_ENTER_FUNCTION; if( script->warning ) msg = ferite_buffer_get( script, script->warning, NULL ); else msg = fstrdup(""); FE_LEAVE_FUNCTION( msg ); }
/** * @function ferite_get_error_log * @declaration char *ferite_get_error_log( FeriteScript *script ) * @brief Get a null terminated string containing the error and warning logs on a script * @param FeriteScript *script The script to get the errror logs from * @return A null terminated string, you will need to ffree the string when done to prevent memory leak */ char *ferite_get_error_log( FeriteScript *script ) { int err_size = 0, warn_size = 0; char *msg, *err_ptr, *warn_ptr; FE_ENTER_FUNCTION; if( script->error ) err_ptr = ferite_buffer_get( script, script->error, &err_size ); else err_ptr = fstrdup(""); if( script->warning ) warn_ptr = ferite_buffer_get( script, script->warning, &warn_size ); else warn_ptr = fstrdup(""); msg = fmalloc( err_size + warn_size + 1 ); strcpy( msg, warn_ptr ); strcat( msg, err_ptr ); ffree( err_ptr ); ffree( warn_ptr ); FE_LEAVE_FUNCTION( msg ); }
/** * @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_verror * @declaration void ferite_verror( FeriteScript *script, char *errormsg, va_list *ap ) * @brief Raise an error * @param FeriteScript *script The script * @param int err The error number associated with the error * @param char *errormsg The error with formating codes in it * @param va_list *ap The list of arguments */ void ferite_verror( FeriteScript *script, int err, char *errormsg, va_list *ap ) { char *real_errormsg = fstrdup(errormsg); int length = strlen(real_errormsg); FE_ENTER_FUNCTION; if( real_errormsg[length - 1] == '\n' ) { real_errormsg[length - 1] = '\0'; } if( script == NULL ) { vprintf(real_errormsg, *ap ); printf("\n"); ffree( real_errormsg ); FE_LEAVE_FUNCTION( NOWT ); } if( script->error == NULL ) script->error = ferite_buffer_new( script, 0 ); ferite_buffer_add_str( script, script->error, "Error: " ); ferite_buffer_vprintf( script, script->error, real_errormsg, ap ); ferite_buffer_add_str( script, script->error, "\n" ); if( script->error_state != FE_ERROR_THROWN ) { if( ferite_is_executing( script ) ) { int len = 0, sub_length = strlen("Error: "); char *ptr = ferite_buffer_get( script, script->error, &len ); char *real_ptr = ferite_replace_string( ptr, "%", "%%" ); char *msg = fmalloc(len + 1); memcpy( msg, real_ptr + sub_length, len - sub_length ); ferite_raise_script_error( script, err, msg ); ffree( msg ); ffree( ptr ); ffree( real_ptr ); } script->error_state = FE_ERROR_THROWN; } ffree( real_errormsg ); FE_LEAVE_FUNCTION( NOWT ); }