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