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