1 /*++ 2 3 Copyright (c) 2004, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 DepexParser.c 15 16 Abstract: 17 18 Validate Dependency Expression syntax 19 recursive descent Algorithm 20 21 The original BNF grammar(taken from "Pre EFI Initialization Core Interface Specification 22 draft review 0.9") is thus: 23 <depex> ::= BEFORE <guid> END 24 | AFTER <guid> END 25 | SOR <bool> END 26 | <bool> END 27 <bool> ::= <bool> AND <term> 28 | <bool> OR <term> 29 | <term> 30 <term> ::= NOT <factor> 31 | <factor> 32 <factor> ::= <bool> 33 | TRUE 34 | FALSE 35 | GUID 36 37 <guid> ::= '{' <hex32> ',' <hex16> ',' <hex16> ',' 38 <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' 39 <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}' 40 <hex32> ::= <hexprefix> <hexvalue> 41 <hex16> ::= <hexprefix> <hexvalue> 42 <hex8> ::= <hexprefix> <hexvalue> 43 <hexprefix>::= '0' 'x' 44 | '0' 'X' 45 <hexvalue> ::= <hexdigit> <hexvalue> 46 | <hexdigit> 47 <hexdigit> ::= [0-9] 48 | [a-f] 49 | [A-F] 50 51 After cleaning left recursive and parentheses supported, the BNF grammar used in this module is thus: 52 <depex> ::= BEFORE <guid> 53 | AFTER <guid> 54 | SOR <bool> 55 | <bool> 56 <bool> ::= <term><rightbool> 57 <rightbool>::= AND <term><rightbool> 58 | OR <term><rightbool> 59 | '' 60 <term> ::= NOT <factor> 61 | <factor> 62 <factor> ::= '('<bool>')'<rightfactor> 63 | NOT <factor> <rightbool> <rightfactor> 64 | TRUE <rightfactor> 65 | FALSE <rightfactor> 66 | END <rightfactor> 67 | <guid> <rightfactor> 68 <rightfactor> ::=AND <term><rightbool> <rightfactor> 69 | OR <term><rightbool> <rightfactor> 70 | '' 71 <guid> ::= '{' <hex32> ',' <hex16> ',' <hex16> ',' 72 <hex8> ',' <hex8> ',' <hex8> ',' <hex8> ',' 73 <hex8> ',' <hex8> ',' <hex8> ',' <hex8> '}' 74 <hex32> ::= <hexprefix> <hexvalue> 75 <hex16> ::= <hexprefix> <hexvalue> 76 <hex8> ::= <hexprefix> <hexvalue> 77 <hexprefix>::= '0' 'x' 78 | '0' 'X' 79 <hexvalue> ::= <hexdigit> <hexvalue> 80 | <hexdigit> 81 <hexdigit> ::= [0-9] 82 | [a-f] 83 | [A-F] 84 85 Note: 1. There's no precedence in operators except parentheses; 86 2. For hex32, less and equal than 8 bits is valid, more than 8 bits is invalid. 87 Same constraint for hex16 is 4, hex8 is 2. All hex should contains at least 1 bit. 88 3. "<factor> ::= '('<bool>')'<rightfactor>" is added to support parentheses; 89 4. "<factor> ::= GUID" is changed to "<factor> ::= <guid>"; 90 5. "DEPENDENCY_END" is the terminal of the expression. But it has been filtered by caller. 91 During parsing, "DEPENDENCY_END" will be treated as illegal factor; 92 93 This code should build in any environment that supports a standard C-library w/ string 94 operations and File I/O services. 95 96 As an example of usage, consider the following: 97 98 The input string could be something like: 99 100 NOT ({ 0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, 0x0, 0xa0, 0xc9, 0x69, 0x72, 101 0x3b } AND { 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 102 0x72, 0x3b }) OR { 0x03c4e603, 0xac28, 0x11d3, 0x9a, 0x2d, 0x00, 0x90, 0x27, 103 0x3f, 0xc1, 0x4d } AND 104 105 It's invalid for an extra "AND" in the end. 106 107 Complies with Tiano C Coding Standards Document, version 0.33, 16 Aug 2001. 108 109 --*/ 110 111 #include "DepexParser.h" 112 113 BOOLEAN 114 ParseBool ( 115 IN INT8 *Pbegin, 116 IN UINT32 length, 117 IN OUT INT8 **Pindex 118 ); 119 120 BOOLEAN 121 ParseTerm ( 122 IN INT8 *Pbegin, 123 IN UINT32 length, 124 IN OUT INT8 **Pindex 125 ); 126 127 BOOLEAN 128 ParseRightBool ( 129 IN INT8 *Pbegin, 130 IN UINT32 length, 131 IN OUT INT8 **Pindex 132 ); 133 134 BOOLEAN 135 ParseFactor ( 136 IN INT8 *Pbegin, 137 IN UINT32 length, 138 IN OUT INT8 **Pindex 139 ); 140 141 VOID 142 LeftTrim ( 143 IN INT8 *Pbegin, 144 IN UINT32 length, 145 IN OUT INT8 **Pindex 146 ) 147 /*++ 148 149 Routine Description: 150 151 Left trim the space, '\n' and '\r' character in string. 152 The space at the end does not need trim. 153 154 155 Arguments: 156 157 Pbegin The pointer to the string 158 length length of the string 159 Pindex The pointer of pointer to the next parse character in the string 160 161 Returns: 162 163 None 164 165 166 --*/ 167 { 168 while 169 ( 170 ((*Pindex) < (Pbegin + length)) && 171 ((strncmp (*Pindex, " ", 1) == 0) || (strncmp (*Pindex, "\n", 1) == 0) || (strncmp (*Pindex, "\r", 1) == 0)) 172 ) { 173 (*Pindex)++; 174 } 175 } 176 177 BOOLEAN 178 ParseHexdigit ( 179 IN INT8 *Pbegin, 180 IN UINT32 length, 181 IN OUT INT8 **Pindex 182 ) 183 /*++ 184 185 Routine Description: 186 187 Parse Hex bit in dependency expression. 188 189 Arguments: 190 191 Pbegin The pointer to the string 192 length Length of the string 193 Pindex The pointer of pointer to the next parse character in the string 194 195 Returns: 196 197 BOOLEAN If parses a valid hex bit, return TRUE, otherwise FALSE 198 199 200 --*/ 201 { 202 // 203 // <hexdigit> ::= [0-9] | [a-f] | [A-F] 204 // 205 if (((**Pindex) >= '0' && (**Pindex) <= '9') || 206 ((**Pindex) >= 'a' && (**Pindex) <= 'f') || 207 ((**Pindex) >= 'A' && (**Pindex) <= 'F') 208 ) { 209 (*Pindex)++; 210 return TRUE; 211 } else { 212 return FALSE; 213 } 214 } 215 216 BOOLEAN 217 ParseHex32 ( 218 IN INT8 *Pbegin, 219 IN UINT32 length, 220 IN OUT INT8 **Pindex 221 ) 222 /*++ 223 224 Routine Description: 225 226 Parse Hex32 in dependency expression. 227 228 Arguments: 229 230 Pbegin The pointer to the string 231 length Length of the string 232 Pindex The pointer of point to the next parse character in the string 233 234 Returns: 235 236 BOOLEAN If parses a valid hex32, return TRUE, otherwise FALSE 237 238 239 --*/ 240 { 241 INT32 Index; 242 INT8 *Pin; 243 244 Index = 0; 245 Pin = *Pindex; 246 LeftTrim (Pbegin, length, Pindex); 247 248 if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { 249 return FALSE; 250 } 251 (*Pindex) += 2; 252 253 while (ParseHexdigit (Pbegin, length, Pindex)) { 254 Index++; 255 } 256 257 if (Index > 0 && Index <= 8) { 258 return TRUE; 259 } else { 260 *Pindex = Pin; 261 return FALSE; 262 } 263 } 264 265 BOOLEAN 266 ParseHex16 ( 267 IN INT8 *Pbegin, 268 IN UINT32 length, 269 IN OUT INT8 **Pindex 270 ) 271 /*++ 272 273 Routine Description: 274 275 Parse Hex16 in dependency expression. 276 277 Arguments: 278 279 Pbegin The pointer to the string 280 length Length of the string 281 Pindex The pointer of pointer to the next parse character in the string 282 283 Returns: 284 285 BOOLEAN If parses a valid hex16, return TRUE, otherwise FALSE 286 287 288 --*/ 289 { 290 int Index; 291 INT8 *Pin; 292 293 Index = 0; 294 Pin = *Pindex; 295 LeftTrim (Pbegin, length, Pindex); 296 297 if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { 298 return FALSE; 299 } 300 (*Pindex) += 2; 301 302 while (ParseHexdigit (Pbegin, length, Pindex)) { 303 Index++; 304 } 305 306 if (Index > 0 && Index <= 4) { 307 return TRUE; 308 } else { 309 *Pindex = Pin; 310 return FALSE; 311 } 312 } 313 314 BOOLEAN 315 ParseHex8 ( 316 IN INT8 *Pbegin, 317 IN UINT32 length, 318 IN OUT INT8 **Pindex 319 ) 320 /*++ 321 322 Routine Description: 323 324 Parse Hex8 in dependency expression. 325 326 Arguments: 327 328 Pbegin The pointer to the string 329 length Length of the string 330 Pindex The pointer of pointer to the next parse character in the string 331 332 Returns: 333 334 BOOLEAN If parses a valid hex8, return TRUE, otherwise FALSE 335 336 337 --*/ 338 { 339 int Index; 340 INT8 *Pin; 341 342 Index = 0; 343 Pin = *Pindex; 344 LeftTrim (Pbegin, length, Pindex); 345 346 if ((strncmp (*Pindex, "0x", 2) != 0) && (strncmp (*Pindex, "0X", 2) != 0)) { 347 return FALSE; 348 } 349 (*Pindex) += 2; 350 351 while (ParseHexdigit (Pbegin, length, Pindex)) { 352 Index++; 353 } 354 355 if (Index > 0 && Index <= 2) { 356 return TRUE; 357 } else { 358 *Pindex = Pin; 359 return FALSE; 360 } 361 } 362 363 BOOLEAN 364 ParseGuid ( 365 IN INT8 *Pbegin, 366 IN UINT32 length, 367 IN OUT INT8 **Pindex 368 ) 369 /*++ 370 371 Routine Description: 372 373 Parse guid in dependency expression. 374 There can be any number of spaces between '{' and hexword, ',' and hexword, 375 hexword and ',', hexword and '}'. The hexword include hex32, hex16 and hex8. 376 377 Arguments: 378 379 Pbegin The pointer to the string 380 length length of the string 381 Pindex The pointer of pointer to the next parse character in the string 382 383 Returns: 384 385 BOOLEAN If parses a valid guid, return TRUE, otherwise FALSE 386 387 388 --*/ 389 { 390 INT32 Index; 391 INT8 *Pin; 392 Pin = *Pindex; 393 LeftTrim (Pbegin, length, Pindex); 394 if (strncmp (*Pindex, "{", 1) != 0) { 395 return FALSE; 396 } 397 (*Pindex)++; 398 399 LeftTrim (Pbegin, length, Pindex); 400 if (!ParseHex32 (Pbegin, length, Pindex)) { 401 *Pindex = Pin; 402 return FALSE; 403 } 404 405 LeftTrim (Pbegin, length, Pindex); 406 if (strncmp (*Pindex, ",", 1) != 0) { 407 return FALSE; 408 } else { 409 (*Pindex)++; 410 } 411 412 for (Index = 0; Index < 2; Index++) { 413 LeftTrim (Pbegin, length, Pindex); 414 if (!ParseHex16 (Pbegin, length, Pindex)) { 415 *Pindex = Pin; 416 return FALSE; 417 } 418 419 LeftTrim (Pbegin, length, Pindex); 420 if (strncmp (*Pindex, ",", 1) != 0) { 421 return FALSE; 422 } else { 423 (*Pindex)++; 424 } 425 } 426 427 for (Index = 0; Index < 7; Index++) { 428 LeftTrim (Pbegin, length, Pindex); 429 if (!ParseHex8 (Pbegin, length, Pindex)) { 430 *Pindex = Pin; 431 return FALSE; 432 } 433 434 LeftTrim (Pbegin, length, Pindex); 435 if (strncmp (*Pindex, ",", 1) != 0) { 436 return FALSE; 437 } else { 438 (*Pindex)++; 439 } 440 } 441 442 LeftTrim (Pbegin, length, Pindex); 443 if (!ParseHex8 (Pbegin, length, Pindex)) { 444 *Pindex = Pin; 445 return FALSE; 446 } 447 448 LeftTrim (Pbegin, length, Pindex); 449 if (strncmp (*Pindex, "}", 1) != 0) { 450 return FALSE; 451 } else { 452 (*Pindex)++; 453 } 454 455 return TRUE; 456 } 457 458 BOOLEAN 459 ParseRightFactor ( 460 IN INT8 *Pbegin, 461 IN UINT32 length, 462 IN OUT INT8 **Pindex 463 ) 464 /*++ 465 466 Routine Description: 467 468 Parse rightfactor in bool expression. 469 470 Arguments: 471 472 Pbegin The pointer to the string 473 length length of the string 474 Pindex The pointer of pointer to the next parse character in the string 475 476 Returns: 477 478 BOOLEAN If string is a valid rightfactor expression, return TRUE, otherwise FALSE 479 480 481 --*/ 482 { 483 INT8 *Pin; 484 485 Pin = *Pindex; 486 LeftTrim (Pbegin, length, Pindex); 487 488 // 489 // <rightfactor> ::=AND <term> <rightbool> <rightfactor> 490 // 491 if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { 492 *Pindex += strlen (OPERATOR_AND); 493 LeftTrim (Pbegin, length, Pindex); 494 495 if (ParseTerm (Pbegin, length, Pindex)) { 496 LeftTrim (Pbegin, length, Pindex); 497 498 if (ParseRightBool (Pbegin, length, Pindex)) { 499 LeftTrim (Pbegin, length, Pindex); 500 if (ParseRightFactor (Pbegin, length, Pindex)) { 501 return TRUE; 502 } else { 503 *Pindex = Pin; 504 } 505 } else { 506 *Pindex = Pin; 507 } 508 } else { 509 *Pindex = Pin; 510 } 511 } 512 // 513 // <rightfactor> ::=OR <term> <rightbool> <rightfactor> 514 // 515 if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { 516 *Pindex += strlen (OPERATOR_OR); 517 LeftTrim (Pbegin, length, Pindex); 518 519 if (ParseTerm (Pbegin, length, Pindex)) { 520 LeftTrim (Pbegin, length, Pindex); 521 522 if (ParseRightBool (Pbegin, length, Pindex)) { 523 LeftTrim (Pbegin, length, Pindex); 524 if (ParseRightFactor (Pbegin, length, Pindex)) { 525 return TRUE; 526 } else { 527 *Pindex = Pin; 528 } 529 } else { 530 *Pindex = Pin; 531 } 532 } else { 533 *Pindex = Pin; 534 } 535 } 536 // 537 // <rightfactor> ::= '' 538 // 539 *Pindex = Pin; 540 return TRUE; 541 } 542 543 BOOLEAN 544 ParseRightBool ( 545 IN INT8 *Pbegin, 546 IN UINT32 length, 547 IN OUT INT8 **Pindex 548 ) 549 /*++ 550 551 Routine Description: 552 553 Parse rightbool in bool expression. 554 555 Arguments: 556 557 Pbegin The pointer to the string 558 length length of the string 559 Pindex The pointer of pointer to the next parse character in the string 560 561 Returns: 562 563 BOOLEAN If string is a valid rightbool expression, return TRUE, otherwise FALSE 564 565 566 --*/ 567 { 568 INT8 *Pin; 569 570 Pin = *Pindex; 571 LeftTrim (Pbegin, length, Pindex); 572 573 // 574 // <rightbool>::= AND <term><rightbool> 575 // 576 if (strncmp (*Pindex, OPERATOR_AND, strlen (OPERATOR_AND)) == 0) { 577 *Pindex += strlen (OPERATOR_AND); 578 LeftTrim (Pbegin, length, Pindex); 579 580 if (ParseTerm (Pbegin, length, Pindex)) { 581 LeftTrim (Pbegin, length, Pindex); 582 583 if (ParseRightBool (Pbegin, length, Pindex)) { 584 return TRUE; 585 } else { 586 *Pindex = Pin; 587 } 588 } else { 589 *Pindex = Pin; 590 } 591 } 592 // 593 // <rightbool>::= OR <term><rightbool> 594 // 595 if (strncmp (*Pindex, OPERATOR_OR, strlen (OPERATOR_OR)) == 0) { 596 *Pindex += strlen (OPERATOR_OR); 597 LeftTrim (Pbegin, length, Pindex); 598 599 if (ParseTerm (Pbegin, length, Pindex)) { 600 LeftTrim (Pbegin, length, Pindex); 601 602 if (ParseRightBool (Pbegin, length, Pindex)) { 603 return TRUE; 604 } else { 605 *Pindex = Pin; 606 } 607 } else { 608 *Pindex = Pin; 609 } 610 } 611 // 612 // <rightbool>::= '' 613 // 614 *Pindex = Pin; 615 return TRUE; 616 } 617 618 BOOLEAN 619 ParseFactor ( 620 IN INT8 *Pbegin, 621 IN UINT32 length, 622 IN OUT INT8 **Pindex 623 ) 624 /*++ 625 626 Routine Description: 627 628 Parse factor in bool expression. 629 630 Arguments: 631 632 Pbegin The pointer to the string 633 length length of the string 634 Pindex The pointer of pointer to the next parse character in the string 635 636 Returns: 637 638 BOOLEAN If string is a valid factor, return TRUE, otherwise FALSE 639 640 641 --*/ 642 { 643 INT8 *Pin; 644 645 Pin = *Pindex; 646 LeftTrim (Pbegin, length, Pindex); 647 648 // 649 // <factor> ::= '('<bool>')'<rightfactor> 650 // 651 if (strncmp (*Pindex, OPERATOR_LEFT_PARENTHESIS, strlen (OPERATOR_LEFT_PARENTHESIS)) == 0) { 652 *Pindex += strlen (OPERATOR_LEFT_PARENTHESIS); 653 LeftTrim (Pbegin, length, Pindex); 654 655 if (!ParseBool (Pbegin, length, Pindex)) { 656 *Pindex = Pin; 657 } else { 658 LeftTrim (Pbegin, length, Pindex); 659 660 if (strncmp (*Pindex, OPERATOR_RIGHT_PARENTHESIS, strlen (OPERATOR_RIGHT_PARENTHESIS)) == 0) { 661 *Pindex += strlen (OPERATOR_RIGHT_PARENTHESIS); 662 LeftTrim (Pbegin, length, Pindex); 663 664 if (ParseRightFactor (Pbegin, length, Pindex)) { 665 return TRUE; 666 } else { 667 *Pindex = Pin; 668 } 669 } 670 } 671 } 672 // 673 // <factor> ::= NOT <factor> <rightbool> <rightfactor> 674 // 675 if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { 676 *Pindex += strlen (OPERATOR_NOT); 677 LeftTrim (Pbegin, length, Pindex); 678 679 if (ParseFactor (Pbegin, length, Pindex)) { 680 LeftTrim (Pbegin, length, Pindex); 681 682 if (ParseRightBool (Pbegin, length, Pindex)) { 683 LeftTrim (Pbegin, length, Pindex); 684 685 if (ParseRightFactor (Pbegin, length, Pindex)) { 686 return TRUE; 687 } else { 688 *Pindex = Pin; 689 } 690 } else { 691 *Pindex = Pin; 692 } 693 } else { 694 *Pindex = Pin; 695 } 696 } 697 // 698 // <factor> ::= TRUE <rightfactor> 699 // 700 if (strncmp (*Pindex, OPERATOR_TRUE, strlen (OPERATOR_TRUE)) == 0) { 701 *Pindex += strlen (OPERATOR_TRUE); 702 LeftTrim (Pbegin, length, Pindex); 703 704 if (ParseRightFactor (Pbegin, length, Pindex)) { 705 return TRUE; 706 } else { 707 *Pindex = Pin; 708 } 709 } 710 // 711 // <factor> ::= FALSE <rightfactor> 712 // 713 if (strncmp (*Pindex, OPERATOR_FALSE, strlen (OPERATOR_FALSE)) == 0) { 714 *Pindex += strlen (OPERATOR_FALSE); 715 LeftTrim (Pbegin, length, Pindex); 716 717 if (ParseRightFactor (Pbegin, length, Pindex)) { 718 return TRUE; 719 } else { 720 *Pindex = Pin; 721 } 722 } 723 // 724 // <factor> ::= <guid> <rightfactor> 725 // 726 if (ParseGuid (Pbegin, length, Pindex)) { 727 LeftTrim (Pbegin, length, Pindex); 728 729 if (ParseRightFactor (Pbegin, length, Pindex)) { 730 return TRUE; 731 } else { 732 *Pindex = Pin; 733 return FALSE; 734 } 735 } else { 736 *Pindex = Pin; 737 return FALSE; 738 } 739 } 740 741 BOOLEAN 742 ParseTerm ( 743 IN INT8 *Pbegin, 744 IN UINT32 length, 745 IN OUT INT8 **Pindex 746 ) 747 /*++ 748 749 Routine Description: 750 751 Parse term in bool expression. 752 753 Arguments: 754 755 Pbegin The pointer to the string 756 length length of the string 757 Pindex The pointer of pointer to the next parse character in the string 758 759 Returns: 760 761 BOOLEAN If string is a valid term, return TRUE, otherwise FALSE 762 763 764 --*/ 765 { 766 INT8 *Pin; 767 768 Pin = *Pindex; 769 LeftTrim (Pbegin, length, Pindex); 770 771 // 772 // <term> ::= NOT <factor> 773 // 774 if (strncmp (*Pindex, OPERATOR_NOT, strlen (OPERATOR_NOT)) == 0) { 775 *Pindex += strlen (OPERATOR_NOT); 776 LeftTrim (Pbegin, length, Pindex); 777 778 if (!ParseFactor (Pbegin, length, Pindex)) { 779 *Pindex = Pin; 780 } else { 781 return TRUE; 782 } 783 } 784 // 785 // <term> ::=<factor> 786 // 787 if (ParseFactor (Pbegin, length, Pindex)) { 788 return TRUE; 789 } else { 790 *Pindex = Pin; 791 return FALSE; 792 } 793 } 794 795 BOOLEAN 796 ParseBool ( 797 IN INT8 *Pbegin, 798 IN UINT32 length, 799 IN OUT INT8 **Pindex 800 ) 801 /*++ 802 803 Routine Description: 804 805 Parse bool expression. 806 807 Arguments: 808 809 Pbegin The pointer to the string 810 length length of the string 811 Pindex The pointer of pointer to the next parse character in the string 812 813 Returns: 814 815 BOOLEAN If string is a valid bool expression, return TRUE, otherwise FALSE 816 817 818 --*/ 819 { 820 INT8 *Pin; 821 Pin = *Pindex; 822 LeftTrim (Pbegin, length, Pindex); 823 824 if (ParseTerm (Pbegin, length, Pindex)) { 825 LeftTrim (Pbegin, length, Pindex); 826 827 if (!ParseRightBool (Pbegin, length, Pindex)) { 828 *Pindex = Pin; 829 return FALSE; 830 } else { 831 return TRUE; 832 } 833 } else { 834 *Pindex = Pin; 835 return FALSE; 836 } 837 } 838 839 BOOLEAN 840 ParseDepex ( 841 IN INT8 *Pbegin, 842 IN UINT32 length 843 ) 844 /*++ 845 846 Routine Description: 847 848 Parse whole dependency expression. 849 850 Arguments: 851 852 Pbegin The pointer to the string 853 length length of the string 854 855 Returns: 856 857 BOOLEAN If string is a valid dependency expression, return TRUE, otherwise FALSE 858 859 860 --*/ 861 { 862 BOOLEAN Result; 863 INT8 **Pindex; 864 INT8 *temp; 865 866 Result = FALSE; 867 temp = Pbegin; 868 Pindex = &temp; 869 870 LeftTrim (Pbegin, length, Pindex); 871 if (strncmp (*Pindex, OPERATOR_BEFORE, strlen (OPERATOR_BEFORE)) == 0) { 872 (*Pindex) += strlen (OPERATOR_BEFORE); 873 Result = ParseGuid (Pbegin, length, Pindex); 874 875 } else if (strncmp (*Pindex, OPERATOR_AFTER, strlen (OPERATOR_AFTER)) == 0) { 876 (*Pindex) += strlen (OPERATOR_AFTER); 877 Result = ParseGuid (Pbegin, length, Pindex); 878 879 } else if (strncmp (*Pindex, OPERATOR_SOR, strlen (OPERATOR_SOR)) == 0) { 880 (*Pindex) += strlen (OPERATOR_SOR); 881 Result = ParseBool (Pbegin, length, Pindex); 882 883 } else { 884 Result = ParseBool (Pbegin, length, Pindex); 885 886 } 887 888 LeftTrim (Pbegin, length, Pindex); 889 return (BOOLEAN) (Result && (*Pindex) >= (Pbegin + length)); 890 } 891