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