]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSUnserializeXML.cpp
xnu-792.tar.gz
[apple/xnu.git] / libkern / c++ / OSUnserializeXML.cpp
CommitLineData
1c79356b 1/*
55e303ae 2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
1c79356b
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
e5568f75
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
e5568f75
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
e5568f75
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
55e303ae
A
23/*
24 * HISTORY
25 *
26 * OSUnserializeXML.y created by rsulack on Tue Oct 12 1999
27 */
1c79356b 28
55e303ae 29// parser for unserializing OSContainer objects serialized to XML
1c79356b
A
30//
31// to build :
32// bison -p OSUnserializeXML OSUnserializeXML.y
33// head -50 OSUnserializeXML.y > OSUnserializeXML.cpp
55e303ae 34// sed -e "s/#include <stdio.h>//" < OSUnserializeXML.tab.c >> OSUnserializeXML.cpp
1c79356b
A
35//
36// when changing code check in both OSUnserializeXML.y and OSUnserializeXML.cpp
37//
38//
39//
40//
41//
1c79356b
A
42// DO NOT EDIT OSUnserializeXML.cpp!
43//
44// this means you!
45//
46//
47//
48//
49//
50//
1c79356b
A
51
52/* A Bison parser, made from OSUnserializeXML.y
53 by GNU Bison version 1.28 */
54
55#define YYBISON 1 /* Identify Bison output. */
56
57#define yyparse OSUnserializeXMLparse
58#define yylex OSUnserializeXMLlex
59#define yyerror OSUnserializeXMLerror
60#define yylval OSUnserializeXMLlval
61#define yychar OSUnserializeXMLchar
62#define yydebug OSUnserializeXMLdebug
63#define yynerrs OSUnserializeXMLnerrs
64#define ARRAY 257
65#define BOOLEAN 258
66#define DATA 259
67#define DICTIONARY 260
68#define IDREF 261
69#define KEY 262
70#define NUMBER 263
71#define SET 264
72#define STRING 265
73#define SYNTAX_ERROR 266
74
55e303ae 75#line 55 "OSUnserializeXML.y"
1c79356b
A
76
77#include <string.h>
78#include <libkern/c++/OSMetaClass.h>
79#include <libkern/c++/OSContainers.h>
80#include <libkern/c++/OSLib.h>
81
55e303ae
A
82#define YYSTYPE object_t *
83#define YYPARSE_PARAM state
84#define YYLEX_PARAM state
85
86// this is the internal struct used to hold objects on parser stack
87// it represents objects both before and after they have been created
1c79356b
A
88typedef struct object {
89 struct object *next;
90 struct object *free;
91 struct object *elements;
92 OSObject *object;
55e303ae 93 OSString *key; // for dictionary
1c79356b 94 int size;
55e303ae
A
95 void *data; // for data
96 char *string; // for string & symbol
97 long long number; // for number
1c79356b
A
98 int idref;
99} object_t;
100
55e303ae
A
101// this code is reentrant, this structure contains all
102// state information for the parsing of a single buffer
103typedef struct parser_state {
104 const char *parseBuffer; // start of text to be parsed
105 int parseBufferIndex; // current index into text
106 int lineNumber; // current line number
107 object_t *objects; // internal objects in use
108 object_t *freeObjects; // internal objects that are free
109 OSDictionary *tags; // used to remember "ID" tags
110 OSString **errorString; // parse error with line
111 OSObject *parsedObject; // resultant object of parsed text
112} parser_state_t;
113
114#define STATE ((parser_state_t *)state)
115
116#undef yyerror
117#define yyerror(s) OSUnserializeerror(STATE, (s))
118static int OSUnserializeerror(parser_state_t *state, char *s);
119
120static int yylex(YYSTYPE *lvalp, parser_state_t *state);
121static int yyparse(void * state);
122
123static object_t *newObject(parser_state_t *state);
124static void freeObject(parser_state_t *state, object_t *o);
125static void rememberObject(parser_state_t *state, int tag, OSObject *o);
126static object_t *retrieveObject(parser_state_t *state, int tag);
127static void cleanupObjects(parser_state_t *state);
128
129static object_t *buildDictionary(parser_state_t *state, object_t *o);
130static object_t *buildArray(parser_state_t *state, object_t *o);
131static object_t *buildSet(parser_state_t *state, object_t *o);
132static object_t *buildString(parser_state_t *state, object_t *o);
133static object_t *buildData(parser_state_t *state, object_t *o);
134static object_t *buildNumber(parser_state_t *state, object_t *o);
135static object_t *buildBoolean(parser_state_t *state, object_t *o);
1c79356b
A
136
137extern "C" {
55e303ae
A
138extern void *kern_os_malloc(size_t size);
139extern void *kern_os_realloc(void * addr, size_t size);
140extern void kern_os_free(void * addr);
1c79356b
A
141
142//XXX shouldn't have to define these
55e303ae
A
143extern long strtol(const char *, char **, int);
144extern unsigned long strtoul(const char *, char **, int);
1c79356b
A
145
146} /* extern "C" */
147
148#define malloc(s) kern_os_malloc(s)
149#define realloc(a, s) kern_os_realloc(a, s)
150#define free(a) kern_os_free(a)
151
152#ifndef YYSTYPE
153#define YYSTYPE int
154#endif
1c79356b 155
55e303ae 156
1c79356b
A
157#ifndef __cplusplus
158#ifndef __STDC__
159#define const
160#endif
161#endif
162
163
164
165#define YYFINAL 40
166#define YYFLAG -32768
167#define YYNTBASE 19
168
169#define YYTRANSLATE(x) ((unsigned)(x) <= 266 ? yytranslate[x] : 33)
170
171static const char yytranslate[] = { 0,
172 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
173 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
174 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
175 2, 2, 2, 2, 2, 2, 2, 2, 2, 15,
176 16, 2, 2, 2, 2, 2, 2, 2, 2, 2,
177 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
178 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
179 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
180 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
181 17, 2, 18, 2, 2, 2, 2, 2, 2, 2,
182 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
183 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
184 2, 2, 13, 2, 14, 2, 2, 2, 2, 2,
185 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
186 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
187 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
188 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
189 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
190 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
191 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
192 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
193 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
194 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
195 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
196 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
197 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
198 7, 8, 9, 10, 11, 12
199};
200
201#if YYDEBUG != 0
202static const short yyprhs[] = { 0,
203 0, 1, 3, 5, 7, 9, 11, 13, 15, 17,
204 19, 21, 24, 28, 30, 32, 35, 38, 40, 43,
205 47, 49, 52, 56, 58, 60, 63, 65, 67, 69,
206 71
207};
208
209static const short yyrhs[] = { -1,
210 20, 0, 12, 0, 21, 0, 25, 0, 26, 0,
211 32, 0, 29, 0, 31, 0, 28, 0, 30, 0,
212 13, 14, 0, 13, 22, 14, 0, 6, 0, 23,
213 0, 22, 23, 0, 24, 20, 0, 8, 0, 15,
214 16, 0, 15, 27, 16, 0, 3, 0, 17, 18,
215 0, 17, 27, 18, 0, 10, 0, 20, 0, 27,
216 20, 0, 4, 0, 5, 0, 7, 0, 9, 0,
217 11, 0
218};
219
220#endif
221
222#if YYDEBUG != 0
223static const short yyrline[] = { 0,
55e303ae
A
224 144, 147, 152, 157, 158, 159, 160, 161, 162, 163,
225 164, 177, 180, 183, 186, 187, 192, 201, 206, 209,
226 212, 215, 218, 221, 224, 227, 234, 237, 240, 243,
227 246
1c79356b
A
228};
229#endif
230
231
232#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
233
234static const char * const yytname[] = { "$","error","$undefined.","ARRAY",
235"BOOLEAN","DATA","DICTIONARY","IDREF","KEY","NUMBER","SET","STRING","SYNTAX_ERROR",
236"'{'","'}'","'('","')'","'['","']'","input","object","dict","pairs","pair","key",
237"array","set","elements","boolean","data","idref","number","string", NULL
238};
239#endif
240
241static const short yyr1[] = { 0,
242 19, 19, 19, 20, 20, 20, 20, 20, 20, 20,
243 20, 21, 21, 21, 22, 22, 23, 24, 25, 25,
244 25, 26, 26, 26, 27, 27, 28, 29, 30, 31,
245 32
246};
247
248static const short yyr2[] = { 0,
249 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
250 1, 2, 3, 1, 1, 2, 2, 1, 2, 3,
251 1, 2, 3, 1, 1, 2, 1, 1, 1, 1,
252 1
253};
254
255static const short yydefact[] = { 1,
256 21, 27, 28, 14, 29, 30, 24, 31, 3, 0,
257 0, 0, 2, 4, 5, 6, 10, 8, 11, 9,
258 7, 18, 12, 0, 15, 0, 19, 25, 0, 22,
259 0, 13, 16, 17, 20, 26, 23, 0, 0, 0
260};
261
262static const short yydefgoto[] = { 38,
263 28, 14, 24, 25, 26, 15, 16, 29, 17, 18,
264 19, 20, 21
265};
266
267static const short yypact[] = { 45,
268-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 4,
269 60, -2,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
270-32768,-32768,-32768, 6,-32768, 90,-32768,-32768, 75,-32768,
271 29,-32768,-32768,-32768,-32768,-32768,-32768, 10, 17,-32768
272};
273
274static const short yypgoto[] = {-32768,
275 0,-32768,-32768, -18,-32768,-32768,-32768, 7,-32768,-32768,
276-32768,-32768,-32768
277};
278
279
280#define YYLAST 107
281
282
283static const short yytable[] = { 13,
284 1, 2, 3, 4, 5, 33, 6, 7, 8, 39,
285 10, 22, 11, 22, 12, 30, 40, 23, 31, 32,
286 0, 0, 0, 0, 0, 34, 0, 0, 36, 0,
287 36, 1, 2, 3, 4, 5, 0, 6, 7, 8,
288 0, 10, 0, 11, 0, 12, 37, 1, 2, 3,
289 4, 5, 0, 6, 7, 8, 9, 10, 0, 11,
290 0, 12, 1, 2, 3, 4, 5, 0, 6, 7,
291 8, 0, 10, 0, 11, 27, 12, 1, 2, 3,
292 4, 5, 0, 6, 7, 8, 0, 10, 0, 11,
293 35, 12, 1, 2, 3, 4, 5, 0, 6, 7,
294 8, 0, 10, 0, 11, 0, 12
295};
296
297static const short yycheck[] = { 0,
298 3, 4, 5, 6, 7, 24, 9, 10, 11, 0,
299 13, 8, 15, 8, 17, 18, 0, 14, 12, 14,
300 -1, -1, -1, -1, -1, 26, -1, -1, 29, -1,
301 31, 3, 4, 5, 6, 7, -1, 9, 10, 11,
302 -1, 13, -1, 15, -1, 17, 18, 3, 4, 5,
303 6, 7, -1, 9, 10, 11, 12, 13, -1, 15,
304 -1, 17, 3, 4, 5, 6, 7, -1, 9, 10,
305 11, -1, 13, -1, 15, 16, 17, 3, 4, 5,
306 6, 7, -1, 9, 10, 11, -1, 13, -1, 15,
307 16, 17, 3, 4, 5, 6, 7, -1, 9, 10,
308 11, -1, 13, -1, 15, -1, 17
309};
55e303ae
A
310#define YYPURE 1
311
1c79356b
A
312/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
313#line 3 "/usr/share/bison.simple"
314/* This file comes from bison-1.28. */
315
316/* Skeleton output parser for bison,
317 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
318
319 This program is free software; you can redistribute it and/or modify
320 it under the terms of the GNU General Public License as published by
321 the Free Software Foundation; either version 2, or (at your option)
322 any later version.
323
324 This program is distributed in the hope that it will be useful,
325 but WITHOUT ANY WARRANTY; without even the implied warranty of
326 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
327 GNU General Public License for more details.
328
329 You should have received a copy of the GNU General Public License
330 along with this program; if not, write to the Free Software
331 Foundation, Inc., 59 Temple Place - Suite 330,
332 Boston, MA 02111-1307, USA. */
333
334/* As a special exception, when this file is copied by Bison into a
335 Bison output file, you may use that output file without restriction.
336 This special exception was added by the Free Software Foundation
337 in version 1.24 of Bison. */
338
339/* This is the parser code that is written into each bison parser
340 when the %semantic_parser declaration is not specified in the grammar.
341 It was written by Richard Stallman by simplifying the hairy parser
342 used when %semantic_parser is specified. */
343
344#ifndef YYSTACK_USE_ALLOCA
345#ifdef alloca
346#define YYSTACK_USE_ALLOCA
347#else /* alloca not defined */
348#ifdef __GNUC__
349#define YYSTACK_USE_ALLOCA
350#define alloca __builtin_alloca
351#else /* not GNU C. */
352#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
353#define YYSTACK_USE_ALLOCA
354#include <alloca.h>
355#else /* not sparc */
356/* We think this test detects Watcom and Microsoft C. */
357/* This used to test MSDOS, but that is a bad idea
358 since that symbol is in the user namespace. */
359#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
360#if 0 /* No need for malloc.h, which pollutes the namespace;
361 instead, just don't use alloca. */
362#include <malloc.h>
363#endif
364#else /* not MSDOS, or __TURBOC__ */
365#if defined(_AIX)
366/* I don't know what this was needed for, but it pollutes the namespace.
367 So I turned it off. rms, 2 May 1997. */
368/* #include <malloc.h> */
369 #pragma alloca
370#define YYSTACK_USE_ALLOCA
371#else /* not MSDOS, or __TURBOC__, or _AIX */
372#if 0
373#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
374 and on HPUX 10. Eventually we can turn this on. */
375#define YYSTACK_USE_ALLOCA
376#define alloca __builtin_alloca
377#endif /* __hpux */
378#endif
379#endif /* not _AIX */
380#endif /* not MSDOS, or __TURBOC__ */
381#endif /* not sparc */
382#endif /* not GNU C */
383#endif /* alloca not defined */
384#endif /* YYSTACK_USE_ALLOCA not defined */
385
386#ifdef YYSTACK_USE_ALLOCA
387#define YYSTACK_ALLOC alloca
388#else
389#define YYSTACK_ALLOC malloc
390#endif
391
392/* Note: there must be only one dollar sign in this file.
393 It is replaced by the list of actions, each action
394 as one case of the switch. */
395
396#define yyerrok (yyerrstatus = 0)
397#define yyclearin (yychar = YYEMPTY)
398#define YYEMPTY -2
399#define YYEOF 0
400#define YYACCEPT goto yyacceptlab
401#define YYABORT goto yyabortlab
402#define YYERROR goto yyerrlab1
403/* Like YYERROR except do call yyerror.
404 This remains here temporarily to ease the
405 transition to the new meaning of YYERROR, for GCC.
406 Once GCC version 2 has supplanted version 1, this can go. */
407#define YYFAIL goto yyerrlab
408#define YYRECOVERING() (!!yyerrstatus)
409#define YYBACKUP(token, value) \
410do \
411 if (yychar == YYEMPTY && yylen == 1) \
412 { yychar = (token), yylval = (value); \
413 yychar1 = YYTRANSLATE (yychar); \
414 YYPOPSTACK; \
415 goto yybackup; \
416 } \
417 else \
418 { yyerror ("syntax error: cannot back up"); YYERROR; } \
419while (0)
420
421#define YYTERROR 1
422#define YYERRCODE 256
423
424#ifndef YYPURE
425#define YYLEX yylex()
426#endif
427
428#ifdef YYPURE
429#ifdef YYLSP_NEEDED
430#ifdef YYLEX_PARAM
431#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
432#else
433#define YYLEX yylex(&yylval, &yylloc)
434#endif
435#else /* not YYLSP_NEEDED */
436#ifdef YYLEX_PARAM
437#define YYLEX yylex(&yylval, YYLEX_PARAM)
438#else
439#define YYLEX yylex(&yylval)
440#endif
441#endif /* not YYLSP_NEEDED */
442#endif
443
444/* If nonreentrant, generate the variables here */
445
446#ifndef YYPURE
447
448int yychar; /* the lookahead symbol */
449YYSTYPE yylval; /* the semantic value of the */
450 /* lookahead symbol */
451
452#ifdef YYLSP_NEEDED
453YYLTYPE yylloc; /* location data for the lookahead */
454 /* symbol */
455#endif
456
457int yynerrs; /* number of parse errors so far */
458#endif /* not YYPURE */
459
460#if YYDEBUG != 0
461int yydebug; /* nonzero means print parse trace */
462/* Since this is uninitialized, it does not stop multiple parsers
463 from coexisting. */
464#endif
465
466/* YYINITDEPTH indicates the initial size of the parser's stacks */
467
468#ifndef YYINITDEPTH
469#define YYINITDEPTH 200
470#endif
471
472/* YYMAXDEPTH is the maximum size the stacks can grow to
473 (effective only if the built-in stack extension method is used). */
474
475#if YYMAXDEPTH == 0
476#undef YYMAXDEPTH
477#endif
478
479#ifndef YYMAXDEPTH
480#define YYMAXDEPTH 10000
481#endif
482\f
483/* Define __yy_memcpy. Note that the size argument
484 should be passed with type unsigned int, because that is what the non-GCC
485 definitions require. With GCC, __builtin_memcpy takes an arg
486 of type size_t, but it can handle unsigned int. */
487
488#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
489#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
490#else /* not GNU C or C++ */
491#ifndef __cplusplus
492
493/* This is the most reliable way to avoid incompatibilities
494 in available built-in functions on various systems. */
495static void
496__yy_memcpy (to, from, count)
497 char *to;
498 char *from;
499 unsigned int count;
500{
501 register char *f = from;
502 register char *t = to;
503 register int i = count;
504
505 while (i-- > 0)
506 *t++ = *f++;
507}
508
509#else /* __cplusplus */
510
511/* This is the most reliable way to avoid incompatibilities
512 in available built-in functions on various systems. */
513static void
514__yy_memcpy (char *to, char *from, unsigned int count)
515{
516 register char *t = to;
517 register char *f = from;
518 register int i = count;
519
520 while (i-- > 0)
521 *t++ = *f++;
522}
523
524#endif
525#endif
526\f
527#line 217 "/usr/share/bison.simple"
528
529/* The user can define YYPARSE_PARAM as the name of an argument to be passed
530 into yyparse. The argument should have type void *.
531 It should actually point to an object.
532 Grammar actions can access the variable by casting it
533 to the proper pointer type. */
534
535#ifdef YYPARSE_PARAM
536#ifdef __cplusplus
537#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
538#define YYPARSE_PARAM_DECL
539#else /* not __cplusplus */
540#define YYPARSE_PARAM_ARG YYPARSE_PARAM
541#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
542#endif /* not __cplusplus */
543#else /* not YYPARSE_PARAM */
544#define YYPARSE_PARAM_ARG
545#define YYPARSE_PARAM_DECL
546#endif /* not YYPARSE_PARAM */
547
548/* Prevent warning if -Wstrict-prototypes. */
549#ifdef __GNUC__
550#ifdef YYPARSE_PARAM
551int yyparse (void *);
552#else
553int yyparse (void);
554#endif
555#endif
556
557int
558yyparse(YYPARSE_PARAM_ARG)
559 YYPARSE_PARAM_DECL
560{
561 register int yystate;
562 register int yyn;
563 register short *yyssp;
564 register YYSTYPE *yyvsp;
565 int yyerrstatus; /* number of tokens to shift before error messages enabled */
566 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
567
568 short yyssa[YYINITDEPTH]; /* the state stack */
569 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
570
571 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
572 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
573
574#ifdef YYLSP_NEEDED
575 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
576 YYLTYPE *yyls = yylsa;
577 YYLTYPE *yylsp;
578
579#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
580#else
581#define YYPOPSTACK (yyvsp--, yyssp--)
582#endif
583
584 int yystacksize = YYINITDEPTH;
585 int yyfree_stacks = 0;
586
587#ifdef YYPURE
588 int yychar;
589 YYSTYPE yylval;
590 int yynerrs;
591#ifdef YYLSP_NEEDED
592 YYLTYPE yylloc;
593#endif
594#endif
595
596 YYSTYPE yyval; /* the variable used to return */
597 /* semantic values from the action */
598 /* routines */
599
600 int yylen;
601
602#if YYDEBUG != 0
603 if (yydebug)
604 fprintf(stderr, "Starting parse\n");
605#endif
606
607 yystate = 0;
608 yyerrstatus = 0;
609 yynerrs = 0;
610 yychar = YYEMPTY; /* Cause a token to be read. */
611
612 /* Initialize stack pointers.
613 Waste one element of value and location stack
614 so that they stay on the same level as the state stack.
615 The wasted elements are never initialized. */
616
617 yyssp = yyss - 1;
618 yyvsp = yyvs;
619#ifdef YYLSP_NEEDED
620 yylsp = yyls;
621#endif
622
623/* Push a new state, which is found in yystate . */
624/* In all cases, when you get here, the value and location stacks
625 have just been pushed. so pushing a state here evens the stacks. */
626yynewstate:
627
628 *++yyssp = yystate;
629
630 if (yyssp >= yyss + yystacksize - 1)
631 {
632 /* Give user a chance to reallocate the stack */
633 /* Use copies of these so that the &'s don't force the real ones into memory. */
634 YYSTYPE *yyvs1 = yyvs;
635 short *yyss1 = yyss;
636#ifdef YYLSP_NEEDED
637 YYLTYPE *yyls1 = yyls;
638#endif
639
640 /* Get the current used size of the three stacks, in elements. */
641 int size = yyssp - yyss + 1;
642
643#ifdef yyoverflow
644 /* Each stack pointer address is followed by the size of
645 the data in use in that stack, in bytes. */
646#ifdef YYLSP_NEEDED
647 /* This used to be a conditional around just the two extra args,
648 but that might be undefined if yyoverflow is a macro. */
649 yyoverflow("parser stack overflow",
650 &yyss1, size * sizeof (*yyssp),
651 &yyvs1, size * sizeof (*yyvsp),
652 &yyls1, size * sizeof (*yylsp),
653 &yystacksize);
654#else
655 yyoverflow("parser stack overflow",
656 &yyss1, size * sizeof (*yyssp),
657 &yyvs1, size * sizeof (*yyvsp),
658 &yystacksize);
659#endif
660
661 yyss = yyss1; yyvs = yyvs1;
662#ifdef YYLSP_NEEDED
663 yyls = yyls1;
664#endif
665#else /* no yyoverflow */
666 /* Extend the stack our own way. */
667 if (yystacksize >= YYMAXDEPTH)
668 {
669 yyerror("parser stack overflow");
670 if (yyfree_stacks)
671 {
672 free (yyss);
673 free (yyvs);
674#ifdef YYLSP_NEEDED
675 free (yyls);
676#endif
677 }
678 return 2;
679 }
680 yystacksize *= 2;
681 if (yystacksize > YYMAXDEPTH)
682 yystacksize = YYMAXDEPTH;
683#ifndef YYSTACK_USE_ALLOCA
684 yyfree_stacks = 1;
685#endif
686 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
687 __yy_memcpy ((char *)yyss, (char *)yyss1,
688 size * (unsigned int) sizeof (*yyssp));
689 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
690 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
691 size * (unsigned int) sizeof (*yyvsp));
692#ifdef YYLSP_NEEDED
693 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
694 __yy_memcpy ((char *)yyls, (char *)yyls1,
695 size * (unsigned int) sizeof (*yylsp));
696#endif
697#endif /* no yyoverflow */
698
699 yyssp = yyss + size - 1;
700 yyvsp = yyvs + size - 1;
701#ifdef YYLSP_NEEDED
702 yylsp = yyls + size - 1;
703#endif
704
705#if YYDEBUG != 0
706 if (yydebug)
707 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
708#endif
709
710 if (yyssp >= yyss + yystacksize - 1)
711 YYABORT;
712 }
713
714#if YYDEBUG != 0
715 if (yydebug)
716 fprintf(stderr, "Entering state %d\n", yystate);
717#endif
718
719 goto yybackup;
720 yybackup:
721
722/* Do appropriate processing given the current state. */
723/* Read a lookahead token if we need one and don't already have one. */
724/* yyresume: */
725
726 /* First try to decide what to do without reference to lookahead token. */
727
728 yyn = yypact[yystate];
729 if (yyn == YYFLAG)
730 goto yydefault;
731
732 /* Not known => get a lookahead token if don't already have one. */
733
734 /* yychar is either YYEMPTY or YYEOF
735 or a valid token in external form. */
736
737 if (yychar == YYEMPTY)
738 {
739#if YYDEBUG != 0
740 if (yydebug)
741 fprintf(stderr, "Reading a token: ");
742#endif
743 yychar = YYLEX;
744 }
745
746 /* Convert token to internal form (in yychar1) for indexing tables with */
747
748 if (yychar <= 0) /* This means end of input. */
749 {
750 yychar1 = 0;
751 yychar = YYEOF; /* Don't call YYLEX any more */
752
753#if YYDEBUG != 0
754 if (yydebug)
755 fprintf(stderr, "Now at end of input.\n");
756#endif
757 }
758 else
759 {
760 yychar1 = YYTRANSLATE(yychar);
761
762#if YYDEBUG != 0
763 if (yydebug)
764 {
765 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
766 /* Give the individual parser a way to print the precise meaning
767 of a token, for further debugging info. */
768#ifdef YYPRINT
769 YYPRINT (stderr, yychar, yylval);
770#endif
771 fprintf (stderr, ")\n");
772 }
773#endif
774 }
775
776 yyn += yychar1;
777 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
778 goto yydefault;
779
780 yyn = yytable[yyn];
781
782 /* yyn is what to do for this token type in this state.
783 Negative => reduce, -yyn is rule number.
784 Positive => shift, yyn is new state.
785 New state is final state => don't bother to shift,
786 just return success.
787 0, or most negative number => error. */
788
789 if (yyn < 0)
790 {
791 if (yyn == YYFLAG)
792 goto yyerrlab;
793 yyn = -yyn;
794 goto yyreduce;
795 }
796 else if (yyn == 0)
797 goto yyerrlab;
798
799 if (yyn == YYFINAL)
800 YYACCEPT;
801
802 /* Shift the lookahead token. */
803
804#if YYDEBUG != 0
805 if (yydebug)
806 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
807#endif
808
809 /* Discard the token being shifted unless it is eof. */
810 if (yychar != YYEOF)
811 yychar = YYEMPTY;
812
813 *++yyvsp = yylval;
814#ifdef YYLSP_NEEDED
815 *++yylsp = yylloc;
816#endif
817
818 /* count tokens shifted since error; after three, turn off error status. */
819 if (yyerrstatus) yyerrstatus--;
820
821 yystate = yyn;
822 goto yynewstate;
823
824/* Do the default action for the current state. */
825yydefault:
826
827 yyn = yydefact[yystate];
828 if (yyn == 0)
829 goto yyerrlab;
830
831/* Do a reduction. yyn is the number of a rule to reduce with. */
832yyreduce:
833 yylen = yyr2[yyn];
834 if (yylen > 0)
835 yyval = yyvsp[1-yylen]; /* implement default value of the action */
836
837#if YYDEBUG != 0
838 if (yydebug)
839 {
840 int i;
841
842 fprintf (stderr, "Reducing via rule %d (line %d), ",
843 yyn, yyrline[yyn]);
844
845 /* Print the symbols being reduced, and their result. */
846 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
847 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
848 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
849 }
850#endif
851
852
853 switch (yyn) {
854
855case 1:
55e303ae
A
856#line 144 "OSUnserializeXML.y"
857{ yyerror("unexpected end of buffer");
858 YYERROR;
859 ;
1c79356b
A
860 break;}
861case 2:
55e303ae
A
862#line 147 "OSUnserializeXML.y"
863{ STATE->parsedObject = yyvsp[0]->object;
1c79356b 864 yyvsp[0]->object = 0;
55e303ae 865 freeObject(STATE, yyvsp[0]);
1c79356b
A
866 YYACCEPT;
867 ;
868 break;}
869case 3:
55e303ae
A
870#line 152 "OSUnserializeXML.y"
871{ yyerror("syntax error");
1c79356b
A
872 YYERROR;
873 ;
874 break;}
875case 4:
55e303ae
A
876#line 157 "OSUnserializeXML.y"
877{ yyval = buildDictionary(STATE, yyvsp[0]); ;
1c79356b
A
878 break;}
879case 5:
55e303ae
A
880#line 158 "OSUnserializeXML.y"
881{ yyval = buildArray(STATE, yyvsp[0]); ;
1c79356b
A
882 break;}
883case 6:
55e303ae
A
884#line 159 "OSUnserializeXML.y"
885{ yyval = buildSet(STATE, yyvsp[0]); ;
1c79356b
A
886 break;}
887case 7:
55e303ae
A
888#line 160 "OSUnserializeXML.y"
889{ yyval = buildString(STATE, yyvsp[0]); ;
1c79356b
A
890 break;}
891case 8:
55e303ae
A
892#line 161 "OSUnserializeXML.y"
893{ yyval = buildData(STATE, yyvsp[0]); ;
1c79356b
A
894 break;}
895case 9:
55e303ae
A
896#line 162 "OSUnserializeXML.y"
897{ yyval = buildNumber(STATE, yyvsp[0]); ;
1c79356b
A
898 break;}
899case 10:
55e303ae
A
900#line 163 "OSUnserializeXML.y"
901{ yyval = buildBoolean(STATE, yyvsp[0]); ;
1c79356b
A
902 break;}
903case 11:
55e303ae
A
904#line 164 "OSUnserializeXML.y"
905{ yyval = retrieveObject(STATE, yyvsp[0]->idref);
1c79356b
A
906 if (yyval) {
907 yyval->object->retain();
908 } else {
909 yyerror("forward reference detected");
910 YYERROR;
911 }
55e303ae 912 freeObject(STATE, yyvsp[0]);
1c79356b
A
913 ;
914 break;}
915case 12:
55e303ae 916#line 177 "OSUnserializeXML.y"
1c79356b
A
917{ yyval = yyvsp[-1];
918 yyval->elements = NULL;
919 ;
920 break;}
921case 13:
55e303ae 922#line 180 "OSUnserializeXML.y"
1c79356b
A
923{ yyval = yyvsp[-2];
924 yyval->elements = yyvsp[-1];
925 ;
926 break;}
927case 16:
55e303ae 928#line 187 "OSUnserializeXML.y"
1c79356b
A
929{ yyval = yyvsp[0];
930 yyval->next = yyvsp[-1];
931 ;
932 break;}
933case 17:
55e303ae 934#line 192 "OSUnserializeXML.y"
1c79356b 935{ yyval = yyvsp[-1];
55e303ae 936 yyval->key = yyval->object;
1c79356b 937 yyval->object = yyvsp[0]->object;
55e303ae 938 yyval->next = NULL;
1c79356b 939 yyvsp[0]->object = 0;
55e303ae 940 freeObject(STATE, yyvsp[0]);
1c79356b
A
941 ;
942 break;}
943case 18:
55e303ae
A
944#line 201 "OSUnserializeXML.y"
945{ yyval = buildString(STATE, yyvsp[0]); ;
1c79356b
A
946 break;}
947case 19:
55e303ae 948#line 206 "OSUnserializeXML.y"
1c79356b
A
949{ yyval = yyvsp[-1];
950 yyval->elements = NULL;
951 ;
952 break;}
953case 20:
55e303ae 954#line 209 "OSUnserializeXML.y"
1c79356b
A
955{ yyval = yyvsp[-2];
956 yyval->elements = yyvsp[-1];
957 ;
958 break;}
959case 22:
55e303ae 960#line 215 "OSUnserializeXML.y"
1c79356b
A
961{ yyval = yyvsp[-1];
962 yyval->elements = NULL;
963 ;
964 break;}
965case 23:
55e303ae 966#line 218 "OSUnserializeXML.y"
1c79356b
A
967{ yyval = yyvsp[-2];
968 yyval->elements = yyvsp[-1];
969 ;
970 break;}
971case 25:
55e303ae 972#line 224 "OSUnserializeXML.y"
1c79356b
A
973{ yyval = yyvsp[0];
974 yyval->next = NULL;
975 ;
976 break;}
977case 26:
55e303ae 978#line 227 "OSUnserializeXML.y"
1c79356b
A
979{ yyval = yyvsp[0];
980 yyval->next = yyvsp[-1];
981 ;
982 break;}
983}
984 /* the action file gets copied in in place of this dollarsign */
985#line 543 "/usr/share/bison.simple"
986\f
987 yyvsp -= yylen;
988 yyssp -= yylen;
989#ifdef YYLSP_NEEDED
990 yylsp -= yylen;
991#endif
992
993#if YYDEBUG != 0
994 if (yydebug)
995 {
996 short *ssp1 = yyss - 1;
997 fprintf (stderr, "state stack now");
998 while (ssp1 != yyssp)
999 fprintf (stderr, " %d", *++ssp1);
1000 fprintf (stderr, "\n");
1001 }
1002#endif
1003
1004 *++yyvsp = yyval;
1005
1006#ifdef YYLSP_NEEDED
1007 yylsp++;
1008 if (yylen == 0)
1009 {
1010 yylsp->first_line = yylloc.first_line;
1011 yylsp->first_column = yylloc.first_column;
1012 yylsp->last_line = (yylsp-1)->last_line;
1013 yylsp->last_column = (yylsp-1)->last_column;
1014 yylsp->text = 0;
1015 }
1016 else
1017 {
1018 yylsp->last_line = (yylsp+yylen-1)->last_line;
1019 yylsp->last_column = (yylsp+yylen-1)->last_column;
1020 }
1021#endif
1022
1023 /* Now "shift" the result of the reduction.
1024 Determine what state that goes to,
1025 based on the state we popped back to
1026 and the rule number reduced by. */
1027
1028 yyn = yyr1[yyn];
1029
1030 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1031 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1032 yystate = yytable[yystate];
1033 else
1034 yystate = yydefgoto[yyn - YYNTBASE];
1035
1036 goto yynewstate;
1037
1038yyerrlab: /* here on detecting error */
1039
1040 if (! yyerrstatus)
1041 /* If not already recovering from an error, report this error. */
1042 {
1043 ++yynerrs;
1044
1045#ifdef YYERROR_VERBOSE
1046 yyn = yypact[yystate];
1047
1048 if (yyn > YYFLAG && yyn < YYLAST)
1049 {
1050 int size = 0;
1051 char *msg;
1052 int x, count;
1053
1054 count = 0;
1055 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1056 for (x = (yyn < 0 ? -yyn : 0);
1057 x < (sizeof(yytname) / sizeof(char *)); x++)
1058 if (yycheck[x + yyn] == x)
1059 size += strlen(yytname[x]) + 15, count++;
1060 msg = (char *) malloc(size + 15);
1061 if (msg != 0)
1062 {
1063 strcpy(msg, "parse error");
1064
1065 if (count < 5)
1066 {
1067 count = 0;
1068 for (x = (yyn < 0 ? -yyn : 0);
1069 x < (sizeof(yytname) / sizeof(char *)); x++)
1070 if (yycheck[x + yyn] == x)
1071 {
1072 strcat(msg, count == 0 ? ", expecting `" : " or `");
1073 strcat(msg, yytname[x]);
1074 strcat(msg, "'");
1075 count++;
1076 }
1077 }
1078 yyerror(msg);
1079 free(msg);
1080 }
1081 else
1082 yyerror ("parse error; also virtual memory exceeded");
1083 }
1084 else
1085#endif /* YYERROR_VERBOSE */
1086 yyerror("parse error");
1087 }
1088
1089 goto yyerrlab1;
1090yyerrlab1: /* here on error raised explicitly by an action */
1091
1092 if (yyerrstatus == 3)
1093 {
1094 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1095
1096 /* return failure if at end of input */
1097 if (yychar == YYEOF)
1098 YYABORT;
1099
1100#if YYDEBUG != 0
1101 if (yydebug)
1102 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1103#endif
1104
1105 yychar = YYEMPTY;
1106 }
1107
1108 /* Else will try to reuse lookahead token
1109 after shifting the error token. */
1110
1111 yyerrstatus = 3; /* Each real token shifted decrements this */
1112
1113 goto yyerrhandle;
1114
1115yyerrdefault: /* current state does not do anything special for the error token. */
1116
1117#if 0
1118 /* This is wrong; only states that explicitly want error tokens
1119 should shift them. */
1120 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1121 if (yyn) goto yydefault;
1122#endif
1123
1124yyerrpop: /* pop the current state because it cannot handle the error token */
1125
1126 if (yyssp == yyss) YYABORT;
1127 yyvsp--;
1128 yystate = *--yyssp;
1129#ifdef YYLSP_NEEDED
1130 yylsp--;
1131#endif
1132
1133#if YYDEBUG != 0
1134 if (yydebug)
1135 {
1136 short *ssp1 = yyss - 1;
1137 fprintf (stderr, "Error: state stack now");
1138 while (ssp1 != yyssp)
1139 fprintf (stderr, " %d", *++ssp1);
1140 fprintf (stderr, "\n");
1141 }
1142#endif
1143
1144yyerrhandle:
1145
1146 yyn = yypact[yystate];
1147 if (yyn == YYFLAG)
1148 goto yyerrdefault;
1149
1150 yyn += YYTERROR;
1151 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1152 goto yyerrdefault;
1153
1154 yyn = yytable[yyn];
1155 if (yyn < 0)
1156 {
1157 if (yyn == YYFLAG)
1158 goto yyerrpop;
1159 yyn = -yyn;
1160 goto yyreduce;
1161 }
1162 else if (yyn == 0)
1163 goto yyerrpop;
1164
1165 if (yyn == YYFINAL)
1166 YYACCEPT;
1167
1168#if YYDEBUG != 0
1169 if (yydebug)
1170 fprintf(stderr, "Shifting error token, ");
1171#endif
1172
1173 *++yyvsp = yylval;
1174#ifdef YYLSP_NEEDED
1175 *++yylsp = yylloc;
1176#endif
1177
1178 yystate = yyn;
1179 goto yynewstate;
1180
1181 yyacceptlab:
1182 /* YYACCEPT comes here. */
1183 if (yyfree_stacks)
1184 {
1185 free (yyss);
1186 free (yyvs);
1187#ifdef YYLSP_NEEDED
1188 free (yyls);
1189#endif
1190 }
1191 return 0;
1192
1193 yyabortlab:
1194 /* YYABORT comes here. */
1195 if (yyfree_stacks)
1196 {
1197 free (yyss);
1198 free (yyvs);
1199#ifdef YYLSP_NEEDED
1200 free (yyls);
1201#endif
1202 }
1203 return 1;
1204}
55e303ae 1205#line 249 "OSUnserializeXML.y"
1c79356b 1206
1c79356b
A
1207
1208int
55e303ae 1209OSUnserializeerror(parser_state_t * state, char *s) /* Called by yyparse on errors */
1c79356b 1210{
55e303ae
A
1211 char tempString[128];
1212
1213 if (state->errorString) {
1214 snprintf(tempString, 128, "OSUnserializeXML: %s near line %d\n", s, state->lineNumber);
1215 *(state->errorString) = OSString::withCString(tempString);
1216 }
1217
1218 return 0;
1c79356b
A
1219}
1220
1221#define TAG_MAX_LENGTH 32
1222#define TAG_MAX_ATTRIBUTES 32
1223#define TAG_BAD 0
1224#define TAG_START 1
1225#define TAG_END 2
1226#define TAG_EMPTY 3
1227#define TAG_COMMENT 4
1228
55e303ae
A
1229#define currentChar() (state->parseBuffer[state->parseBufferIndex])
1230#define nextChar() (state->parseBuffer[++state->parseBufferIndex])
1231#define prevChar() (state->parseBuffer[state->parseBufferIndex - 1])
1232
1233#define isSpace(c) ((c) == ' ' || (c) == '\t')
1234#define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1235#define isDigit(c) ((c) >= '0' && (c) <= '9')
1236#define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
1237#define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
1238#define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1239
1c79356b 1240static int
55e303ae
A
1241getTag(parser_state_t *state,
1242 char tag[TAG_MAX_LENGTH],
1c79356b
A
1243 int *attributeCount,
1244 char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH],
1245 char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH] )
1246{
55e303ae 1247 int length = 0;
1c79356b
A
1248 int c = currentChar();
1249 int tagType = TAG_START;
1250
1251 *attributeCount = 0;
1252
1253 if (c != '<') return TAG_BAD;
1254 c = nextChar(); // skip '<'
1255
1256 if (c == '?' || c == '!') {
1257 while ((c = nextChar()) != 0) {
55e303ae 1258 if (c == '\n') state->lineNumber++;
1c79356b
A
1259 if (c == '>') {
1260 (void)nextChar();
1261 return TAG_COMMENT;
1262 }
1263 }
1264 }
1265
1266 if (c == '/') {
1267 c = nextChar(); // skip '/'
1268 tagType = TAG_END;
1269 }
1270 if (!isAlpha(c)) return TAG_BAD;
1271
1272 /* find end of tag while copying it */
1273 while (isAlphaNumeric(c)) {
1274 tag[length++] = c;
1275 c = nextChar();
1276 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
1277 }
1278
1279 tag[length] = 0;
1280
55e303ae 1281// printf("tag %s, type %d\n", tag, tagType);
1c79356b
A
1282
1283 // look for attributes of the form attribute = "value" ...
1284 while ((c != '>') && (c != '/')) {
1285 while (isSpace(c)) c = nextChar();
1286
1287 length = 0;
1288 while (isAlphaNumeric(c)) {
1289 attributes[*attributeCount][length++] = c;
1290 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
1291 c = nextChar();
1292 }
1293 attributes[*attributeCount][length] = 0;
1294
1295 while (isSpace(c)) c = nextChar();
1296
1297 if (c != '=') return TAG_BAD;
1298 c = nextChar();
1299
1300 while (isSpace(c)) c = nextChar();
1301
1302 if (c != '"') return TAG_BAD;
1303 c = nextChar();
1304 length = 0;
1305 while (c != '"') {
1306 values[*attributeCount][length++] = c;
1307 if (length >= (TAG_MAX_LENGTH - 1)) return TAG_BAD;
1308 c = nextChar();
1309 }
1310 values[*attributeCount][length] = 0;
1311
1312 c = nextChar(); // skip closing quote
1313
55e303ae
A
1314// printf(" attribute '%s' = '%s', nextchar = '%c'\n",
1315// attributes[*attributeCount], values[*attributeCount], c);
1c79356b
A
1316
1317 (*attributeCount)++;
1318 if (*attributeCount >= TAG_MAX_ATTRIBUTES) return TAG_BAD;
1319 }
1320
1321 if (c == '/') {
1322 c = nextChar(); // skip '/'
1323 tagType = TAG_EMPTY;
1324 }
1325 if (c != '>') return TAG_BAD;
1326 c = nextChar(); // skip '>'
1327
1328 return tagType;
1329}
1330
1331static char *
55e303ae 1332getString(parser_state_t *state)
1c79356b
A
1333{
1334 int c = currentChar();
55e303ae 1335 int start, length, i, j;
1c79356b
A
1336 char * tempString;
1337
55e303ae 1338 start = state->parseBufferIndex;
1c79356b
A
1339 /* find end of string */
1340
1341 while (c != 0) {
55e303ae 1342 if (c == '\n') state->lineNumber++;
1c79356b
A
1343 if (c == '<') {
1344 break;
1345 }
1346 c = nextChar();
1347 }
1348
1349 if (c != '<') return 0;
1350
55e303ae 1351 length = state->parseBufferIndex - start;
1c79356b
A
1352
1353 /* copy to null terminated buffer */
1354 tempString = (char *)malloc(length + 1);
1355 if (tempString == 0) {
1356 printf("OSUnserializeXML: can't alloc temp memory\n");
55e303ae 1357 goto error;
1c79356b
A
1358 }
1359
1360 // copy out string in tempString
1361 // "&amp;" -> '&', "&lt;" -> '<', "&gt;" -> '>'
1362
1363 i = j = 0;
1364 while (i < length) {
55e303ae 1365 c = state->parseBuffer[start + i++];
1c79356b
A
1366 if (c != '&') {
1367 tempString[j++] = c;
1368 } else {
1369 if ((i+3) > length) goto error;
55e303ae 1370 c = state->parseBuffer[start + i++];
1c79356b 1371 if (c == 'l') {
55e303ae
A
1372 if (state->parseBuffer[start + i++] != 't') goto error;
1373 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
1374 tempString[j++] = '<';
1375 continue;
1376 }
1377 if (c == 'g') {
55e303ae
A
1378 if (state->parseBuffer[start + i++] != 't') goto error;
1379 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
1380 tempString[j++] = '>';
1381 continue;
1382 }
1383 if ((i+3) > length) goto error;
1384 if (c == 'a') {
55e303ae
A
1385 if (state->parseBuffer[start + i++] != 'm') goto error;
1386 if (state->parseBuffer[start + i++] != 'p') goto error;
1387 if (state->parseBuffer[start + i++] != ';') goto error;
1c79356b
A
1388 tempString[j++] = '&';
1389 continue;
1390 }
1391 goto error;
1392 }
1393 }
1394 tempString[j] = 0;
1395
55e303ae 1396// printf("string %s\n", tempString);
1c79356b
A
1397
1398 return tempString;
1399
1400error:
1401 if (tempString) free(tempString);
1402 return 0;
1403}
1404
1405static long long
55e303ae 1406getNumber(parser_state_t *state)
1c79356b
A
1407{
1408 unsigned long long n = 0;
1409 int base = 10;
91447636 1410 bool negate = false;
1c79356b
A
1411 int c = currentChar();
1412
1c79356b
A
1413 if (c == '0') {
1414 c = nextChar();
1415 if (c == 'x') {
1416 base = 16;
1417 c = nextChar();
1418 }
1419 }
1420 if (base == 10) {
91447636
A
1421 if (c == '-') {
1422 negate = true;
1423 c = nextChar();
1424 }
1c79356b
A
1425 while(isDigit(c)) {
1426 n = (n * base + c - '0');
1427 c = nextChar();
1428 }
91447636
A
1429 if (negate) {
1430 n = (unsigned long long)((long long)n * (long long)-1);
1431 }
1c79356b
A
1432 } else {
1433 while(isHexDigit(c)) {
1434 if (isDigit(c)) {
1435 n = (n * base + c - '0');
1436 } else {
1437 n = (n * base + 0xa + c - 'a');
1438 }
1439 c = nextChar();
1440 }
1441 }
55e303ae 1442// printf("number 0x%x\n", (unsigned long)n);
1c79356b
A
1443 return n;
1444}
1445
1446// taken from CFXMLParsing/CFPropertyList.c
1447
1448static const signed char __CFPLDataDecodeTable[128] = {
1449 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
1450 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
1451 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
1452 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
1453 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
1454 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
1455 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
1456 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1,
1457 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6,
1458 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14,
1459 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
1460 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
1461 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
1462 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
1463 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
1464 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
1465};
1466
55e303ae 1467#define DATA_ALLOC_SIZE 4096
1c79356b
A
1468
1469static void *
55e303ae 1470getCFEncodedData(parser_state_t *state, unsigned int *size)
1c79356b
A
1471{
1472 int numeq = 0, acc = 0, cntr = 0;
1473 int tmpbufpos = 0, tmpbuflen = 0;
55e303ae 1474 unsigned char *tmpbuf = (unsigned char *)malloc(DATA_ALLOC_SIZE);
1c79356b
A
1475
1476 int c = currentChar();
1477 *size = 0;
1478
1479 while (c != '<') {
1480 c &= 0x7f;
1481 if (c == 0) {
1482 free(tmpbuf);
1483 return 0;
1484 }
1485 if (c == '=') numeq++; else numeq = 0;
55e303ae 1486 if (c == '\n') state->lineNumber++;
1c79356b
A
1487 if (__CFPLDataDecodeTable[c] < 0) {
1488 c = nextChar();
1489 continue;
1490 }
1491 cntr++;
1492 acc <<= 6;
1493 acc += __CFPLDataDecodeTable[c];
1494 if (0 == (cntr & 0x3)) {
1495 if (tmpbuflen <= tmpbufpos + 2) {
55e303ae 1496 tmpbuflen += DATA_ALLOC_SIZE;
1c79356b
A
1497 tmpbuf = (unsigned char *)realloc(tmpbuf, tmpbuflen);
1498 }
1499 tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
1500 if (numeq < 2)
1501 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
1502 if (numeq < 1)
1503 tmpbuf[tmpbufpos++] = acc & 0xff;
1504 }
1505 c = nextChar();
1506 }
1507 *size = tmpbufpos;
55e303ae
A
1508 if (*size == 0) {
1509 free(tmpbuf);
1510 return 0;
1511 }
1c79356b
A
1512 return tmpbuf;
1513}
1514
1515static void *
55e303ae 1516getHexData(parser_state_t *state, unsigned int *size)
1c79356b
A
1517{
1518 int c;
1519 unsigned char *d, *start, *lastStart;
1520
55e303ae 1521 start = lastStart = d = (unsigned char *)malloc(DATA_ALLOC_SIZE);
1c79356b
A
1522 c = currentChar();
1523
1524 while (c != '<') {
1525
1526 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1527 if (c == '\n') {
55e303ae 1528 state->lineNumber++;
1c79356b
A
1529 c = nextChar();
1530 continue;
1531 }
1532
1533 // get high nibble
1534 if (isDigit(c)) {
1535 *d = (c - '0') << 4;
1536 } else if (isAlphaDigit(c)) {
1537 *d = (0xa + (c - 'a')) << 4;
1538 } else {
1539 goto error;
1540 }
1541
1542 // get low nibble
1543 c = nextChar();
1544 if (isDigit(c)) {
1545 *d |= c - '0';
1546 } else if (isAlphaDigit(c)) {
1547 *d |= 0xa + (c - 'a');
1548 } else {
1549 goto error;
1550 }
1551
1552 d++;
55e303ae 1553 if ((d - lastStart) >= DATA_ALLOC_SIZE) {
1c79356b 1554 int oldsize = d - start;
55e303ae 1555 start = (unsigned char *)realloc(start, oldsize + DATA_ALLOC_SIZE);
1c79356b
A
1556 d = lastStart = start + oldsize;
1557 }
1558 c = nextChar();
1559 }
1560
1561 *size = d - start;
1562 return start;
1563
1564 error:
1565
1566 *size = 0;
1567 free(start);
1568 return 0;
1569}
1570
1571static int
55e303ae 1572yylex(YYSTYPE *lvalp, parser_state_t *state)
1c79356b 1573{
55e303ae 1574 int c, i;
1c79356b
A
1575 int tagType;
1576 char tag[TAG_MAX_LENGTH];
1577 int attributeCount;
1578 char attributes[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
1579 char values[TAG_MAX_ATTRIBUTES][TAG_MAX_LENGTH];
55e303ae 1580 object_t *object;
1c79356b
A
1581
1582 top:
1583 c = currentChar();
1584
1585 /* skip white space */
1586 if (isSpace(c)) while ((c = nextChar()) != 0 && isSpace(c)) {};
1587
1588 /* keep track of line number, don't return \n's */
1589 if (c == '\n') {
55e303ae 1590 STATE->lineNumber++;
1c79356b
A
1591 (void)nextChar();
1592 goto top;
1593 }
1c79356b 1594
55e303ae
A
1595 // end of the buffer?
1596 if (!c) return 0;
1597
1598 tagType = getTag(STATE, tag, &attributeCount, attributes, values);
1c79356b
A
1599 if (tagType == TAG_BAD) return SYNTAX_ERROR;
1600 if (tagType == TAG_COMMENT) goto top;
1601
1602 // handle allocation and check for "ID" and "IDREF" tags up front
55e303ae
A
1603 *lvalp = object = newObject(STATE);
1604 object->idref = -1;
1605 for (i=0; i < attributeCount; i++) {
1c79356b
A
1606 if (attributes[i][0] == 'I' && attributes[i][1] == 'D') {
1607 // check for idref's, note: we ignore the tag, for
1608 // this to work correctly, all idrefs must be unique
1609 // across the whole serialization
1610 if (attributes[i][2] == 'R' && attributes[i][3] == 'E' &&
1611 attributes[i][4] == 'F' && !attributes[i][5]) {
1612 if (tagType != TAG_EMPTY) return SYNTAX_ERROR;
55e303ae 1613 object->idref = strtol(values[i], NULL, 0);
1c79356b
A
1614 return IDREF;
1615 }
1616 // check for id's
1617 if (!attributes[i][2]) {
55e303ae 1618 object->idref = strtol(values[i], NULL, 0);
1c79356b
A
1619 } else {
1620 return SYNTAX_ERROR;
1621 }
1622 }
1623 }
1624
1625 switch (*tag) {
1626 case 'a':
1627 if (!strcmp(tag, "array")) {
1628 if (tagType == TAG_EMPTY) {
55e303ae 1629 object->elements = NULL;
1c79356b
A
1630 return ARRAY;
1631 }
1632 return (tagType == TAG_START) ? '(' : ')';
1633 }
1634 break;
1635 case 'd':
1636 if (!strcmp(tag, "dict")) {
1637 if (tagType == TAG_EMPTY) {
55e303ae 1638 object->elements = NULL;
1c79356b
A
1639 return DICTIONARY;
1640 }
1641 return (tagType == TAG_START) ? '{' : '}';
1642 }
1643 if (!strcmp(tag, "data")) {
1644 unsigned int size;
1c79356b 1645 if (tagType == TAG_EMPTY) {
55e303ae
A
1646 object->data = NULL;
1647 object->size = 0;
1c79356b
A
1648 return DATA;
1649 }
55e303ae
A
1650
1651 bool isHexFormat = false;
1c79356b
A
1652 for (int i=0; i < attributeCount; i++) {
1653 if (!strcmp(attributes[i], "format") && !strcmp(values[i], "hex")) {
55e303ae 1654 isHexFormat = true;
1c79356b
A
1655 break;
1656 }
1657 }
1658 // CF encoded is the default form
55e303ae
A
1659 if (isHexFormat) {
1660 object->data = getHexData(STATE, &size);
1c79356b 1661 } else {
55e303ae 1662 object->data = getCFEncodedData(STATE, &size);
1c79356b 1663 }
55e303ae
A
1664 object->size = size;
1665 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "data")) {
1c79356b
A
1666 return SYNTAX_ERROR;
1667 }
1668 return DATA;
1669 }
1670 break;
1671 case 'f':
1672 if (!strcmp(tag, "false")) {
1673 if (tagType == TAG_EMPTY) {
55e303ae 1674 object->number = 0;
1c79356b
A
1675 return BOOLEAN;
1676 }
1677 }
1678 break;
1679 case 'i':
1680 if (!strcmp(tag, "integer")) {
55e303ae
A
1681 object->size = 64; // default
1682 for (i=0; i < attributeCount; i++) {
1c79356b 1683 if (!strcmp(attributes[i], "size")) {
55e303ae 1684 object->size = strtoul(values[i], NULL, 0);
1c79356b
A
1685 }
1686 }
1687 if (tagType == TAG_EMPTY) {
55e303ae 1688 object->number = 0;
1c79356b
A
1689 return NUMBER;
1690 }
55e303ae
A
1691 object->number = getNumber(STATE);
1692 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END) || strcmp(tag, "integer")) {
1c79356b
A
1693 return SYNTAX_ERROR;
1694 }
1695 return NUMBER;
1696 }
1697 break;
1698 case 'k':
1699 if (!strcmp(tag, "key")) {
1700 if (tagType == TAG_EMPTY) return SYNTAX_ERROR;
55e303ae
A
1701 object->string = getString(STATE);
1702 if (!object->string) {
1c79356b
A
1703 return SYNTAX_ERROR;
1704 }
55e303ae 1705 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
1c79356b
A
1706 || strcmp(tag, "key")) {
1707 return SYNTAX_ERROR;
1708 }
1709 return KEY;
1710 }
1711 break;
1712 case 'p':
1713 if (!strcmp(tag, "plist")) {
55e303ae 1714 freeObject(STATE, object);
1c79356b
A
1715 goto top;
1716 }
1717 break;
1718 case 's':
1719 if (!strcmp(tag, "string")) {
1720 if (tagType == TAG_EMPTY) {
55e303ae
A
1721 object->string = (char *)malloc(1);
1722 object->string[0] = 0;
1c79356b
A
1723 return STRING;
1724 }
55e303ae
A
1725 object->string = getString(STATE);
1726 if (!object->string) {
1c79356b
A
1727 return SYNTAX_ERROR;
1728 }
55e303ae 1729 if ((getTag(STATE, tag, &attributeCount, attributes, values) != TAG_END)
1c79356b
A
1730 || strcmp(tag, "string")) {
1731 return SYNTAX_ERROR;
1732 }
1733 return STRING;
1734 }
1735 if (!strcmp(tag, "set")) {
1736 if (tagType == TAG_EMPTY) {
55e303ae 1737 object->elements = NULL;
1c79356b
A
1738 return SET;;
1739 }
1740 if (tagType == TAG_START) {
1741 return '[';
1742 } else {
1743 return ']';
1744 }
1745 }
1746 break;
1747 case 't':
1748 if (!strcmp(tag, "true")) {
1749 if (tagType == TAG_EMPTY) {
55e303ae 1750 object->number = 1;
1c79356b
A
1751 return BOOLEAN;
1752 }
1753 }
1754 break;
1c79356b
A
1755 }
1756
55e303ae 1757 return SYNTAX_ERROR;
1c79356b
A
1758}
1759
1760// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1761// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1762// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1763
1764// "java" like allocation, if this code hits a syntax error in the
1765// the middle of the parsed string we just bail with pointers hanging
55e303ae 1766// all over place, this code helps keeps it all together
1c79356b 1767
55e303ae 1768//static int object_count = 0;
1c79356b
A
1769
1770object_t *
55e303ae 1771newObject(parser_state_t *state)
1c79356b
A
1772{
1773 object_t *o;
1774
55e303ae
A
1775 if (state->freeObjects) {
1776 o = state->freeObjects;
1777 state->freeObjects = state->freeObjects->next;
1c79356b
A
1778 } else {
1779 o = (object_t *)malloc(sizeof(object_t));
55e303ae 1780// object_count++;
1c79356b 1781 bzero(o, sizeof(object_t));
55e303ae
A
1782 o->free = state->objects;
1783 state->objects = o;
1c79356b
A
1784 }
1785
1786 return o;
1787}
1788
1789void
55e303ae 1790freeObject(parser_state_t * state, object_t *o)
1c79356b 1791{
55e303ae
A
1792 o->next = state->freeObjects;
1793 state->freeObjects = o;
1c79356b
A
1794}
1795
1796void
55e303ae 1797cleanupObjects(parser_state_t *state)
1c79356b 1798{
55e303ae 1799 object_t *t, *o = state->objects;
1c79356b
A
1800
1801 while (o) {
1802 if (o->object) {
55e303ae 1803// printf("OSUnserializeXML: releasing object o=%x object=%x\n", (int)o, (int)o->object);
1c79356b
A
1804 o->object->release();
1805 }
1806 if (o->data) {
55e303ae 1807// printf("OSUnserializeXML: freeing object o=%x data=%x\n", (int)o, (int)o->data);
1c79356b
A
1808 free(o->data);
1809 }
1810 if (o->key) {
55e303ae 1811// printf("OSUnserializeXML: releasing object o=%x key=%x\n", (int)o, (int)o->key);
1c79356b
A
1812 o->key->release();
1813 }
1814 if (o->string) {
55e303ae 1815// printf("OSUnserializeXML: freeing object o=%x string=%x\n", (int)o, (int)o->string);
1c79356b
A
1816 free(o->string);
1817 }
1818
1819 t = o;
1820 o = o->free;
1821 free(t);
55e303ae 1822// object_count--;
1c79356b 1823 }
55e303ae 1824// printf("object_count = %d\n", object_count);
1c79356b
A
1825}
1826
1827// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1828// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1829// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1830
1c79356b 1831static void
55e303ae 1832rememberObject(parser_state_t *state, int tag, OSObject *o)
1c79356b
A
1833{
1834 char key[16];
55e303ae 1835 snprintf(key, 16, "%u", tag);
1c79356b 1836
55e303ae 1837// printf("remember key %s\n", key);
1c79356b 1838
55e303ae 1839 state->tags->setObject(key, o);
1c79356b
A
1840}
1841
1842static object_t *
55e303ae 1843retrieveObject(parser_state_t *state, int tag)
1c79356b 1844{
55e303ae
A
1845 OSObject *ref;
1846 object_t *o;
1c79356b 1847 char key[16];
55e303ae 1848 snprintf(key, 16, "%u", tag);
1c79356b 1849
55e303ae 1850// printf("retrieve key '%s'\n", key);
1c79356b 1851
55e303ae 1852 ref = state->tags->getObject(key);
1c79356b
A
1853 if (!ref) return 0;
1854
55e303ae 1855 o = newObject(state);
1c79356b
A
1856 o->object = ref;
1857 return o;
1858}
1859
1860// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1861// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1862// !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
1863
1864object_t *
55e303ae 1865buildDictionary(parser_state_t *state, object_t * header)
1c79356b
A
1866{
1867 object_t *o, *t;
1868 int count = 0;
55e303ae 1869 OSDictionary *dict;
1c79356b
A
1870
1871 // get count and reverse order
1872 o = header->elements;
1873 header->elements = 0;
1874 while (o) {
1875 count++;
1876 t = o;
1877 o = o->next;
1878
1879 t->next = header->elements;
1880 header->elements = t;
1881 }
1882
55e303ae
A
1883 dict = OSDictionary::withCapacity(count);
1884 if (header->idref >= 0) rememberObject(state, header->idref, dict);
1c79356b
A
1885
1886 o = header->elements;
1887 while (o) {
55e303ae
A
1888 dict->setObject(o->key, o->object);
1889
1c79356b 1890 o->key->release();
55e303ae 1891 o->object->release();
1c79356b 1892 o->key = 0;
55e303ae
A
1893 o->object = 0;
1894
1c79356b
A
1895 t = o;
1896 o = o->next;
55e303ae 1897 freeObject(state, t);
1c79356b
A
1898 }
1899 o = header;
55e303ae 1900 o->object = dict;
1c79356b
A
1901 return o;
1902};
1903
1904object_t *
55e303ae 1905buildArray(parser_state_t *state, object_t * header)
1c79356b
A
1906{
1907 object_t *o, *t;
1908 int count = 0;
55e303ae 1909 OSArray *array;
1c79356b
A
1910
1911 // get count and reverse order
1912 o = header->elements;
1913 header->elements = 0;
1914 while (o) {
1915 count++;
1916 t = o;
1917 o = o->next;
1918
1919 t->next = header->elements;
1920 header->elements = t;
1921 }
1922
55e303ae
A
1923 array = OSArray::withCapacity(count);
1924 if (header->idref >= 0) rememberObject(state, header->idref, array);
1c79356b
A
1925
1926 o = header->elements;
1927 while (o) {
55e303ae
A
1928 array->setObject(o->object);
1929
1c79356b
A
1930 o->object->release();
1931 o->object = 0;
55e303ae 1932
1c79356b
A
1933 t = o;
1934 o = o->next;
55e303ae 1935 freeObject(state, t);
1c79356b
A
1936 }
1937 o = header;
55e303ae 1938 o->object = array;
1c79356b
A
1939 return o;
1940};
1941
1942object_t *
55e303ae 1943buildSet(parser_state_t *state, object_t *header)
1c79356b 1944{
55e303ae 1945 object_t *o = buildArray(state, header);
1c79356b 1946
55e303ae
A
1947 OSArray *array = (OSArray *)o->object;
1948 OSSet *set = OSSet::withArray(array, array->getCapacity());
1c79356b 1949
55e303ae
A
1950 // write over the reference created in buildArray
1951 if (header->idref >= 0) rememberObject(state, header->idref, set);
1c79356b 1952
55e303ae
A
1953 array->release();
1954 o->object = set;
1c79356b
A
1955 return o;
1956};
1957
1958object_t *
55e303ae 1959buildString(parser_state_t *state, object_t *o)
1c79356b 1960{
55e303ae 1961 OSString *string;
1c79356b 1962
55e303ae
A
1963 string = OSString::withCString(o->string);
1964 if (o->idref >= 0) rememberObject(state, o->idref, string);
1c79356b
A
1965
1966 free(o->string);
1967 o->string = 0;
55e303ae 1968 o->object = string;
1c79356b
A
1969
1970 return o;
1971};
1972
1973object_t *
55e303ae 1974buildData(parser_state_t *state, object_t *o)
1c79356b 1975{
55e303ae 1976 OSData *data;
1c79356b
A
1977
1978 if (o->size) {
55e303ae 1979 data = OSData::withBytes(o->data, o->size);
1c79356b 1980 } else {
55e303ae 1981 data = OSData::withCapacity(0);
1c79356b 1982 }
55e303ae 1983 if (o->idref >= 0) rememberObject(state, o->idref, data);
1c79356b 1984
55e303ae 1985 if (o->size) free(o->data);
1c79356b 1986 o->data = 0;
55e303ae 1987 o->object = data;
1c79356b
A
1988 return o;
1989};
1990
1991object_t *
55e303ae 1992buildNumber(parser_state_t *state, object_t *o)
1c79356b 1993{
55e303ae 1994 OSNumber *number = OSNumber::withNumber(o->number, o->size);
1c79356b 1995
55e303ae 1996 if (o->idref >= 0) rememberObject(state, o->idref, number);
1c79356b 1997
55e303ae 1998 o->object = number;
1c79356b
A
1999 return o;
2000};
2001
2002object_t *
55e303ae 2003buildBoolean(parser_state_t *state, object_t *o)
1c79356b 2004{
55e303ae
A
2005 o->object = ((o->number == 0) ? kOSBooleanFalse : kOSBooleanTrue);
2006 o->object->retain();
1c79356b
A
2007 return o;
2008};
2009
1c79356b
A
2010OSObject*
2011OSUnserializeXML(const char *buffer, OSString **errorString)
2012{
2013 OSObject *object;
55e303ae 2014 parser_state_t *state = (parser_state_t *)malloc(sizeof(parser_state_t));
1c79356b 2015
55e303ae 2016 if ((!state) || (!buffer)) return 0;
1c79356b 2017
55e303ae
A
2018 // just in case
2019 if (errorString) *errorString = NULL;
1c79356b 2020
55e303ae
A
2021 state->parseBuffer = buffer;
2022 state->parseBufferIndex = 0;
2023 state->lineNumber = 1;
2024 state->objects = 0;
2025 state->freeObjects = 0;
2026 state->tags = OSDictionary::withCapacity(128);
2027 state->errorString = errorString;
2028 state->parsedObject = 0;
2029
2030 (void)yyparse((void *)state);
2031
2032 object = state->parsedObject;
1c79356b 2033
55e303ae
A
2034 cleanupObjects(state);
2035 state->tags->release();
2036 free(state);
1c79356b
A
2037
2038 return object;
2039}
2040
2041
2042//
2043//
2044//
2045//
2046//
2047// DO NOT EDIT OSUnserializeXML.cpp!
2048//
2049// this means you!
2050//
2051//
2052//
2053//
2054//