nitdoc: escape html chars in documentation
[nit.git] / clib / nit_main.c
index 3661cf8..630847f 100644 (file)
 #include "nit_common.h"
 #include <signal.h>
 #include <stdarg.h>
+#include "gc.h"
+
 bigint object_id_counter = 1000000;
+enum gc_option { large, gc_opt_malloc, boehm, nitgc } gc_option;
 
 #ifdef WITH_LIBGC
 #define GC_DEBUG
 #include <gc/gc.h>
-int nolibgc = 0;
-void *simple_alloc(size_t s0);
-void *alloc(size_t s0)
+#endif
+
+void *raw_alloc(size_t s0)
 {
-       if (!nolibgc) { return GC_MALLOC(s0); }
-       else return simple_alloc(s0);
+       switch (gc_option) {
+       case nitgc: return malloc(s0);
+       case gc_opt_malloc: return malloc(s0);
+       default: return alloc(s0);
+       }
 }
-#define alloc simple_alloc
-#endif
 
-void * alloc(size_t s0)
+void register_static_object(val_t *o)
+{
+       switch (gc_option) {
+       case nitgc: GC_add_static_object(o); break;
+       default: break;
+       }
+       return;
+}
+
+void *large_alloc(size_t s0)
 {
        static char * alloc_pos = NULL;
        static size_t alloc_size = 0;
@@ -45,6 +58,19 @@ void * alloc(size_t s0)
        return res;
 }
 
+void * alloc(size_t s0)
+{
+       switch (gc_option) {
+#ifdef WITH_LIBGC
+       case boehm: return GC_MALLOC(s0);
+#endif
+       case nitgc: return Nit_gc_malloc(s0);
+       case gc_opt_malloc: return calloc(1, s0);
+       case large:
+       default: return large_alloc(s0);
+       }
+}
+
 int glob_argc;
 char **glob_argv;
 val_t G_sys;
@@ -53,13 +79,56 @@ void exithandler(int s) {
        fprintf(stderr, "Recieved signal %d\n", s);
        nit_exit(1);
 }
-void prepare_signals(void) {
-#if WITH_LIBGC
-       nolibgc = (getenv("NIT_NOLIBGC") != NULL);
-       if (!nolibgc) {
-               GC_INIT();
+void initialize_gc_option(void) {
+       /* GC default */
+       char *def;
+#ifdef WITH_LIBGC
+       gc_option = boehm;
+       def = "boehm";
+#else
+       gc_option = nitgc;
+       def = "nitgc";
+#endif
+
+       /* Process GC runtime selection */
+       if (getenv("NIT_GC_OPTION") != NULL) {
+               char *opt=getenv("NIT_GC_OPTION");
+               if (strcmp(opt, "boehm")==0) {
+#ifdef WITH_LIBGC
+                       gc_option = boehm;
+#else
+               fprintf(stderr, "Compiled without Boehm GC support. Using default '%s'.\n", def);
+#endif
+               } else if (strcmp(opt, "nitgc")==0) {
+                       gc_option = nitgc;
+               } else if (strcmp(opt, "malloc")==0) {
+                       gc_option = gc_opt_malloc;
+               } else if (strcmp(opt, "large")==0) {
+                       gc_option = large;
+               } else if (strcmp(opt, "help")==0) {
+                       fprintf(stderr, "NIT_GC_OPTION accepts 'nitgc'"
+#ifdef WITH_LIBGC
+                                       ", 'boehm'"
+#endif
+                                       ", 'large', 'malloc'. Default is '%s'.\n", def);
+                       exit(1);
+               } else {
+                       fprintf(stderr, "Invalid GC option in NIT_GC_OPTION environment variable. Using default '%s'.\n", def);
+               }
        }
+
+       /* Initialize GC (if needed) */
+       switch(gc_option) {
+#ifdef WITH_LIBGC
+               case boehm: GC_INIT(); break;
 #endif
+               case nitgc: Nit_gc_init(); break;
+               default: break; /* Nothing */
+       }
+}
+void prepare_signals(void) {
+       initialize_gc_option();
+
        signal(SIGINT,exithandler);
        signal(SIGABRT,exithandler);
        signal(SIGSEGV,exithandler);
@@ -68,14 +137,25 @@ void prepare_signals(void) {
        signal(SIGTERM,exithandler);
        signal(SIGBUS, exithandler);
 }
-struct trace_t *tracehead = NULL;
+struct stack_frame_t *stack_frame_head = NULL;
 void nit_exit(int i) {
-       fprintf(stderr, ",---- Stack trace -- - -  -\n");
-       while(tracehead != NULL) {
-               fprintf(stderr, "| %s (%s:%d)\n", tracehead->meth, tracehead->file, tracehead->line);
-               if (tracehead == tracehead->prev) break;
-               tracehead = tracehead->prev;
+       char *opt=getenv("NIT_NO_STACK");
+       if (opt == NULL || strcmp(opt, "0")==0) {
+               fprintf(stderr, ",---- Stack trace -- - -  -\n");
+               while(stack_frame_head != NULL) {
+                       fprintf(stderr, "| %s (%s:%d)\n", stack_frame_head->meth, stack_frame_head->file, stack_frame_head->line);
+                       if (stack_frame_head == stack_frame_head->prev) break;
+                       stack_frame_head = stack_frame_head->prev;
+               }
+               fprintf(stderr, "`------------------- - -  -\n");
        }
-       fprintf(stderr, "`------------------- - -  -\n");
        exit(i);
 }
+
+void nit_abort(const char* s, const char* msg, const char* loc, int line) {
+       fprintf(stderr, s, msg);
+       fprintf(stderr, " (%s", loc);
+       if (line != 0) fprintf(stderr, ":%d", line);
+       fprintf(stderr, ")\n");
+       nit_exit(1);
+}