xref: /xnu-11215/libkern/c++/OSUnserialize.y (revision 1031c584)
1c1dac77fSApple OSS Distributions /*
2c1dac77fSApple OSS Distributions  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3c1dac77fSApple OSS Distributions  *
4e13b1fa5SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5c1dac77fSApple OSS Distributions  *
6e13b1fa5SApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7e13b1fa5SApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8e13b1fa5SApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9e13b1fa5SApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10e13b1fa5SApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11e13b1fa5SApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12e13b1fa5SApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13e13b1fa5SApple OSS Distributions  * terms of an Apple operating system software license agreement.
14c1dac77fSApple OSS Distributions  *
15e13b1fa5SApple OSS Distributions  * Please obtain a copy of the License at
16e13b1fa5SApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17e13b1fa5SApple OSS Distributions  *
18e13b1fa5SApple OSS Distributions  * The Original Code and all software distributed under the License are
19e13b1fa5SApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20c1dac77fSApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21c1dac77fSApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22e13b1fa5SApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23e13b1fa5SApple OSS Distributions  * Please see the License for the specific language governing rights and
24e13b1fa5SApple OSS Distributions  * limitations under the License.
25c1dac77fSApple OSS Distributions  *
26e13b1fa5SApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27c1dac77fSApple OSS Distributions  */
28c1dac77fSApple OSS Distributions 
29c1dac77fSApple OSS Distributions /*  OSUnserialize.y created by rsulack on Nov 21 1998 */
30c1dac77fSApple OSS Distributions 
31c1dac77fSApple OSS Distributions // 		"classic" parser for unserializing OSContainer objects
32c1dac77fSApple OSS Distributions //
33c1dac77fSApple OSS Distributions //  XXX - this code should really be removed!
34c1dac77fSApple OSS Distributions //	- the XML format is now prefered
35c1dac77fSApple OSS Distributions //	- this code leaks on syntax errors, the XML doesn't
36c1dac77fSApple OSS Distributions //	- "classic" looks, reads, ... much better than XML :-(
37c1dac77fSApple OSS Distributions //	- well except the XML is more efficent on OSData
38c1dac77fSApple OSS Distributions //
39c1dac77fSApple OSS Distributions //
40c1dac77fSApple OSS Distributions // to build :
41c1dac77fSApple OSS Distributions //	bison -p OSUnserialize OSUnserialize.y
42c1dac77fSApple OSS Distributions //	head -50 OSUnserialize.y > OSUnserialize.cpp
43c1dac77fSApple OSS Distributions //	sed -e "s/stdio.h/stddef.h/" < OSUnserialize.tab.c >> OSUnserialize.cpp
44c1dac77fSApple OSS Distributions //
45c1dac77fSApple OSS Distributions //	when changing code check in both OSUnserialize.y and OSUnserialize.cpp
46c1dac77fSApple OSS Distributions //
47c1dac77fSApple OSS Distributions //
48c1dac77fSApple OSS Distributions //
49c1dac77fSApple OSS Distributions //
50c1dac77fSApple OSS Distributions //		 DO NOT EDIT OSUnserialize.tab.cpp!
51c1dac77fSApple OSS Distributions //
52c1dac77fSApple OSS Distributions //			this means you!
53c1dac77fSApple OSS Distributions //
54c1dac77fSApple OSS Distributions //
55c1dac77fSApple OSS Distributions //
56c1dac77fSApple OSS Distributions //
57c1dac77fSApple OSS Distributions //
58c1dac77fSApple OSS Distributions 
59c1dac77fSApple OSS Distributions 
60c1dac77fSApple OSS Distributions %{
61c1dac77fSApple OSS Distributions #include <libkern/c++/OSMetaClass.h>
62c1dac77fSApple OSS Distributions #include <libkern/c++/OSContainers.h>
63c1dac77fSApple OSS Distributions #include <libkern/c++/OSLib.h>
64c1dac77fSApple OSS Distributions 
65c1dac77fSApple OSS Distributions typedef	struct object {
66c1dac77fSApple OSS Distributions 	struct object	*next;
67c1dac77fSApple OSS Distributions 	struct object	*prev;
68c1dac77fSApple OSS Distributions 	void		*object;
69c1dac77fSApple OSS Distributions 	int		size;		// for data
70c1dac77fSApple OSS Distributions 	union {
71c1dac77fSApple OSS Distributions 		void	*key;		// for dictionary
72c1dac77fSApple OSS Distributions 		long long offset;	// for offset
73c1dac77fSApple OSS Distributions 	} u;
74c1dac77fSApple OSS Distributions 
75c1dac77fSApple OSS Distributions } object_t;
76c1dac77fSApple OSS Distributions 
773ca3bd55SApple OSS Distributions static int yyerror(const char *s);
78c1dac77fSApple OSS Distributions static int yylex();
79c1dac77fSApple OSS Distributions 
80c1dac77fSApple OSS Distributions static object_t * newObject();
81c1dac77fSApple OSS Distributions static void freeObject(object_t *o);
82c1dac77fSApple OSS Distributions 
83c1dac77fSApple OSS Distributions static OSObject *buildOSDictionary(object_t *);
84c1dac77fSApple OSS Distributions static OSObject *buildOSArray(object_t *);
85c1dac77fSApple OSS Distributions static OSObject *buildOSSet(object_t *);
86c1dac77fSApple OSS Distributions static OSObject *buildOSString(object_t *);
87c1dac77fSApple OSS Distributions static OSObject *buildOSData(object_t *);
88c1dac77fSApple OSS Distributions static OSObject *buildOSOffset(object_t *);
89c1dac77fSApple OSS Distributions static OSObject *buildOSBoolean(object_t *o);
90c1dac77fSApple OSS Distributions 
91c1dac77fSApple OSS Distributions static void rememberObject(int, object_t *);
92c1dac77fSApple OSS Distributions static OSObject *retrieveObject(int);
93c1dac77fSApple OSS Distributions 
94c1dac77fSApple OSS Distributions // temp variable to use during parsing
953ca3bd55SApple OSS Distributions static object_t *oo;
96c1dac77fSApple OSS Distributions 
97c1dac77fSApple OSS Distributions // resultant object of parsed text
98c1dac77fSApple OSS Distributions static OSObject	*parsedObject;
99c1dac77fSApple OSS Distributions 
100c1dac77fSApple OSS Distributions #define YYSTYPE object_t *
101c1dac77fSApple OSS Distributions 
102bb611c8fSApple OSS Distributions __BEGIN_DECLS
103bb611c8fSApple OSS Distributions #include <kern/kalloc.h>
104bb611c8fSApple OSS Distributions __END_DECLS
105c1dac77fSApple OSS Distributions 
106e6231be0SApple OSS Distributions // Omit from static analysis.
107e6231be0SApple OSS Distributions #ifndef __clang_analyzer__
108e6231be0SApple OSS Distributions 
109bb611c8fSApple OSS Distributions #define malloc(size)         malloc_impl(size)
110*1031c584SApple OSS Distributions #define malloc_type(type)    kalloc_type(type, Z_SET_NOTSHARED)
111bb611c8fSApple OSS Distributions static inline void *
malloc_impl(size_t size)112bb611c8fSApple OSS Distributions malloc_impl(size_t size)
113bb611c8fSApple OSS Distributions {
114bb611c8fSApple OSS Distributions 	if (size == 0) {
115bb611c8fSApple OSS Distributions 		return NULL;
116bb611c8fSApple OSS Distributions 	}
117e7776783SApple OSS Distributions 	return kalloc_data(size,
118e7776783SApple OSS Distributions 		Z_VM_TAG_BT(Z_WAITOK_ZERO, VM_KERN_MEMORY_LIBKERN));
119bb611c8fSApple OSS Distributions }
120bb611c8fSApple OSS Distributions 
121bb611c8fSApple OSS Distributions #define free(addr)             free_impl(addr)
122e6231be0SApple OSS Distributions #define free_type(type, addr)  kfree_type(type, addr)
123bb611c8fSApple OSS Distributions static inline void
free_impl(void * addr)124bb611c8fSApple OSS Distributions free_impl(void *addr)
125bb611c8fSApple OSS Distributions {
126e7776783SApple OSS Distributions 	kfree_data_addr(addr);
127bb611c8fSApple OSS Distributions }
128bb611c8fSApple OSS Distributions static inline void
safe_free(void * addr,size_t size)129bb611c8fSApple OSS Distributions safe_free(void *addr, size_t size)
130bb611c8fSApple OSS Distributions {
131e7776783SApple OSS Distributions 	kfree_data(addr, size);
132bb611c8fSApple OSS Distributions }
133bb611c8fSApple OSS Distributions 
134bb611c8fSApple OSS Distributions #define realloc(addr, osize, nsize) realloc_impl(addr, osize, nsize)
135bb611c8fSApple OSS Distributions static inline void *
realloc_impl(void * addr,size_t osize,size_t nsize)136bb611c8fSApple OSS Distributions realloc_impl(void *addr, size_t osize, size_t nsize)
137bb611c8fSApple OSS Distributions {
138e7776783SApple OSS Distributions 	return krealloc_data(addr, osize, nsize,
139e7776783SApple OSS Distributions 		Z_VM_TAG_BT(Z_WAITOK_ZERO, VM_KERN_MEMORY_LIBKERN));
140bb611c8fSApple OSS Distributions }
141c1dac77fSApple OSS Distributions 
142c1dac77fSApple OSS Distributions %}
143c1dac77fSApple OSS Distributions %token NUMBER
144c1dac77fSApple OSS Distributions %token STRING
145c1dac77fSApple OSS Distributions %token DATA
146c1dac77fSApple OSS Distributions %token BOOLEAN
147c1dac77fSApple OSS Distributions %token SYNTAX_ERROR
148c1dac77fSApple OSS Distributions 
149c1dac77fSApple OSS Distributions %% /* Grammar rules and actions follow */
150c1dac77fSApple OSS Distributions 
151c1dac77fSApple OSS Distributions input:	  /* empty */		{ parsedObject = (OSObject *)NULL; YYACCEPT; }
152c1dac77fSApple OSS Distributions 	| object		{ parsedObject = (OSObject *)$1;   YYACCEPT; }
153c1dac77fSApple OSS Distributions 	| SYNTAX_ERROR		{ yyerror("syntax error");	   YYERROR; }
154c1dac77fSApple OSS Distributions 	;
155c1dac77fSApple OSS Distributions 
156c1dac77fSApple OSS Distributions object:	  dict			{ $$ = (object_t *)buildOSDictionary($1); }
157c1dac77fSApple OSS Distributions 	| array			{ $$ = (object_t *)buildOSArray($1); }
158c1dac77fSApple OSS Distributions 	| set			{ $$ = (object_t *)buildOSSet($1); }
159c1dac77fSApple OSS Distributions 	| string		{ $$ = (object_t *)buildOSString($1); }
160c1dac77fSApple OSS Distributions 	| data			{ $$ = (object_t *)buildOSData($1); }
161c1dac77fSApple OSS Distributions 	| offset		{ $$ = (object_t *)buildOSOffset($1); }
162c1dac77fSApple OSS Distributions 	| boolean		{ $$ = (object_t *)buildOSBoolean($1); }
163c1dac77fSApple OSS Distributions 	| '@' NUMBER		{ $$ = (object_t *)retrieveObject($2->u.offset);
164c1dac77fSApple OSS Distributions 				  if ($$) {
165c1dac77fSApple OSS Distributions 				    ((OSObject *)$$)->retain();
166c1dac77fSApple OSS Distributions 				  } else {
167c1dac77fSApple OSS Distributions 				    yyerror("forward reference detected");
168c1dac77fSApple OSS Distributions 				    YYERROR;
169c1dac77fSApple OSS Distributions 				  }
170c1dac77fSApple OSS Distributions 				  freeObject($2);
171c1dac77fSApple OSS Distributions 				}
172c1dac77fSApple OSS Distributions 	| object '@' NUMBER	{ $$ = $1;
173c1dac77fSApple OSS Distributions 				  rememberObject($3->u.offset, $1);
174c1dac77fSApple OSS Distributions 				  freeObject($3);
175c1dac77fSApple OSS Distributions 				}
176c1dac77fSApple OSS Distributions 	;
177c1dac77fSApple OSS Distributions 
178c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
179c1dac77fSApple OSS Distributions 
180c1dac77fSApple OSS Distributions dict:	  '{' '}'		{ $$ = NULL; }
181c1dac77fSApple OSS Distributions 	| '{' pairs '}'		{ $$ = $2; }
182c1dac77fSApple OSS Distributions 	;
183c1dac77fSApple OSS Distributions 
184c1dac77fSApple OSS Distributions pairs:	  pair
185c1dac77fSApple OSS Distributions 	| pairs pair		{ $2->next = $1; $1->prev = $2; $$ = $2; }
186c1dac77fSApple OSS Distributions 	;
187c1dac77fSApple OSS Distributions 
188c1dac77fSApple OSS Distributions pair:	  object '=' object ';'	{ $$ = newObject();
189c1dac77fSApple OSS Distributions 				  $$->next = NULL;
190c1dac77fSApple OSS Distributions 				  $$->prev = NULL;
191c1dac77fSApple OSS Distributions 				  $$->u.key = $1;
192c1dac77fSApple OSS Distributions 				  $$->object = $3;
193c1dac77fSApple OSS Distributions 				}
194c1dac77fSApple OSS Distributions 	;
195c1dac77fSApple OSS Distributions 
196c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
197c1dac77fSApple OSS Distributions 
198c1dac77fSApple OSS Distributions array:	  '(' ')'		{ $$ = NULL; }
199c1dac77fSApple OSS Distributions 	| '(' elements ')'	{ $$ = $2; }
200c1dac77fSApple OSS Distributions 	;
201c1dac77fSApple OSS Distributions 
202c1dac77fSApple OSS Distributions set:	  '[' ']'		{ $$ = NULL; }
203c1dac77fSApple OSS Distributions 	| '[' elements ']'	{ $$ = $2; }
204c1dac77fSApple OSS Distributions 	;
205c1dac77fSApple OSS Distributions 
206c1dac77fSApple OSS Distributions elements: object		{ $$ = newObject();
207c1dac77fSApple OSS Distributions 				  $$->object = $1;
208c1dac77fSApple OSS Distributions 				  $$->next = NULL;
209c1dac77fSApple OSS Distributions 				  $$->prev = NULL;
210c1dac77fSApple OSS Distributions 				}
2113ca3bd55SApple OSS Distributions 	| elements ',' object	{ oo = newObject();
2123ca3bd55SApple OSS Distributions 				  oo->object = $3;
2133ca3bd55SApple OSS Distributions 				  oo->next = $1;
2143ca3bd55SApple OSS Distributions 				  oo->prev = NULL;
2153ca3bd55SApple OSS Distributions 				  $1->prev = oo;
2163ca3bd55SApple OSS Distributions 				  $$ = oo;
217c1dac77fSApple OSS Distributions 				}
218c1dac77fSApple OSS Distributions 	;
219c1dac77fSApple OSS Distributions 
220c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
221c1dac77fSApple OSS Distributions 
222c1dac77fSApple OSS Distributions offset:	  NUMBER ':' NUMBER	{ $$ = $1;
223c1dac77fSApple OSS Distributions 				  $$->size = $3->u.offset;
224c1dac77fSApple OSS Distributions 				  freeObject($3);
225c1dac77fSApple OSS Distributions 				}
226c1dac77fSApple OSS Distributions 	;
227c1dac77fSApple OSS Distributions 
228c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
229c1dac77fSApple OSS Distributions 
230c1dac77fSApple OSS Distributions data:	  DATA
231c1dac77fSApple OSS Distributions 	;
232c1dac77fSApple OSS Distributions 
233c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
234c1dac77fSApple OSS Distributions 
235c1dac77fSApple OSS Distributions string:	  STRING
236c1dac77fSApple OSS Distributions 	;
237c1dac77fSApple OSS Distributions 
238c1dac77fSApple OSS Distributions //------------------------------------------------------------------------------
239c1dac77fSApple OSS Distributions 
240c1dac77fSApple OSS Distributions boolean:  BOOLEAN
241c1dac77fSApple OSS Distributions 	;
242c1dac77fSApple OSS Distributions 
243c1dac77fSApple OSS Distributions %%
244c1dac77fSApple OSS Distributions 
245c1dac77fSApple OSS Distributions static int		lineNumber = 0;
246c1dac77fSApple OSS Distributions static const char	*parseBuffer;
247c1dac77fSApple OSS Distributions static int		parseBufferIndex;
248c1dac77fSApple OSS Distributions 
249c1dac77fSApple OSS Distributions #define currentChar()	(parseBuffer[parseBufferIndex])
250c1dac77fSApple OSS Distributions #define nextChar()	(parseBuffer[++parseBufferIndex])
251c1dac77fSApple OSS Distributions #define prevChar()	(parseBuffer[parseBufferIndex - 1])
252c1dac77fSApple OSS Distributions 
253c1dac77fSApple OSS Distributions #define isSpace(c)	((c) == ' ' || (c) == '\t')
254c1dac77fSApple OSS Distributions #define isAlpha(c)	(((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
255c1dac77fSApple OSS Distributions #define isDigit(c)	((c) >= '0' && (c) <= '9')
256c1dac77fSApple OSS Distributions #define isAlphaDigit(c)	((c) >= 'a' && (c) <= 'f')
257c1dac77fSApple OSS Distributions #define isHexDigit(c)	(isDigit(c) || isAlphaDigit(c))
258c1dac77fSApple OSS Distributions #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
259c1dac77fSApple OSS Distributions 
260c1dac77fSApple OSS Distributions static char yyerror_message[128];
261c1dac77fSApple OSS Distributions 
262c1dac77fSApple OSS Distributions int
yyerror(const char * s)2633ca3bd55SApple OSS Distributions yyerror(const char *s)  /* Called by yyparse on error */
264c1dac77fSApple OSS Distributions {
2653ca3bd55SApple OSS Distributions 	snprintf(yyerror_message, sizeof(yyerror_message), "OSUnserialize: %s near line %d\n", s, lineNumber);
266c1dac77fSApple OSS Distributions 	return 0;
267c1dac77fSApple OSS Distributions }
268c1dac77fSApple OSS Distributions 
269c1dac77fSApple OSS Distributions int
yylex()270c1dac77fSApple OSS Distributions yylex()
271c1dac77fSApple OSS Distributions {
272c1dac77fSApple OSS Distributions 	int c;
273c1dac77fSApple OSS Distributions 
274c1dac77fSApple OSS Distributions 	if (parseBufferIndex == 0) lineNumber = 1;
275c1dac77fSApple OSS Distributions 
276c1dac77fSApple OSS Distributions  top:
277c1dac77fSApple OSS Distributions 	c = currentChar();
278c1dac77fSApple OSS Distributions 
279c1dac77fSApple OSS Distributions 	/* skip white space  */
280c1dac77fSApple OSS Distributions 	if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
281c1dac77fSApple OSS Distributions 
282c1dac77fSApple OSS Distributions 	/* skip over comments */
283c1dac77fSApple OSS Distributions 	if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
284c1dac77fSApple OSS Distributions 
285c1dac77fSApple OSS Distributions 	/* keep track of line number, don't return \n's */
286c1dac77fSApple OSS Distributions 	if (c == '\n') {
287c1dac77fSApple OSS Distributions 		lineNumber++;
288c1dac77fSApple OSS Distributions 		(void)nextChar();
289c1dac77fSApple OSS Distributions 		goto top;
290c1dac77fSApple OSS Distributions 	}
291c1dac77fSApple OSS Distributions 
292c1dac77fSApple OSS Distributions 	/* parse boolean */
293c1dac77fSApple OSS Distributions 	if (c == '.') {
294c1dac77fSApple OSS Distributions 		bool boolean = false;
295c1dac77fSApple OSS Distributions 		if (nextChar() == 't') {
296c1dac77fSApple OSS Distributions 			if (nextChar() != 'r') return SYNTAX_ERROR;
297c1dac77fSApple OSS Distributions 			if (nextChar() != 'u') return SYNTAX_ERROR;
298c1dac77fSApple OSS Distributions 			if (nextChar() != 'e') return SYNTAX_ERROR;
299c1dac77fSApple OSS Distributions 			boolean = true;
300c1dac77fSApple OSS Distributions 		} else {
301c1dac77fSApple OSS Distributions 			if (currentChar() != 'f') return SYNTAX_ERROR;
302c1dac77fSApple OSS Distributions 			if (nextChar() != 'a') return SYNTAX_ERROR;
303c1dac77fSApple OSS Distributions 			if (nextChar() != 'l') return SYNTAX_ERROR;
304c1dac77fSApple OSS Distributions 			if (nextChar() != 's') return SYNTAX_ERROR;
305c1dac77fSApple OSS Distributions 			if (nextChar() != 'e') return SYNTAX_ERROR;
306c1dac77fSApple OSS Distributions 		}
307c1dac77fSApple OSS Distributions 		if (nextChar() != '.') return SYNTAX_ERROR;
308c1dac77fSApple OSS Distributions 		/* skip over dot */
309c1dac77fSApple OSS Distributions 		(void)nextChar();
310c1dac77fSApple OSS Distributions 
311c1dac77fSApple OSS Distributions 		yylval = (object_t *)boolean;
312c1dac77fSApple OSS Distributions 		return BOOLEAN;
313c1dac77fSApple OSS Distributions 	}
314c1dac77fSApple OSS Distributions 
315c1dac77fSApple OSS Distributions 	/* parse unquoted string */
316c1dac77fSApple OSS Distributions 	if (isAlpha(c)) {
317c1dac77fSApple OSS Distributions 		int start, length;
318c1dac77fSApple OSS Distributions 		char * tempString;
319c1dac77fSApple OSS Distributions 
320c1dac77fSApple OSS Distributions 		start = parseBufferIndex;
321c1dac77fSApple OSS Distributions 		/* find end of string */
322c1dac77fSApple OSS Distributions 		while (isAlphaNumeric(c)) {
323c1dac77fSApple OSS Distributions 			c = nextChar();
324c1dac77fSApple OSS Distributions 		}
325c1dac77fSApple OSS Distributions 		length = parseBufferIndex - start;
326c1dac77fSApple OSS Distributions 
327c1dac77fSApple OSS Distributions 		/* copy to null terminated buffer */
328c1dac77fSApple OSS Distributions 		tempString = (char *)malloc(length + 1);
329a5e72196SApple OSS Distributions 		if (tempString == NULL) {
330c1dac77fSApple OSS Distributions 			printf("OSUnserialize: can't alloc temp memory\n");
331c1dac77fSApple OSS Distributions 			return 0;
332c1dac77fSApple OSS Distributions 		}
333c1dac77fSApple OSS Distributions 		bcopy(&parseBuffer[start], tempString, length);
334c1dac77fSApple OSS Distributions 		tempString[length] = 0;
335c1dac77fSApple OSS Distributions 		yylval = (object_t *)tempString;
336c1dac77fSApple OSS Distributions 		return STRING;
337c1dac77fSApple OSS Distributions 	}
338c1dac77fSApple OSS Distributions 
339c1dac77fSApple OSS Distributions 	/* parse quoted string */
340c1dac77fSApple OSS Distributions 	if (c == '"' || c == '\'') {
341c1dac77fSApple OSS Distributions 		int start, length;
342c1dac77fSApple OSS Distributions 		char * tempString;
343c1dac77fSApple OSS Distributions 		char quoteChar = c;
344c1dac77fSApple OSS Distributions 
345c1dac77fSApple OSS Distributions 		start = parseBufferIndex + 1;		// skip quote
346c1dac77fSApple OSS Distributions 		/* find end of string, line, buffer */
347c1dac77fSApple OSS Distributions 		while ((c = nextChar()) != quoteChar) {
348c1dac77fSApple OSS Distributions 			if (c == '\\') c = nextChar();
349c1dac77fSApple OSS Distributions 			if (c == '\n') lineNumber++;
350c1dac77fSApple OSS Distributions 			if (c == 0) return SYNTAX_ERROR;
351c1dac77fSApple OSS Distributions 		}
352c1dac77fSApple OSS Distributions 		length = parseBufferIndex - start;
353c1dac77fSApple OSS Distributions 		/* skip over trailing quote */
354c1dac77fSApple OSS Distributions 		(void)nextChar();
355c1dac77fSApple OSS Distributions 		/* copy to null terminated buffer */
356c1dac77fSApple OSS Distributions 		tempString = (char *)malloc(length + 1);
357a5e72196SApple OSS Distributions 		if (tempString == NULL) {
358c1dac77fSApple OSS Distributions 			printf("OSUnserialize: can't alloc temp memory\n");
359c1dac77fSApple OSS Distributions 			return 0;
360c1dac77fSApple OSS Distributions 		}
361c1dac77fSApple OSS Distributions 
362c1dac77fSApple OSS Distributions 		int to = 0;
363c1dac77fSApple OSS Distributions 		for (int from=start; from < parseBufferIndex; from++) {
364c1dac77fSApple OSS Distributions 			// hack - skip over backslashes
365c1dac77fSApple OSS Distributions 			if (parseBuffer[from] == '\\') {
366c1dac77fSApple OSS Distributions 				length--;
367c1dac77fSApple OSS Distributions 				continue;
368c1dac77fSApple OSS Distributions 			}
369c1dac77fSApple OSS Distributions 			tempString[to] = parseBuffer[from];
370c1dac77fSApple OSS Distributions 			to++;
371c1dac77fSApple OSS Distributions 		}
372c1dac77fSApple OSS Distributions 		tempString[length] = 0;
373c1dac77fSApple OSS Distributions 		yylval = (object_t *)tempString;
374c1dac77fSApple OSS Distributions 		return STRING;
375c1dac77fSApple OSS Distributions 	}
376c1dac77fSApple OSS Distributions 
377c1dac77fSApple OSS Distributions 	/* process numbers */
378c1dac77fSApple OSS Distributions 	if (isDigit (c))
379c1dac77fSApple OSS Distributions 	{
380c1dac77fSApple OSS Distributions 		unsigned long long n = 0;
381c1dac77fSApple OSS Distributions 		int base = 10;
382c1dac77fSApple OSS Distributions 
383c1dac77fSApple OSS Distributions 		if (c == '0') {
384c1dac77fSApple OSS Distributions 			c = nextChar();
385c1dac77fSApple OSS Distributions 			if (c == 'x') {
386c1dac77fSApple OSS Distributions 				base = 16;
387c1dac77fSApple OSS Distributions 				c = nextChar();
388c1dac77fSApple OSS Distributions 			}
389c1dac77fSApple OSS Distributions 		}
390c1dac77fSApple OSS Distributions 		if (base == 10) {
391c1dac77fSApple OSS Distributions 			while(isDigit(c)) {
392c1dac77fSApple OSS Distributions 				n = (n * base + c - '0');
393c1dac77fSApple OSS Distributions 				c = nextChar();
394c1dac77fSApple OSS Distributions 			}
395c1dac77fSApple OSS Distributions 		} else {
396c1dac77fSApple OSS Distributions 			while(isHexDigit(c)) {
397c1dac77fSApple OSS Distributions 				if (isDigit(c)) {
398c1dac77fSApple OSS Distributions 					n = (n * base + c - '0');
399c1dac77fSApple OSS Distributions 				} else {
400c1dac77fSApple OSS Distributions 					n = (n * base + 0xa + c - 'a');
401c1dac77fSApple OSS Distributions 				}
402c1dac77fSApple OSS Distributions 				c = nextChar();
403c1dac77fSApple OSS Distributions 			}
404c1dac77fSApple OSS Distributions 		}
405c1dac77fSApple OSS Distributions 
406c1dac77fSApple OSS Distributions 		yylval = newObject();
407c1dac77fSApple OSS Distributions 		yylval->u.offset = n;
408c1dac77fSApple OSS Distributions 
409c1dac77fSApple OSS Distributions 		return NUMBER;
410c1dac77fSApple OSS Distributions 	}
411c1dac77fSApple OSS Distributions 
412c1dac77fSApple OSS Distributions #define OSDATA_ALLOC_SIZE 4096
413c1dac77fSApple OSS Distributions 
414c1dac77fSApple OSS Distributions 	/* process data */
415c1dac77fSApple OSS Distributions 	if (c == '<') {
416c1dac77fSApple OSS Distributions 		unsigned char *d, *start, *lastStart;
417c1dac77fSApple OSS Distributions 
418bb611c8fSApple OSS Distributions 		size_t buflen = OSDATA_ALLOC_SIZE;
419bb611c8fSApple OSS Distributions 		start = lastStart = d = (unsigned char *)malloc(buflen);
420c1dac77fSApple OSS Distributions 		c = nextChar();	// skip over '<'
421c1dac77fSApple OSS Distributions 		while (c != 0 && c != '>') {
422c1dac77fSApple OSS Distributions 
423c1dac77fSApple OSS Distributions 			if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
424c1dac77fSApple OSS Distributions 			if (c == '#') while ((c = nextChar()) != 0 && c != '\n') {};
425c1dac77fSApple OSS Distributions 			if (c == '\n') {
426c1dac77fSApple OSS Distributions 				lineNumber++;
427c1dac77fSApple OSS Distributions 				c = nextChar();
428c1dac77fSApple OSS Distributions 				continue;
429c1dac77fSApple OSS Distributions 			}
430c1dac77fSApple OSS Distributions 
431c1dac77fSApple OSS Distributions 			// get high nibble
432c1dac77fSApple OSS Distributions 			if (!isHexDigit(c)) break;
433c1dac77fSApple OSS Distributions 			if (isDigit(c)) {
434c1dac77fSApple OSS Distributions 				*d = (c - '0') << 4;
435c1dac77fSApple OSS Distributions 			} else {
436c1dac77fSApple OSS Distributions 				*d =  (0xa + (c - 'a')) << 4;
437c1dac77fSApple OSS Distributions 			}
438c1dac77fSApple OSS Distributions 
439c1dac77fSApple OSS Distributions 			// get low nibble
440c1dac77fSApple OSS Distributions 			c = nextChar();
441c1dac77fSApple OSS Distributions 			if (!isHexDigit(c)) break;
442c1dac77fSApple OSS Distributions 			if (isDigit(c)) {
443c1dac77fSApple OSS Distributions 				*d |= c - '0';
444c1dac77fSApple OSS Distributions 			} else {
445c1dac77fSApple OSS Distributions 				*d |= 0xa + (c - 'a');
446c1dac77fSApple OSS Distributions 			}
447c1dac77fSApple OSS Distributions 
448c1dac77fSApple OSS Distributions 			d++;
449c1dac77fSApple OSS Distributions 			if ((d - lastStart) >= OSDATA_ALLOC_SIZE) {
450c1dac77fSApple OSS Distributions 				int oldsize = d - start;
451bb611c8fSApple OSS Distributions 				assert(buflen == oldsize);
452bb611c8fSApple OSS Distributions 				start = (unsigned char *)realloc(start, oldsize, buflen);
453c1dac77fSApple OSS Distributions 				d = lastStart = start + oldsize;
454c1dac77fSApple OSS Distributions 			}
455c1dac77fSApple OSS Distributions 			c = nextChar();
456c1dac77fSApple OSS Distributions 		}
457c1dac77fSApple OSS Distributions 		if (c != '>' ) {
458bb611c8fSApple OSS Distributions 			safe_free(start, buflen);
459c1dac77fSApple OSS Distributions 			return SYNTAX_ERROR;
460c1dac77fSApple OSS Distributions 		}
461c1dac77fSApple OSS Distributions 
462c1dac77fSApple OSS Distributions 		// got it!
463c1dac77fSApple OSS Distributions 		yylval = newObject();
464c1dac77fSApple OSS Distributions 		yylval->object = start;
465c1dac77fSApple OSS Distributions 		yylval->size = d - start;
466c1dac77fSApple OSS Distributions 
467c1dac77fSApple OSS Distributions 		(void)nextChar();	// skip over '>'
468c1dac77fSApple OSS Distributions 		return DATA;
469c1dac77fSApple OSS Distributions 	}
470c1dac77fSApple OSS Distributions 
471c1dac77fSApple OSS Distributions 
472c1dac77fSApple OSS Distributions 	/* return single chars, move pointer to next char */
473c1dac77fSApple OSS Distributions 	(void)nextChar();
474c1dac77fSApple OSS Distributions 	return c;
475c1dac77fSApple OSS Distributions }
476c1dac77fSApple OSS Distributions 
477c1dac77fSApple OSS Distributions // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
478c1dac77fSApple OSS Distributions // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
479c1dac77fSApple OSS Distributions // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
480c1dac77fSApple OSS Distributions 
4813ca3bd55SApple OSS Distributions #if DEBUG
482c1dac77fSApple OSS Distributions int debugUnserializeAllocCount = 0;
483c1dac77fSApple OSS Distributions #endif
484c1dac77fSApple OSS Distributions 
485c1dac77fSApple OSS Distributions object_t *
newObject()486c1dac77fSApple OSS Distributions newObject()
487c1dac77fSApple OSS Distributions {
4883ca3bd55SApple OSS Distributions #if DEBUG
489c1dac77fSApple OSS Distributions 	debugUnserializeAllocCount++;
490c1dac77fSApple OSS Distributions #endif
491e6231be0SApple OSS Distributions 	return malloc_type(object_t);
492c1dac77fSApple OSS Distributions }
493c1dac77fSApple OSS Distributions 
494c1dac77fSApple OSS Distributions void
freeObject(object_t * o)495c1dac77fSApple OSS Distributions freeObject(object_t *o)
496c1dac77fSApple OSS Distributions {
4973ca3bd55SApple OSS Distributions #if DEBUG
498c1dac77fSApple OSS Distributions 	debugUnserializeAllocCount--;
499c1dac77fSApple OSS Distributions #endif
500e6231be0SApple OSS Distributions 	free_type(object_t, o);
501c1dac77fSApple OSS Distributions }
502c1dac77fSApple OSS Distributions 
503c1dac77fSApple OSS Distributions static OSDictionary *tags;
504c1dac77fSApple OSS Distributions 
505c1dac77fSApple OSS Distributions static void
rememberObject(int tag,object_t * o)506c1dac77fSApple OSS Distributions rememberObject(int tag, object_t *o)
507c1dac77fSApple OSS Distributions {
508c1dac77fSApple OSS Distributions 	char key[16];
5093ca3bd55SApple OSS Distributions 	snprintf(key, sizeof(key), "%u", tag);
510c1dac77fSApple OSS Distributions 
511c1dac77fSApple OSS Distributions 	tags->setObject(key, (OSObject *)o);
512c1dac77fSApple OSS Distributions }
513c1dac77fSApple OSS Distributions 
514c1dac77fSApple OSS Distributions static OSObject *
retrieveObject(int tag)515c1dac77fSApple OSS Distributions retrieveObject(int tag)
516c1dac77fSApple OSS Distributions {
517c1dac77fSApple OSS Distributions 	char key[16];
5183ca3bd55SApple OSS Distributions 	snprintf(key, sizeof(key), "%u", tag);
519c1dac77fSApple OSS Distributions 
520c1dac77fSApple OSS Distributions 	return tags->getObject(key);
521c1dac77fSApple OSS Distributions }
522c1dac77fSApple OSS Distributions 
523c1dac77fSApple OSS Distributions OSObject *
buildOSDictionary(object_t * o)524c1dac77fSApple OSS Distributions buildOSDictionary(object_t *o)
525c1dac77fSApple OSS Distributions {
526c1dac77fSApple OSS Distributions 	object_t *temp, *last = o;
527c1dac77fSApple OSS Distributions 	int count = 0;
528c1dac77fSApple OSS Distributions 
529c1dac77fSApple OSS Distributions 	// get count and last object
530c1dac77fSApple OSS Distributions 	while (o) {
531c1dac77fSApple OSS Distributions 		count++;
532c1dac77fSApple OSS Distributions 		last = o;
533c1dac77fSApple OSS Distributions 		o = o->next;
534c1dac77fSApple OSS Distributions 	}
535c1dac77fSApple OSS Distributions 	o = last;
536c1dac77fSApple OSS Distributions 
537c1dac77fSApple OSS Distributions 	OSDictionary *d = OSDictionary::withCapacity(count);
538c1dac77fSApple OSS Distributions 
539c1dac77fSApple OSS Distributions 	while (o) {
540c1dac77fSApple OSS Distributions #ifdef metaclass_stuff_worksXXX
541c1dac77fSApple OSS Distributions 		if (((OSObject *)o->u.key)->metaCast("OSSymbol")) {
542c1dac77fSApple OSS Distributions 			// XXX the evil frontdoor
543c1dac77fSApple OSS Distributions 			d->setObject((OSSymbol *)o->u.key, (OSObject *)o->object);
544c1dac77fSApple OSS Distributions 		} else {
545c1dac77fSApple OSS Distributions                         // If it isn't a symbol, I hope it's a string!
546c1dac77fSApple OSS Distributions 			d->setObject((OSString *)o->u.key, (OSObject *)o->object);
547c1dac77fSApple OSS Distributions 		}
548c1dac77fSApple OSS Distributions #else
549c1dac77fSApple OSS Distributions 		d->setObject((OSString *)o->u.key, (OSObject *)o->object);
550c1dac77fSApple OSS Distributions #endif
551c1dac77fSApple OSS Distributions 		((OSObject *)o->object)->release();
552c1dac77fSApple OSS Distributions 		((OSObject *)o->u.key)->release();
553c1dac77fSApple OSS Distributions 		temp = o;
554c1dac77fSApple OSS Distributions 		o = o->prev;
555c1dac77fSApple OSS Distributions 		freeObject(temp);
556c1dac77fSApple OSS Distributions 	}
557c1dac77fSApple OSS Distributions 	return d;
558c1dac77fSApple OSS Distributions };
559c1dac77fSApple OSS Distributions 
560c1dac77fSApple OSS Distributions OSObject *
buildOSArray(object_t * o)561c1dac77fSApple OSS Distributions buildOSArray(object_t *o)
562c1dac77fSApple OSS Distributions {
563c1dac77fSApple OSS Distributions 	object_t *temp, *last = o;
564c1dac77fSApple OSS Distributions 	int count = 0;
565c1dac77fSApple OSS Distributions 
566c1dac77fSApple OSS Distributions 	// get count and last object
567c1dac77fSApple OSS Distributions 	while (o) {
568c1dac77fSApple OSS Distributions 		count++;
569c1dac77fSApple OSS Distributions 		last = o;
570c1dac77fSApple OSS Distributions 		o = o->next;
571c1dac77fSApple OSS Distributions 	}
572c1dac77fSApple OSS Distributions 	o = last;
573c1dac77fSApple OSS Distributions 
574c1dac77fSApple OSS Distributions 	OSArray *a = OSArray::withCapacity(count);
575c1dac77fSApple OSS Distributions 
576c1dac77fSApple OSS Distributions 	while (o) {
577c1dac77fSApple OSS Distributions 		a->setObject((OSObject *)o->object);
578c1dac77fSApple OSS Distributions 		((OSObject *)o->object)->release();
579c1dac77fSApple OSS Distributions 		temp = o;
580c1dac77fSApple OSS Distributions 		o = o->prev;
581c1dac77fSApple OSS Distributions 		freeObject(temp);
582c1dac77fSApple OSS Distributions 	}
583c1dac77fSApple OSS Distributions 	return a;
584c1dac77fSApple OSS Distributions };
585c1dac77fSApple OSS Distributions 
586c1dac77fSApple OSS Distributions OSObject *
buildOSSet(object_t * o)587c1dac77fSApple OSS Distributions buildOSSet(object_t *o)
588c1dac77fSApple OSS Distributions {
589c1dac77fSApple OSS Distributions 	OSArray *a = (OSArray *)buildOSArray(o);
590c1dac77fSApple OSS Distributions 	OSSet *s = OSSet::withArray(a, a->getCapacity());
591c1dac77fSApple OSS Distributions 
592c1dac77fSApple OSS Distributions 	a->release();
593c1dac77fSApple OSS Distributions 	return s;
594c1dac77fSApple OSS Distributions };
595c1dac77fSApple OSS Distributions 
596c1dac77fSApple OSS Distributions OSObject *
buildOSString(object_t * o)597c1dac77fSApple OSS Distributions buildOSString(object_t *o)
598c1dac77fSApple OSS Distributions {
599c1dac77fSApple OSS Distributions 	OSString *s = OSString::withCString((char *)o);
600c1dac77fSApple OSS Distributions 
601bb611c8fSApple OSS Distributions 	safe_free(o, strlen((char *)o) + 1);
602c1dac77fSApple OSS Distributions 
603c1dac77fSApple OSS Distributions 	return s;
604c1dac77fSApple OSS Distributions };
605c1dac77fSApple OSS Distributions 
606c1dac77fSApple OSS Distributions OSObject *
buildOSData(object_t * o)607c1dac77fSApple OSS Distributions buildOSData(object_t *o)
608c1dac77fSApple OSS Distributions {
609c1dac77fSApple OSS Distributions 	OSData *d;
610c1dac77fSApple OSS Distributions 
611c1dac77fSApple OSS Distributions 	if (o->size) {
612c1dac77fSApple OSS Distributions 		d = OSData::withBytes(o->object, o->size);
613c1dac77fSApple OSS Distributions 	} else {
614c1dac77fSApple OSS Distributions 		d = OSData::withCapacity(0);
615c1dac77fSApple OSS Distributions 	}
616bb611c8fSApple OSS Distributions 	safe_free(o->object, o->size);
617c1dac77fSApple OSS Distributions 	freeObject(o);
618c1dac77fSApple OSS Distributions 	return d;
619c1dac77fSApple OSS Distributions };
620c1dac77fSApple OSS Distributions 
621c1dac77fSApple OSS Distributions OSObject *
buildOSOffset(object_t * o)622c1dac77fSApple OSS Distributions buildOSOffset(object_t *o)
623c1dac77fSApple OSS Distributions {
624c1dac77fSApple OSS Distributions 	OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
625c1dac77fSApple OSS Distributions 	freeObject(o);
626c1dac77fSApple OSS Distributions 	return off;
627c1dac77fSApple OSS Distributions };
628c1dac77fSApple OSS Distributions 
629c1dac77fSApple OSS Distributions OSObject *
buildOSBoolean(object_t * o)630c1dac77fSApple OSS Distributions buildOSBoolean(object_t *o)
631c1dac77fSApple OSS Distributions {
632c1dac77fSApple OSS Distributions 	OSBoolean *b = OSBoolean::withBoolean((bool)o);
633c1dac77fSApple OSS Distributions 	return b;
634c1dac77fSApple OSS Distributions };
635c1dac77fSApple OSS Distributions 
636c1dac77fSApple OSS Distributions __BEGIN_DECLS
6373ca3bd55SApple OSS Distributions #include <kern/locks.h>
638c1dac77fSApple OSS Distributions __END_DECLS
639c1dac77fSApple OSS Distributions 
6403ca3bd55SApple OSS Distributions static lck_mtx_t *lock = 0;
6413ca3bd55SApple OSS Distributions extern lck_grp_t *IOLockGroup;
642c1dac77fSApple OSS Distributions 
643c1dac77fSApple OSS Distributions OSObject*
OSUnserialize(const char * buffer,OSString ** errorString)644c1dac77fSApple OSS Distributions OSUnserialize(const char *buffer, OSString **errorString)
645c1dac77fSApple OSS Distributions {
646c1dac77fSApple OSS Distributions 	OSObject *object;
647c1dac77fSApple OSS Distributions 
648c1dac77fSApple OSS Distributions 	if (!lock) {
6493ca3bd55SApple OSS Distributions 		lock = lck_mtx_alloc_init(IOLockGroup, LCK_ATTR_NULL);
6503ca3bd55SApple OSS Distributions 		lck_mtx_lock(lock);
651c1dac77fSApple OSS Distributions 	} else {
6523ca3bd55SApple OSS Distributions 		lck_mtx_lock(lock);
653c1dac77fSApple OSS Distributions 
654c1dac77fSApple OSS Distributions 	}
655c1dac77fSApple OSS Distributions 
6563ca3bd55SApple OSS Distributions #if DEBUG
657c1dac77fSApple OSS Distributions 	debugUnserializeAllocCount = 0;
658c1dac77fSApple OSS Distributions #endif
659c1dac77fSApple OSS Distributions 	yyerror_message[0] = 0;	//just in case
660c1dac77fSApple OSS Distributions 	parseBuffer = buffer;
661c1dac77fSApple OSS Distributions 	parseBufferIndex = 0;
662c1dac77fSApple OSS Distributions 	tags = OSDictionary::withCapacity(128);
663c1dac77fSApple OSS Distributions 	if (yyparse() == 0) {
664c1dac77fSApple OSS Distributions 		object = parsedObject;
665a5e72196SApple OSS Distributions 		if (errorString) *errorString = NULL;
666c1dac77fSApple OSS Distributions 	} else {
667a5e72196SApple OSS Distributions 		object = NULL;
668c1dac77fSApple OSS Distributions 		if (errorString)
669c1dac77fSApple OSS Distributions 			*errorString = OSString::withCString(yyerror_message);
670c1dac77fSApple OSS Distributions 	}
671c1dac77fSApple OSS Distributions 
672c1dac77fSApple OSS Distributions 	tags->release();
6733ca3bd55SApple OSS Distributions #if DEBUG
674c1dac77fSApple OSS Distributions 	if (debugUnserializeAllocCount) {
675c1dac77fSApple OSS Distributions 		printf("OSUnserialize: allocation check failed, count = %d.\n",
676c1dac77fSApple OSS Distributions 		       debugUnserializeAllocCount);
677c1dac77fSApple OSS Distributions 	}
678c1dac77fSApple OSS Distributions #endif
6793ca3bd55SApple OSS Distributions 	lck_mtx_unlock(lock);
680c1dac77fSApple OSS Distributions 
681c1dac77fSApple OSS Distributions 	return object;
682c1dac77fSApple OSS Distributions }
683c1dac77fSApple OSS Distributions 
684e6231be0SApple OSS Distributions #endif // not __clang_analyzer__
685e6231be0SApple OSS Distributions 
686c1dac77fSApple OSS Distributions 
687c1dac77fSApple OSS Distributions //
688c1dac77fSApple OSS Distributions //
689c1dac77fSApple OSS Distributions //
690c1dac77fSApple OSS Distributions //
691c1dac77fSApple OSS Distributions //
692c1dac77fSApple OSS Distributions //		 DO NOT EDIT OSUnserialize.cpp!
693c1dac77fSApple OSS Distributions //
694c1dac77fSApple OSS Distributions //			this means you!
695c1dac77fSApple OSS Distributions //
696c1dac77fSApple OSS Distributions //
697c1dac77fSApple OSS Distributions //
698c1dac77fSApple OSS Distributions //
699c1dac77fSApple OSS Distributions //
700