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