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) ...@@ -236,6 +236,7 @@ libmxml.a: $(LIBOBJS)
$(RANLIB) $@ $(RANLIB) $@
$(LIBOBJS): mxml.h $(LIBOBJS): mxml.h
mxml-entity.o mxml-file.o mxml-private.o: mxml-private.h
# #
......
...@@ -25,33 +25,14 @@ ...@@ -25,33 +25,14 @@
* mxmlEntityGetValue() - Get the character corresponding to a named * mxmlEntityGetValue() - Get the character corresponding to a named
* entity. * entity.
* mxmlEntityRemoveCallback() - Remove a callback. * mxmlEntityRemoveCallback() - Remove a callback.
* default_callback() - Lookup standard (X)HTML entities. * _mxml_entity_cb() - Lookup standard (X)HTML entities.
*/ */
/* /*
* Include necessary headers... * Include necessary headers...
*/ */
#include "config.h" #include "mxml-private.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
};
/* /*
...@@ -59,13 +40,17 @@ static int (*callbacks[100])(const char *name) = ...@@ -59,13 +40,17 @@ static int (*callbacks[100])(const char *name) =
*/ */
int /* O - 0 on success, -1 on failure */ int /* O - 0 on success, -1 on failure */
mxmlEntityAddCallback(int (*cb)(const char *name)) mxmlEntityAddCallback(
/* I - Callback function to add */ 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; global->entity_cbs[global->num_entity_cbs] = cb;
num_callbacks ++; global->num_entity_cbs ++;
return (0); return (0);
} }
...@@ -117,12 +102,14 @@ mxmlEntityGetName(int val) /* I - Character value */ ...@@ -117,12 +102,14 @@ mxmlEntityGetName(int val) /* I - Character value */
int /* O - Character value or -1 on error */ int /* O - Character value or -1 on error */
mxmlEntityGetValue(const char *name) /* I - Entity name */ mxmlEntityGetValue(const char *name) /* I - Entity name */
{ {
int i; /* Looping var */ int i; /* Looping var */
int ch; /* Character value */ int ch; /* Character value */
_mxml_global_t *global = _mxml_global();
/* Global data */
for (i = 0; i < num_callbacks; i ++) for (i = 0; i < global->num_entity_cbs; i ++)
if ((ch = (callbacks[i])(name)) >= 0) if ((ch = (global->entity_cbs[i])(name)) >= 0)
return (ch); return (ch);
return (-1); return (-1);
...@@ -137,21 +124,23 @@ void ...@@ -137,21 +124,23 @@ void
mxmlEntityRemoveCallback(int (*cb)(const char *name)) mxmlEntityRemoveCallback(int (*cb)(const char *name))
/* I - Callback function to remove */ /* 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 ++) for (i = 0; i < global->num_entity_cbs; i ++)
if (cb == callbacks[i]) if (cb == global->entity_cbs[i])
{ {
/* /*
* Remove the callback... * Remove the callback...
*/ */
num_callbacks --; global->num_entity_cbs --;
if (i < num_callbacks) if (i < global->num_entity_cbs)
memmove(callbacks + i, callbacks + i + 1, memmove(global->entity_cbs + i, global->entity_cbs + i + 1,
(num_callbacks - i) * sizeof(callbacks[0])); (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0]));
return; return;
} }
...@@ -159,11 +148,11 @@ mxmlEntityRemoveCallback(int (*cb)(const char *name)) ...@@ -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 */ int /* O - Unicode value or -1 */
default_callback(const char *name) /* I - Entity name */ _mxml_entity_cb(const char *name) /* I - Entity name */
{ {
int diff, /* Difference between names */ int diff, /* Difference between names */
current, /* Current entity in search */ current, /* Current entity in search */
......
...@@ -55,8 +55,7 @@ ...@@ -55,8 +55,7 @@
* Include necessary headers... * Include necessary headers...
*/ */
#include "config.h" #include "mxml-private.h"
#include "mxml.h"
#ifdef WIN32 #ifdef WIN32
# include <io.h> # include <io.h>
#else #else
...@@ -96,28 +95,6 @@ typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/ ...@@ -96,28 +95,6 @@ typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/
} _mxml_fdbuf_t; } _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... * Local functions...
*/ */
...@@ -151,7 +128,8 @@ static int mxml_write_name(const char *s, void *p, ...@@ -151,7 +128,8 @@ static int mxml_write_name(const char *s, void *p,
_mxml_putc_cb_t putc_cb); _mxml_putc_cb_t putc_cb);
static int mxml_write_node(mxml_node_t *node, void *p, static int mxml_write_node(mxml_node_t *node, void *p,
mxml_save_cb_t cb, int col, 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, static int mxml_write_string(const char *s, void *p,
_mxml_putc_cb_t putc_cb); _mxml_putc_cb_t putc_cb);
static int mxml_write_ws(mxml_node_t *node, void *p, static int mxml_write_ws(mxml_node_t *node, void *p,
...@@ -335,6 +313,8 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */ ...@@ -335,6 +313,8 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
{ {
int col; /* Final column */ int col; /* Final column */
_mxml_fdbuf_t buf; /* File descriptor buffer */ _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 */ ...@@ -349,7 +329,7 @@ mxmlSaveFd(mxml_node_t *node, /* I - Node to write */
* Write the node... * 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); return (-1);
if (col > 0) if (col > 0)
...@@ -380,13 +360,15 @@ mxmlSaveFile(mxml_node_t *node, /* I - Node to write */ ...@@ -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 */ mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */
{ {
int col; /* Final column */ int col; /* Final column */
_mxml_global_t *global = _mxml_global();
/* Global data */
/* /*
* Write the node... * 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); return (-1);
if (col > 0) if (col > 0)
...@@ -423,6 +405,8 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */ ...@@ -423,6 +405,8 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
{ {
int col; /* Final column */ int col; /* Final column */
char *ptr[2]; /* Pointers for putc_cb */ 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 */ ...@@ -432,7 +416,7 @@ mxmlSaveString(mxml_node_t *node, /* I - Node to write */
ptr[0] = buffer; ptr[0] = buffer;
ptr[1] = buffer + bufsize; 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); return (-1);
if (col > 0) if (col > 0)
...@@ -595,8 +579,12 @@ mxmlSetCustomHandlers( ...@@ -595,8 +579,12 @@ mxmlSetCustomHandlers(
mxml_custom_load_cb_t load, /* I - Load function */ mxml_custom_load_cb_t load, /* I - Load function */
mxml_custom_save_cb_t save) /* I - Save function */ mxml_custom_save_cb_t save) /* I - Save function */
{ {
mxml_custom_load_cb = load; _mxml_global_t *global = _mxml_global();
mxml_custom_save_cb = save; /* Global data */
global->custom_load_cb = load;
global->custom_save_cb = save;
} }
...@@ -607,7 +595,11 @@ mxmlSetCustomHandlers( ...@@ -607,7 +595,11 @@ mxmlSetCustomHandlers(
void void
mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */ 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 */ ...@@ -622,10 +614,14 @@ mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */
void void
mxmlSetWrapMargin(int column) /* I - Column for wrapping */ mxmlSetWrapMargin(int column) /* I - Column for wrapping */
{ {
_mxml_global_t *global = _mxml_global();
/* Global data */
if (column <= 0) if (column <= 0)
mxml_wrap = 2147483647; global->wrap = 2147483647;
else else
mxml_wrap = column; global->wrap = column;
} }
...@@ -1489,6 +1485,8 @@ mxml_load_data( ...@@ -1489,6 +1485,8 @@ mxml_load_data(
int bufsize; /* Size of buffer */ int bufsize; /* Size of buffer */
mxml_type_t type; /* Current node type */ mxml_type_t type; /* Current node type */
int encoding; /* Character encoding */ int encoding; /* Character encoding */
_mxml_global_t *global = _mxml_global();
/* Global data */
static const char * const types[] = /* Type strings... */ static const char * const types[] = /* Type strings... */
{ {
"MXML_ELEMENT", /* XML element with attributes */ "MXML_ELEMENT", /* XML element with attributes */
...@@ -1553,7 +1551,7 @@ mxml_load_data( ...@@ -1553,7 +1551,7 @@ mxml_load_data(
break; break;
case MXML_CUSTOM : case MXML_CUSTOM :
if (mxml_custom_load_cb) if (global->custom_load_cb)
{ {
/* /*
* Use the callback to fill in the custom data... * Use the callback to fill in the custom data...
...@@ -1561,7 +1559,7 @@ mxml_load_data( ...@@ -1561,7 +1559,7 @@ mxml_load_data(
node = mxmlNewCustom(parent, NULL, NULL); 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>!", mxml_error("Bad custom value '%s' in parent <%s>!",
buffer, parent ? parent->value.element.name : "null"); buffer, parent ? parent->value.element.name : "null");
...@@ -2752,7 +2750,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2752,7 +2750,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
void *p, /* I - File to write to */ void *p, /* I - File to write to */
mxml_save_cb_t cb, /* I - Whitespace callback */ mxml_save_cb_t cb, /* I - Whitespace callback */
int col, /* I - Current column */ 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 */ int i, /* Looping var */
width; /* Width of attr + value */ width; /* Width of attr + value */
...@@ -2794,7 +2793,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2794,7 +2793,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
*/ */
if (!strncmp(node->value.element.name, "?xml", 4)) 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) else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
return (-1); return (-1);
...@@ -2810,7 +2809,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2810,7 +2809,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
if (attr->value) if (attr->value)
width += strlen(attr->value) + 3; width += strlen(attr->value) + 3;
if ((col + width) > mxml_wrap) if ((col + width) > global->wrap)
{ {
if ((*putc_cb)('\n', p) < 0) if ((*putc_cb)('\n', p) < 0)
return (-1); return (-1);
...@@ -2856,7 +2855,8 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -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); 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); return (-1);
/* /*
...@@ -2914,7 +2914,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2914,7 +2914,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_INTEGER : case MXML_INTEGER :
if (node->prev) if (node->prev)
{ {
if (col > mxml_wrap) if (col > global->wrap)
{ {
if ((*putc_cb)('\n', p) < 0) if ((*putc_cb)('\n', p) < 0)
return (-1); return (-1);
...@@ -2944,7 +2944,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2944,7 +2944,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_REAL : case MXML_REAL :
if (node->prev) if (node->prev)
{ {
if (col > mxml_wrap) if (col > global->wrap)
{ {
if ((*putc_cb)('\n', p) < 0) if ((*putc_cb)('\n', p) < 0)
return (-1); return (-1);
...@@ -2967,7 +2967,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2967,7 +2967,7 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
case MXML_TEXT : case MXML_TEXT :
if (node->value.text.whitespace && col > 0) if (node->value.text.whitespace && col > 0)
{ {
if (col > mxml_wrap) if (col > global->wrap)
{ {
if ((*putc_cb)('\n', p) < 0) if ((*putc_cb)('\n', p) < 0)
return (-1); return (-1);
...@@ -2987,13 +2987,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */ ...@@ -2987,13 +2987,13 @@ mxml_write_node(mxml_node_t *node, /* I - Node to write */
break; break;
case MXML_CUSTOM : case MXML_CUSTOM :
if (mxml_custom_save_cb) if (global->custom_save_cb)
{ {
char *data; /* Custom data string */ char *data; /* Custom data string */
const char *newline; /* Last newline in 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); return (-1);
if (mxml_write_string(data, p, putc_cb) < 0) if (mxml_write_string(data, p, putc_cb) < 0)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Private functions for Mini-XML, a small XML-like file parsing library. * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* Contents: * Contents:
* *
* mxml_error() - Display an error message. * mxml_error() - Display an error message.
* mxml_global() - Get global data.
* mxml_integer_cb() - Default callback for integer values. * mxml_integer_cb() - Default callback for integer values.
* mxml_opaque_cb() - Default callback for opaque values. * mxml_opaque_cb() - Default callback for opaque values.
* mxml_real_cb() - Default callback for real number values. * mxml_real_cb() - Default callback for real number values.
...@@ -27,15 +28,7 @@ ...@@ -27,15 +28,7 @@
* Include necessary headers... * Include necessary headers...
*/ */
#include "config.h" #include "mxml-private.h"
#include "mxml.h"
/*
* Error callback function...
*/
void (*mxml_error_cb)(const char *) = NULL;
/* /*
...@@ -48,6 +41,8 @@ mxml_error(const char *format, /* I - Printf-style format string */ ...@@ -48,6 +41,8 @@ mxml_error(const char *format, /* I - Printf-style format string */
{ {
va_list ap; /* Pointer to arguments */ va_list ap; /* Pointer to arguments */
char s[1024]; /* Message string */ 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 */ ...@@ -71,13 +66,35 @@ mxml_error(const char *format, /* I - Printf-style format string */
* And then display the error message... * And then display the error message...
*/ */
if (mxml_error_cb) if (global->error_cb)
(*mxml_error_cb)(s); (*global->error_cb)(s);
else else
fprintf(stderr, "mxml: %s\n", s); 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. * '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