Commit 1f5e9b07 authored by Michael R Sweet's avatar Michael R Sweet

Prep work to add threading support to Mini-XML.

parent 658c6bd6
......@@ -236,6 +236,7 @@ libmxml.a: $(LIBOBJS)
$(RANLIB) $@
$(LIBOBJS): mxml.h
mxml-entity.o mxml-file.o mxml-private.o: mxml-private.h
#
......
......@@ -25,33 +25,14 @@
* mxmlEntityGetValue() - Get the character corresponding to a named
* entity.
* mxmlEntityRemoveCallback() - Remove a callback.
* default_callback() - Lookup standard (X)HTML entities.
* _mxml_entity_cb() - Lookup standard (X)HTML entities.
*/
/*
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
/*
* Local functions...
*/
static int default_callback(const char *name);
/*
* Callback array...
*/
static int num_callbacks = 1;
static int (*callbacks[100])(const char *name) =
{
default_callback
};
#include "mxml-private.h"
/*
......@@ -59,13 +40,17 @@ static int (*callbacks[100])(const char *name) =
*/
int /* O - 0 on success, -1 on failure */
mxmlEntityAddCallback(int (*cb)(const char *name))
/* I - Callback function to add */
mxmlEntityAddCallback(
int (*cb)(const char *name)) /* I - Callback function to add */
{
if (num_callbacks < (int)(sizeof(callbacks) / sizeof(callbacks[0])))
_mxml_global_t *global = _mxml_global();
/* Global data */
if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0])))
{
callbacks[num_callbacks] = cb;
num_callbacks ++;
global->entity_cbs[global->num_entity_cbs] = cb;
global->num_entity_cbs ++;
return (0);
}
......@@ -117,12 +102,14 @@ mxmlEntityGetName(int val) /* I - Character value */
int /* O - Character value or -1 on error */
mxmlEntityGetValue(const char *name) /* I - Entity name */
{
int i; /* Looping var */
int ch; /* Character value */
int i; /* Looping var */
int ch; /* Character value */
_mxml_global_t *global = _mxml_global();
/* Global data */
for (i = 0; i < num_callbacks; i ++)
if ((ch = (callbacks[i])(name)) >= 0)
for (i = 0; i < global->num_entity_cbs; i ++)
if ((ch = (global->entity_cbs[i])(name)) >= 0)
return (ch);
return (-1);
......@@ -137,21 +124,23 @@ void
mxmlEntityRemoveCallback(int (*cb)(const char *name))
/* I - Callback function to remove */
{
int i; /* Looping var */
int i; /* Looping var */
_mxml_global_t *global = _mxml_global();
/* Global data */
for (i = 0; i < num_callbacks; i ++)
if (cb == callbacks[i])
for (i = 0; i < global->num_entity_cbs; i ++)
if (cb == global->entity_cbs[i])
{
/*
* Remove the callback...
*/
num_callbacks --;
global->num_entity_cbs --;
if (i < num_callbacks)
memmove(callbacks + i, callbacks + i + 1,
(num_callbacks - i) * sizeof(callbacks[0]));
if (i < global->num_entity_cbs)
memmove(global->entity_cbs + i, global->entity_cbs + i + 1,
(global->num_entity_cbs - i) * sizeof(global->entity_cbs[0]));
return;
}
......@@ -159,11 +148,11 @@ mxmlEntityRemoveCallback(int (*cb)(const char *name))
/*
* 'default_callback()' - Lookup standard (X)HTML entities.
* '_mxml_entity_cb()' - Lookup standard (X)HTML entities.
*/
static int /* O - Unicode value or -1 */
default_callback(const char *name) /* I - Entity name */
int /* O - Unicode value or -1 */
_mxml_entity_cb(const char *name) /* I - Entity name */
{
int diff, /* Difference between names */
current, /* Current entity in search */
......
......@@ -55,8 +55,7 @@
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
#include "mxml-private.h"
#ifdef WIN32
# include <io.h>
#else
......@@ -96,28 +95,6 @@ typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/
} _mxml_fdbuf_t;
/*
* Global error handler...
*/
extern void (*mxml_error_cb)(const char *);
/*
* Settings...
*/
static int mxml_wrap = 72;
/*
* Custom data handlers...
*/
static mxml_custom_load_cb_t mxml_custom_load_cb = NULL;
static mxml_custom_save_cb_t mxml_custom_save_cb = NULL;
/*
* Local functions...
*/
......@@ -151,7 +128,8 @@ static int mxml_write_name(const char *s, void *p,
_mxml_putc_cb_t putc_cb);
static int mxml_write_node(mxml_node_t *node, void *p,
mxml_save_cb_t cb, int col,
_mxml_putc_cb_t putc_cb);
_mxml_putc_cb_t putc_cb,
_mxml_global_t *global);
static int mxml_write_string(const char *s, void *p,
_mxml_putc_cb_t putc_cb);
static int mxml_write_ws(mxml_node_t *node, void *p,
......@@ -335,6 +313,8 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
{
int col; /* Final column */
_mxml_fdbuf_t buf; /* File descriptor buffer */
_mxml_global_t *global = _mxml_global();
/* Global data */
/*
......@@ -349,7 +329,7 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
* Write the node...
*/
if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc)) < 0)
if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0)
return (-1);
if (col > 0)
......@@ -380,13 +360,15 @@ mxmlSaveFile(mxml_node_t *node, /* I - Node to write */
mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
{
int col; /* Final column */
_mxml_global_t *global = _mxml_global();
/* Global data */
/*
* Write the node...
*/
if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc)) < 0)
if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0)
return (-1);
if (col > 0)
......@@ -423,6 +405,8 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
{
int col; /* Final column */
char *ptr[2]; /* Pointers for putc_cb */
_mxml_global_t *global = _mxml_global();
/* Global data */
/*
......@@ -432,7 +416,7 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
ptr[0] = buffer;
ptr[1] = buffer + bufsize;
if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc)) < 0)
if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global)) < 0)
return (-1);
if (col > 0)
......@@ -595,8 +579,12 @@ mxmlSetCustomHandlers(
mxml_custom_load_cb_t load, /* I - Load function */
mxml_custom_save_cb_t save) /* I - Save function */
{
mxml_custom_load_cb = load;
mxml_custom_save_cb = save;
_mxml_global_t *global = _mxml_global();
/* Global data */
global->custom_load_cb = load;
global->custom_save_cb = save;
}
......@@ -607,7 +595,11 @@ mxmlSetCustomHandlers(
void
mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */
{
mxml_error_cb = cb;
_mxml_global_t *global = _mxml_global();
/* Global data */
global->error_cb = cb;
}
......@@ -622,10 +614,14 @@ mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */
void
mxmlSetWrapMargin(int column) /* I - Column for wrapping */
{
_mxml_global_t *global = _mxml_global();
/* Global data */
if (column <= 0)
mxml_wrap = 2147483647;
global->wrap = 2147483647;
else
mxml_wrap = column;
global->wrap = column;
}
......@@ -1489,6 +1485,8 @@ mxml_load_data(
int bufsize; /* Size of buffer */
mxml_type_t type; /* Current node type */
int encoding; /* Character encoding */
_mxml_global_t *global = _mxml_global();
/* Global data */
static const char * const types[] = /* Type strings... */
{
"MXML_ELEMENT", /* XML element with attributes */
......@@ -1553,7 +1551,7 @@ mxml_load_data(
break;
case MXML_CUSTOM :
if (mxml_custom_load_cb)
if (global->custom_load_cb)
{
/*
* Use the callback to fill in the custom data...
......@@ -1561,7 +1559,7 @@ mxml_load_data(
node = mxmlNewCustom(parent, NULL, NULL);
if ((*mxml_custom_load_cb)(node, buffer))
if ((*global->custom_load_cb)(node, buffer))
{
mxml_error("Bad custom value '%s' in parent <%s>!",
buffer, parent ? parent->value.element.name : "null");
......@@ -2752,7 +2750,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
void *p, /* I - File to write to */
mxml_save_cb_t cb, /* I - Whitespace callback */
int col, /* I - Current column */
_mxml_putc_cb_t putc_cb)/* I - Output callback */
_mxml_putc_cb_t putc_cb,/* I - Output callback */
_mxml_global_t *global)/* I - Global data */
{
int i, /* Looping var */
width; /* Width of attr + value */
......@@ -2794,7 +2793,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
*/
if (!strncmp(node->value.element.name, "?xml", 4))
col = mxml_wrap;
col = global->wrap;
}
else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
return (-1);
......@@ -2810,7 +2809,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
if (attr->value)
width += strlen(attr->value) + 3;
if ((col + width) > mxml_wrap)
if ((col + width) > global->wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
......@@ -2856,7 +2855,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb);
if ((col = mxml_write_node(node->child, p, cb, col, putc_cb)) < 0)
if ((col = mxml_write_node(node->child, p, cb, col, putc_cb,
global)) < 0)
return (-1);
/*
......@@ -2914,7 +2914,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_INTEGER :
if (node->prev)
{
if (col > mxml_wrap)
if (col > global->wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
......@@ -2944,7 +2944,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_REAL :
if (node->prev)
{
if (col > mxml_wrap)
if (col > global->wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
......@@ -2967,7 +2967,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_TEXT :
if (node->value.text.whitespace && col > 0)
{
if (col > mxml_wrap)
if (col > global->wrap)
{
if ((*putc_cb)('\n', p) < 0)
return (-1);
......@@ -2987,13 +2987,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
break;
case MXML_CUSTOM :
if (mxml_custom_save_cb)
if (global->custom_save_cb)
{
char *data; /* Custom data string */
const char *newline; /* Last newline in string */
if ((data = (*mxml_custom_save_cb)(node)) == NULL)
if ((data = (*global->custom_save_cb)(node)) == NULL)
return (-1);
if (mxml_write_string(data, p, putc_cb) < 0)
......
......@@ -3,7 +3,7 @@
*
* Private functions for Mini-XML, a small XML-like file parsing library.
*
* Copyright 2003-2005 by Michael Sweet.
* Copyright 2003-2007 by Michael Sweet.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -18,6 +18,7 @@
* Contents:
*
* mxml_error() - Display an error message.
* mxml_global() - Get global data.
* mxml_integer_cb() - Default callback for integer values.
* mxml_opaque_cb() - Default callback for opaque values.
* mxml_real_cb() - Default callback for real number values.
......@@ -27,15 +28,7 @@
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
/*
* Error callback function...
*/
void (*mxml_error_cb)(const char *) = NULL;
#include "mxml-private.h"
/*
......@@ -48,6 +41,8 @@ mxml_error(const char *format, /* I - Printf-style format string */
{
va_list ap; /* Pointer to arguments */
char s[1024]; /* Message string */
_mxml_global_t *global = _mxml_global();
/* Global data */
/*
......@@ -71,13 +66,35 @@ mxml_error(const char *format, /* I - Printf-style format string */
* And then display the error message...
*/
if (mxml_error_cb)
(*mxml_error_cb)(s);
if (global->error_cb)
(*global->error_cb)(s);
else
fprintf(stderr, "mxml: %s\n", s);
}
/*
* 'mxml_global()' - Get global data.
*/
_mxml_global_t * /* O - Global data */
_mxml_global(void)
{
static _mxml_global_t global = /* Global data */
{
NULL, /* error_cb */
1, /* num_entity_cbs */
{ _mxml_entity_cb }, /* entity_cbs */
72, /* wrap */
NULL, /* custom_load_cb */
NULL /* custom_save_cb */
};
return (&global);
}
/*
* 'mxml_ignore_cb()' - Default callback for ignored values.
*/
......
/*
* "$Id$"
*
* Private definitions for Mini-XML, a small XML-like file parsing library.
*
* Copyright 2007 by Michael Sweet.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
* Include necessary headers...
*/
#include "config.h"
#include "mxml.h"
/*
* Global, per-thread data...
*/
typedef struct _mxml_global_s
{
void (*error_cb)(const char *);
int num_entity_cbs;
int (*entity_cbs[100])(const char *name);
int wrap;
mxml_custom_load_cb_t custom_load_cb;
mxml_custom_save_cb_t custom_save_cb;
} _mxml_global_t;
/*
* Functions...
*/
extern _mxml_global_t *_mxml_global(void);
extern int _mxml_entity_cb(const char *name);
/*
* End of "$Id$".
*/
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment