Merge pull request #2916 from felixjones/master
[mruby.git] / include / mruby.h
index e5d19b1..0db9002 100644 (file)
 #ifndef MRUBY_H
 #define MRUBY_H
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
 #include <stdint.h>
 #include <stddef.h>
 #include <limits.h>
 
 #include "mrbconf.h"
+#include "mruby/common.h"
 #include "mruby/value.h"
 #include "mruby/version.h"
 
+/**
+ * MRuby C API entry point
+ */
+MRB_BEGIN_DECL
+
 typedef uint32_t mrb_code;
+
+/**
+ * Required arguments signature type.
+ */
 typedef uint32_t mrb_aspec;
 
+
 struct mrb_irep;
 struct mrb_state;
 
+/**
+ * Function pointer type of custom allocator used in @see mrb_open_allocf.
+ *
+ * The function pointing it must behave similarly as realloc except:
+ * - If ptr is NULL it must allocate new space.
+ * - If s is NULL, ptr must be freed.
+ *
+ * See @see mrb_default_allocf for the default implementation.
+ */
 typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
 
 #ifndef MRB_GC_ARENA_SIZE
@@ -188,34 +204,170 @@ typedef struct mrb_state {
   mrb_int atexit_stack_len;
 } mrb_state;
 
-#if __STDC_VERSION__ >= 201112L
-# define mrb_noreturn _Noreturn
-#elif defined __GNUC__ && !defined __STRICT_ANSI__
-# define mrb_noreturn __attribute__((noreturn))
-# define mrb_deprecated __attribute__((deprecated))
-#elif defined _MSC_VER
-# define mrb_noreturn __declspec(noreturn)
-# define mrb_deprecated __declspec(deprecated)
-#else
-# define mrb_noreturn
-# define mrb_deprecated
-#endif
 
 typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
-MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*);
+
+/**
+ * Defines a new class.
+ *
+ * If you're creating a gem it may look something like this:
+ *
+ *      !!!c
+ *      void mrb_example_gem_init(mrb_state* mrb) {
+ *              struct RClass *example_class;
+ *              example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class);
+ *      }
+ *
+ *      void mrb_example_gem_final(mrb_state* mrb) {
+ *              //free(TheAnimals);
+ *      }
+ *
+ * @param mrb The current mruby state.
+ * @param name The name of the defined class
+ * @param super The new class parent
+ * @return Reference to the newly defined class
+ * @see mrb_define_class_under
+ */
+MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super);
+
+/**
+ * Defines a new module.
+ * @param mrb_state* The current mruby state.
+ * @param char* The name of the module.
+ * @return Reference to the newly defined module.
+ */
 MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
 MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
+
+/**
+ * Include a module in another class or module.
+ * Equivalent to: 
+ *
+ *   module B                                                                                                         *
+ *     include A                                                                                                      *
+ *   end 
+ * @param mrb_state* The current mruby state.
+ * @param RClass* A reference to module or a class.
+ * @param RClass* A reference to the module to be included.
+ */
 MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
 
-MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
+/**
+ * Prepends a module in another class or module.
+ * Equivalent to:
+ *  module B
+ *    prepend A
+ *  end
+ * @param mrb_state* The current mruby state.
+ * @param RClass* A reference to module or a class.
+ * @param RClass* A reference to the module to be prepended.
+ */ 
+MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
+
+/**
+ * Defines a global function in ruby.
+ *
+ * If you're creating a gem it may look something like this:
+ *
+ *     !!!c
+ *     mrb_value example_method(mrb_state* mrb, mrb_value self)
+ *     {
+ *          puts("Executing example command!");
+ *          return self;
+ *     }
+ *
+ *     void mrb_example_gem_init(mrb_state* mrb)
+ *     {
+ *           mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE());
+ *     }
+ *
+ * @param mrb The MRuby state reference.
+ * @param cla The class pointer where the method will be defined.
+ * @param func The function pointer to the method definition.
+ * @param aspec The method parameters declaration.
+ */
+MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
+
+/**
+ * Defines a class method.
+ *   # Ruby style
+ *   class Foo
+ *     def Foo.bar
+ *     end
+ *   end
+ *   // C style
+ *   mrb_value bar_method(mrb_state* mrb, mrb_value self){
+ *     return mrb_nil_value();
+ *   }
+ *   void mrb_example_gem_init(mrb_state* mrb){
+ *     struct RClass *foo;
+ *     foo = mrb_define_class(mrb, "Foo", mrb->object_class);
+ *     mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE()); 
+ *   }
+ * @param mrb_state* The MRuby state reference. 
+ * @param RClass* The class where the class method will be defined.
+ * @param char* The name of the class method.
+ * @param mrb_func_t The function pointer to the class method definition.
+ * @param mrb_aspec The method parameters declaration.
+ */
 MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
 MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec);
+
+/**
+ *  Defines a module fuction.
+ *   # Ruby style
+ *   module Foo                                                                                                     
+ *     def Foo.bar                                                                                                    *     end
+ *   end                                                                                                             
+ *   // C style                                                                                                      
+ *   mrb_value bar_method(mrb_state* mrb, mrb_value self){                                                           
+ *     return mrb_nil_value();                                                                                                      
+ *   }                                                                                                               
+ *   void mrb_example_gem_init(mrb_state* mrb){                                                                      
+ *     struct RClass *foo;                                                                                           
+ *     foo = mrb_define_module(mrb, "Foo");                                                        
+ *     mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
+ *   }    
+ *  @param mrb_state* The MRuby state reference.
+ *  @param RClass* The module where the module function will be defined.
+ *  @param char* The name of the module function.
+ *  @param mrb_func_t The function pointer to the module function definition. 
+ *  @param mrb_aspec The method parameters declaration.
+ */
 MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
+
+/**
+ *  Defines a constant.
+ *    # Ruby style
+ *    AGE = 22
+ *    // C style
+ *    mrb_define_const(mrb, mrb->kernel_module, "AGE", mrb_fixnum_value(22));
+ *  @param mrb_state* The MRuby state reference.
+ *  @param RClass* A class or module the constant is defined in.
+ *  @param name The name of the constant.
+ *  @param mrb_value The value for the constant.
+ */
 MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
 MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*);
 MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
+
+/**
+ * Initialize a new object instace of c class.
+ *
+ * @param mrb The current mruby state.
+ * @param c Reference to the class of the new object.
+ * @param argc Number of arguments in argv
+ * @param argv Array of mrb_value to initialize the object
+ * @return The newly initialized object
+ */
 MRB_API mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv);
-#define mrb_class_new_instance(mrb,argc,argv,c) mrb_obj_new(mrb,c,argc,argv)
+
+/** @see mrb_obj_new */
+MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const mrb_value *argv, struct RClass *c)
+{
+  return mrb_obj_new(mrb,c,argc,argv);
+}
+
 MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
 MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
 MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
@@ -229,31 +381,110 @@ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value);
 MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
 MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
 MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid);
+
+/**
+ * Defines a new class under a given module
+ *
+ * @param mrb The current mruby state.
+ * @param outer Reference to the module under which the new class will be defined
+ * @param name The name of the defined class
+ * @param super The new class parent
+ * @return Reference to the newly defined class
+ * @see mrb_define_class
+ */
 MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
+
 MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
 
-/* required arguments */
+/**
+ * Function requires n arguments.
+ *
+ * @param n
+ *      The number of required arguments.
+ */
 #define MRB_ARGS_REQ(n)     ((mrb_aspec)((n)&0x1f) << 18)
-/* optional arguments */
+
+/**
+ * Funtion takes n optional arguments
+ *
+ * @param n
+ *      The number of optional arguments.
+ */
 #define MRB_ARGS_OPT(n)     ((mrb_aspec)((n)&0x1f) << 13)
-/* mandatory and optinal arguments */
+
+/**
+ * Funtion takes n1 mandatory arguments and n2 optional arguments
+ *
+ * @param n1
+ *      The number of required arguments.
+ * @param n2
+ *      The number of optional arguments.
+ */
 #define MRB_ARGS_ARG(n1,n2)   (MRB_ARGS_REQ(n1)|MRB_ARGS_OPT(n2))
 
-/* rest argument */
+/** rest argument */
 #define MRB_ARGS_REST()     ((mrb_aspec)(1 << 12))
-/* required arguments after rest */
+
+/** required arguments after rest */
 #define MRB_ARGS_POST(n)    ((mrb_aspec)((n)&0x1f) << 7)
-/* keyword arguments (n of keys, kdict) */
+
+/** keyword arguments (n of keys, kdict) */
 #define MRB_ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 2) | ((n2)?(1<<1):0)))
-/* block argument */
+
+/**
+ * Function takes a block argument
+ */
 #define MRB_ARGS_BLOCK()    ((mrb_aspec)1)
 
-/* accept any number of arguments */
+/**
+ * Function accepts any number of arguments
+ */
 #define MRB_ARGS_ANY()      MRB_ARGS_REST()
-/* accept no arguments */
+
+/**
+ * Function accepts no arguments
+ */
 #define MRB_ARGS_NONE()     ((mrb_aspec)0)
 
-MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...);
+/**
+ * Format specifiers for \ref mrb_get_args function
+ *
+ * Must be a list of following format specifiers:
+ *
+ * | char | mruby type     | retrieve types      |note                                                |
+ * |:----:|----------------|---------------------|----------------------------------------------------|
+ * | o    | Object         | mrb_value           | Could be used to retrieve any type of argument     |
+ * | C    | Class/Module   | mrb_value           |                                                    |
+ * | S    | String         | mrb_value           | when ! follows, the value may be nil               |
+ * | A    | Array          | mrb_value           | when ! follows, the value may be nil               |
+ * | H    | Hash           | mrb_value           | when ! follows, the value may be nil               |
+ * | s    | String         | char *, mrb_int      |  Receive two arguments; s! gives (NULL,0) for nil  |
+ * | z    | String         | char *               | NUL terminated string; z! gives NULL for nil       |
+ * | a    | Array          | mrb_value *, mrb_int | Receive two arguments; a! gives (NULL,0) for nil   |
+ * | f    | Float          | mrb_float           |                                                    |
+ * | i    | Integer        | mrb_int             |                                                    |
+ * | b    | boolean        | mrb_bool            |                                                    |
+ * | n    | Symbol         | mrb_sym             |                                                    |
+ * | &    | block          | mrb_value           |                                                    |
+ * | *    | rest arguments | mrb_value *, mrb_int | Receive the rest of arguments as an array.         |
+ * | \|   | optional       |                     | After this spec following specs would be optional. |
+ * | ?    | optional given | mrb_bool            | True if preceding argument is given. Used to check optional argument is given. |
+ */
+typedef const char *mrb_args_format;
+
+/**
+ * Retrieve arguments from mrb_state.
+ *
+ * When applicable, implicit conversions (such as to_str, to_ary, to_hash) are
+ * applied to received arguments.
+ * Use it inside a function pointed by mrb_func_t.
+ *
+ * @param mrb The current MRuby state.
+ * @param format is a list of format specifiers see @ref mrb_args_format
+ * @param ... The passing variadic arguments must be a pointer of retrieving type.
+ * @return the number of arguments retrieved.
+ */
+MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
 
 static inline mrb_sym
 mrb_get_mid(mrb_state *mrb) /* get method symbol */
@@ -275,6 +506,9 @@ mrb_get_argc(mrb_state *mrb) /* get argc */
 */
 #define mrb_strlen_lit(lit) (sizeof(lit "") - 1)
 
+/**
+ * Call existing ruby functions.
+ */
 MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
 MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*);
 MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value);
@@ -299,15 +533,74 @@ MRB_API struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*)
 MRB_API void mrb_free(mrb_state*, void*);
 
 MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len);
+
+/**
+ * Turns a C string into a Ruby string value.
+ */
 MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
 MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
 #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
 
+#ifdef _WIN32
+char* mrb_utf8_from_locale(const char *p, size_t len);
+char* mrb_locale_from_utf8(const char *p, size_t len);
+#define mrb_locale_free(p) free(p)
+#define mrb_utf8_free(p) free(p)
+#else
+#define mrb_utf8_from_locale(p, l) (p)
+#define mrb_locale_from_utf8(p, l) (p)
+#define mrb_locale_free(p)
+#define mrb_utf8_free(p)
+#endif
+
+/**
+ * Creates new mrb_state.
+ *
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
 MRB_API mrb_state* mrb_open(void);
-MRB_API mrb_state* mrb_open_allocf(mrb_allocf, void *ud);
-MRB_API mrb_state* mrb_open_core(mrb_allocf, void *ud);
-MRB_API void mrb_close(mrb_state*);
 
+/**
+ * Create new mrb_state with custom allocators.
+ *
+ * @param f
+ *      Reference to the allocation function.
+ * @param ud
+ *      User data will be passed to custom allocator f.
+ *      If user data isn't required just pass NULL.
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
+MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud);
+
+/**
+ * Create new mrb_state with just the MRuby core
+ *
+ * @param f
+ *      Reference to the allocation function.
+ *      Use mrb_default_allocf for the default
+ * @param ud
+ *      User data will be passed to custom allocator f.
+ *      If user data isn't required just pass NULL.
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
+MRB_API mrb_state* mrb_open_core(mrb_allocf f, void *ud);
+
+/**
+ * Closes and frees a mrb_state.
+ *
+ * @param mrb
+ *      Pointer to the mrb_state to be closed.
+ */
+MRB_API void mrb_close(mrb_state *mrb);
+
+/**
+ * The default allocation function.
+ *
+ * @ref mrb_allocf
+ */
 MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
 
 MRB_API mrb_value mrb_top_self(mrb_state *);
@@ -407,7 +700,13 @@ MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg);
 MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv);
 MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c);
 
+/* mrb_gc_protect() leaves the object in the arena */
 MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
+/* mrb_gc_register() keeps the object from GC. */
+MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
+/* mrb_gc_unregister() removes the object from GC root. */
+MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
+
 MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
 #define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
 MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
@@ -464,8 +763,6 @@ MRB_API void mrb_show_copyright(mrb_state *mrb);
 
 MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
 
-#if defined(__cplusplus)
-}  /* extern "C" { */
-#endif
+MRB_END_DECL
 
 #endif  /* MRUBY_H */