1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /* OSUnserialize.y created by rsulack on Nov 21 1998 */
30
31 // "classic" parser for unserializing OSContainer objects
32 //
33 // XXX - this code should really be removed!
34 // - the XML format is now prefered
35 // - this code leaks on syntax errors, the XML doesn't
36 // - "classic" looks, reads, ... much better than XML :-(
37 // - well except the XML is more efficent on OSData
38 //
39 //
40 // to build :
41 // bison -p OSUnserialize OSUnserialize.y
42 // head -50 OSUnserialize.y > OSUnserialize.cpp
43 // sed -e "s/stdio.h/stddef.h/" < OSUnserialize.tab.c >> OSUnserialize.cpp
44 //
45 // when changing code check in both OSUnserialize.y and OSUnserialize.cpp
46 //
47 //
48 //
49 //
50 // DO NOT EDIT OSUnserialize.tab.cpp!
51 /* A Bison parser, made by GNU Bison 2.3. */
52
53 /* Skeleton implementation for Bison's Yacc-like parsers in C
54 *
55 * Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
56 * Free Software Foundation, Inc.
57 *
58 * This program is free software; you can redistribute it and/or modify
59 * it under the terms of the GNU General Public License as published by
60 * the Free Software Foundation; either version 2, or (at your option)
61 * any later version.
62 *
63 * This program is distributed in the hope that it will be useful,
64 * but WITHOUT ANY WARRANTY; without even the implied warranty of
65 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66 * GNU General Public License for more details.
67 *
68 * You should have received a copy of the GNU General Public License
69 * along with this program; if not, write to the Free Software
70 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
71 * Boston, MA 02110-1301, USA. */
72
73 /* As a special exception, you may create a larger work that contains
74 * part or all of the Bison parser skeleton and distribute that work
75 * under terms of your choice, so long as that work isn't itself a
76 * parser generator using the skeleton or a modified version thereof
77 * as a parser skeleton. Alternatively, if you modify or redistribute
78 * the parser skeleton itself, you may (at your option) remove this
79 * special exception, which will cause the skeleton and the resulting
80 * Bison output files to be licensed under the GNU General Public
81 * License without this special exception.
82 *
83 * This special exception was added by the Free Software Foundation in
84 * version 2.2 of Bison. */
85
86 /* C LALR(1) parser skeleton written by Richard Stallman, by
87 * simplifying the original so-called "semantic" parser. */
88
89 /* All symbols defined below should begin with yy or YY, to avoid
90 * infringing on user name space. This should be done even for local
91 * variables, as they might otherwise be expanded by user macros.
92 * There are some unavoidable exceptions within include files to
93 * define necessary library symbols; they are noted "INFRINGES ON
94 * USER NAME SPACE" below. */
95
96 /* Identify Bison output. */
97 #define YYBISON 1
98
99 /* Bison version. */
100 #define YYBISON_VERSION "2.3"
101
102 /* Skeleton name. */
103 #define YYSKELETON_NAME "yacc.c"
104
105 /* Pure parsers. */
106 #define YYPURE 0
107
108 /* Using locations. */
109 #define YYLSP_NEEDED 0
110
111 /* Substitute the variable and function names. */
112 #define yyparse OSUnserializeparse
113 #define yylex OSUnserializelex
114 #define yyerror OSUnserializeerror
115 #define yylval OSUnserializelval
116 #define yychar OSUnserializechar
117 #define yydebug OSUnserializedebug
118 #define yynerrs OSUnserializenerrs
119
120
121 /* Tokens. */
122 #ifndef YYTOKENTYPE
123 # define YYTOKENTYPE
124 /* Put the tokens into the symbol table, so that GDB and other debuggers
125 * know about them. */
126 enum yytokentype {
127 NUMBER = 258,
128 STRING = 259,
129 DATA = 260,
130 BOOLEAN = 261,
131 SYNTAX_ERROR = 262
132 };
133 #endif
134 /* Tokens. */
135 #define NUMBER 258
136 #define STRING 259
137 #define DATA 260
138 #define BOOLEAN 261
139 #define SYNTAX_ERROR 262
140
141
142
143
144 /* Copy the first part of user declarations. */
145 #line 60 "OSUnserialize.y"
146
147 #include <libkern/c++/OSMetaClass.h>
148 #include <libkern/c++/OSContainers.h>
149 #include <libkern/c++/OSLib.h>
150
151 typedef struct object {
152 struct object *next;
153 struct object *prev;
154 void *object;
155 int size; // for data
156 union {
157 void *key; // for dictionary
158 long long offset; // for offset
159 } u;
160 } object_t;
161
162 static int yyerror(const char *s);
163 static int yylex();
164
165 static object_t * newObject();
166 static void freeObject(object_t *o);
167
168 static OSObject *buildOSDictionary(object_t *);
169 static OSObject *buildOSArray(object_t *);
170 static OSObject *buildOSSet(object_t *);
171 static OSObject *buildOSString(object_t *);
172 static OSObject *buildOSData(object_t *);
173 static OSObject *buildOSOffset(object_t *);
174 static OSObject *buildOSBoolean(object_t *o);
175
176 static void rememberObject(int, object_t *);
177 static OSObject *retrieveObject(int);
178
179 // temp variable to use during parsing
180 static object_t *oo;
181
182 // resultant object of parsed text
183 static OSObject *parsedObject;
184
185 #define YYSTYPE object_t *
186
187 __BEGIN_DECLS
188 #include <kern/kalloc.h>
189 __END_DECLS
190
191 // Omit from static analysis.
192 #ifndef __clang_analyzer__
193
194 #define malloc(size) malloc_impl(size)
195 #define malloc_type(type) kalloc_type(type, Z_WAITOK)
196 static inline void *
malloc_impl(size_t size)197 malloc_impl(size_t size)
198 {
199 if (size == 0) {
200 return NULL;
201 }
202 return kheap_alloc_tag_bt(KHEAP_DATA_BUFFERS, size,
203 (zalloc_flags_t) (Z_WAITOK | Z_ZERO),
204 VM_KERN_MEMORY_LIBKERN);
205 }
206
207 #define free(addr) free_impl(addr)
208 #define free_type(type, addr) kfree_type(type, addr)
209 static inline void
free_impl(void * addr)210 free_impl(void *addr)
211 {
212 kheap_free_addr(KHEAP_DATA_BUFFERS, addr);
213 }
214 static inline void
safe_free(void * addr,size_t size)215 safe_free(void *addr, size_t size)
216 {
217 if (addr) {
218 assert(size != 0);
219 kheap_free(KHEAP_DATA_BUFFERS, addr, size);
220 }
221 }
222
223 #define realloc(addr, osize, nsize) realloc_impl(addr, osize, nsize)
224 static inline void *
realloc_impl(void * addr,size_t osize,size_t nsize)225 realloc_impl(void *addr, size_t osize, size_t nsize)
226 {
227 if (!addr) {
228 return malloc(nsize);
229 }
230 if (nsize == osize) {
231 return addr;
232 }
233 void *nmem = malloc(nsize);
234 if (!nmem) {
235 safe_free(addr, osize);
236 return NULL;
237 }
238 (void)memcpy(nmem, addr, (nsize > osize) ? osize : nsize);
239 safe_free(addr, osize);
240
241 return nmem;
242 }
243
244
245
246 /* Enabling traces. */
247 #ifndef YYDEBUG
248 # define YYDEBUG 0
249 #endif
250
251 /* Enabling verbose error messages. */
252 #ifdef YYERROR_VERBOSE
253 # undef YYERROR_VERBOSE
254 # define YYERROR_VERBOSE 1
255 #else
256 # define YYERROR_VERBOSE 0
257 #endif
258
259 /* Enabling the token table. */
260 #ifndef YYTOKEN_TABLE
261 # define YYTOKEN_TABLE 0
262 #endif
263
264 #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED
265 typedef int YYSTYPE;
266 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
267 # define YYSTYPE_IS_DECLARED 1
268 # define YYSTYPE_IS_TRIVIAL 1
269 #endif
270
271
272
273 /* Copy the second part of user declarations. */
274
275
276 /* Line 216 of yacc.c. */
277 #line 229 "OSUnserialize.tab.c"
278
279 #ifdef short
280 # undef short
281 #endif
282
283 #ifdef YYTYPE_UINT8
284 typedef YYTYPE_UINT8 yytype_uint8;
285 #else
286 typedef unsigned char yytype_uint8;
287 #endif
288
289 #ifdef YYTYPE_INT8
290 typedef YYTYPE_INT8 yytype_int8;
291 #elif (defined __STDC__ || defined __C99__FUNC__ \
292 || defined __cplusplus || defined _MSC_VER)
293 typedef signed char yytype_int8;
294 #else
295 typedef short int yytype_int8;
296 #endif
297
298 #ifdef YYTYPE_UINT16
299 typedef YYTYPE_UINT16 yytype_uint16;
300 #else
301 typedef unsigned short int yytype_uint16;
302 #endif
303
304 #ifdef YYTYPE_INT16
305 typedef YYTYPE_INT16 yytype_int16;
306 #else
307 typedef short int yytype_int16;
308 #endif
309
310 #ifndef YYSIZE_T
311 # ifdef __SIZE_TYPE__
312 # define YYSIZE_T __SIZE_TYPE__
313 # elif defined size_t
314 # define YYSIZE_T size_t
315 # elif !defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
316 || defined __cplusplus || defined _MSC_VER)
317 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
318 # define YYSIZE_T size_t
319 # else
320 # define YYSIZE_T unsigned int
321 # endif
322 #endif
323
324 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
325
326 #ifndef YY_
327 # if defined YYENABLE_NLS && YYENABLE_NLS
328 # if ENABLE_NLS
329 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
330 # define YY_(msgid) dgettext ("bison-runtime", msgid)
331 # endif
332 # endif
333 # ifndef YY_
334 # define YY_(msgid) msgid
335 # endif
336 #endif
337
338 /* Suppress unused-variable warnings by "using" E. */
339 #if !defined lint || defined __GNUC__
340 # define YYUSE(e) ((void) (e))
341 #else
342 # define YYUSE(e) /* empty */
343 #endif
344
345 /* Identity function, used to suppress warnings about constant conditions. */
346 #ifndef lint
347 # define YYID(n) (n)
348 #else
349 #if (defined __STDC__ || defined __C99__FUNC__ \
350 || defined __cplusplus || defined _MSC_VER)
351 static int
YYID(int i)352 YYID(int i)
353 #else
354 static int
355 YYID(i)
356 int i;
357 #endif
358 {
359 return i;
360 }
361 #endif
362
363 #if !defined yyoverflow || YYERROR_VERBOSE
364
365 /* The parser invokes alloca or malloc; define the necessary symbols. */
366
367 # ifdef YYSTACK_USE_ALLOCA
368 # if YYSTACK_USE_ALLOCA
369 # ifdef __GNUC__
370 # define YYSTACK_ALLOC __builtin_alloca
371 # elif defined __BUILTIN_VA_ARG_INCR
372 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
373 # elif defined _AIX
374 # define YYSTACK_ALLOC __alloca
375 # elif defined _MSC_VER
376 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
377 # define alloca _alloca
378 # else
379 # define YYSTACK_ALLOC alloca
380 # if !defined _ALLOCA_H && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
381 || defined __cplusplus || defined _MSC_VER)
382 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
383 # ifndef _STDLIB_H
384 # define _STDLIB_H 1
385 # endif
386 # endif
387 # endif
388 # endif
389 # endif
390
391 # ifdef YYSTACK_ALLOC
392 /* Pacify GCC's `empty if-body' warning. */
393 # define YYSTACK_FREE(Ptr) do { /* empty */ ; } while (YYID (0))
394 # ifndef YYSTACK_ALLOC_MAXIMUM
395 /* The OS might guarantee only one guard page at the bottom of the stack,
396 * and a page size can be as small as 4096 bytes. So we cannot safely
397 * invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
398 * to allow for a few compiler-allocated temporary stack slots. */
399 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
400 # endif
401 # else
402 # define YYSTACK_ALLOC YYMALLOC
403 # define YYSTACK_FREE YYFREE
404 # ifndef YYSTACK_ALLOC_MAXIMUM
405 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
406 # endif
407 # if (defined __cplusplus && !defined _STDLIB_H \
408 && !((defined YYMALLOC || defined malloc) \
409 && (defined YYFREE || defined free)))
410 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
411 # ifndef _STDLIB_H
412 # define _STDLIB_H 1
413 # endif
414 # endif
415 # ifndef YYMALLOC
416 # define YYMALLOC malloc
417 # if !defined malloc && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
418 || defined __cplusplus || defined _MSC_VER)
419 void *malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
420 # endif
421 # endif
422 # ifndef YYFREE
423 # define YYFREE free
424 # if !defined free && !defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
425 || defined __cplusplus || defined _MSC_VER)
426 void free(void *); /* INFRINGES ON USER NAME SPACE */
427 # endif
428 # endif
429 # endif
430 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
431
432
433 #if (!defined yyoverflow \
434 && (!defined __cplusplus \
435 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
436
437 /* A type that is properly aligned for any stack member. */
438 union yyalloc {
439 yytype_int16 yyss;
440 YYSTYPE yyvs;
441 };
442
443 /* The size of the maximum gap between one aligned stack and the next. */
444 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
445
446 /* The size of an array large to enough to hold all stacks, each with
447 * N elements. */
448 # define YYSTACK_BYTES(N) \
449 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
450 + YYSTACK_GAP_MAXIMUM)
451
452 /* Copy COUNT objects from FROM to TO. The source and destination do
453 * not overlap. */
454 # ifndef YYCOPY
455 # if defined __GNUC__ && 1 < __GNUC__
456 # define YYCOPY(To, From, Count) \
457 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
458 # else
459 # define YYCOPY(To, From, Count) \
460 do \
461 { \
462 YYSIZE_T yyi; \
463 for (yyi = 0; yyi < (Count); yyi++) \
464 (To)[yyi] = (From)[yyi]; \
465 } \
466 while (YYID (0))
467 # endif
468 # endif
469
470 /* Relocate STACK from its old location to the new one. The
471 * local variables YYSIZE and YYSTACKSIZE give the old and new number of
472 * elements in the stack, and YYPTR gives the new location of the
473 * stack. Advance YYPTR to a properly aligned location for the next
474 * stack. */
475 # define YYSTACK_RELOCATE(Stack) \
476 do \
477 { \
478 YYSIZE_T yynewbytes; \
479 YYCOPY (&yyptr->Stack, Stack, yysize); \
480 Stack = &yyptr->Stack; \
481 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
482 yyptr += yynewbytes / sizeof (*yyptr); \
483 } \
484 while (YYID (0))
485
486 #endif
487
488 /* YYFINAL -- State number of the termination state. */
489 #define YYFINAL 30
490 /* YYLAST -- Last index in YYTABLE. */
491 #define YYLAST 80
492
493 /* YYNTOKENS -- Number of terminals. */
494 #define YYNTOKENS 19
495 /* YYNNTS -- Number of nonterminals. */
496 #define YYNNTS 13
497 /* YYNRULES -- Number of rules. */
498 #define YYNRULES 28
499 /* YYNRULES -- Number of states. */
500 #define YYNSTATES 43
501
502 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
503 #define YYUNDEFTOK 2
504 #define YYMAXUTOK 262
505
506 #define YYTRANSLATE(YYX) \
507 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
508
509 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
510 static const yytype_uint8 yytranslate[] =
511 {
512 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
513 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
514 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
515 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 13, 14, 2, 2, 17, 2, 2, 2, 2, 2,
517 2, 2, 2, 2, 2, 2, 2, 2, 18, 12,
518 2, 11, 2, 2, 8, 2, 2, 2, 2, 2,
519 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
520 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
521 2, 15, 2, 16, 2, 2, 2, 2, 2, 2,
522 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
523 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
524 2, 2, 2, 9, 2, 10, 2, 2, 2, 2,
525 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
526 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
527 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
528 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
529 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
530 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
531 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
532 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
533 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
534 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
535 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
536 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
537 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
538 5, 6, 7
539 };
540
541 #if YYDEBUG
542 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
543 * YYRHS. */
544 static const yytype_uint8 yyprhs[] =
545 {
546 0, 0, 3, 4, 6, 8, 10, 12, 14, 16,
547 18, 20, 22, 25, 29, 32, 36, 38, 41, 46,
548 49, 53, 56, 60, 62, 66, 70, 72, 74
549 };
550
551 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
552 static const yytype_int8 yyrhs[] =
553 {
554 20, 0, -1, -1, 21, -1, 7, -1, 22, -1,
555 25, -1, 26, -1, 30, -1, 29, -1, 28, -1,
556 31, -1, 8, 3, -1, 21, 8, 3, -1, 9,
557 10, -1, 9, 23, 10, -1, 24, -1, 23, 24,
558 -1, 21, 11, 21, 12, -1, 13, 14, -1, 13,
559 27, 14, -1, 15, 16, -1, 15, 27, 16, -1,
560 21, -1, 27, 17, 21, -1, 3, 18, 3, -1,
561 5, -1, 4, -1, 6, -1
562 };
563
564 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
565 static const yytype_uint16 yyrline[] =
566 {
567 0, 168, 168, 169, 170, 173, 174, 175, 176, 177,
568 178, 179, 180, 189, 197, 198, 201, 202, 205, 215,
569 216, 219, 220, 223, 228, 239, 247, 252, 257
570 };
571 #endif
572
573 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
574 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
575 * First, the terminals, then, starting at YYNTOKENS, nonterminals. */
576 static const char *const yytname[] =
577 {
578 "$end", "error", "$undefined", "NUMBER", "STRING", "DATA", "BOOLEAN",
579 "SYNTAX_ERROR", "'@'", "'{'", "'}'", "'='", "';'", "'('", "')'", "'['",
580 "']'", "','", "':'", "$accept", "input", "object", "dict", "pairs",
581 "pair", "array", "set", "elements", "offset", "data", "string",
582 "boolean", 0
583 };
584 #endif
585
586 # ifdef YYPRINT
587 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
588 * token YYLEX-NUM. */
589 static const yytype_uint16 yytoknum[] =
590 {
591 0, 256, 257, 258, 259, 260, 261, 262, 64, 123,
592 125, 61, 59, 40, 41, 91, 93, 44, 58
593 };
594 # endif
595
596 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
597 static const yytype_uint8 yyr1[] =
598 {
599 0, 19, 20, 20, 20, 21, 21, 21, 21, 21,
600 21, 21, 21, 21, 22, 22, 23, 23, 24, 25,
601 25, 26, 26, 27, 27, 28, 29, 30, 31
602 };
603
604 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
605 static const yytype_uint8 yyr2[] =
606 {
607 0, 2, 0, 1, 1, 1, 1, 1, 1, 1,
608 1, 1, 2, 3, 2, 3, 1, 2, 4, 2,
609 3, 2, 3, 1, 3, 3, 1, 1, 1
610 };
611
612 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
613 * STATE-NUM when YYTABLE doesn't specify something else to do. Zero
614 * means the default is an error. */
615 static const yytype_uint8 yydefact[] =
616 {
617 2, 0, 27, 26, 28, 4, 0, 0, 0, 0,
618 0, 3, 5, 6, 7, 10, 9, 8, 11, 0,
619 12, 14, 0, 0, 16, 19, 23, 0, 21, 0,
620 1, 0, 25, 0, 15, 17, 20, 0, 22, 13,
621 0, 24, 18
622 };
623
624 /* YYDEFGOTO[NTERM-NUM]. */
625 static const yytype_int8 yydefgoto[] =
626 {
627 -1, 10, 22, 12, 23, 24, 13, 14, 27, 15,
628 16, 17, 18
629 };
630
631 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
632 * STATE-NUM. */
633 #define YYPACT_NINF -14
634 static const yytype_int8 yypact[] =
635 {
636 12, -13, -14, -14, -14, -14, 9, 26, 39, -2,
637 10, 20, -14, -14, -14, -14, -14, -14, -14, 35,
638 -14, -14, 38, 52, -14, -14, 20, 49, -14, 7,
639 -14, 37, -14, 65, -14, -14, -14, 65, -14, -14,
640 14, 20, -14
641 };
642
643 /* YYPGOTO[NTERM-NUM]. */
644 static const yytype_int8 yypgoto[] =
645 {
646 -14, -14, 0, -14, -14, 27, -14, -14, 42, -14,
647 -14, -14, -14
648 };
649
650 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
651 * positive, shift that token. If negative, reduce the rule which
652 * number is the opposite. If zero, do what YYDEFACT says.
653 * If YYTABLE_NINF, syntax error. */
654 #define YYTABLE_NINF -1
655 static const yytype_uint8 yytable[] =
656 {
657 11, 1, 2, 3, 4, 19, 6, 7, 26, 26,
658 30, 8, 20, 9, 28, 1, 2, 3, 4, 5,
659 6, 7, 31, 38, 37, 8, 42, 9, 31, 1,
660 2, 3, 4, 40, 6, 7, 21, 41, 32, 8,
661 39, 9, 1, 2, 3, 4, 31, 6, 7, 33,
662 35, 29, 8, 25, 9, 1, 2, 3, 4, 0,
663 6, 7, 34, 36, 0, 8, 37, 9, 1, 2,
664 3, 4, 0, 6, 7, 0, 0, 0, 8, 0,
665 9
666 };
667
668 static const yytype_int8 yycheck[] =
669 {
670 0, 3, 4, 5, 6, 18, 8, 9, 8, 9,
671 0, 13, 3, 15, 16, 3, 4, 5, 6, 7,
672 8, 9, 8, 16, 17, 13, 12, 15, 8, 3,
673 4, 5, 6, 33, 8, 9, 10, 37, 3, 13,
674 3, 15, 3, 4, 5, 6, 8, 8, 9, 11,
675 23, 9, 13, 14, 15, 3, 4, 5, 6, -1,
676 8, 9, 10, 14, -1, 13, 17, 15, 3, 4,
677 5, 6, -1, 8, 9, -1, -1, -1, 13, -1,
678 15
679 };
680
681 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
682 * symbol of state STATE-NUM. */
683 static const yytype_uint8 yystos[] =
684 {
685 0, 3, 4, 5, 6, 7, 8, 9, 13, 15,
686 20, 21, 22, 25, 26, 28, 29, 30, 31, 18,
687 3, 10, 21, 23, 24, 14, 21, 27, 16, 27,
688 0, 8, 3, 11, 10, 24, 14, 17, 16, 3,
689 21, 21, 12
690 };
691
692 #define yyerrok (yyerrstatus = 0)
693 #define yyclearin (yychar = YYEMPTY)
694 #define YYEMPTY (-2)
695 #define YYEOF 0
696
697 #define YYACCEPT goto yyacceptlab
698 #define YYABORT goto yyabortlab
699 #define YYERROR goto yyerrorlab
700
701
702 /* Like YYERROR except do call yyerror. This remains here temporarily
703 * to ease the transition to the new meaning of YYERROR, for GCC.
704 * Once GCC version 2 has supplanted version 1, this can go. */
705
706 #define YYFAIL goto yyerrlab
707
708 #define YYRECOVERING() (!!yyerrstatus)
709
710 #define YYBACKUP(Token, Value) \
711 do \
712 if (yychar == YYEMPTY && yylen == 1) \
713 { \
714 yychar = (Token); \
715 yylval = (Value); \
716 yytoken = YYTRANSLATE (yychar); \
717 YYPOPSTACK (1); \
718 goto yybackup; \
719 } \
720 else \
721 { \
722 yyerror (YY_("syntax error: cannot back up")); \
723 YYERROR; \
724 } \
725 while (YYID (0))
726
727
728 #define YYTERROR 1
729 #define YYERRCODE 256
730
731
732 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
733 * If N is 0, then set CURRENT to the empty location which ends
734 * the previous symbol: RHS[0] (always defined). */
735
736 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
737 #ifndef YYLLOC_DEFAULT
738 # define YYLLOC_DEFAULT(Current, Rhs, N) \
739 do \
740 if (YYID (N)) \
741 { \
742 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
743 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
744 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
745 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
746 } \
747 else \
748 { \
749 (Current).first_line = (Current).last_line = \
750 YYRHSLOC (Rhs, 0).last_line; \
751 (Current).first_column = (Current).last_column = \
752 YYRHSLOC (Rhs, 0).last_column; \
753 } \
754 while (YYID (0))
755 #endif
756
757
758 /* YY_LOCATION_PRINT -- Print the location on the stream.
759 * This macro was not mandated originally: define only if we know
760 * we won't break user code: when these are the locations we know. */
761
762 #ifndef YY_LOCATION_PRINT
763 # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
764 # define YY_LOCATION_PRINT(File, Loc) \
765 fprintf (File, "%d.%d-%d.%d", \
766 (Loc).first_line, (Loc).first_column, \
767 (Loc).last_line, (Loc).last_column)
768 # else
769 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
770 # endif
771 #endif
772
773
774 /* YYLEX -- calling `yylex' with the right arguments. */
775
776 #ifdef YYLEX_PARAM
777 # define YYLEX yylex (YYLEX_PARAM)
778 #else
779 # define YYLEX yylex ()
780 #endif
781
782 /* Enable debugging if requested. */
783 #if YYDEBUG
784
785 # ifndef YYFPRINTF
786 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
787 # define YYFPRINTF fprintf
788 # endif
789
790 # define YYDPRINTF(Args) \
791 do { \
792 if (yydebug) \
793 YYFPRINTF Args; \
794 } while (YYID (0))
795
796 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
797 do { \
798 if (yydebug) \
799 { \
800 YYFPRINTF (stderr, "%s ", Title); \
801 yy_symbol_print (stderr, \
802 Type, Value); \
803 YYFPRINTF (stderr, "\n"); \
804 } \
805 } while (YYID (0))
806
807
808 /*--------------------------------.
809 | Print this symbol on YYOUTPUT. |
810 | `--------------------------------*/
811
812 /*ARGSUSED*/
813 #if (defined __STDC__ || defined __C99__FUNC__ \
814 || defined __cplusplus || defined _MSC_VER)
815 static void
yy_symbol_value_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)816 yy_symbol_value_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
817 #else
818 static void
819 yy_symbol_value_print(yyoutput, yytype, yyvaluep)
820 FILE *yyoutput;
821 int yytype;
822 YYSTYPE const * const yyvaluep;
823 #endif
824 {
825 if (!yyvaluep) {
826 return;
827 }
828 # ifdef YYPRINT
829 if (yytype < YYNTOKENS) {
830 YYPRINT(yyoutput, yytoknum[yytype], *yyvaluep);
831 }
832 # else
833 YYUSE(yyoutput);
834 # endif
835 switch (yytype) {
836 default:
837 break;
838 }
839 }
840
841
842 /*--------------------------------.
843 | Print this symbol on YYOUTPUT. |
844 | `--------------------------------*/
845
846 #if (defined __STDC__ || defined __C99__FUNC__ \
847 || defined __cplusplus || defined _MSC_VER)
848 static void
yy_symbol_print(FILE * yyoutput,int yytype,YYSTYPE const * const yyvaluep)849 yy_symbol_print(FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
850 #else
851 static void
852 yy_symbol_print(yyoutput, yytype, yyvaluep)
853 FILE *yyoutput;
854 int yytype;
855 YYSTYPE const * const yyvaluep;
856 #endif
857 {
858 if (yytype < YYNTOKENS) {
859 YYFPRINTF(yyoutput, "token %s (", yytname[yytype]);
860 } else {
861 YYFPRINTF(yyoutput, "nterm %s (", yytname[yytype]);
862 }
863
864 yy_symbol_value_print(yyoutput, yytype, yyvaluep);
865 YYFPRINTF(yyoutput, ")");
866 }
867
868 /*------------------------------------------------------------------.
869 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
870 | TOP (included). |
871 | `------------------------------------------------------------------*/
872
873 #if (defined __STDC__ || defined __C99__FUNC__ \
874 || defined __cplusplus || defined _MSC_VER)
875 static void
yy_stack_print(yytype_int16 * bottom,yytype_int16 * top)876 yy_stack_print(yytype_int16 *bottom, yytype_int16 *top)
877 #else
878 static void
879 yy_stack_print(bottom, top)
880 yytype_int16 *bottom;
881 yytype_int16 *top;
882 #endif
883 {
884 YYFPRINTF(stderr, "Stack now");
885 for (; bottom <= top; ++bottom) {
886 YYFPRINTF(stderr, " %d", *bottom);
887 }
888 YYFPRINTF(stderr, "\n");
889 }
890
891 # define YY_STACK_PRINT(Bottom, Top) \
892 do { \
893 if (yydebug) \
894 yy_stack_print ((Bottom), (Top)); \
895 } while (YYID (0))
896
897
898 /*------------------------------------------------.
899 | Report that the YYRULE is going to be reduced. |
900 | `------------------------------------------------*/
901
902 #if (defined __STDC__ || defined __C99__FUNC__ \
903 || defined __cplusplus || defined _MSC_VER)
904 static void
yy_reduce_print(YYSTYPE * yyvsp,int yyrule)905 yy_reduce_print(YYSTYPE *yyvsp, int yyrule)
906 #else
907 static void
908 yy_reduce_print(yyvsp, yyrule)
909 YYSTYPE *yyvsp;
910 int yyrule;
911 #endif
912 {
913 int yynrhs = yyr2[yyrule];
914 int yyi;
915 unsigned long int yylno = yyrline[yyrule];
916 YYFPRINTF(stderr, "Reducing stack by rule %d (line %lu):\n",
917 yyrule - 1, yylno);
918 /* The symbols being reduced. */
919 for (yyi = 0; yyi < yynrhs; yyi++) {
920 fprintf(stderr, " $%d = ", yyi + 1);
921 yy_symbol_print(stderr, yyrhs[yyprhs[yyrule] + yyi],
922 &(yyvsp[(yyi + 1) - (yynrhs)])
923 );
924 fprintf(stderr, "\n");
925 }
926 }
927
928 # define YY_REDUCE_PRINT(Rule) \
929 do { \
930 if (yydebug) \
931 yy_reduce_print (yyvsp, Rule); \
932 } while (YYID (0))
933
934 /* Nonzero means print parse trace. It is left uninitialized so that
935 * multiple parsers can coexist. */
936 int yydebug;
937 #else /* !YYDEBUG */
938 # define YYDPRINTF(Args)
939 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
940 # define YY_STACK_PRINT(Bottom, Top)
941 # define YY_REDUCE_PRINT(Rule)
942 #endif /* !YYDEBUG */
943
944
945 /* YYINITDEPTH -- initial size of the parser's stacks. */
946 #ifndef YYINITDEPTH
947 # define YYINITDEPTH 200
948 #endif
949
950 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
951 * if the built-in stack extension method is used).
952 *
953 * Do not make this value too large; the results are undefined if
954 * YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
955 * evaluated with infinite-precision integer arithmetic. */
956
957 #ifndef YYMAXDEPTH
958 # define YYMAXDEPTH 10000
959 #endif
960
961
962
963 #if YYERROR_VERBOSE
964
965 # ifndef yystrlen
966 # if defined __GLIBC__ && defined _STRING_H
967 # define yystrlen strlen
968 # else
969 /* Return the length of YYSTR. */
970 #if (defined __STDC__ || defined __C99__FUNC__ \
971 || defined __cplusplus || defined _MSC_VER)
972 static YYSIZE_T
yystrlen(const char * yystr)973 yystrlen(const char *yystr)
974 #else
975 static YYSIZE_T
976 yystrlen(yystr)
977 const char *yystr;
978 #endif
979 {
980 YYSIZE_T yylen;
981 for (yylen = 0; yystr[yylen]; yylen++) {
982 continue;
983 }
984 return yylen;
985 }
986 # endif
987 # endif
988
989 # ifndef yystpcpy
990 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
991 # define yystpcpy stpcpy
992 # else
993 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
994 * YYDEST. */
995 #if (defined __STDC__ || defined __C99__FUNC__ \
996 || defined __cplusplus || defined _MSC_VER)
997 static char *
yystpcpy(char * yydest,const char * yysrc)998 yystpcpy(char *yydest, const char *yysrc)
999 #else
1000 static char *
1001 yystpcpy(yydest, yysrc)
1002 char *yydest;
1003 const char *yysrc;
1004 #endif
1005 {
1006 char *yyd = yydest;
1007 const char *yys = yysrc;
1008
1009 while ((*yyd++ = *yys++) != '\0') {
1010 continue;
1011 }
1012
1013 return yyd - 1;
1014 }
1015 # endif
1016 # endif
1017
1018 # ifndef yytnamerr
1019 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1020 * quotes and backslashes, so that it's suitable for yyerror. The
1021 * heuristic is that double-quoting is unnecessary unless the string
1022 * contains an apostrophe, a comma, or backslash (other than
1023 * backslash-backslash). YYSTR is taken from yytname. If YYRES is
1024 * null, do not copy; instead, return the length of what the result
1025 * would have been. */
1026 static YYSIZE_T
yytnamerr(char * yyres,const char * yystr)1027 yytnamerr(char *yyres, const char *yystr)
1028 {
1029 if (*yystr == '"') {
1030 YYSIZE_T yyn = 0;
1031 char const *yyp = yystr;
1032
1033 for (;;) {
1034 switch (*++yyp) {
1035 case '\'':
1036 case ',':
1037 goto do_not_strip_quotes;
1038
1039 case '\\':
1040 if (*++yyp != '\\') {
1041 goto do_not_strip_quotes;
1042 }
1043 /* Fall through. */
1044 default:
1045 if (yyres) {
1046 yyres[yyn] = *yyp;
1047 }
1048 yyn++;
1049 break;
1050
1051 case '"':
1052 if (yyres) {
1053 yyres[yyn] = '\0';
1054 }
1055 return yyn;
1056 }
1057 }
1058 do_not_strip_quotes:;
1059 }
1060
1061 if (!yyres) {
1062 return yystrlen(yystr);
1063 }
1064
1065 return yystpcpy(yyres, yystr) - yyres;
1066 }
1067 # endif
1068
1069 /* Copy into YYRESULT an error message about the unexpected token
1070 * YYCHAR while in state YYSTATE. Return the number of bytes copied,
1071 * including the terminating null byte. If YYRESULT is null, do not
1072 * copy anything; just return the number of bytes that would be
1073 * copied. As a special case, return 0 if an ordinary "syntax error"
1074 * message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1075 * size calculation. */
1076 static YYSIZE_T
yysyntax_error(char * yyresult,int yystate,int yychar)1077 yysyntax_error(char *yyresult, int yystate, int yychar)
1078 {
1079 int yyn = yypact[yystate];
1080
1081 if (!(YYPACT_NINF < yyn && yyn <= YYLAST)) {
1082 return 0;
1083 } else {
1084 int yytype = YYTRANSLATE(yychar);
1085 YYSIZE_T yysize0 = yytnamerr(0, yytname[yytype]);
1086 YYSIZE_T yysize = yysize0;
1087 YYSIZE_T yysize1;
1088 int yysize_overflow = 0;
1089 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1090 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1091 int yyx;
1092
1093 # if 0
1094 /* This is so xgettext sees the translatable formats that are
1095 * constructed on the fly. */
1096 YY_("syntax error, unexpected %s");
1097 YY_("syntax error, unexpected %s, expecting %s");
1098 YY_("syntax error, unexpected %s, expecting %s or %s");
1099 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1100 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1101 # endif
1102 char *yyfmt;
1103 char const *yyf;
1104 static char const yyunexpected[] = "syntax error, unexpected %s";
1105 static char const yyexpecting[] = ", expecting %s";
1106 static char const yyor[] = " or %s";
1107 char yyformat[sizeof yyunexpected
1108 + sizeof yyexpecting - 1
1109 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1110 * (sizeof yyor - 1))];
1111 char const *yyprefix = yyexpecting;
1112
1113 /* Start YYX at -YYN if negative to avoid negative indexes in
1114 * YYCHECK. */
1115 int yyxbegin = yyn < 0 ? -yyn : 0;
1116
1117 /* Stay within bounds of both yycheck and yytname. */
1118 int yychecklim = YYLAST - yyn + 1;
1119 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1120 int yycount = 1;
1121
1122 yyarg[0] = yytname[yytype];
1123 yyfmt = yystpcpy(yyformat, yyunexpected);
1124
1125 for (yyx = yyxbegin; yyx < yyxend; ++yyx) {
1126 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) {
1127 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) {
1128 yycount = 1;
1129 yysize = yysize0;
1130 yyformat[sizeof yyunexpected - 1] = '\0';
1131 break;
1132 }
1133 yyarg[yycount++] = yytname[yyx];
1134 yysize1 = yysize + yytnamerr(0, yytname[yyx]);
1135 yysize_overflow |= (yysize1 < yysize);
1136 yysize = yysize1;
1137 yyfmt = yystpcpy(yyfmt, yyprefix);
1138 yyprefix = yyor;
1139 }
1140 }
1141
1142 yyf = YY_(yyformat);
1143 yysize1 = yysize + yystrlen(yyf);
1144 yysize_overflow |= (yysize1 < yysize);
1145 yysize = yysize1;
1146
1147 if (yysize_overflow) {
1148 return YYSIZE_MAXIMUM;
1149 }
1150
1151 if (yyresult) {
1152 /* Avoid sprintf, as that infringes on the user's name space.
1153 * Don't have undefined behavior even if the translation
1154 * produced a string with the wrong number of "%s"s. */
1155 char *yyp = yyresult;
1156 int yyi = 0;
1157 while ((*yyp = *yyf) != '\0') {
1158 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) {
1159 yyp += yytnamerr(yyp, yyarg[yyi++]);
1160 yyf += 2;
1161 } else {
1162 yyp++;
1163 yyf++;
1164 }
1165 }
1166 }
1167 return yysize;
1168 }
1169 }
1170 #endif /* YYERROR_VERBOSE */
1171
1172
1173 /*-----------------------------------------------.
1174 | Release the memory associated to this symbol. |
1175 | `-----------------------------------------------*/
1176
1177 /*ARGSUSED*/
1178 #if (defined __STDC__ || defined __C99__FUNC__ \
1179 || defined __cplusplus || defined _MSC_VER)
1180 static void
yydestruct(const char * yymsg,int yytype,YYSTYPE * yyvaluep)1181 yydestruct(const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1182 #else
1183 static void
1184 yydestruct(yymsg, yytype, yyvaluep)
1185 const char *yymsg;
1186 int yytype;
1187 YYSTYPE *yyvaluep;
1188 #endif
1189 {
1190 YYUSE(yyvaluep);
1191
1192 if (!yymsg) {
1193 yymsg = "Deleting";
1194 }
1195 YY_SYMBOL_PRINT(yymsg, yytype, yyvaluep, yylocationp);
1196
1197 switch (yytype) {
1198 default:
1199 break;
1200 }
1201 }
1202
1203
1204 /* Prevent warnings from -Wmissing-prototypes. */
1205
1206 #ifdef YYPARSE_PARAM
1207 #if defined __STDC__ || defined __cplusplus
1208 int yyparse(void *YYPARSE_PARAM);
1209 #else
1210 int yyparse();
1211 #endif
1212 #else /* ! YYPARSE_PARAM */
1213 #if defined __STDC__ || defined __cplusplus
1214 int yyparse(void);
1215 #else
1216 int yyparse();
1217 #endif
1218 #endif /* ! YYPARSE_PARAM */
1219
1220
1221
1222 /* The look-ahead symbol. */
1223 int yychar;
1224
1225 /* The semantic value of the look-ahead symbol. */
1226 YYSTYPE yylval;
1227
1228 /* Number of syntax errors so far. */
1229 int yynerrs;
1230
1231
1232
1233 /*----------.
1234 | yyparse. |
1235 | `----------*/
1236
1237 #ifdef YYPARSE_PARAM
1238 #if (defined __STDC__ || defined __C99__FUNC__ \
1239 || defined __cplusplus || defined _MSC_VER)
1240 int
yyparse(void * YYPARSE_PARAM)1241 yyparse(void *YYPARSE_PARAM)
1242 #else
1243 int
1244 yyparse(YYPARSE_PARAM)
1245 void *YYPARSE_PARAM;
1246 #endif
1247 #else /* ! YYPARSE_PARAM */
1248 #if (defined __STDC__ || defined __C99__FUNC__ \
1249 || defined __cplusplus || defined _MSC_VER)
1250 int
1251 yyparse(void)
1252 #else
1253 int
1254 yyparse()
1255
1256 #endif
1257 #endif
1258 {
1259 int yystate;
1260 int yyn;
1261 int yyresult;
1262 /* Number of tokens to shift before error messages enabled. */
1263 int yyerrstatus;
1264 /* Look-ahead token as an internal (translated) token number. */
1265 int yytoken = 0;
1266 #if YYERROR_VERBOSE
1267 /* Buffer for error messages, and its allocated size. */
1268 char yymsgbuf[128];
1269 char *yymsg = yymsgbuf;
1270 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1271 #endif
1272
1273 /* Three stacks and their tools:
1274 * `yyss': related to states,
1275 * `yyvs': related to semantic values,
1276 * `yyls': related to locations.
1277 *
1278 * Refer to the stacks thru separate pointers, to allow yyoverflow
1279 * to reallocate them elsewhere. */
1280
1281 /* The state stack. */
1282 yytype_int16 yyssa[YYINITDEPTH];
1283 yytype_int16 *yyss = yyssa;
1284 yytype_int16 *yyssp;
1285
1286 /* The semantic value stack. */
1287 YYSTYPE yyvsa[YYINITDEPTH];
1288 YYSTYPE *yyvs = yyvsa;
1289 YYSTYPE *yyvsp;
1290
1291
1292
1293 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1294
1295 YYSIZE_T yystacksize = YYINITDEPTH;
1296
1297 /* The variables used to return semantic value and location from the
1298 * action routines. */
1299 YYSTYPE yyval;
1300
1301
1302 /* The number of symbols on the RHS of the reduced rule.
1303 * Keep to zero when no symbol should be popped. */
1304 int yylen = 0;
1305
1306 YYDPRINTF((stderr, "Starting parse\n"));
1307
1308 yystate = 0;
1309 yyerrstatus = 0;
1310 yynerrs = 0;
1311 yychar = YYEMPTY; /* Cause a token to be read. */
1312
1313 /* Initialize stack pointers.
1314 * Waste one element of value and location stack
1315 * so that they stay on the same level as the state stack.
1316 * The wasted elements are never initialized. */
1317
1318 yyssp = yyss;
1319 yyvsp = yyvs;
1320
1321 goto yysetstate;
1322
1323 /*------------------------------------------------------------.
1324 | yynewstate -- Push a new state, which is found in yystate. |
1325 | `------------------------------------------------------------*/
1326 yynewstate:
1327 /* In all cases, when you get here, the value and location stacks
1328 * have just been pushed. So pushing a state here evens the stacks. */
1329 yyssp++;
1330
1331 yysetstate:
1332 *yyssp = yystate;
1333
1334 if (yyss + yystacksize - 1 <= yyssp) {
1335 /* Get the current used size of the three stacks, in elements. */
1336 YYSIZE_T yysize = yyssp - yyss + 1;
1337
1338 #ifdef yyoverflow
1339 {
1340 /* Give user a chance to reallocate the stack. Use copies of
1341 * these so that the &'s don't force the real ones into
1342 * memory. */
1343 YYSTYPE *yyvs1 = yyvs;
1344 yytype_int16 *yyss1 = yyss;
1345
1346
1347 /* Each stack pointer address is followed by the size of the
1348 * data in use in that stack, in bytes. This used to be a
1349 * conditional around just the two extra args, but that might
1350 * be undefined if yyoverflow is a macro. */
1351 yyoverflow(YY_("memory exhausted"),
1352 &yyss1, yysize * sizeof(*yyssp),
1353 &yyvs1, yysize * sizeof(*yyvsp),
1354
1355 &yystacksize);
1356
1357 yyss = yyss1;
1358 yyvs = yyvs1;
1359 }
1360 #else /* no yyoverflow */
1361 # ifndef YYSTACK_RELOCATE
1362 goto yyexhaustedlab;
1363 # else
1364 /* Extend the stack our own way. */
1365 if (YYMAXDEPTH <= yystacksize) {
1366 goto yyexhaustedlab;
1367 }
1368 yystacksize *= 2;
1369 if (YYMAXDEPTH < yystacksize) {
1370 yystacksize = YYMAXDEPTH;
1371 }
1372
1373 {
1374 yytype_int16 *yyss1 = yyss;
1375 union yyalloc *yyptr =
1376 (union yyalloc *) YYSTACK_ALLOC(YYSTACK_BYTES(yystacksize));
1377 if (!yyptr) {
1378 goto yyexhaustedlab;
1379 }
1380 YYSTACK_RELOCATE(yyss);
1381 YYSTACK_RELOCATE(yyvs);
1382
1383 # undef YYSTACK_RELOCATE
1384 if (yyss1 != yyssa) {
1385 YYSTACK_FREE(yyss1);
1386 }
1387 }
1388 # endif
1389 #endif /* no yyoverflow */
1390
1391 yyssp = yyss + yysize - 1;
1392 yyvsp = yyvs + yysize - 1;
1393
1394
1395 YYDPRINTF((stderr, "Stack size increased to %lu\n",
1396 (unsigned long int) yystacksize));
1397
1398 if (yyss + yystacksize - 1 <= yyssp) {
1399 YYABORT;
1400 }
1401 }
1402
1403 YYDPRINTF((stderr, "Entering state %d\n", yystate));
1404
1405 goto yybackup;
1406
1407 /*-----------.
1408 | yybackup. |
1409 | `-----------*/
1410 yybackup:
1411
1412 /* Do appropriate processing given the current state. Read a
1413 * look-ahead token if we need one and don't already have one. */
1414
1415 /* First try to decide what to do without reference to look-ahead token. */
1416 yyn = yypact[yystate];
1417 if (yyn == YYPACT_NINF) {
1418 goto yydefault;
1419 }
1420
1421 /* Not known => get a look-ahead token if don't already have one. */
1422
1423 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1424 if (yychar == YYEMPTY) {
1425 YYDPRINTF((stderr, "Reading a token: "));
1426 yychar = YYLEX;
1427 }
1428
1429 if (yychar <= YYEOF) {
1430 yychar = yytoken = YYEOF;
1431 YYDPRINTF((stderr, "Now at end of input.\n"));
1432 } else {
1433 yytoken = YYTRANSLATE(yychar);
1434 YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
1435 }
1436
1437 /* If the proper action on seeing token YYTOKEN is to reduce or to
1438 * detect an error, take that action. */
1439 yyn += yytoken;
1440 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) {
1441 goto yydefault;
1442 }
1443 yyn = yytable[yyn];
1444 if (yyn <= 0) {
1445 if (yyn == 0 || yyn == YYTABLE_NINF) {
1446 goto yyerrlab;
1447 }
1448 yyn = -yyn;
1449 goto yyreduce;
1450 }
1451
1452 if (yyn == YYFINAL) {
1453 YYACCEPT;
1454 }
1455
1456 /* Count tokens shifted since error; after three, turn off error
1457 * status. */
1458 if (yyerrstatus) {
1459 yyerrstatus--;
1460 }
1461
1462 /* Shift the look-ahead token. */
1463 YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
1464
1465 /* Discard the shifted token unless it is eof. */
1466 if (yychar != YYEOF) {
1467 yychar = YYEMPTY;
1468 }
1469
1470 yystate = yyn;
1471 *++yyvsp = yylval;
1472
1473 goto yynewstate;
1474
1475
1476 /*-----------------------------------------------------------.
1477 | yydefault -- do the default action for the current state. |
1478 | `-----------------------------------------------------------*/
1479 yydefault:
1480 yyn = yydefact[yystate];
1481 if (yyn == 0) {
1482 goto yyerrlab;
1483 }
1484 goto yyreduce;
1485
1486
1487 /*-----------------------------.
1488 | yyreduce -- Do a reduction. |
1489 | `-----------------------------*/
1490 yyreduce:
1491 /* yyn is the number of a rule to reduce with. */
1492 yylen = yyr2[yyn];
1493
1494 /* If YYLEN is nonzero, implement the default value of the action:
1495 * `$$ = $1'.
1496 *
1497 * Otherwise, the following line sets YYVAL to garbage.
1498 * This behavior is undocumented and Bison
1499 * users should not rely upon it. Assigning to YYVAL
1500 * unconditionally makes the parser a bit smaller, and it avoids a
1501 * GCC warning that YYVAL may be used uninitialized. */
1502 yyval = yyvsp[1 - yylen];
1503
1504
1505 YY_REDUCE_PRINT(yyn);
1506 switch (yyn) {
1507 case 2:
1508 #line 168 "OSUnserialize.y"
1509 { parsedObject = (OSObject *)NULL; YYACCEPT;;}
1510 break;
1511
1512 case 3:
1513 #line 169 "OSUnserialize.y"
1514 { parsedObject = (OSObject *)(yyvsp[(1) - (1)]); YYACCEPT;;}
1515 break;
1516
1517 case 4:
1518 #line 170 "OSUnserialize.y"
1519 { yyerror("syntax error"); YYERROR;;}
1520 break;
1521
1522 case 5:
1523 #line 173 "OSUnserialize.y"
1524 { (yyval) = (object_t *)buildOSDictionary((yyvsp[(1) - (1)]));;}
1525 break;
1526
1527 case 6:
1528 #line 174 "OSUnserialize.y"
1529 { (yyval) = (object_t *)buildOSArray((yyvsp[(1) - (1)]));;}
1530 break;
1531
1532 case 7:
1533 #line 175 "OSUnserialize.y"
1534 { (yyval) = (object_t *)buildOSSet((yyvsp[(1) - (1)]));;}
1535 break;
1536
1537 case 8:
1538 #line 176 "OSUnserialize.y"
1539 { (yyval) = (object_t *)buildOSString((yyvsp[(1) - (1)]));;}
1540 break;
1541
1542 case 9:
1543 #line 177 "OSUnserialize.y"
1544 { (yyval) = (object_t *)buildOSData((yyvsp[(1) - (1)]));;}
1545 break;
1546
1547 case 10:
1548 #line 178 "OSUnserialize.y"
1549 { (yyval) = (object_t *)buildOSOffset((yyvsp[(1) - (1)]));;}
1550 break;
1551
1552 case 11:
1553 #line 179 "OSUnserialize.y"
1554 { (yyval) = (object_t *)buildOSBoolean((yyvsp[(1) - (1)]));;}
1555 break;
1556
1557 case 12:
1558 #line 180 "OSUnserialize.y"
1559 { (yyval) = (object_t *)retrieveObject((yyvsp[(2) - (2)])->u.offset);
1560 if ((yyval)) {
1561 ((OSObject *)(yyval))->retain();
1562 } else {
1563 yyerror("forward reference detected");
1564 YYERROR;
1565 }
1566 freeObject((yyvsp[(2) - (2)]));
1567 ;}
1568 break;
1569
1570 case 13:
1571 #line 189 "OSUnserialize.y"
1572 { (yyval) = (yyvsp[(1) - (3)]);
1573 rememberObject((yyvsp[(3) - (3)])->u.offset, (yyvsp[(1) - (3)]));
1574 freeObject((yyvsp[(3) - (3)]));
1575 ;}
1576 break;
1577
1578 case 14:
1579 #line 197 "OSUnserialize.y"
1580 { (yyval) = NULL;;}
1581 break;
1582
1583 case 15:
1584 #line 198 "OSUnserialize.y"
1585 { (yyval) = (yyvsp[(2) - (3)]);;}
1586 break;
1587
1588 case 17:
1589 #line 202 "OSUnserialize.y"
1590 { (yyvsp[(2) - (2)])->next = (yyvsp[(1) - (2)]); (yyvsp[(1) - (2)])->prev = (yyvsp[(2) - (2)]); (yyval) = (yyvsp[(2) - (2)]);;}
1591 break;
1592
1593 case 18:
1594 #line 205 "OSUnserialize.y"
1595 { (yyval) = newObject();
1596 (yyval)->next = NULL;
1597 (yyval)->prev = NULL;
1598 (yyval)->u.key = (yyvsp[(1) - (4)]);
1599 (yyval)->object = (yyvsp[(3) - (4)]);
1600 ;}
1601 break;
1602
1603 case 19:
1604 #line 215 "OSUnserialize.y"
1605 { (yyval) = NULL;;}
1606 break;
1607
1608 case 20:
1609 #line 216 "OSUnserialize.y"
1610 { (yyval) = (yyvsp[(2) - (3)]);;}
1611 break;
1612
1613 case 21:
1614 #line 219 "OSUnserialize.y"
1615 { (yyval) = NULL;;}
1616 break;
1617
1618 case 22:
1619 #line 220 "OSUnserialize.y"
1620 { (yyval) = (yyvsp[(2) - (3)]);;}
1621 break;
1622
1623 case 23:
1624 #line 223 "OSUnserialize.y"
1625 { (yyval) = newObject();
1626 (yyval)->object = (yyvsp[(1) - (1)]);
1627 (yyval)->next = NULL;
1628 (yyval)->prev = NULL;
1629 ;}
1630 break;
1631
1632 case 24:
1633 #line 228 "OSUnserialize.y"
1634 { oo = newObject();
1635 oo->object = (yyvsp[(3) - (3)]);
1636 oo->next = (yyvsp[(1) - (3)]);
1637 oo->prev = NULL;
1638 (yyvsp[(1) - (3)])->prev = oo;
1639 (yyval) = oo;
1640 ;}
1641 break;
1642
1643 case 25:
1644 #line 239 "OSUnserialize.y"
1645 { (yyval) = (yyvsp[(1) - (3)]);
1646 (yyval)->size = (yyvsp[(3) - (3)])->u.offset;
1647 freeObject((yyvsp[(3) - (3)]));
1648 ;}
1649 break;
1650
1651
1652 /* Line 1267 of yacc.c. */
1653 #line 1602 "OSUnserialize.tab.c"
1654 default: break;
1655 }
1656 YY_SYMBOL_PRINT("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1657
1658 YYPOPSTACK(yylen);
1659 yylen = 0;
1660 YY_STACK_PRINT(yyss, yyssp);
1661
1662 *++yyvsp = yyval;
1663
1664
1665 /* Now `shift' the result of the reduction. Determine what state
1666 * that goes to, based on the state we popped back to and the rule
1667 * number reduced by. */
1668
1669 yyn = yyr1[yyn];
1670
1671 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1672 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) {
1673 yystate = yytable[yystate];
1674 } else {
1675 yystate = yydefgoto[yyn - YYNTOKENS];
1676 }
1677
1678 goto yynewstate;
1679
1680
1681 /*------------------------------------.
1682 | yyerrlab -- here on detecting error |
1683 | `------------------------------------*/
1684 yyerrlab:
1685 /* If not already recovering from an error, report this error. */
1686 if (!yyerrstatus) {
1687 ++yynerrs;
1688 #if !YYERROR_VERBOSE
1689 yyerror(YY_("syntax error"));
1690 #else
1691 {
1692 YYSIZE_T yysize = yysyntax_error(0, yystate, yychar);
1693 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) {
1694 YYSIZE_T yyalloc = 2 * yysize;
1695 if (!(yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) {
1696 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1697 }
1698 if (yymsg != yymsgbuf) {
1699 YYSTACK_FREE(yymsg);
1700 }
1701 yymsg = (char *) YYSTACK_ALLOC(yyalloc);
1702 if (yymsg) {
1703 yymsg_alloc = yyalloc;
1704 } else {
1705 yymsg = yymsgbuf;
1706 yymsg_alloc = sizeof yymsgbuf;
1707 }
1708 }
1709
1710 if (0 < yysize && yysize <= yymsg_alloc) {
1711 (void) yysyntax_error(yymsg, yystate, yychar);
1712 yyerror(yymsg);
1713 } else {
1714 yyerror(YY_("syntax error"));
1715 if (yysize != 0) {
1716 goto yyexhaustedlab;
1717 }
1718 }
1719 }
1720 #endif
1721 }
1722
1723
1724
1725 if (yyerrstatus == 3) {
1726 /* If just tried and failed to reuse look-ahead token after an
1727 * error, discard it. */
1728
1729 if (yychar <= YYEOF) {
1730 /* Return failure if at end of input. */
1731 if (yychar == YYEOF) {
1732 YYABORT;
1733 }
1734 } else {
1735 yydestruct("Error: discarding",
1736 yytoken, &yylval);
1737 yychar = YYEMPTY;
1738 }
1739 }
1740
1741 /* Else will try to reuse look-ahead token after shifting the error
1742 * token. */
1743 goto yyerrlab1;
1744
1745
1746 /*---------------------------------------------------.
1747 | yyerrorlab -- error raised explicitly by YYERROR. |
1748 | `---------------------------------------------------*/
1749 yyerrorlab:
1750
1751 /* Pacify compilers like GCC when the user code never invokes
1752 * YYERROR and the label yyerrorlab therefore never appears in user
1753 * code. */
1754 if (/*CONSTCOND*/ 0) {
1755 goto yyerrorlab;
1756 }
1757
1758 /* Do not reclaim the symbols of the rule which action triggered
1759 * this YYERROR. */
1760 YYPOPSTACK(yylen);
1761 yylen = 0;
1762 YY_STACK_PRINT(yyss, yyssp);
1763 yystate = *yyssp;
1764 goto yyerrlab1;
1765
1766
1767 /*-------------------------------------------------------------.
1768 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1769 | `-------------------------------------------------------------*/
1770 yyerrlab1:
1771 yyerrstatus = 3; /* Each real token shifted decrements this. */
1772
1773 for (;;) {
1774 yyn = yypact[yystate];
1775 if (yyn != YYPACT_NINF) {
1776 yyn += YYTERROR;
1777 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
1778 yyn = yytable[yyn];
1779 if (0 < yyn) {
1780 break;
1781 }
1782 }
1783 }
1784
1785 /* Pop the current state because it cannot handle the error token. */
1786 if (yyssp == yyss) {
1787 YYABORT;
1788 }
1789
1790
1791 yydestruct("Error: popping",
1792 yystos[yystate], yyvsp);
1793 YYPOPSTACK(1);
1794 yystate = *yyssp;
1795 YY_STACK_PRINT(yyss, yyssp);
1796 }
1797
1798 if (yyn == YYFINAL) {
1799 YYACCEPT;
1800 }
1801
1802 *++yyvsp = yylval;
1803
1804
1805 /* Shift the error token. */
1806 YY_SYMBOL_PRINT("Shifting", yystos[yyn], yyvsp, yylsp);
1807
1808 yystate = yyn;
1809 goto yynewstate;
1810
1811
1812 /*-------------------------------------.
1813 | yyacceptlab -- YYACCEPT comes here. |
1814 | `-------------------------------------*/
1815 yyacceptlab:
1816 yyresult = 0;
1817 goto yyreturn;
1818
1819 /*-----------------------------------.
1820 | yyabortlab -- YYABORT comes here. |
1821 | `-----------------------------------*/
1822 yyabortlab:
1823 yyresult = 1;
1824 goto yyreturn;
1825
1826 #ifndef yyoverflow
1827 /*-------------------------------------------------.
1828 | yyexhaustedlab -- memory exhaustion comes here. |
1829 | `-------------------------------------------------*/
1830 yyexhaustedlab:
1831 yyerror(YY_("memory exhausted"));
1832 yyresult = 2;
1833 /* Fall through. */
1834 #endif
1835
1836 yyreturn:
1837 if (yychar != YYEOF && yychar != YYEMPTY) {
1838 yydestruct("Cleanup: discarding lookahead",
1839 yytoken, &yylval);
1840 }
1841 /* Do not reclaim the symbols of the rule which action triggered
1842 * this YYABORT or YYACCEPT. */
1843 YYPOPSTACK(yylen);
1844 YY_STACK_PRINT(yyss, yyssp);
1845 while (yyssp != yyss) {
1846 yydestruct("Cleanup: popping",
1847 yystos[*yyssp], yyvsp);
1848 YYPOPSTACK(1);
1849 }
1850 #ifndef yyoverflow
1851 if (yyss != yyssa) {
1852 YYSTACK_FREE(yyss);
1853 }
1854 #endif
1855 #if YYERROR_VERBOSE
1856 if (yymsg != yymsgbuf) {
1857 YYSTACK_FREE(yymsg);
1858 }
1859 #endif
1860 /* Make sure YYID is used. */
1861 return YYID(yyresult);
1862 }
1863
1864
1865 #line 260 "OSUnserialize.y"
1866
1867
1868 static int lineNumber = 0;
1869 static const char *parseBuffer;
1870 static int parseBufferIndex;
1871
1872 #define currentChar() (parseBuffer[parseBufferIndex])
1873 #define nextChar() (parseBuffer[++parseBufferIndex])
1874 #define prevChar() (parseBuffer[parseBufferIndex - 1])
1875
1876 #define isSpace(c) ((c) == ' ' || (c) == '\t')
1877 #define isAlpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
1878 #define isDigit(c) ((c) >= '0' && (c) <= '9')
1879 #define isAlphaDigit(c) ((c) >= 'a' && (c) <= 'f')
1880 #define isHexDigit(c) (isDigit(c) || isAlphaDigit(c))
1881 #define isAlphaNumeric(c) (isAlpha(c) || isDigit(c) || ((c) == '-'))
1882
1883 static char yyerror_message[128];
1884
1885 int
yyerror(const char * s)1886 yyerror(const char *s) /* Called by yyparse on error */
1887 {
1888 snprintf(yyerror_message, sizeof(yyerror_message), "OSUnserialize: %s near line %d\n", s, lineNumber);
1889 return 0;
1890 }
1891
1892 int
yylex()1893 yylex()
1894 {
1895 int c;
1896
1897 if (parseBufferIndex == 0) {
1898 lineNumber = 1;
1899 }
1900
1901 top:
1902 c = currentChar();
1903
1904 /* skip white space */
1905 if (isSpace(c)) {
1906 while ((c = nextChar()) != 0 && isSpace(c)) {
1907 }
1908 }
1909 ;
1910
1911 /* skip over comments */
1912 if (c == '#') {
1913 while ((c = nextChar()) != 0 && c != '\n') {
1914 }
1915 }
1916 ;
1917
1918 /* keep track of line number, don't return \n's */
1919 if (c == '\n') {
1920 lineNumber++;
1921 (void)nextChar();
1922 goto top;
1923 }
1924
1925 /* parse boolean */
1926 if (c == '.') {
1927 bool boolean = false;
1928 if (nextChar() == 't') {
1929 if (nextChar() != 'r') {
1930 return SYNTAX_ERROR;
1931 }
1932 if (nextChar() != 'u') {
1933 return SYNTAX_ERROR;
1934 }
1935 if (nextChar() != 'e') {
1936 return SYNTAX_ERROR;
1937 }
1938 boolean = true;
1939 } else {
1940 if (currentChar() != 'f') {
1941 return SYNTAX_ERROR;
1942 }
1943 if (nextChar() != 'a') {
1944 return SYNTAX_ERROR;
1945 }
1946 if (nextChar() != 'l') {
1947 return SYNTAX_ERROR;
1948 }
1949 if (nextChar() != 's') {
1950 return SYNTAX_ERROR;
1951 }
1952 if (nextChar() != 'e') {
1953 return SYNTAX_ERROR;
1954 }
1955 }
1956 if (nextChar() != '.') {
1957 return SYNTAX_ERROR;
1958 }
1959 /* skip over dot */
1960 (void)nextChar();
1961
1962 yylval = (object_t *)boolean;
1963 return BOOLEAN;
1964 }
1965
1966 /* parse unquoted string */
1967 if (isAlpha(c)) {
1968 int start, length;
1969 char * tempString;
1970
1971 start = parseBufferIndex;
1972 /* find end of string */
1973 while (isAlphaNumeric(c)) {
1974 c = nextChar();
1975 }
1976 length = parseBufferIndex - start;
1977
1978 /* copy to null terminated buffer */
1979 tempString = (char *)malloc(length + 1);
1980 if (tempString == NULL) {
1981 printf("OSUnserialize: can't alloc temp memory\n");
1982 return 0;
1983 }
1984 bcopy(&parseBuffer[start], tempString, length);
1985 tempString[length] = 0;
1986 yylval = (object_t *)tempString;
1987 return STRING;
1988 }
1989
1990 /* parse quoted string */
1991 if (c == '"' || c == '\'') {
1992 int start, length;
1993 char * tempString;
1994 char quoteChar = c;
1995
1996 start = parseBufferIndex + 1; // skip quote
1997 /* find end of string, line, buffer */
1998 while ((c = nextChar()) != quoteChar) {
1999 if (c == '\\') {
2000 c = nextChar();
2001 }
2002 if (c == '\n') {
2003 lineNumber++;
2004 }
2005 if (c == 0) {
2006 return SYNTAX_ERROR;
2007 }
2008 }
2009 length = parseBufferIndex - start;
2010 /* skip over trailing quote */
2011 (void)nextChar();
2012 /* copy to null terminated buffer */
2013 tempString = (char *)malloc(length + 1);
2014 if (tempString == NULL) {
2015 printf("OSUnserialize: can't alloc temp memory\n");
2016 return 0;
2017 }
2018
2019 int to = 0;
2020 for (int from = start; from < parseBufferIndex; from++) {
2021 // hack - skip over backslashes
2022 if (parseBuffer[from] == '\\') {
2023 length--;
2024 continue;
2025 }
2026 tempString[to] = parseBuffer[from];
2027 to++;
2028 }
2029 tempString[length] = 0;
2030 yylval = (object_t *)tempString;
2031 return STRING;
2032 }
2033
2034 /* process numbers */
2035 if (isDigit(c)) {
2036 unsigned long long n = 0;
2037 int base = 10;
2038
2039 if (c == '0') {
2040 c = nextChar();
2041 if (c == 'x') {
2042 base = 16;
2043 c = nextChar();
2044 }
2045 }
2046 if (base == 10) {
2047 while (isDigit(c)) {
2048 n = (n * base + c - '0');
2049 c = nextChar();
2050 }
2051 } else {
2052 while (isHexDigit(c)) {
2053 if (isDigit(c)) {
2054 n = (n * base + c - '0');
2055 } else {
2056 n = (n * base + 0xa + c - 'a');
2057 }
2058 c = nextChar();
2059 }
2060 }
2061
2062 yylval = newObject();
2063 yylval->u.offset = n;
2064
2065 return NUMBER;
2066 }
2067
2068 #define OSDATA_ALLOC_SIZE 4096
2069
2070 /* process data */
2071 if (c == '<') {
2072 unsigned char *d, *start, *lastStart;
2073
2074 size_t buflen = OSDATA_ALLOC_SIZE;
2075 start = lastStart = d = (unsigned char *)malloc(buflen);
2076 c = nextChar(); // skip over '<'
2077 while (c != 0 && c != '>') {
2078 if (isSpace(c)) {
2079 while ((c = nextChar()) != 0 && isSpace(c)) {
2080 }
2081 }
2082 ;
2083 if (c == '#') {
2084 while ((c = nextChar()) != 0 && c != '\n') {
2085 }
2086 }
2087 ;
2088 if (c == '\n') {
2089 lineNumber++;
2090 c = nextChar();
2091 continue;
2092 }
2093
2094 // get high nibble
2095 if (!isHexDigit(c)) {
2096 break;
2097 }
2098 if (isDigit(c)) {
2099 *d = (c - '0') << 4;
2100 } else {
2101 *d = (0xa + (c - 'a')) << 4;
2102 }
2103
2104 // get low nibble
2105 c = nextChar();
2106 if (!isHexDigit(c)) {
2107 break;
2108 }
2109 if (isDigit(c)) {
2110 *d |= c - '0';
2111 } else {
2112 *d |= 0xa + (c - 'a');
2113 }
2114
2115 d++;
2116 if ((d - lastStart) >= OSDATA_ALLOC_SIZE) {
2117 int oldsize = d - start;
2118 assert(buflen == oldsize);
2119 start = (unsigned char *)realloc(start, oldsize, buflen);
2120 d = lastStart = start + oldsize;
2121 }
2122 c = nextChar();
2123 }
2124 if (c != '>') {
2125 safe_free(start, buflen);
2126 return SYNTAX_ERROR;
2127 }
2128
2129 // got it!
2130 yylval = newObject();
2131 yylval->object = start;
2132 yylval->size = d - start;
2133
2134 (void)nextChar(); // skip over '>'
2135 return DATA;
2136 }
2137
2138
2139 /* return single chars, move pointer to next char */
2140 (void)nextChar();
2141 return c;
2142 }
2143
2144 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2145 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2146 // !@$&)(^Q$&*^!$(*!@$_(^%_(*Q#$(_*&!$_(*&!$_(*&!#$(*!@&^!@#%!_!#
2147
2148 #if DEBUG
2149 int debugUnserializeAllocCount = 0;
2150 #endif
2151
2152 object_t *
newObject()2153 newObject()
2154 {
2155 #if DEBUG
2156 debugUnserializeAllocCount++;
2157 #endif
2158 return malloc_type(object_t);
2159 }
2160
2161 void
freeObject(object_t * o)2162 freeObject(object_t *o)
2163 {
2164 #if DEBUG
2165 debugUnserializeAllocCount--;
2166 #endif
2167 free_type(object_t, o);
2168 }
2169
2170 static OSDictionary *tags;
2171
2172 static void
rememberObject(int tag,object_t * o)2173 rememberObject(int tag, object_t *o)
2174 {
2175 char key[16];
2176 snprintf(key, sizeof(key), "%u", tag);
2177
2178 tags->setObject(key, (OSObject *)o);
2179 }
2180
2181 static OSObject *
retrieveObject(int tag)2182 retrieveObject(int tag)
2183 {
2184 char key[16];
2185 snprintf(key, sizeof(key), "%u", tag);
2186
2187 return tags->getObject(key);
2188 }
2189
2190 OSObject *
buildOSDictionary(object_t * o)2191 buildOSDictionary(object_t *o)
2192 {
2193 object_t *temp, *last = o;
2194 int count = 0;
2195
2196 // get count and last object
2197 while (o) {
2198 count++;
2199 last = o;
2200 o = o->next;
2201 }
2202 o = last;
2203
2204 OSDictionary *d = OSDictionary::withCapacity(count);
2205
2206 while (o) {
2207 #ifdef metaclass_stuff_worksXXX
2208 if (((OSObject *)o->u.key)->metaCast("OSSymbol")) {
2209 // XXX the evil frontdoor
2210 d->setObject((OSSymbol *)o->u.key, (OSObject *)o->object);
2211 } else {
2212 // If it isn't a symbol, I hope it's a string!
2213 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
2214 }
2215 #else
2216 d->setObject((OSString *)o->u.key, (OSObject *)o->object);
2217 #endif
2218 ((OSObject *)o->object)->release();
2219 ((OSObject *)o->u.key)->release();
2220 temp = o;
2221 o = o->prev;
2222 freeObject(temp);
2223 }
2224 return d;
2225 };
2226
2227 OSObject *
buildOSArray(object_t * o)2228 buildOSArray(object_t *o)
2229 {
2230 object_t *temp, *last = o;
2231 int count = 0;
2232
2233 // get count and last object
2234 while (o) {
2235 count++;
2236 last = o;
2237 o = o->next;
2238 }
2239 o = last;
2240
2241 OSArray *a = OSArray::withCapacity(count);
2242
2243 while (o) {
2244 a->setObject((OSObject *)o->object);
2245 ((OSObject *)o->object)->release();
2246 temp = o;
2247 o = o->prev;
2248 freeObject(temp);
2249 }
2250 return a;
2251 };
2252
2253 OSObject *
buildOSSet(object_t * o)2254 buildOSSet(object_t *o)
2255 {
2256 OSArray *a = (OSArray *)buildOSArray(o);
2257 OSSet *s = OSSet::withArray(a, a->getCapacity());
2258
2259 a->release();
2260 return s;
2261 };
2262
2263 OSObject *
buildOSString(object_t * o)2264 buildOSString(object_t *o)
2265 {
2266 OSString *s = OSString::withCString((char *)o);
2267
2268 safe_free(o, strlen((char *)o) + 1);
2269
2270 return s;
2271 };
2272
2273 OSObject *
buildOSData(object_t * o)2274 buildOSData(object_t *o)
2275 {
2276 OSData *d;
2277
2278 if (o->size) {
2279 d = OSData::withBytes(o->object, o->size);
2280 } else {
2281 d = OSData::withCapacity(0);
2282 }
2283 safe_free(o->object, o->size);
2284 freeObject(o);
2285 return d;
2286 };
2287
2288 OSObject *
buildOSOffset(object_t * o)2289 buildOSOffset(object_t *o)
2290 {
2291 OSNumber *off = OSNumber::withNumber(o->u.offset, o->size);
2292 freeObject(o);
2293 return off;
2294 };
2295
2296 OSObject *
buildOSBoolean(object_t * o)2297 buildOSBoolean(object_t *o)
2298 {
2299 OSBoolean *b = OSBoolean::withBoolean((bool)o);
2300 return b;
2301 };
2302
2303 __BEGIN_DECLS
2304 #include <kern/locks.h>
2305 __END_DECLS
2306
2307 static lck_mtx_t * lock = 0;
2308 extern lck_grp_t *IOLockGroup;
2309
2310 OSObject*
OSUnserialize(const char * buffer,OSString ** errorString)2311 OSUnserialize(const char *buffer, OSString **errorString)
2312 {
2313 OSObject *object;
2314
2315 if (!lock) {
2316 lock = lck_mtx_alloc_init(IOLockGroup, LCK_ATTR_NULL);
2317 lck_mtx_lock(lock);
2318 } else {
2319 lck_mtx_lock(lock);
2320 }
2321
2322 #if DEBUG
2323 debugUnserializeAllocCount = 0;
2324 #endif
2325 yyerror_message[0] = 0; //just in case
2326 parseBuffer = buffer;
2327 parseBufferIndex = 0;
2328 tags = OSDictionary::withCapacity(128);
2329 if (yyparse() == 0) {
2330 object = parsedObject;
2331 if (errorString) {
2332 *errorString = NULL;
2333 }
2334 } else {
2335 object = NULL;
2336 if (errorString) {
2337 *errorString = OSString::withCString(yyerror_message);
2338 }
2339 }
2340
2341 tags->release();
2342 #if DEBUG
2343 if (debugUnserializeAllocCount) {
2344 printf("OSUnserialize: allocation check failed, count = %d.\n",
2345 debugUnserializeAllocCount);
2346 }
2347 #endif
2348 lck_mtx_unlock(lock);
2349
2350 return object;
2351 }
2352
2353 #endif // not __clang_analyzer__
2354
2355
2356 //
2357 //
2358 //
2359 //
2360 //
2361 // DO NOT EDIT OSUnserialize.cpp!
2362 //
2363 // this means you!
2364 //
2365 //
2366 //
2367 //
2368 //
2369