mxml-private.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: mxml-private.c 315 2007-11-22 18:01:52Z mike $"
00003  *
00004  * Private functions for Mini-XML, a small XML-like file parsing library.
00005  *
00006  * Copyright 2003-2007 by Michael Sweet.
00007  *
00008  * This program is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Library General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2, or (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * Contents:
00019  *
00020  *   mxml_error()      - Display an error message.
00021  *   mxml_integer_cb() - Default callback for integer values.
00022  *   mxml_opaque_cb()  - Default callback for opaque values.
00023  *   mxml_real_cb()    - Default callback for real number values.
00024  *   _mxml_global()    - Get global data.
00025  */
00026 
00027 /*
00028  * Include necessary headers...
00029  */
00030 
00031 #include "mxml-private.h"
00032 
00033 
00034 /*
00035  * 'mxml_error()' - Display an error message.
00036  */
00037 
00038 void
00039 mxml_error(const char *format,      /* I - Printf-style format string */
00040            ...)             /* I - Additional arguments as needed */
00041 {
00042   va_list   ap;         /* Pointer to arguments */
00043   char      s[1024];        /* Message string */
00044   _mxml_global_t *global = _mxml_global();
00045                     /* Global data */
00046 
00047 
00048  /*
00049   * Range check input...
00050   */
00051 
00052   if (!format)
00053     return;
00054 
00055  /*
00056   * Format the error message string...
00057   */
00058 
00059   va_start(ap, format);
00060 
00061   vsnprintf(s, sizeof(s), format, ap);
00062 
00063   va_end(ap);
00064 
00065  /*
00066   * And then display the error message...
00067   */
00068 
00069   if (global->error_cb)
00070     (*global->error_cb)(s);
00071   else
00072     fprintf(stderr, "mxml: %s\n", s);
00073 }
00074 
00075 
00076 /*
00077  * 'mxml_ignore_cb()' - Default callback for ignored values.
00078  */
00079 
00080 mxml_type_t             /* O - Node type */
00081 mxml_ignore_cb(mxml_node_t *node)   /* I - Current node */
00082 {
00083   (void)node;
00084 
00085   return (MXML_IGNORE);
00086 }
00087 
00088 
00089 /*
00090  * 'mxml_integer_cb()' - Default callback for integer values.
00091  */
00092 
00093 mxml_type_t             /* O - Node type */
00094 mxml_integer_cb(mxml_node_t *node)  /* I - Current node */
00095 {
00096   (void)node;
00097 
00098   return (MXML_INTEGER);
00099 }
00100 
00101 
00102 /*
00103  * 'mxml_opaque_cb()' - Default callback for opaque values.
00104  */
00105 
00106 mxml_type_t             /* O - Node type */
00107 mxml_opaque_cb(mxml_node_t *node)   /* I - Current node */
00108 {
00109   (void)node;
00110 
00111   return (MXML_OPAQUE);
00112 }
00113 
00114 
00115 /*
00116  * 'mxml_real_cb()' - Default callback for real number values.
00117  */
00118 
00119 mxml_type_t             /* O - Node type */
00120 mxml_real_cb(mxml_node_t *node)     /* I - Current node */
00121 {
00122   (void)node;
00123 
00124   return (MXML_REAL);
00125 }
00126 
00127 
00128 #ifdef HAVE_PTHREAD_H           /**** POSIX threading ****/
00129 #  include <pthread.h>
00130 
00131 static pthread_key_t    _mxml_key = -1; /* Thread local storage key */
00132 static pthread_once_t   _mxml_key_once = PTHREAD_ONCE_INIT;
00133                     /* One-time initialization object */
00134 static void     _mxml_init(void);
00135 static void     _mxml_destructor(void *g);
00136 
00137 
00138 /*
00139  * '_mxml_global()' - Get global data.
00140  */
00141 
00142 _mxml_global_t *            /* O - Global data */
00143 _mxml_global(void)
00144 {
00145   _mxml_global_t    *global;    /* Global data */
00146 
00147 
00148   pthread_once(&_mxml_key_once, _mxml_init);
00149 
00150   if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) == NULL)
00151   {
00152     global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
00153     pthread_setspecific(_mxml_key, global);
00154 
00155     global->num_entity_cbs = 1;
00156     global->entity_cbs[0]  = _mxml_entity_cb;
00157     global->wrap           = 72;
00158   }
00159 
00160   return (global);
00161 }
00162 
00163 
00164 /*
00165  * '_mxml_init()' - Initialize global data...
00166  */
00167 
00168 static void
00169 _mxml_init(void)
00170 {
00171   pthread_key_create(&_mxml_key, _mxml_destructor);
00172 }
00173 
00174 
00175 /*
00176  * '_mxml_destructor()' - Free memory used for globals...
00177  */
00178 
00179 static void
00180 _mxml_destructor(void *g)       /* I - Global data */
00181 {
00182   free(g);
00183 }
00184 
00185 
00186 #elif defined(WIN32)            /**** WIN32 threading ****/
00187 #  include <windows.h>
00188 
00189 static DWORD _mxml_tls_index;       /* Index for global storage */
00190 
00191 
00192 /*
00193  * 'DllMain()' - Main entry for library.
00194  */
00195 
00196 BOOL WINAPI             /* O - Success/failure */
00197 DllMain(HINSTANCE hinst,        /* I - DLL module handle */
00198         DWORD     reason,       /* I - Reason */
00199         LPVOID    reserved)     /* I - Unused */
00200 {
00201   _mxml_global_t    *global;    /* Global data */
00202 
00203 
00204   (void)hinst;
00205   (void)reserved;
00206 
00207   switch (reason)
00208   {
00209     case DLL_PROCESS_ATTACH :       /* Called on library initialization */
00210         if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES)
00211           return (FALSE);
00212         break;
00213 
00214     case DLL_THREAD_DETACH :        /* Called when a thread terminates */
00215         if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
00216           free(global);
00217         break;
00218 
00219     case DLL_PROCESS_DETACH :       /* Called when library is unloaded */
00220         if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL)
00221           free(global);
00222 
00223         TlsFree(_mxml_tls_index);
00224         break;
00225 
00226     default:
00227         break;
00228   }
00229 
00230   return (TRUE);
00231 }
00232 
00233 
00234 /*
00235  * '_mxml_global()' - Get global data.
00236  */
00237 
00238 _mxml_global_t *            /* O - Global data */
00239 _mxml_global(void)
00240 {
00241   _mxml_global_t    *global;    /* Global data */
00242 
00243 
00244   if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL)
00245   {
00246     global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t));
00247 
00248     global->num_entity_cbs = 1;
00249     global->entity_cbs[0]  = _mxml_entity_cb;
00250     global->wrap           = 72;
00251 
00252     TlsSetValue(_mxml_tls_index, (LPVOID)global);
00253   }
00254 
00255   return (global);
00256 }
00257 
00258 
00259 #else                   /**** No threading ****/
00260 /*
00261  * '_mxml_global()' - Get global data.
00262  */
00263 
00264 _mxml_global_t *            /* O - Global data */
00265 _mxml_global(void)
00266 {
00267   static _mxml_global_t global =    /* Global data */
00268   {
00269     NULL,               /* error_cb */
00270     1,                  /* num_entity_cbs */
00271     { _mxml_entity_cb },        /* entity_cbs */
00272     72,                 /* wrap */
00273     NULL,               /* custom_load_cb */
00274     NULL                /* custom_save_cb */
00275   };
00276 
00277 
00278   return (&global);
00279 }
00280 #endif /* HAVE_PTHREAD_H */

Generated by  doxygen 1.6.2