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