home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68.zip / src / asm / log.c < prev    next >
C/C++ Source or Header  |  2008-04-01  |  6KB  |  218 lines

  1. /*
  2.  * Copyright (c) 2002, 2003 Magnus Lind.
  3.  *
  4.  * This software is provided 'as-is', without any express or implied warranty.
  5.  * In no event will the authors be held liable for any damages arising from
  6.  * the use of this software.
  7.  *
  8.  * Permission is granted to anyone to use this software, alter it and re-
  9.  * distribute it freely for any non-commercial, non-profit purpose subject to
  10.  * the following restrictions:
  11.  *
  12.  *   1. The origin of this software must not be misrepresented; you must not
  13.  *   claim that you wrote the original software. If you use this software in a
  14.  *   product, an acknowledgment in the product documentation would be
  15.  *   appreciated but is not required.
  16.  *
  17.  *   2. Altered source versions must be plainly marked as such, and must not
  18.  *   be misrepresented as being the original software.
  19.  *
  20.  *   3. This notice may not be removed or altered from any distribution.
  21.  *
  22.  *   4. The names of this software and/or it's copyright holders may not be
  23.  *   used to endorse or promote products derived from this software without
  24.  *   specific prior written permission.
  25.  *
  26.  * This file is a part of the Exomizer v1.1 release
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include "log.h"
  33.  
  34.  
  35. #ifdef WIN32
  36. #define vsnprintf _vsnprintf
  37. #endif
  38. #ifdef DJGPP
  39. #define vsnprintf(A, B, C, D) vsprintf((A),(C),(D))
  40. #endif
  41.  
  42. struct log_output {
  43.     enum log_level min;
  44.     enum log_level max;
  45.     FILE *stream;
  46.     log_formatter_f *f;
  47. };
  48.  
  49. struct log_ctx {
  50.     enum log_level level;
  51.     int out_len;
  52.     struct log_output *out;
  53.     int buf_len;
  54.     char *buf;
  55. };
  56.  
  57. struct log_ctx *G_log_ctx = NULL;
  58. enum log_level G_log_level = 0;
  59. enum log_level G_log_log_level = 0;
  60.  
  61. struct log_ctx *log_new(void)
  62. {
  63.     struct log_ctx *ctx;
  64.  
  65.     ctx = malloc(sizeof(*ctx));
  66.     if (ctx == NULL)
  67.     {
  68.         fprintf(stderr,
  69.                 "fatal error, can't allocate memory for log context\n");
  70.         exit(1);
  71.     }
  72.     ctx->level = LOG_NORMAL;
  73.     ctx->out_len = 0;
  74.     ctx->out = NULL;
  75.     ctx->buf_len = 0;
  76.     ctx->buf = NULL;
  77.  
  78.     return ctx;
  79. }
  80.  
  81. /* log_delete closes all added output streams
  82.  * and files except for stdout and stderr
  83.  */
  84. void log_delete(struct log_ctx *ctx)
  85. {
  86.     int i;
  87.  
  88.     for (i = 0; i < ctx->out_len; ++i)
  89.     {
  90.         FILE *file = ctx->out[i].stream;
  91.         if (file != stderr && file != stdout)
  92.         {
  93.             fclose(file);
  94.         }
  95.     }
  96.     free(ctx->out);
  97.     free(ctx->buf);
  98.     free(ctx);
  99. }
  100.  
  101. void log_set_level(struct log_ctx *ctx, /* IN/OUT */
  102.                    enum log_level level)        /* IN */
  103. {
  104.     ctx->level = level;
  105. }
  106.  
  107. void log_add_output_stream(struct log_ctx *ctx, /* IN/OUT */
  108.                            enum log_level min,  /* IN */
  109.                            enum log_level max,  /* IN */
  110.                            log_formatter_f * default_f, /* IN */
  111.                            FILE * out_stream)   /* IN */
  112. {
  113.     struct log_output *out;
  114.  
  115.     ctx->out_len += 1;
  116.     ctx->out = realloc(ctx->out, ctx->out_len * sizeof(*(ctx->out)));
  117.     if (ctx->out == NULL)
  118.     {
  119.         fprintf(stderr,
  120.                 "fatal error, can't allocate memory for log output\n");
  121.         exit(1);
  122.     }
  123.     out = &(ctx->out[ctx->out_len - 1]);
  124.     out->min = min;
  125.     out->max = max;
  126.     out->stream = out_stream;
  127.     out->f = default_f;
  128. }
  129.  
  130. void raw_log_formatter(FILE * out,      /* IN */
  131.                        enum log_level level,    /* IN */
  132.                        const char *context,     /* IN */
  133.                        const char *log) /* IN */
  134. {
  135.     fprintf(out, log);
  136.     fflush(out);
  137. }
  138.  
  139. void log_vlog(struct log_ctx *ctx,      /* IN */
  140.               enum log_level level,     /* IN */
  141.               const char *context,      /* IN */
  142.               log_formatter_f * f,      /* IN */
  143.               const char *printf_str,   /* IN */
  144.               va_list argp)
  145. {
  146.     int len;
  147.     int i;
  148.  
  149.     if (ctx->level < level)
  150.     {
  151.         /* don't log this */
  152.         return;
  153.     }
  154.  
  155.     len = 0;
  156.     do
  157.     {
  158.         if (len >= ctx->buf_len)
  159.         {
  160.             ctx->buf_len = len + 1024;
  161.             ctx->buf = realloc(ctx->buf, ctx->buf_len);
  162.             if (ctx->buf == NULL)
  163.             {
  164.                 fprintf(stderr,
  165.                         "fatal error, can't allocate memory for log log\n");
  166.                 exit(1);
  167.             }
  168.         }
  169.         len = vsnprintf(ctx->buf, ctx->buf_len, printf_str, argp);
  170.     }
  171.  
  172.     while (len >= ctx->buf_len);
  173.  
  174.     for (i = 0; i < ctx->out_len; ++i)
  175.     {
  176.         struct log_output *o = &ctx->out[i];
  177.         log_formatter_f *of = f;
  178.  
  179.         if (level >= o->min && level <= o->max)
  180.         {
  181.             /* generate log for this output */
  182.             if (of == NULL)
  183.             {
  184.                 of = o->f;
  185.             }
  186.             if (of != NULL)
  187.             {
  188.                 of(o->stream, level, context, ctx->buf);
  189.             } else
  190.             {
  191.                 fprintf(o->stream, "%s\n", ctx->buf);
  192.                 fflush(o->stream);
  193.             }
  194.         }
  195.     }
  196. }
  197.  
  198. void log_log_default(const char *printf_str,    /* IN */
  199.                      ...)
  200. {
  201.     va_list argp;
  202.     va_start(argp, printf_str);
  203.     log_vlog(G_log_ctx, G_log_log_level,
  204.              NULL, raw_log_formatter, printf_str, argp);
  205. }
  206.  
  207. void log_log(struct log_ctx *ctx,       /* IN */
  208.              enum log_level level,      /* IN */
  209.              const char *context,       /* IN */
  210.              log_formatter_f * f,       /* IN */
  211.              const char *printf_str,    /* IN */
  212.              ...)
  213. {
  214.     va_list argp;
  215.     va_start(argp, printf_str);
  216.     log_vlog(ctx, level, context, f, printf_str, argp);
  217. }
  218.