Loading...
libkern/c++/OSUnserializeXML.cpp xnu-792.6.76 xnu-344.26
--- xnu/xnu-792.6.76/libkern/c++/OSUnserializeXML.cpp
+++ xnu/xnu-344.26/libkern/c++/OSUnserializeXML.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -20,18 +20,14 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/*
- * HISTORY
- *
- * OSUnserializeXML.y created by rsulack on Tue Oct 12 1999
- */
-
-// parser for unserializing OSContainer objects serialized to XML
+/*  OSUnserializeXML.y created by rsulack on Tue Oct 12 1999 */
+
+// 		XML parser for unserializing OSContainer objects
 //
 // to build :
 //	bison -p OSUnserializeXML OSUnserializeXML.y
 //	head -50 OSUnserializeXML.y > OSUnserializeXML.cpp
-//	sed -e "s/#include <stdio.h>//" < OSUnserializeXML.tab.c >> OSUnserializeXML.cpp
+//	sed -e "s/stdio.h/stddef.h/" < OSUnserializeXML.tab.c >> OSUnserializeXML.cpp
 //
 //	when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
 //
@@ -39,6 +35,8 @@
 //
 //
 //
+//
+//
 //		 DO NOT EDIT OSUnserializeXML.cpp!
 //
 //			this means you!
@@ -48,6 +46,8 @@
 //
 //
 //
+//
+
 
 /*  A Bison parser, made from OSUnserializeXML.y
     by GNU Bison version 1.28  */
@@ -72,76 +72,58 @@
 #define	STRING	265
 #define	SYNTAX_ERROR	266
 
-#line 55 "OSUnserializeXML.y"
+#line 52 "OSUnserializeXML.y"
 
 #include <string.h>
 #include <libkern/c++/OSMetaClass.h>
 #include <libkern/c++/OSContainers.h>
 #include <libkern/c++/OSLib.h>
 
-#define YYSTYPE object_t *
-#define YYPARSE_PARAM	state
-#define YYLEX_PARAM	state
-
-// this is the internal struct used to hold objects on parser stack
-// it represents objects both before and after they have been created
 typedef	struct object {
 	struct object	*next;
 	struct object	*free;
 	struct object	*elements;
 	OSObject	*object;
-	OSString	*key;			// for dictionary
+	const OSSymbol	*key;		// for dictionary
 	int		size;
-	void		*data;			// for data
-	char		*string;		// for string & symbol
-	long long 	number;			// for number
+	void		*data;		// for data
+	char		*string;	// for string & symbol
+	long long 	number;		// for number
 	int		idref;
 } object_t;
 
-// this code is reentrant, this structure contains all
-// state information for the parsing of a single buffer
-typedef struct parser_state {
-	const char	*parseBuffer;		// start of text to be parsed
-	int		parseBufferIndex;	// current index into text
-	int		lineNumber;		// current line number
-	object_t	*objects;		// internal objects in use
-	object_t	*freeObjects;		// internal objects that are free
-	OSDictionary	*tags;			// used to remember "ID" tags
-	OSString	**errorString;		// parse error with line
-	OSObject	*parsedObject;		// resultant object of parsed text
-} parser_state_t;
-
-#define STATE		((parser_state_t *)state)
-
-#undef yyerror 	
-#define yyerror(s)	OSUnserializeerror(STATE, (s))
-static int		OSUnserializeerror(parser_state_t *state, char *s);
-
-static int		yylex(YYSTYPE *lvalp, parser_state_t *state);
-static int		yyparse(void * state);
-
-static object_t 	*newObject(parser_state_t *state);
-static void 		freeObject(parser_state_t *state, object_t *o);
-static void		rememberObject(parser_state_t *state, int tag, OSObject *o);
-static object_t		*retrieveObject(parser_state_t *state, int tag);
-static void		cleanupObjects(parser_state_t *state);
-
-static object_t		*buildDictionary(parser_state_t *state, object_t *o);
-static object_t		*buildArray(parser_state_t *state, object_t *o);
-static object_t		*buildSet(parser_state_t *state, object_t *o);
-static object_t		*buildString(parser_state_t *state, object_t *o);
-static object_t		*buildData(parser_state_t *state, object_t *o);
-static object_t		*buildNumber(parser_state_t *state, object_t *o);
-static object_t		*buildBoolean(parser_state_t *state, object_t *o);
+static int yyparse();
+static int yyerror(char *s);
+static int yylex();
+
+static object_t * newObject();
+static void freeObject(object_t *o);
+
+static object_t *buildOSDictionary(object_t *);
+static object_t *buildOSArray(object_t *);
+static object_t *buildOSSet(object_t *);
+static object_t *buildOSString(object_t *);
+static object_t *buildKey(object_t *);
+static object_t *buildOSData(object_t *);
+static object_t *buildOSNumber(object_t *);
+static object_t *buildOSBoolean(object_t *o);
+
+static void rememberObject(int, OSObject *);
+static object_t *retrieveObject(int);
+
+// resultant object of parsed text
+static OSObject	*parsedObject;
+
+#define YYSTYPE object_t *
 
 extern "C" {
-extern void		*kern_os_malloc(size_t size);
-extern void		*kern_os_realloc(void * addr, size_t size);
-extern void		kern_os_free(void * addr);
+extern void *kern_os_malloc(size_t size);
+extern void *kern_os_realloc(void * addr, size_t size);
+extern void kern_os_free(void * addr);
 
 //XXX shouldn't have to define these
-extern long		strtol(const char *, char **, int);
-extern unsigned long	strtoul(const char *, char **, int);
+extern long strtol(const char *, char **, int);
+extern unsigned long strtoul(const char *, char **, int);
 
 } /* extern "C" */
 
@@ -152,7 +134,6 @@
 #ifndef YYSTYPE
 #define YYSTYPE int
 #endif
-
 
 #ifndef __cplusplus
 #ifndef __STDC__
@@ -221,10 +202,10 @@
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   144,   147,   152,   157,   158,   159,   160,   161,   162,   163,
-   164,   177,   180,   183,   186,   187,   192,   201,   206,   209,
-   212,   215,   218,   221,   224,   227,   234,   237,   240,   243,
-   246
+   123,   124,   129,   135,   136,   137,   138,   139,   140,   141,
+   142,   155,   158,   161,   164,   165,   170,   178,   183,   186,
+   189,   192,   195,   198,   201,   204,   211,   214,   217,   220,
+   223
 };
 #endif
 
@@ -307,8 +288,6 @@
     16,    17,     3,     4,     5,     6,     7,    -1,     9,    10,
     11,    -1,    13,    -1,    15,    -1,    17
 };
-#define YYPURE 1
-
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
 #line 3 "/usr/share/bison.simple"
 /* This file comes from bison-1.28.  */
@@ -855,129 +834,127 @@
   switch (yyn) {
 
 case 1:
-#line 144 "OSUnserializeXML.y"
-{ yyerror("unexpected end of buffer");
+#line 123 "OSUnserializeXML.y"
+{ parsedObject = (OSObject *)NULL; YYACCEPT; ;
+    break;}
+case 2:
+#line 124 "OSUnserializeXML.y"
+{ parsedObject = yyvsp[0]->object;
+				  yyvsp[0]->object = 0;
+				  freeObject(yyvsp[0]);
+				  YYACCEPT;
+				;
+    break;}
+case 3:
+#line 129 "OSUnserializeXML.y"
+{
+				  yyerror("syntax error");
 				  YYERROR;
 				;
     break;}
-case 2:
-#line 147 "OSUnserializeXML.y"
-{ STATE->parsedObject = yyvsp[0]->object;
-				  yyvsp[0]->object = 0;
-				  freeObject(STATE, yyvsp[0]);
-				  YYACCEPT;
-				;
-    break;}
-case 3:
-#line 152 "OSUnserializeXML.y"
-{ yyerror("syntax error");
-				  YYERROR;
-				;
-    break;}
 case 4:
-#line 157 "OSUnserializeXML.y"
-{ yyval = buildDictionary(STATE, yyvsp[0]); ;
+#line 135 "OSUnserializeXML.y"
+{ yyval = buildOSDictionary(yyvsp[0]); ;
     break;}
 case 5:
-#line 158 "OSUnserializeXML.y"
-{ yyval = buildArray(STATE, yyvsp[0]); ;
+#line 136 "OSUnserializeXML.y"
+{ yyval = buildOSArray(yyvsp[0]); ;
     break;}
 case 6:
-#line 159 "OSUnserializeXML.y"
-{ yyval = buildSet(STATE, yyvsp[0]); ;
+#line 137 "OSUnserializeXML.y"
+{ yyval = buildOSSet(yyvsp[0]); ;
     break;}
 case 7:
-#line 160 "OSUnserializeXML.y"
-{ yyval = buildString(STATE, yyvsp[0]); ;
+#line 138 "OSUnserializeXML.y"
+{ yyval = buildOSString(yyvsp[0]); ;
     break;}
 case 8:
-#line 161 "OSUnserializeXML.y"
-{ yyval = buildData(STATE, yyvsp[0]); ;
+#line 139 "OSUnserializeXML.y"
+{ yyval = buildOSData(yyvsp[0]); ;
     break;}
 case 9:
-#line 162 "OSUnserializeXML.y"
-{ yyval = buildNumber(STATE, yyvsp[0]); ;
+#line 140 "OSUnserializeXML.y"
+{ yyval = buildOSNumber(yyvsp[0]); ;
     break;}
 case 10:
-#line 163 "OSUnserializeXML.y"
-{ yyval = buildBoolean(STATE, yyvsp[0]); ;
+#line 141 "OSUnserializeXML.y"
+{ yyval = buildOSBoolean(yyvsp[0]); ;
     break;}
 case 11:
-#line 164 "OSUnserializeXML.y"
-{ yyval = retrieveObject(STATE, yyvsp[0]->idref);
+#line 142 "OSUnserializeXML.y"
+{ yyval = retrieveObject(yyvsp[0]->idref);
 				  if (yyval) {
 				    yyval->object->retain();
 				  } else { 
 				    yyerror("forward reference detected");
 				    YYERROR;
 				  }
-				  freeObject(STATE, yyvsp[0]);
+				  freeObject(yyvsp[0]);
 				;
     break;}
 case 12:
-#line 177 "OSUnserializeXML.y"
+#line 155 "OSUnserializeXML.y"
 { yyval = yyvsp[-1];
 				  yyval->elements = NULL;
 				;
     break;}
 case 13:
-#line 180 "OSUnserializeXML.y"
+#line 158 "OSUnserializeXML.y"
 { yyval = yyvsp[-2];
 				  yyval->elements = yyvsp[-1];
 				;
     break;}
 case 16:
-#line 187 "OSUnserializeXML.y"
+#line 165 "OSUnserializeXML.y"
 { yyval = yyvsp[0];
 				  yyval->next = yyvsp[-1];
 				;
     break;}
 case 17:
-#line 192 "OSUnserializeXML.y"
+#line 170 "OSUnserializeXML.y"
 { yyval = yyvsp[-1];
-				  yyval->key = yyval->object;
+				  yyval->next = NULL; 
 				  yyval->object = yyvsp[0]->object;
-				  yyval->next = NULL; 
 				  yyvsp[0]->object = 0;
-				  freeObject(STATE, yyvsp[0]);
+				  freeObject(yyvsp[0]);
 				;
     break;}
 case 18:
-#line 201 "OSUnserializeXML.y"
-{ yyval = buildString(STATE, yyvsp[0]); ;
+#line 178 "OSUnserializeXML.y"
+{ yyval = buildKey(yyvsp[0]); ;
     break;}
 case 19:
-#line 206 "OSUnserializeXML.y"
+#line 183 "OSUnserializeXML.y"
 { yyval = yyvsp[-1];
 				  yyval->elements = NULL;
 				;
     break;}
 case 20:
-#line 209 "OSUnserializeXML.y"
+#line 186 "OSUnserializeXML.y"
 { yyval = yyvsp[-2];
 				  yyval->elements = yyvsp[-1];
 				;
     break;}
 case 22:
-#line 215 "OSUnserializeXML.y"
+#line 192 "OSUnserializeXML.y"
 { yyval = yyvsp[-1];
 				  yyval->elements = NULL;
 				;
     break;}
 case 23:
-#line 218 "OSUnserializeXML.y"
+#line 195 "OSUnserializeXML.y"
 { yyval = yyvsp[-2];
 				  yyval->elements = yyvsp[-1];
 				;
     break;}
 case 25:
-#line 224 "OSUnserializeXML.y"
+#line 201 "OSUnserializeXML.y"
 { yyval = yyvsp[0]; 
 				  yyval->next = NULL; 
 				;
     break;}
 case 26:
-#line 227 "OSUnserializeXML.y"
+#line 204 "OSUnserializeXML.y"
 { yyval = yyvsp[0];
 				  yyval->next = yyvsp[-1];
 				;
@@ -1205,20 +1182,31 @@
     }
   return 1;
 }
-#line 249 "OSUnserializeXML.y"
-
+#line 226 "OSUnserializeXML.y"
+
+     
+static int		lineNumber = 0;
+static const char	*parseBuffer;
+static int		parseBufferIndex;
+
+#define currentChar()	(parseBuffer[parseBufferIndex])
+#define nextChar()	(parseBuffer[++parseBufferIndex])
+#define prevChar()	(parseBuffer[parseBufferIndex - 1])
+
+#define isSpace(c)	((c) == ' ' || (c) == '\t')
+#define isAlpha(c)	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
+#define isDigit(c)	((c) >= '0' && (c) <= '9')
+#define isAlphaDigit(c)	((c) >= 'a' && (c) <= 'f')
+#define isHexDigit(c)	(isDigit(c) || isAlphaDigit(c))
+#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-')) 
+
+static char yyerror_message[128];
 
 int
-OSUnserializeerror(parser_state_t * state, char *s)  /* Called by yyparse on errors */
-{
-    char tempString[128];
-
-    if (state->errorString) {
-	snprintf(tempString, 128, "OSUnserializeXML: %s near line %d\n", s, state->lineNumber);
-	*(state->errorString) = OSString::withCString(tempString);
-    }
-
-    return 0;
+yyerror(char *s)  /* Called by yyparse on error */
+{
+	sprintf(yyerror_message, "OSUnserializeXML: %s near line %d\n", s, lineNumber);
+	return 0;
 }
 
 #define TAG_MAX_LENGTH		32
@@ -1229,25 +1217,13 @@
 #define TAG_EMPTY		3
 #define TAG_COMMENT		4
 
-#define currentChar()	(state->parseBuffer[state->parseBufferIndex])
-#define nextChar()	(state->parseBuffer[++state->parseBufferIndex])
-#define prevChar()	(state->parseBuffer[state->parseBufferIndex - 1])
-
-#define isSpace(c)	((c) == ' ' || (c) == '\t')
-#define isAlpha(c)	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
-#define isDigit(c)	((c) >= '0' && (c) <= '9')
-#define isAlphaDigit(c)	((c) >= 'a' && (c) <= 'f')
-#define isHexDigit(c)	(isDigit(c) || isAlphaDigit(c))
-#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-')) 
-
 static int
-getTag(parser_state_t *state,
-       char tag[TAG_MAX_LENGTH],
+getTag(char tag[TAG_MAX_LENGTH],
        int *attributeCount, 
        char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
        char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
 {
-	int length = 0;
+	int length = 0;;
 	int c = currentChar();
 	int tagType = TAG_START;
 
@@ -1258,7 +1234,7 @@
 
         if (c == '?' || c == '!') {
                 while ((c = nextChar()) != 0) {
-                        if (c == '\n') state->lineNumber++;
+                        if (c == '\n') lineNumber++;
                         if (c == '>') {
                                 (void)nextChar();
                                 return TAG_COMMENT;
@@ -1281,7 +1257,7 @@
 
 	tag[length] = 0;
 
-//	printf("tag %s, type %d\n", tag, tagType);
+//printf("tag %s, type %d\n", tag, tagType);
 	
 	// look for attributes of the form attribute = "value" ...
 	while ((c != '>') && (c != '/')) {
@@ -1314,8 +1290,7 @@
 
 		c = nextChar(); // skip closing quote
 
-//		printf("	attribute '%s' = '%s', nextchar = '%c'\n", 
-//		       attributes[*attributeCount], values[*attributeCount], c);
+//printf("	attribute '%s' = '%s', nextchar = '%c'\n", attributes[*attributeCount], values[*attributeCount], c);
 
 		(*attributeCount)++;
 		if (*attributeCount >= TAG_MAX_ATTRIBUTES) return TAG_BAD;
@@ -1332,17 +1307,18 @@
 }
 
 static char *
-getString(parser_state_t *state)
+getString()
 {
 	int c = currentChar();
-	int start, length, i, j;
+
+	int start, length, i, j;;
 	char * tempString;
 
-	start = state->parseBufferIndex;
+	start = parseBufferIndex;
 	/* find end of string */
 
 	while (c != 0) {
-		if (c == '\n') state->lineNumber++;
+		if (c == '\n') lineNumber++;
 		if (c == '<') {
 			break;
 		}
@@ -1351,13 +1327,13 @@
 
 	if (c != '<') return 0;
 
-	length = state->parseBufferIndex - start;
+	length = parseBufferIndex - start;
 
 	/* copy to null terminated buffer */
 	tempString = (char *)malloc(length + 1);
 	if (tempString == 0) {
 		printf("OSUnserializeXML: can't alloc temp memory\n");
-		goto error;
+		return 0;
 	}
 
 	// copy out string in tempString
@@ -1365,29 +1341,29 @@
 
 	i = j = 0;
 	while (i < length) {
-		c = state->parseBuffer[start + i++];
+		c = parseBuffer[start + i++];
 		if (c != '&') {
 			tempString[j++] = c;
 		} else {
 			if ((i+3) > length) goto error;
-			c = state->parseBuffer[start + i++];
+			c = parseBuffer[start + i++];
 			if (c == 'l') {
-				if (state->parseBuffer[start + i++] != 't') goto error;
-				if (state->parseBuffer[start + i++] != ';') goto error;
+				if (parseBuffer[start + i++] != 't') goto error;
+				if (parseBuffer[start + i++] != ';') goto error;
 				tempString[j++] = '<';
 				continue;
 			}	
 			if (c == 'g') {
-				if (state->parseBuffer[start + i++] != 't') goto error;
-				if (state->parseBuffer[start + i++] != ';') goto error;
+				if (parseBuffer[start + i++] != 't') goto error;
+				if (parseBuffer[start + i++] != ';') goto error;
 				tempString[j++] = '>';
 				continue;
 			}	
 			if ((i+3) > length) goto error;
 			if (c == 'a') {
-				if (state->parseBuffer[start + i++] != 'm') goto error;
-				if (state->parseBuffer[start + i++] != 'p') goto error;
-				if (state->parseBuffer[start + i++] != ';') goto error;
+				if (parseBuffer[start + i++] != 'm') goto error;
+				if (parseBuffer[start + i++] != 'p') goto error;
+				if (parseBuffer[start + i++] != ';') goto error;
 				tempString[j++] = '&';
 				continue;
 			}
@@ -1396,7 +1372,7 @@
 	}
 	tempString[j] = 0;
 
-//	printf("string %s\n", tempString);
+//printf("string %s\n", tempString);
 
 	return tempString;
 
@@ -1406,12 +1382,13 @@
 }
 
 static long long
-getNumber(parser_state_t *state)
+getNumber()
 {
 	unsigned long long n = 0;
 	int base = 10;
-	bool negate = false;
 	int c = currentChar();
+
+	if (!isDigit (c)) return 0;
 
 	if (c == '0') {
 		c = nextChar();
@@ -1421,16 +1398,9 @@
 		}
 	}
 	if (base == 10) {
-		if (c == '-') {
-			negate = true;
-			c = nextChar();
-		}
 		while(isDigit(c)) {
 			n = (n * base + c - '0');
 			c = nextChar();
-		}
-		if (negate) {
-			n = (unsigned long long)((long long)n * (long long)-1);
 		}
 	} else {
 		while(isHexDigit(c)) {
@@ -1442,7 +1412,7 @@
 			c = nextChar();
 		}
 	}
-//	printf("number 0x%x\n", (unsigned long)n);
+//printf("number 0x%x\n", (unsigned long)n);
 	return n;
 }
 
@@ -1467,14 +1437,14 @@
     /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
 };
 
-#define DATA_ALLOC_SIZE 4096
+#define OSDATA_ALLOC_SIZE 4096
 
 static void *
-getCFEncodedData(parser_state_t *state, unsigned int *size)
+getCFEncodedData(unsigned int *size)
 {
     int numeq = 0, acc = 0, cntr = 0;
     int tmpbufpos = 0, tmpbuflen = 0;
-    unsigned char *tmpbuf = (unsigned char *)malloc(DATA_ALLOC_SIZE);
+    unsigned char *tmpbuf = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
 
     int c = currentChar();
     *size = 0;
@@ -1486,7 +1456,7 @@
 		return 0;
 	}
 	if (c == '=') numeq++; else numeq = 0;
-	if (c == '\n') state->lineNumber++;
+	if (c == '\n') lineNumber++;
         if (__CFPLDataDecodeTable[c] < 0) {
 	    c = nextChar();
             continue;
@@ -1496,7 +1466,7 @@
         acc += __CFPLDataDecodeTable[c];
         if (0 == (cntr & 0x3)) {
             if (tmpbuflen <= tmpbufpos + 2) {
-                tmpbuflen += DATA_ALLOC_SIZE;
+                tmpbuflen += OSDATA_ALLOC_SIZE;
 		tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
             }
             tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
@@ -1508,27 +1478,23 @@
 	c = nextChar();
     }
     *size = tmpbufpos;
-    if (*size == 0) {
-	free(tmpbuf);
-	return 0;
-    }
     return tmpbuf;
 }
 
 static void *
-getHexData(parser_state_t *state, unsigned int *size)
+getHexData(unsigned int *size)
 {
     int c;
     unsigned char *d, *start, *lastStart;
 
-    start = lastStart = d = (unsigned char *)malloc(DATA_ALLOC_SIZE);
+    start = lastStart = d = (unsigned char *)malloc(OSDATA_ALLOC_SIZE);
     c = currentChar();
 
     while (c != '<') {
 
 	if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
 	if (c == '\n') {
-	    state->lineNumber++;
+	    lineNumber++;
 	    c = nextChar();
 	    continue;
 	}
@@ -1553,9 +1519,9 @@
 	}
 	
 	d++;
-	if ((d - lastStart) >= DATA_ALLOC_SIZE) {
+	if ((d - lastStart) >= OSDATA_ALLOC_SIZE) {
 	    int oldsize = d - start;
-	    start = (unsigned char *)realloc(start, oldsize + DATA_ALLOC_SIZE);
+	    start = (unsigned char *)realloc(start, oldsize + OSDATA_ALLOC_SIZE);
 	    d = lastStart = start + oldsize;
 	}
 	c = nextChar();
@@ -1572,15 +1538,16 @@
 }
 
 static int
-yylex(YYSTYPE *lvalp, parser_state_t *state)
-{
-	int c, i;
+yylex()
+{
+	int c;
 	int tagType;
 	char tag[TAG_MAX_LENGTH];
 	int attributeCount;
 	char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
 	char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
-	object_t *object;
+
+	if (parseBufferIndex == 0) lineNumber = 1;
 
  top:
 	c = currentChar();
@@ -1590,22 +1557,21 @@
 
 	/* keep track of line number, don't return \n's */
 	if (c == '\n') {
-		STATE->lineNumber++;
+		lineNumber++;
 		(void)nextChar();
 		goto top;
 	}
-
-	// end of the buffer?
-	if (!c)	return 0;
-
-	tagType = getTag(STATE, tag, &attributeCount, attributes, values);
+	
+	if (!c)	return c;
+
+	tagType = getTag(tag, &attributeCount, attributes, values);
 	if (tagType == TAG_BAD) return SYNTAX_ERROR;
 	if (tagType == TAG_COMMENT) goto top;
 
 	// handle allocation and check for "ID" and "IDREF" tags up front
-	*lvalp = object = newObject(STATE);
-	object->idref = -1;
-	for (i=0; i < attributeCount; i++) {
+	yylval = newObject();
+	yylval->idref = -1;
+	for (int i=0; i < attributeCount; i++) {
 	    if (attributes[i][0] == 'I' && attributes[i][1] == 'D') {
 		// check for idref's, note: we ignore the tag, for
 		// this to work correctly, all idrefs must be unique
@@ -1613,12 +1579,12 @@
 		if (attributes[i][2] == 'R' && attributes[i][3] == 'E' &&
 		    attributes[i][4] == 'F' && !attributes[i][5]) {
 		    if (tagType != TAG_EMPTY) return SYNTAX_ERROR;
-		    object->idref = strtol(values[i], NULL, 0);
+		    yylval->idref = strtol(values[i], NULL, 0);
 		    return IDREF;
 		}
 		// check for id's
 		if (!attributes[i][2]) {
-		    object->idref = strtol(values[i], NULL, 0);
+		    yylval->idref = strtol(values[i], NULL, 0);
 		} else {
 		    return SYNTAX_ERROR;
 		}
@@ -1629,7 +1595,7 @@
 	case 'a':
 		if (!strcmp(tag, "array")) {
 			if (tagType == TAG_EMPTY) {
-				object->elements = NULL;
+				yylval->elements = NULL;
 				return ARRAY;
 			}
 			return (tagType == TAG_START) ? '(' : ')';
@@ -1638,34 +1604,33 @@
 	case 'd':
 		if (!strcmp(tag, "dict")) {
 			if (tagType == TAG_EMPTY) {
-				object->elements = NULL;
+				yylval->elements = NULL;
 				return DICTIONARY;
 			}
 			return (tagType == TAG_START) ? '{' : '}';
 		}
 		if (!strcmp(tag, "data")) {
 			unsigned int size;
+			int readable = 0;
 			if (tagType == TAG_EMPTY) {
-				object->data = NULL;
-				object->size = 0;
+				yylval->data = NULL;
+				yylval->size = 0;
 				return DATA;
 			}
-
-			bool isHexFormat = false;
 			for (int i=0; i < attributeCount; i++) {
 				if (!strcmp(attributes[i], "format") && !strcmp(values[i], "hex")) {
-					isHexFormat = true;
+					readable++;
 					break;
 				}
 			}
 			// CF encoded is the default form
-			if (isHexFormat) {
-			    object->data = getHexData(STATE, &size);
+			if (readable) {
+			    yylval->data = getHexData(&size);
 			} else {
-			    object->data = getCFEncodedData(STATE, &size);
+			    yylval->data = getCFEncodedData(&size);
 			}
-			object->size = size;
-			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
+			yylval->size = size;
+			if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
 				return SYNTAX_ERROR;
 			}
 			return DATA;
@@ -1674,25 +1639,25 @@
 	case 'f':
 		if (!strcmp(tag, "false")) {
 			if (tagType == TAG_EMPTY) {
-				object->number = 0;
+				yylval->number = 0;
 				return BOOLEAN;
 			}
 		}
 		break;
 	case 'i':
 		if (!strcmp(tag, "integer")) {
-			object->size = 64;	// default
-			for (i=0; i < attributeCount; i++) {
+			yylval->size = 64;	// default
+			for (int i=0; i < attributeCount; i++) {
 				if (!strcmp(attributes[i], "size")) {
-					object->size = strtoul(values[i], NULL, 0);
+					yylval->size = strtoul(values[i], NULL, 0);
 				}
 			}
 			if (tagType == TAG_EMPTY) {
-				object->number = 0;
+				yylval->number = 0;
 				return NUMBER;
 			}
-			object->number = getNumber(STATE);
-			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
+			yylval->number = getNumber();
+			if ((getTag(tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
 				return SYNTAX_ERROR;
 			}
 			return NUMBER;
@@ -1701,11 +1666,11 @@
 	case 'k':
 		if (!strcmp(tag, "key")) {
 			if (tagType == TAG_EMPTY) return SYNTAX_ERROR;
-			object->string = getString(STATE);
-			if (!object->string) {
+			yylval->string = getString();
+			if (!yylval->string) {
 				return SYNTAX_ERROR;
 			}
-			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
+			if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
 			   || strcmp(tag, "key")) {
 				return SYNTAX_ERROR;
 			}
@@ -1714,22 +1679,22 @@
 		break;
 	case 'p':
 		if (!strcmp(tag, "plist")) {
-			freeObject(STATE, object);
+			freeObject(yylval);
 			goto top;
 		}
 		break;
 	case 's':
 		if (!strcmp(tag, "string")) {
 			if (tagType == TAG_EMPTY) {
-			    	object->string = (char *)malloc(1);
-			    	object->string[0] = 0;
+			    	yylval->string = (char *)malloc(1);
+			    	*yylval->string = 0;
 				return STRING;
 			}
-			object->string = getString(STATE);
-			if (!object->string) {
+			yylval->string = getString();
+			if (!yylval->string) {
 				return SYNTAX_ERROR;
 			}
-			if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
+			if ((getTag(tag, &attributeCount, attributes, values) != TAG_END)
 			   || strcmp(tag, "string")) {
 				return SYNTAX_ERROR;
 			}
@@ -1737,7 +1702,7 @@
 		}
 		if (!strcmp(tag, "set")) {
 			if (tagType == TAG_EMPTY) {
-				object->elements = NULL;
+				yylval->elements = NULL;
 				return SET;;
 			}
 			if (tagType == TAG_START) {
@@ -1750,14 +1715,19 @@
 	case 't':
 		if (!strcmp(tag, "true")) {
 			if (tagType == TAG_EMPTY) {
-				object->number = 1;
+				yylval->number = 1;
 				return BOOLEAN;
 			}
 		}
 		break;
-	}
-
-	return SYNTAX_ERROR;
+
+	default:
+		// XXX should we ignore invalid tags?
+		return SYNTAX_ERROR;
+		break;
+	}
+
+	return 0;
 }
 
 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
@@ -1766,96 +1736,94 @@
 
 // "java" like allocation, if this code hits a syntax error in the
 // the middle of the parsed string we just bail with pointers hanging
-// all over place, this code helps keeps it all together
-
-//static int object_count = 0;
+// all over place, so this code helps keeps all together
+
+static object_t *objects = 0;
+static object_t *freeObjects = 0;
 
 object_t *
-newObject(parser_state_t *state)
+newObject()
 {
 	object_t *o;
 
-	if (state->freeObjects) {
-		o = state->freeObjects;
-		state->freeObjects = state->freeObjects->next;
+	if (freeObjects) {
+		o = freeObjects;
+		freeObjects = freeObjects->next;
 	} else {
 		o = (object_t *)malloc(sizeof(object_t));
-//		object_count++;
 		bzero(o, sizeof(object_t));
-		o->free = state->objects;
-		state->objects = o;
+		o->free = objects;
+		objects = o;
 	}
 	
 	return o;
 }
 
 void
-freeObject(parser_state_t * state, object_t *o)
-{
-	o->next = state->freeObjects;
-	state->freeObjects = o;	
+freeObject(object_t *o)
+{
+	o->next = freeObjects;
+	freeObjects = o;	
 }
 
 void
-cleanupObjects(parser_state_t *state)
-{
-	object_t *t, *o = state->objects;
+cleanupObjects()
+{
+	object_t *t, *o = objects;
 
 	while (o) {
 		if (o->object) {
-//			printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
+			printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
 			o->object->release();
 		}
 		if (o->data) {
-//			printf("OSUnserializeXML: freeing   object o=%x data=%x\n", (int)o, (int)o->data);
+			printf("OSUnserializeXML: freeing   object o=%x data=%x\n", (int)o, (int)o->data);
 			free(o->data);
 		}
 		if (o->key) {
-//			printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
+			printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
 			o->key->release();
 		}
 		if (o->string) {
-//			printf("OSUnserializeXML: freeing   object o=%x string=%x\n", (int)o, (int)o->string);
+			printf("OSUnserializeXML: freeing   object o=%x string=%x\n", (int)o, (int)o->string);
 			free(o->string);
 		}
 
 		t = o;
 		o = o->free;
 		free(t);
-//		object_count--;
-	}
-//	printf("object_count = %d\n", object_count);
+	}
 }
 
 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
 
+static OSDictionary *tags;
+
 static void 
-rememberObject(parser_state_t *state, int tag, OSObject *o)
+rememberObject(int tag, OSObject *o)
 {
 	char key[16];
-	snprintf(key, 16, "%u", tag);
-
-//	printf("remember key %s\n", key);
-
-	state->tags->setObject(key, o);
+	sprintf(key, "%u", tag);
+
+//printf("remember key %s\n", key);
+
+	tags->setObject(key, o);
 }
 
 static object_t *
-retrieveObject(parser_state_t *state, int tag)
-{
-	OSObject *ref;
-	object_t *o;
+retrieveObject(int tag)
+{
 	char key[16];
-	snprintf(key, 16, "%u", tag);
-
-//	printf("retrieve key '%s'\n", key);
-
-	ref = state->tags->getObject(key);
+	sprintf(key, "%u", tag);
+
+//printf("retrieve key '%s'\n", key);
+
+	OSObject *ref = tags->getObject(key);
 	if (!ref) return 0;
 
-	o = newObject(state);
+	object_t *o = newObject();
 	o->object = ref;
 	return o;
 }
@@ -1865,11 +1833,10 @@
 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
 
 object_t *
-buildDictionary(parser_state_t *state, object_t * header)
+buildOSDictionary(object_t * header)
 {
 	object_t *o, *t;
 	int count = 0;
-	OSDictionary *dict;
 
 	// get count and reverse order
 	o = header->elements;
@@ -1883,33 +1850,31 @@
 		header->elements = t;
 	}
 
-	dict = OSDictionary::withCapacity(count);
-	if (header->idref >= 0) rememberObject(state, header->idref, dict);
+	OSDictionary *d = OSDictionary::withCapacity(count);
+
+	if (header->idref >= 0) rememberObject(header->idref, d);
 
 	o = header->elements;
 	while (o) {
-		dict->setObject(o->key, o->object);
-
+		d->setObject(o->key, o->object);
+		o->object->release();
+		o->object = 0;
 		o->key->release();
-		o->object->release();
 		o->key = 0;
-		o->object = 0;
-
 		t = o;
 		o = o->next;
-		freeObject(state, t);
+		freeObject(t);
 	}
 	o = header;
-	o->object = dict;
+	o->object = d;
 	return o;
 };
 
 object_t *
-buildArray(parser_state_t *state, object_t * header)
+buildOSArray(object_t * header)
 {
 	object_t *o, *t;
 	int count = 0;
-	OSArray *array;
 
 	// get count and reverse order
 	o = header->elements;
@@ -1923,120 +1888,140 @@
 		header->elements = t;
 	}
 
-	array = OSArray::withCapacity(count);
-	if (header->idref >= 0) rememberObject(state, header->idref, array);
+	OSArray *a = OSArray::withCapacity(count);
+
+	if (header->idref >= 0) rememberObject(header->idref, a);
 
 	o = header->elements;
 	while (o) {
-		array->setObject(o->object);
-
+		a->setObject(o->object);
 		o->object->release();
 		o->object = 0;
-
 		t = o;
 		o = o->next;
-		freeObject(state, t);
+		freeObject(t);
 	}
 	o = header;
-	o->object = array;
+	o->object = a;
 	return o;
 };
 
 object_t *
-buildSet(parser_state_t *state, object_t *header)
-{
-	object_t *o = buildArray(state, header);
-
-	OSArray *array = (OSArray *)o->object;
-	OSSet *set = OSSet::withArray(array, array->getCapacity());
-
-	// write over the reference created in buildArray
-	if (header->idref >= 0) rememberObject(state, header->idref, set);
-
-	array->release();
-	o->object = set;
+buildOSSet(object_t *o)
+{
+	o = buildOSArray(o);
+	OSArray *a = (OSArray *)o->object;
+
+	OSSet *s = OSSet::withArray(a, a->getCapacity());
+
+	//write over reference created in array
+	if (o->idref >= 0) rememberObject(o->idref, s);
+
+	a->release();
+	o->object = s;
 	return o;
 };
 
 object_t *
-buildString(parser_state_t *state, object_t *o)
-{
-	OSString *string;
-
-	string = OSString::withCString(o->string);
-	if (o->idref >= 0) rememberObject(state, o->idref, string);
+buildOSString(object_t *o)
+{
+	OSString *s = OSString::withCString(o->string);
+
+	if (o->idref >= 0) rememberObject(o->idref, s);
 
 	free(o->string);
 	o->string = 0;
-	o->object = string;
+	o->object = s;
 
 	return o;
 };
 
 object_t *
-buildData(parser_state_t *state, object_t *o)
-{
-	OSData *data;
+buildKey(object_t *o)
+{
+	const OSSymbol *s = OSSymbol::withCString(o->string);
+
+	free(o->string);
+	o->string = 0;
+	o->key = s;
+
+	return o;
+};
+
+object_t *
+buildOSData(object_t *o)
+{
+	OSData *d;
 
 	if (o->size) {
-		data = OSData::withBytes(o->data, o->size);
+		d = OSData::withBytes(o->data, o->size);
+		free(o->data);
 	} else {
-		data = OSData::withCapacity(0);
-	}
-	if (o->idref >= 0) rememberObject(state, o->idref, data);
-
-	if (o->size) free(o->data);
+		d = OSData::withCapacity(0);
+	}
+	if (o->idref >= 0) rememberObject(o->idref, d);
+
 	o->data = 0;
-	o->object = data;
+	o->object = d;
 	return o;
 };
 
 object_t *
-buildNumber(parser_state_t *state, object_t *o)
-{
-	OSNumber *number = OSNumber::withNumber(o->number, o->size);
-
-	if (o->idref >= 0) rememberObject(state, o->idref, number);
-
-	o->object = number;
+buildOSNumber(object_t *o)
+{
+	OSNumber *n = OSNumber::withNumber(o->number, o->size);
+
+	if (o->idref >= 0) rememberObject(o->idref, n);
+
+	o->object = n;
 	return o;
 };
 
 object_t *
-buildBoolean(parser_state_t *state, object_t *o)
-{
-	o->object = ((o->number == 0) ? kOSBooleanFalse : kOSBooleanTrue);
-	o->object->retain();
+buildOSBoolean(object_t *o)
+{
+	OSBoolean *b = OSBoolean::withBoolean(o->number != 0);
+	o->object = b;
 	return o;
 };
+
+__BEGIN_DECLS
+#include <kern/lock.h>
+__END_DECLS
+
+static mutex_t *lock = 0;
 
 OSObject*
 OSUnserializeXML(const char *buffer, OSString **errorString)
 {
 	OSObject *object;
-	parser_state_t *state = (parser_state_t *)malloc(sizeof(parser_state_t));
-
-	if ((!state) || (!buffer)) return 0;
-
-	// just in case
-	if (errorString) *errorString = NULL;
-
-	state->parseBuffer = buffer;
-	state->parseBufferIndex = 0;
-	state->lineNumber = 1;
-	state->objects = 0;
-	state->freeObjects = 0;
-	state->tags = OSDictionary::withCapacity(128);
-	state->errorString = errorString;
-	state->parsedObject = 0;
-
-	(void)yyparse((void *)state);
-
-	object = state->parsedObject;
-
-	cleanupObjects(state);
-	state->tags->release();
-	free(state);
+
+	if (!lock) {
+		lock = mutex_alloc(ETAP_IO_AHA);
+		mutex_lock(lock);
+	} else {
+		mutex_lock(lock);
+
+	}
+
+	objects = 0;
+	freeObjects = 0;
+	yyerror_message[0] = 0;		//just in case
+	parseBuffer = buffer;
+	parseBufferIndex = 0;
+	tags = OSDictionary::withCapacity(128);
+	if (yyparse() == 0) {
+		object = parsedObject;
+		if (errorString) *errorString = 0;
+	} else {
+		object = 0;
+		if (errorString)
+			*errorString = OSString::withCString(yyerror_message);
+	}
+
+	cleanupObjects();
+	tags->release();
+	mutex_unlock(lock);
 
 	return object;
 }