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