| OLD | NEW |
| 1 /* | 1 /* |
| 2 ******************************************************************************* | 2 ******************************************************************************* |
| 3 * | 3 * |
| 4 * Copyright (C) 1998-2014, International Business Machines | 4 * Copyright (C) 1998-2015, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. | 5 * Corporation and others. All Rights Reserved. |
| 6 * | 6 * |
| 7 ******************************************************************************* | 7 ******************************************************************************* |
| 8 * | 8 * |
| 9 * File parse.cpp | 9 * File parse.cpp |
| 10 * | 10 * |
| 11 * Modification History: | 11 * Modification History: |
| 12 * | 12 * |
| 13 * Date Name Description | 13 * Date Name Description |
| 14 * 05/26/99 stephen Creation. | 14 * 05/26/99 stephen Creation. |
| 15 * 02/25/00 weiv Overhaul to write udata | 15 * 02/25/00 weiv Overhaul to write udata |
| 16 * 5/10/01 Ram removed ustdio dependency | 16 * 5/10/01 Ram removed ustdio dependency |
| 17 * 06/10/2001 Dominic Ludlam <dom@recoil.org> Rewritten | 17 * 06/10/2001 Dominic Ludlam <dom@recoil.org> Rewritten |
| 18 ******************************************************************************* | 18 ******************************************************************************* |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 // Safer use of UnicodeString. | 21 // Safer use of UnicodeString. |
| 22 #ifndef UNISTR_FROM_CHAR_EXPLICIT | 22 #ifndef UNISTR_FROM_CHAR_EXPLICIT |
| 23 # define UNISTR_FROM_CHAR_EXPLICIT explicit | 23 # define UNISTR_FROM_CHAR_EXPLICIT explicit |
| 24 #endif | 24 #endif |
| 25 | 25 |
| 26 // Less important, but still a good idea. | 26 // Less important, but still a good idea. |
| 27 #ifndef UNISTR_FROM_STRING_EXPLICIT | 27 #ifndef UNISTR_FROM_STRING_EXPLICIT |
| 28 # define UNISTR_FROM_STRING_EXPLICIT explicit | 28 # define UNISTR_FROM_STRING_EXPLICIT explicit |
| 29 #endif | 29 #endif |
| 30 | 30 |
| 31 #include <assert.h> |
| 31 #include "parse.h" | 32 #include "parse.h" |
| 32 #include "errmsg.h" | 33 #include "errmsg.h" |
| 33 #include "uhash.h" | 34 #include "uhash.h" |
| 34 #include "cmemory.h" | 35 #include "cmemory.h" |
| 35 #include "cstring.h" | 36 #include "cstring.h" |
| 36 #include "uinvchar.h" | 37 #include "uinvchar.h" |
| 37 #include "read.h" | 38 #include "read.h" |
| 38 #include "ustr.h" | 39 #include "ustr.h" |
| 39 #include "reslist.h" | 40 #include "reslist.h" |
| 40 #include "rbt_pars.h" | 41 #include "rbt_pars.h" |
| 41 #include "genrb.h" | 42 #include "genrb.h" |
| 43 #include "unicode/stringpiece.h" |
| 44 #include "unicode/unistr.h" |
| 42 #include "unicode/ustring.h" | 45 #include "unicode/ustring.h" |
| 43 #include "unicode/uscript.h" | 46 #include "unicode/uscript.h" |
| 44 #include "unicode/utf16.h" | 47 #include "unicode/utf16.h" |
| 45 #include "unicode/putil.h" | 48 #include "unicode/putil.h" |
| 49 #include "charstr.h" |
| 46 #include "collationbuilder.h" | 50 #include "collationbuilder.h" |
| 47 #include "collationdata.h" | 51 #include "collationdata.h" |
| 48 #include "collationdatareader.h" | 52 #include "collationdatareader.h" |
| 49 #include "collationdatawriter.h" | 53 #include "collationdatawriter.h" |
| 50 #include "collationfastlatinbuilder.h" | 54 #include "collationfastlatinbuilder.h" |
| 51 #include "collationinfo.h" | 55 #include "collationinfo.h" |
| 52 #include "collationroot.h" | 56 #include "collationroot.h" |
| 53 #include "collationruleparser.h" | 57 #include "collationruleparser.h" |
| 54 #include "collationtailoring.h" | 58 #include "collationtailoring.h" |
| 55 #include <stdio.h> | 59 #include <stdio.h> |
| 56 | 60 |
| 57 /* Number of tokens to read ahead of the current stream position */ | 61 /* Number of tokens to read ahead of the current stream position */ |
| 58 #define MAX_LOOKAHEAD 3 | 62 #define MAX_LOOKAHEAD 3 |
| 59 | 63 |
| 60 #define CR 0x000D | 64 #define CR 0x000D |
| 61 #define LF 0x000A | 65 #define LF 0x000A |
| 62 #define SPACE 0x0020 | 66 #define SPACE 0x0020 |
| 63 #define TAB 0x0009 | 67 #define TAB 0x0009 |
| 64 #define ESCAPE 0x005C | 68 #define ESCAPE 0x005C |
| 65 #define HASH 0x0023 | 69 #define HASH 0x0023 |
| 66 #define QUOTE 0x0027 | 70 #define QUOTE 0x0027 |
| 67 #define ZERO 0x0030 | 71 #define ZERO 0x0030 |
| 68 #define STARTCOMMAND 0x005B | 72 #define STARTCOMMAND 0x005B |
| 69 #define ENDCOMMAND 0x005D | 73 #define ENDCOMMAND 0x005D |
| 70 #define OPENSQBRACKET 0x005B | 74 #define OPENSQBRACKET 0x005B |
| 71 #define CLOSESQBRACKET 0x005D | 75 #define CLOSESQBRACKET 0x005D |
| 72 | 76 |
| 77 using icu::CharString; |
| 78 using icu::LocalMemory; |
| 73 using icu::LocalPointer; | 79 using icu::LocalPointer; |
| 80 using icu::LocalUCHARBUFPointer; |
| 81 using icu::StringPiece; |
| 74 using icu::UnicodeString; | 82 using icu::UnicodeString; |
| 75 | 83 |
| 76 struct Lookahead | 84 struct Lookahead |
| 77 { | 85 { |
| 78 enum ETokenType type; | 86 enum ETokenType type; |
| 79 struct UString value; | 87 struct UString value; |
| 80 struct UString comment; | 88 struct UString comment; |
| 81 uint32_t line; | 89 uint32_t line; |
| 82 }; | 90 }; |
| 83 | 91 |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_T
RANSLITERATION ) \n"); | 517 fprintf(stderr, " Warning: writing empty transliteration data ( UCONFIG_NO_T
RANSLITERATION ) \n"); |
| 510 #endif | 518 #endif |
| 511 result = string_open(state->bundle, tag, pTarget, size, NULL, status); | 519 result = string_open(state->bundle, tag, pTarget, size, NULL, status); |
| 512 | 520 |
| 513 ucbuf_close(ucbuf); | 521 ucbuf_close(ucbuf); |
| 514 uprv_free(pTarget); | 522 uprv_free(pTarget); |
| 515 T_FileStream_close(file); | 523 T_FileStream_close(file); |
| 516 | 524 |
| 517 return result; | 525 return result; |
| 518 } | 526 } |
| 519 static struct SResource* dependencyArray = NULL; | 527 static ArrayResource* dependencyArray = NULL; |
| 520 | 528 |
| 521 static struct SResource * | 529 static struct SResource * |
| 522 parseDependency(ParseState* state, char *tag, uint32_t startline, const struct U
String* comment, UErrorCode *status) | 530 parseDependency(ParseState* state, char *tag, uint32_t startline, const struct U
String* comment, UErrorCode *status) |
| 523 { | 531 { |
| 524 struct SResource *result = NULL; | 532 struct SResource *result = NULL; |
| 525 struct SResource *elem = NULL; | 533 struct SResource *elem = NULL; |
| 526 struct UString *tokenValue; | 534 struct UString *tokenValue; |
| 527 uint32_t line; | 535 uint32_t line; |
| 528 char filename[256] = { '\0' }; | 536 char filename[256] = { '\0' }; |
| 529 char cs[128] = { '\0' }; | 537 char cs[128] = { '\0' }; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 } | 572 } |
| 565 } | 573 } |
| 566 if(dependencyArray==NULL){ | 574 if(dependencyArray==NULL){ |
| 567 dependencyArray = array_open(state->bundle, "%%DEPENDENCY", NULL, status
); | 575 dependencyArray = array_open(state->bundle, "%%DEPENDENCY", NULL, status
); |
| 568 } | 576 } |
| 569 if(tag!=NULL){ | 577 if(tag!=NULL){ |
| 570 result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue-
>fLength, comment, status); | 578 result = string_open(state->bundle, tag, tokenValue->fChars, tokenValue-
>fLength, comment, status); |
| 571 } | 579 } |
| 572 elem = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLen
gth, comment, status); | 580 elem = string_open(state->bundle, NULL, tokenValue->fChars, tokenValue->fLen
gth, comment, status); |
| 573 | 581 |
| 574 array_add(dependencyArray, elem, status); | 582 dependencyArray->add(elem); |
| 575 | 583 |
| 576 if (U_FAILURE(*status)) | 584 if (U_FAILURE(*status)) |
| 577 { | 585 { |
| 578 return NULL; | 586 return NULL; |
| 579 } | 587 } |
| 580 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); | 588 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); |
| 581 return result; | 589 return result; |
| 582 } | 590 } |
| 583 static struct SResource * | 591 static struct SResource * |
| 584 parseString(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng* comment, UErrorCode *status) | 592 parseString(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng* comment, UErrorCode *status) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 } | 652 } |
| 645 | 653 |
| 646 return result; | 654 return result; |
| 647 } | 655 } |
| 648 | 656 |
| 649 #if !UCONFIG_NO_COLLATION | 657 #if !UCONFIG_NO_COLLATION |
| 650 | 658 |
| 651 namespace { | 659 namespace { |
| 652 | 660 |
| 653 static struct SResource* resLookup(struct SResource* res, const char* key){ | 661 static struct SResource* resLookup(struct SResource* res, const char* key){ |
| 654 struct SResource *current = NULL; | 662 if (res == res_none() || !res->isTable()) { |
| 655 struct SResTable *list; | |
| 656 if (res == res_none()) { | |
| 657 return NULL; | 663 return NULL; |
| 658 } | 664 } |
| 659 | 665 |
| 660 list = &(res->u.fTable); | 666 TableResource *list = static_cast<TableResource *>(res); |
| 661 | 667 SResource *current = list->fFirst; |
| 662 current = list->fFirst; | |
| 663 while (current != NULL) { | 668 while (current != NULL) { |
| 664 if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), key) == 0) { | 669 if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), key) == 0) { |
| 665 return current; | 670 return current; |
| 666 } | 671 } |
| 667 current = current->fNext; | 672 current = current->fNext; |
| 668 } | 673 } |
| 669 return NULL; | 674 return NULL; |
| 670 } | 675 } |
| 671 | 676 |
| 672 class GenrbImporter : public icu::CollationRuleParser::Importer { | 677 class GenrbImporter : public icu::CollationRuleParser::Importer { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 683 const char *outputDir; | 688 const char *outputDir; |
| 684 }; | 689 }; |
| 685 | 690 |
| 686 GenrbImporter::~GenrbImporter() {} | 691 GenrbImporter::~GenrbImporter() {} |
| 687 | 692 |
| 688 void | 693 void |
| 689 GenrbImporter::getRules( | 694 GenrbImporter::getRules( |
| 690 const char *localeID, const char *collationType, | 695 const char *localeID, const char *collationType, |
| 691 UnicodeString &rules, | 696 UnicodeString &rules, |
| 692 const char *& /*errorReason*/, UErrorCode &errorCode) { | 697 const char *& /*errorReason*/, UErrorCode &errorCode) { |
| 693 struct SRBRoot *data = NULL; | 698 CharString filename(localeID, errorCode); |
| 694 UCHARBUF *ucbuf = NULL; | 699 for(int32_t i = 0; i < filename.length(); i++){ |
| 695 int localeLength = strlen(localeID); | |
| 696 char* filename = (char*)uprv_malloc(localeLength+5); | |
| 697 char *inputDirBuf = NULL; | |
| 698 char *openFileName = NULL; | |
| 699 const char* cp = ""; | |
| 700 int32_t i = 0; | |
| 701 int32_t dirlen = 0; | |
| 702 int32_t filelen = 0; | |
| 703 struct SResource* root; | |
| 704 struct SResource* collations; | |
| 705 struct SResource* collation; | |
| 706 struct SResource* sequence; | |
| 707 | |
| 708 memcpy(filename, localeID, localeLength); | |
| 709 for(i = 0; i < localeLength; i++){ | |
| 710 if(filename[i] == '-'){ | 700 if(filename[i] == '-'){ |
| 711 filename[i] = '_'; | 701 filename.data()[i] = '_'; |
| 712 } | 702 } |
| 713 } | 703 } |
| 714 filename[localeLength] = '.'; | 704 filename.append(".txt", errorCode); |
| 715 filename[localeLength+1] = 't'; | |
| 716 filename[localeLength+2] = 'x'; | |
| 717 filename[localeLength+3] = 't'; | |
| 718 filename[localeLength+4] = 0; | |
| 719 | |
| 720 | |
| 721 if (U_FAILURE(errorCode)) { | 705 if (U_FAILURE(errorCode)) { |
| 722 return; | 706 return; |
| 723 } | 707 } |
| 724 if(filename==NULL){ | 708 CharString inputDirBuf; |
| 725 errorCode=U_ILLEGAL_ARGUMENT_ERROR; | 709 CharString openFileName; |
| 726 return; | |
| 727 }else{ | |
| 728 filelen = (int32_t)uprv_strlen(filename); | |
| 729 } | |
| 730 if(inputDir == NULL) { | 710 if(inputDir == NULL) { |
| 731 const char *filenameBegin = uprv_strrchr(filename, U_FILE_SEP_CHAR); | 711 const char *filenameBegin = uprv_strrchr(filename.data(), U_FILE_SEP_CHA
R); |
| 732 openFileName = (char *) uprv_malloc(dirlen + filelen + 2); | |
| 733 openFileName[0] = '\0'; | |
| 734 if (filenameBegin != NULL) { | 712 if (filenameBegin != NULL) { |
| 735 /* | 713 /* |
| 736 * When a filename ../../../data/root.txt is specified, | 714 * When a filename ../../../data/root.txt is specified, |
| 737 * we presume that the input directory is ../../../data | 715 * we presume that the input directory is ../../../data |
| 738 * This is very important when the resource file includes | 716 * This is very important when the resource file includes |
| 739 * another file, like UCARules.txt or thaidict.brk. | 717 * another file, like UCARules.txt or thaidict.brk. |
| 740 */ | 718 */ |
| 741 int32_t filenameSize = (int32_t)(filenameBegin - filename + 1); | 719 StringPiece dir = filename.toStringPiece(); |
| 742 inputDirBuf = (char *)uprv_malloc(filenameSize); | 720 const char *filenameLimit = filename.data() + filename.length(); |
| 743 | 721 dir.remove_suffix((int32_t)(filenameLimit - filenameBegin)); |
| 744 /* test for NULL */ | 722 inputDirBuf.append(dir, errorCode); |
| 745 if(inputDirBuf == NULL) { | 723 inputDir = inputDirBuf.data(); |
| 746 errorCode = U_MEMORY_ALLOCATION_ERROR; | |
| 747 goto finish; | |
| 748 } | |
| 749 | |
| 750 uprv_strncpy(inputDirBuf, filename, filenameSize); | |
| 751 inputDirBuf[filenameSize - 1] = 0; | |
| 752 inputDir = inputDirBuf; | |
| 753 dirlen = (int32_t)uprv_strlen(inputDir); | |
| 754 } | 724 } |
| 755 }else{ | 725 }else{ |
| 756 dirlen = (int32_t)uprv_strlen(inputDir); | 726 int32_t dirlen = (int32_t)uprv_strlen(inputDir); |
| 757 | 727 |
| 758 if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { | 728 if((filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')) { |
| 759 openFileName = (char *) uprv_malloc(dirlen + filelen + 2); | |
| 760 | |
| 761 /* test for NULL */ | |
| 762 if(openFileName == NULL) { | |
| 763 errorCode = U_MEMORY_ALLOCATION_ERROR; | |
| 764 goto finish; | |
| 765 } | |
| 766 | |
| 767 openFileName[0] = '\0'; | |
| 768 /* | 729 /* |
| 769 * append the input dir to openFileName if the first char in | 730 * append the input dir to openFileName if the first char in |
| 770 * filename is not file seperation char and the last char input dire
ctory is not '.'. | 731 * filename is not file separator char and the last char input direc
tory is not '.'. |
| 771 * This is to support : | 732 * This is to support : |
| 772 * genrb -s. /home/icu/data | 733 * genrb -s. /home/icu/data |
| 773 * genrb -s. icu/data | 734 * genrb -s. icu/data |
| 774 * The user cannot mix notations like | 735 * The user cannot mix notations like |
| 775 * genrb -s. /icu/data --- the absolute path specified. -s redundant | 736 * genrb -s. /icu/data --- the absolute path specified. -s redundant |
| 776 * user should use | 737 * user should use |
| 777 * genrb -s. icu/data --- start from CWD and look in icu/data dir | 738 * genrb -s. icu/data --- start from CWD and look in icu/data dir |
| 778 */ | 739 */ |
| 779 if( (filename[0] != U_FILE_SEP_CHAR) && (inputDir[dirlen-1] !='.')){ | 740 openFileName.append(inputDir, dirlen, errorCode); |
| 780 uprv_strcpy(openFileName, inputDir); | 741 if(inputDir[dirlen-1] != U_FILE_SEP_CHAR) { |
| 781 openFileName[dirlen] = U_FILE_SEP_CHAR; | 742 openFileName.append(U_FILE_SEP_CHAR, errorCode); |
| 782 } | 743 } |
| 783 openFileName[dirlen + 1] = '\0'; | |
| 784 } else { | |
| 785 openFileName = (char *) uprv_malloc(dirlen + filelen + 1); | |
| 786 | |
| 787 /* test for NULL */ | |
| 788 if(openFileName == NULL) { | |
| 789 errorCode = U_MEMORY_ALLOCATION_ERROR; | |
| 790 goto finish; | |
| 791 } | |
| 792 | |
| 793 uprv_strcpy(openFileName, inputDir); | |
| 794 | |
| 795 } | 744 } |
| 796 } | 745 } |
| 797 uprv_strcat(openFileName, filename); | 746 openFileName.append(filename, errorCode); |
| 798 /* printf("%s\n", openFileName); */ | 747 if(U_FAILURE(errorCode)) { |
| 799 errorCode = U_ZERO_ERROR; | 748 return; |
| 800 ucbuf = ucbuf_open(openFileName, &cp,getShowWarning(),TRUE, &errorCode); | 749 } |
| 801 | 750 // printf("GenrbImporter::getRules(%s, %s) reads %s\n", localeID, collationT
ype, openFileName.data()); |
| 751 const char* cp = ""; |
| 752 LocalUCHARBUFPointer ucbuf( |
| 753 ucbuf_open(openFileName.data(), &cp, getShowWarning(), TRUE, &errorC
ode)); |
| 802 if(errorCode == U_FILE_ACCESS_ERROR) { | 754 if(errorCode == U_FILE_ACCESS_ERROR) { |
| 803 | 755 fprintf(stderr, "couldn't open file %s\n", openFileName.data()); |
| 804 fprintf(stderr, "couldn't open file %s\n", openFileName == NULL ? filena
me : openFileName); | 756 return; |
| 805 goto finish; | |
| 806 } | 757 } |
| 807 if (ucbuf == NULL || U_FAILURE(errorCode)) { | 758 if (ucbuf.isNull() || U_FAILURE(errorCode)) { |
| 808 fprintf(stderr, "An error occured processing file %s. Error: %s\n", open
FileName == NULL ? filename : openFileName,u_errorName(errorCode)); | 759 fprintf(stderr, "An error occured processing file %s. Error: %s\n", open
FileName.data(), u_errorName(errorCode)); |
| 809 goto finish; | 760 return; |
| 810 } | 761 } |
| 811 | 762 |
| 812 /* Parse the data into an SRBRoot */ | 763 /* Parse the data into an SRBRoot */ |
| 813 data = parse(ucbuf, inputDir, outputDir, filename, FALSE, FALSE, &errorCode)
; | 764 struct SRBRoot *data = |
| 765 parse(ucbuf.getAlias(), inputDir, outputDir, filename.data(), FALSE,
FALSE, &errorCode); |
| 814 if (U_FAILURE(errorCode)) { | 766 if (U_FAILURE(errorCode)) { |
| 815 goto finish; | 767 return; |
| 816 } | 768 } |
| 817 | 769 |
| 818 root = data->fRoot; | 770 struct SResource *root = data->fRoot; |
| 819 collations = resLookup(root, "collations"); | 771 struct SResource *collations = resLookup(root, "collations"); |
| 820 if (collations != NULL) { | 772 if (collations != NULL) { |
| 821 collation = resLookup(collations, collationType); | 773 struct SResource *collation = resLookup(collations, collationType); |
| 822 if (collation != NULL) { | 774 if (collation != NULL) { |
| 823 sequence = resLookup(collation, "Sequence"); | 775 struct SResource *sequence = resLookup(collation, "Sequence"); |
| 824 if (sequence != NULL) { | 776 if (sequence != NULL && sequence->isString()) { |
| 825 // No string pointer aliasing so that we need not hold onto the resour
ce bundle. | 777 // No string pointer aliasing so that we need not hold onto the resour
ce bundle. |
| 826 rules.setTo(sequence->u.fString.fChars, sequence->u.fString.fLength); | 778 StringResource *sr = static_cast<StringResource *>(sequence); |
| 779 rules = sr->fString; |
| 827 } | 780 } |
| 828 } | 781 } |
| 829 } | 782 } |
| 830 | |
| 831 finish: | |
| 832 if (inputDirBuf != NULL) { | |
| 833 uprv_free(inputDirBuf); | |
| 834 } | |
| 835 | |
| 836 if (openFileName != NULL) { | |
| 837 uprv_free(openFileName); | |
| 838 } | |
| 839 | |
| 840 if(ucbuf) { | |
| 841 ucbuf_close(ucbuf); | |
| 842 } | |
| 843 } | 783 } |
| 844 | 784 |
| 845 // Quick-and-dirty escaping function. | 785 // Quick-and-dirty escaping function. |
| 846 // Assumes that we are on an ASCII-based platform. | 786 // Assumes that we are on an ASCII-based platform. |
| 847 static void | 787 static void |
| 848 escape(const UChar *s, char *buffer) { | 788 escape(const UChar *s, char *buffer) { |
| 849 int32_t length = u_strlen(s); | 789 int32_t length = u_strlen(s); |
| 850 int32_t i = 0; | 790 int32_t i = 0; |
| 851 for (;;) { | 791 for (;;) { |
| 852 UChar32 c; | 792 UChar32 c; |
| 853 U16_NEXT(s, i, length, c); | 793 U16_NEXT(s, i, length, c); |
| 854 if (c == 0) { | 794 if (c == 0) { |
| 855 *buffer = 0; | 795 *buffer = 0; |
| 856 return; | 796 return; |
| 857 } else if (0x20 <= c && c <= 0x7e) { | 797 } else if (0x20 <= c && c <= 0x7e) { |
| 858 // printable ASCII | 798 // printable ASCII |
| 859 *buffer++ = (char)c; // assumes ASCII-based platform | 799 *buffer++ = (char)c; // assumes ASCII-based platform |
| 860 } else { | 800 } else { |
| 861 buffer += sprintf(buffer, "\\u%04X", (int)c); | 801 buffer += sprintf(buffer, "\\u%04X", (int)c); |
| 862 } | 802 } |
| 863 } | 803 } |
| 864 } | 804 } |
| 865 | 805 |
| 866 } // namespace | 806 } // namespace |
| 867 | 807 |
| 868 #endif // !UCONFIG_NO_COLLATION | 808 #endif // !UCONFIG_NO_COLLATION |
| 869 | 809 |
| 870 static struct SResource * | 810 static TableResource * |
| 871 addCollation(ParseState* state, struct SResource *result, const char *collation
Type, | 811 addCollation(ParseState* state, TableResource *result, const char *collationTyp
e, |
| 872 uint32_t startline, UErrorCode *status) | 812 uint32_t startline, UErrorCode *status) |
| 873 { | 813 { |
| 874 // TODO: Use LocalPointer for result, or make caller close it when there is
a failure. | 814 // TODO: Use LocalPointer for result, or make caller close it when there is
a failure. |
| 875 struct SResource *member = NULL; | 815 struct SResource *member = NULL; |
| 876 struct UString *tokenValue; | 816 struct UString *tokenValue; |
| 877 struct UString comment; | 817 struct UString comment; |
| 878 enum ETokenType token; | 818 enum ETokenType token; |
| 879 char subtag[1024]; | 819 char subtag[1024]; |
| 880 UnicodeString rules; | 820 UnicodeString rules; |
| 881 UBool haveRules = FALSE; | 821 UBool haveRules = FALSE; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 924 | 864 |
| 925 if (U_FAILURE(*status)) | 865 if (U_FAILURE(*status)) |
| 926 { | 866 { |
| 927 res_close(result); | 867 res_close(result); |
| 928 return NULL; | 868 return NULL; |
| 929 } | 869 } |
| 930 if (result == NULL) | 870 if (result == NULL) |
| 931 { | 871 { |
| 932 // Ignore the parsed resources, continue parsing. | 872 // Ignore the parsed resources, continue parsing. |
| 933 } | 873 } |
| 934 else if (uprv_strcmp(subtag, "Version") == 0) | 874 else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) |
| 935 { | 875 { |
| 876 StringResource *sr = static_cast<StringResource *>(member); |
| 936 char ver[40]; | 877 char ver[40]; |
| 937 int32_t length = member->u.fString.fLength; | 878 int32_t length = sr->length(); |
| 938 | 879 |
| 939 if (length >= (int32_t) sizeof(ver)) | 880 if (length >= UPRV_LENGTHOF(ver)) |
| 940 { | 881 { |
| 941 length = (int32_t) sizeof(ver) - 1; | 882 length = UPRV_LENGTHOF(ver) - 1; |
| 942 } | 883 } |
| 943 | 884 |
| 944 u_UCharsToChars(member->u.fString.fChars, ver, length + 1); /* +1 fo
r copying NULL */ | 885 sr->fString.extract(0, length, ver, UPRV_LENGTHOF(ver), US_INV); |
| 945 u_versionFromString(version, ver); | 886 u_versionFromString(version, ver); |
| 946 | 887 |
| 947 table_add(result, member, line, status); | 888 result->add(member, line, *status); |
| 948 member = NULL; | 889 member = NULL; |
| 949 } | 890 } |
| 950 else if(uprv_strcmp(subtag, "%%CollationBin")==0) | 891 else if(uprv_strcmp(subtag, "%%CollationBin")==0) |
| 951 { | 892 { |
| 952 /* discard duplicate %%CollationBin if any*/ | 893 /* discard duplicate %%CollationBin if any*/ |
| 953 } | 894 } |
| 954 else if (uprv_strcmp(subtag, "Sequence") == 0) | 895 else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) |
| 955 { | 896 { |
| 956 rules.setTo(member->u.fString.fChars, member->u.fString.fLength); | 897 StringResource *sr = static_cast<StringResource *>(member); |
| 898 rules = sr->fString; |
| 957 haveRules = TRUE; | 899 haveRules = TRUE; |
| 958 // Defer building the collator until we have seen | 900 // Defer building the collator until we have seen |
| 959 // all sub-elements of the collation table, including the Version. | 901 // all sub-elements of the collation table, including the Version. |
| 960 /* in order to achieve smaller data files, we can direct genrb */ | 902 /* in order to achieve smaller data files, we can direct genrb */ |
| 961 /* to omit collation rules */ | 903 /* to omit collation rules */ |
| 962 if(!state->omitCollationRules) { | 904 if(!state->omitCollationRules) { |
| 963 table_add(result, member, line, status); | 905 result->add(member, line, *status); |
| 964 member = NULL; | 906 member = NULL; |
| 965 } | 907 } |
| 966 } | 908 } |
| 967 else // Just copy non-special items. | 909 else // Just copy non-special items. |
| 968 { | 910 { |
| 969 table_add(result, member, line, status); | 911 result->add(member, line, *status); |
| 970 member = NULL; | 912 member = NULL; |
| 971 } | 913 } |
| 972 res_close(member); // TODO: use LocalPointer | 914 res_close(member); // TODO: use LocalPointer |
| 973 if (U_FAILURE(*status)) | 915 if (U_FAILURE(*status)) |
| 974 { | 916 { |
| 975 res_close(result); | 917 res_close(result); |
| 976 return NULL; | 918 return NULL; |
| 977 } | 919 } |
| 978 } | 920 } |
| 979 | 921 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 error(line, "CollationBuilder failed at %s~%s/Sequence rule offset %ld:
%s %s", | 962 error(line, "CollationBuilder failed at %s~%s/Sequence rule offset %ld:
%s %s", |
| 1021 state->filename, collationType, | 963 state->filename, collationType, |
| 1022 (long)parseError.offset, u_errorName(intStatus), reason); | 964 (long)parseError.offset, u_errorName(intStatus), reason); |
| 1023 if(parseError.preContext[0] != 0 || parseError.postContext[0] != 0) { | 965 if(parseError.preContext[0] != 0 || parseError.postContext[0] != 0) { |
| 1024 // Print pre- and post-context. | 966 // Print pre- and post-context. |
| 1025 char preBuffer[100], postBuffer[100]; | 967 char preBuffer[100], postBuffer[100]; |
| 1026 escape(parseError.preContext, preBuffer); | 968 escape(parseError.preContext, preBuffer); |
| 1027 escape(parseError.postContext, postBuffer); | 969 escape(parseError.postContext, postBuffer); |
| 1028 error(line, " error context: \"...%s\" ! \"%s...\"", preBuffer, pos
tBuffer); | 970 error(line, " error context: \"...%s\" ! \"%s...\"", preBuffer, pos
tBuffer); |
| 1029 } | 971 } |
| 1030 if(isStrict()) { | 972 if(isStrict() || t.isNull()) { |
| 1031 *status = intStatus; | 973 *status = intStatus; |
| 1032 res_close(result); | 974 res_close(result); |
| 1033 return NULL; | 975 return NULL; |
| 1034 } | 976 } |
| 1035 } | 977 } |
| 1036 icu::LocalMemory<uint8_t> buffer; | 978 icu::LocalMemory<uint8_t> buffer; |
| 1037 int32_t capacity = 100000; | 979 int32_t capacity = 100000; |
| 1038 uint8_t *dest = buffer.allocateInsteadAndCopy(capacity); | 980 uint8_t *dest = buffer.allocateInsteadAndCopy(capacity); |
| 1039 if(dest == NULL) { | 981 if(dest == NULL) { |
| 1040 fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\
n", | 982 fprintf(stderr, "memory allocation (%ld bytes) for file contents failed\
n", |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1062 } | 1004 } |
| 1063 if(U_FAILURE(intStatus)) { | 1005 if(U_FAILURE(intStatus)) { |
| 1064 fprintf(stderr, "CollationDataWriter::writeTailoring() failed: %s\n", | 1006 fprintf(stderr, "CollationDataWriter::writeTailoring() failed: %s\n", |
| 1065 u_errorName(intStatus)); | 1007 u_errorName(intStatus)); |
| 1066 res_close(result); | 1008 res_close(result); |
| 1067 return NULL; | 1009 return NULL; |
| 1068 } | 1010 } |
| 1069 if(isVerbose()) { | 1011 if(isVerbose()) { |
| 1070 printf("%s~%s collation tailoring part sizes:\n", state->filename, colla
tionType); | 1012 printf("%s~%s collation tailoring part sizes:\n", state->filename, colla
tionType); |
| 1071 icu::CollationInfo::printSizes(totalSize, indexes); | 1013 icu::CollationInfo::printSizes(totalSize, indexes); |
| 1014 if(t->settings->hasReordering()) { |
| 1015 printf("%s~%s collation reordering ranges:\n", state->filename, coll
ationType); |
| 1016 icu::CollationInfo::printReorderRanges( |
| 1017 *t->data, t->settings->reorderCodes, t->settings->reorderCod
esLength); |
| 1018 } |
| 1072 } | 1019 } |
| 1073 struct SResource *collationBin = bin_open(state->bundle, "%%CollationBin", t
otalSize, dest, NULL, NULL, status); | 1020 struct SResource *collationBin = bin_open(state->bundle, "%%CollationBin", t
otalSize, dest, NULL, NULL, status); |
| 1074 table_add(result, collationBin, line, status); | 1021 result->add(collationBin, line, *status); |
| 1075 if (U_FAILURE(*status)) { | 1022 if (U_FAILURE(*status)) { |
| 1076 res_close(result); | 1023 res_close(result); |
| 1077 return NULL; | 1024 return NULL; |
| 1078 } | 1025 } |
| 1079 #endif | 1026 #endif |
| 1080 return result; | 1027 return result; |
| 1081 } | 1028 } |
| 1082 | 1029 |
| 1083 static UBool | 1030 static UBool |
| 1084 keepCollationType(const char * /*type*/) { | 1031 keepCollationType(const char * /*type*/) { |
| 1085 return TRUE; | 1032 return TRUE; |
| 1086 } | 1033 } |
| 1087 | 1034 |
| 1088 static struct SResource * | 1035 static struct SResource * |
| 1089 parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n
ewCollation, UErrorCode *status) | 1036 parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n
ewCollation, UErrorCode *status) |
| 1090 { | 1037 { |
| 1091 struct SResource *result = NULL; | 1038 TableResource *result = NULL; |
| 1092 struct SResource *member = NULL; | 1039 struct SResource *member = NULL; |
| 1093 struct SResource *collationRes = NULL; | |
| 1094 struct UString *tokenValue; | 1040 struct UString *tokenValue; |
| 1095 struct UString comment; | 1041 struct UString comment; |
| 1096 enum ETokenType token; | 1042 enum ETokenType token; |
| 1097 char subtag[1024], typeKeyword[1024]; | 1043 char subtag[1024], typeKeyword[1024]; |
| 1098 uint32_t line; | 1044 uint32_t line; |
| 1099 | 1045 |
| 1100 result = table_open(state->bundle, tag, NULL, status); | 1046 result = table_open(state->bundle, tag, NULL, status); |
| 1101 | 1047 |
| 1102 if (result == NULL || U_FAILURE(*status)) | 1048 if (result == NULL || U_FAILURE(*status)) |
| 1103 { | 1049 { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 if (uprv_strcmp(subtag, "default") == 0) | 1093 if (uprv_strcmp(subtag, "default") == 0) |
| 1148 { | 1094 { |
| 1149 member = parseResource(state, subtag, NULL, status); | 1095 member = parseResource(state, subtag, NULL, status); |
| 1150 | 1096 |
| 1151 if (U_FAILURE(*status)) | 1097 if (U_FAILURE(*status)) |
| 1152 { | 1098 { |
| 1153 res_close(result); | 1099 res_close(result); |
| 1154 return NULL; | 1100 return NULL; |
| 1155 } | 1101 } |
| 1156 | 1102 |
| 1157 table_add(result, member, line, status); | 1103 result->add(member, line, *status); |
| 1158 } | 1104 } |
| 1159 else | 1105 else |
| 1160 { | 1106 { |
| 1161 token = peekToken(state, 0, &tokenValue, &line, &comment, status
); | 1107 token = peekToken(state, 0, &tokenValue, &line, &comment, status
); |
| 1162 /* this probably needs to be refactored or recursively use the p
arser */ | 1108 /* this probably needs to be refactored or recursively use the p
arser */ |
| 1163 /* first we assume that our collation table won't have the expli
cit type */ | 1109 /* first we assume that our collation table won't have the expli
cit type */ |
| 1164 /* then, we cannot handle aliases */ | 1110 /* then, we cannot handle aliases */ |
| 1165 if(token == TOK_OPEN_BRACE) { | 1111 if(token == TOK_OPEN_BRACE) { |
| 1166 token = getToken(state, &tokenValue, &comment, &line, status
); | 1112 token = getToken(state, &tokenValue, &comment, &line, status
); |
| 1113 TableResource *collationRes; |
| 1167 if (keepCollationType(subtag)) { | 1114 if (keepCollationType(subtag)) { |
| 1168 collationRes = table_open(state->bundle, subtag, NULL, s
tatus); | 1115 collationRes = table_open(state->bundle, subtag, NULL, s
tatus); |
| 1169 } else { | 1116 } else { |
| 1170 collationRes = NULL; | 1117 collationRes = NULL; |
| 1171 } | 1118 } |
| 1172 // need to parse the collation data regardless | 1119 // need to parse the collation data regardless |
| 1173 collationRes = addCollation(state, collationRes, subtag, sta
rtline, status); | 1120 collationRes = addCollation(state, collationRes, subtag, sta
rtline, status); |
| 1174 if (collationRes != NULL) { | 1121 if (collationRes != NULL) { |
| 1175 table_add(result, collationRes, startline, status); | 1122 result->add(collationRes, startline, *status); |
| 1176 } | 1123 } |
| 1177 } else if(token == TOK_COLON) { /* right now, we'll just try to
see if we have aliases */ | 1124 } else if(token == TOK_COLON) { /* right now, we'll just try to
see if we have aliases */ |
| 1178 /* we could have a table too */ | 1125 /* we could have a table too */ |
| 1179 token = peekToken(state, 1, &tokenValue, &line, &comment, st
atus); | 1126 token = peekToken(state, 1, &tokenValue, &line, &comment, st
atus); |
| 1180 u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(to
kenValue->fChars) + 1); | 1127 u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(to
kenValue->fChars) + 1); |
| 1181 if(uprv_strcmp(typeKeyword, "alias") == 0) { | 1128 if(uprv_strcmp(typeKeyword, "alias") == 0) { |
| 1182 member = parseResource(state, subtag, NULL, status); | 1129 member = parseResource(state, subtag, NULL, status); |
| 1183 if (U_FAILURE(*status)) | 1130 if (U_FAILURE(*status)) |
| 1184 { | 1131 { |
| 1185 res_close(result); | 1132 res_close(result); |
| 1186 return NULL; | 1133 return NULL; |
| 1187 } | 1134 } |
| 1188 | 1135 |
| 1189 table_add(result, member, line, status); | 1136 result->add(member, line, *status); |
| 1190 } else { | 1137 } else { |
| 1191 res_close(result); | 1138 res_close(result); |
| 1192 *status = U_INVALID_FORMAT_ERROR; | 1139 *status = U_INVALID_FORMAT_ERROR; |
| 1193 return NULL; | 1140 return NULL; |
| 1194 } | 1141 } |
| 1195 } else { | 1142 } else { |
| 1196 res_close(result); | 1143 res_close(result); |
| 1197 *status = U_INVALID_FORMAT_ERROR; | 1144 *status = U_INVALID_FORMAT_ERROR; |
| 1198 return NULL; | 1145 return NULL; |
| 1199 } | 1146 } |
| 1200 } | 1147 } |
| 1201 | 1148 |
| 1202 /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValu
e->fLength, status);*/ | 1149 /*member = string_open(bundle, subtag, tokenValue->fChars, tokenValu
e->fLength, status);*/ |
| 1203 | 1150 |
| 1204 /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ | 1151 /*expect(TOK_CLOSE_BRACE, NULL, NULL, status);*/ |
| 1205 | 1152 |
| 1206 if (U_FAILURE(*status)) | 1153 if (U_FAILURE(*status)) |
| 1207 { | 1154 { |
| 1208 res_close(result); | 1155 res_close(result); |
| 1209 return NULL; | 1156 return NULL; |
| 1210 } | 1157 } |
| 1211 } | 1158 } |
| 1212 } | 1159 } |
| 1213 } | 1160 } |
| 1214 | 1161 |
| 1215 /* Necessary, because CollationElements requires the bundle->fRoot member to be
present which, | 1162 /* Necessary, because CollationElements requires the bundle->fRoot member to be
present which, |
| 1216 if this weren't special-cased, wouldn't be set until the entire file had been
processed. */ | 1163 if this weren't special-cased, wouldn't be set until the entire file had been
processed. */ |
| 1217 static struct SResource * | 1164 static struct SResource * |
| 1218 realParseTable(ParseState* state, struct SResource *table, char *tag, uint32_t s
tartline, UErrorCode *status) | 1165 realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star
tline, UErrorCode *status) |
| 1219 { | 1166 { |
| 1220 struct SResource *member = NULL; | 1167 struct SResource *member = NULL; |
| 1221 struct UString *tokenValue=NULL; | 1168 struct UString *tokenValue=NULL; |
| 1222 struct UString comment; | 1169 struct UString comment; |
| 1223 enum ETokenType token; | 1170 enum ETokenType token; |
| 1224 char subtag[1024]; | 1171 char subtag[1024]; |
| 1225 uint32_t line; | 1172 uint32_t line; |
| 1226 UBool readToken = FALSE; | 1173 UBool readToken = FALSE; |
| 1227 | 1174 |
| 1228 /* '{' . (name resource)* '}' */ | 1175 /* '{' . (name resource)* '}' */ |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 } | 1221 } |
| 1275 | 1222 |
| 1276 member = parseResource(state, subtag, &comment, status); | 1223 member = parseResource(state, subtag, &comment, status); |
| 1277 | 1224 |
| 1278 if (member == NULL || U_FAILURE(*status)) | 1225 if (member == NULL || U_FAILURE(*status)) |
| 1279 { | 1226 { |
| 1280 error(line, "parse error. Stopped parsing resource with %s", u_error
Name(*status)); | 1227 error(line, "parse error. Stopped parsing resource with %s", u_error
Name(*status)); |
| 1281 return NULL; | 1228 return NULL; |
| 1282 } | 1229 } |
| 1283 | 1230 |
| 1284 table_add(table, member, line, status); | 1231 table->add(member, line, *status); |
| 1285 | 1232 |
| 1286 if (U_FAILURE(*status)) | 1233 if (U_FAILURE(*status)) |
| 1287 { | 1234 { |
| 1288 error(line, "parse error. Stopped parsing table with %s", u_errorNam
e(*status)); | 1235 error(line, "parse error. Stopped parsing table with %s", u_errorNam
e(*status)); |
| 1289 return NULL; | 1236 return NULL; |
| 1290 } | 1237 } |
| 1291 readToken = TRUE; | 1238 readToken = TRUE; |
| 1292 ustr_deinit(&comment); | 1239 ustr_deinit(&comment); |
| 1293 } | 1240 } |
| 1294 | 1241 |
| 1295 /* not reached */ | 1242 /* not reached */ |
| 1296 /* A compiler warning will appear if all paths don't contain a return statem
ent. */ | 1243 /* A compiler warning will appear if all paths don't contain a return statem
ent. */ |
| 1297 /* *status = U_INTERNAL_PROGRAM_ERROR; | 1244 /* *status = U_INTERNAL_PROGRAM_ERROR; |
| 1298 return NULL;*/ | 1245 return NULL;*/ |
| 1299 } | 1246 } |
| 1300 | 1247 |
| 1301 static struct SResource * | 1248 static struct SResource * |
| 1302 parseTable(ParseState* state, char *tag, uint32_t startline, const struct UStrin
g *comment, UErrorCode *status) | 1249 parseTable(ParseState* state, char *tag, uint32_t startline, const struct UStrin
g *comment, UErrorCode *status) |
| 1303 { | 1250 { |
| 1304 struct SResource *result; | |
| 1305 | |
| 1306 if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0) | 1251 if (tag != NULL && uprv_strcmp(tag, "CollationElements") == 0) |
| 1307 { | 1252 { |
| 1308 return parseCollationElements(state, tag, startline, FALSE, status); | 1253 return parseCollationElements(state, tag, startline, FALSE, status); |
| 1309 } | 1254 } |
| 1310 if (tag != NULL && uprv_strcmp(tag, "collations") == 0) | 1255 if (tag != NULL && uprv_strcmp(tag, "collations") == 0) |
| 1311 { | 1256 { |
| 1312 return parseCollationElements(state, tag, startline, TRUE, status); | 1257 return parseCollationElements(state, tag, startline, TRUE, status); |
| 1313 } | 1258 } |
| 1314 if(isVerbose()){ | 1259 if(isVerbose()){ |
| 1315 printf(" table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)
startline); | 1260 printf(" table %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)
startline); |
| 1316 } | 1261 } |
| 1317 | 1262 |
| 1318 result = table_open(state->bundle, tag, comment, status); | 1263 TableResource *result = table_open(state->bundle, tag, comment, status); |
| 1319 | 1264 |
| 1320 if (result == NULL || U_FAILURE(*status)) | 1265 if (result == NULL || U_FAILURE(*status)) |
| 1321 { | 1266 { |
| 1322 return NULL; | 1267 return NULL; |
| 1323 } | 1268 } |
| 1324 return realParseTable(state, result, tag, startline, status); | 1269 return realParseTable(state, result, tag, startline, status); |
| 1325 } | 1270 } |
| 1326 | 1271 |
| 1327 static struct SResource * | 1272 static struct SResource * |
| 1328 parseArray(ParseState* state, char *tag, uint32_t startline, const struct UStrin
g *comment, UErrorCode *status) | 1273 parseArray(ParseState* state, char *tag, uint32_t startline, const struct UStrin
g *comment, UErrorCode *status) |
| 1329 { | 1274 { |
| 1330 struct SResource *result = NULL; | |
| 1331 struct SResource *member = NULL; | 1275 struct SResource *member = NULL; |
| 1332 struct UString *tokenValue; | 1276 struct UString *tokenValue; |
| 1333 struct UString memberComments; | 1277 struct UString memberComments; |
| 1334 enum ETokenType token; | 1278 enum ETokenType token; |
| 1335 UBool readToken = FALSE; | 1279 UBool readToken = FALSE; |
| 1336 | 1280 |
| 1337 result = array_open(state->bundle, tag, comment, status); | 1281 ArrayResource *result = array_open(state->bundle, tag, comment, status); |
| 1338 | 1282 |
| 1339 if (result == NULL || U_FAILURE(*status)) | 1283 if (result == NULL || U_FAILURE(*status)) |
| 1340 { | 1284 { |
| 1341 return NULL; | 1285 return NULL; |
| 1342 } | 1286 } |
| 1343 if(isVerbose()){ | 1287 if(isVerbose()){ |
| 1344 printf(" array %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)
startline); | 1288 printf(" array %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int)
startline); |
| 1345 } | 1289 } |
| 1346 | 1290 |
| 1347 ustr_init(&memberComments); | 1291 ustr_init(&memberComments); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 { | 1327 { |
| 1384 member = parseResource(state, NULL, &memberComments, status); | 1328 member = parseResource(state, NULL, &memberComments, status); |
| 1385 } | 1329 } |
| 1386 | 1330 |
| 1387 if (member == NULL || U_FAILURE(*status)) | 1331 if (member == NULL || U_FAILURE(*status)) |
| 1388 { | 1332 { |
| 1389 res_close(result); | 1333 res_close(result); |
| 1390 return NULL; | 1334 return NULL; |
| 1391 } | 1335 } |
| 1392 | 1336 |
| 1393 array_add(result, member, status); | 1337 result->add(member); |
| 1394 | |
| 1395 if (U_FAILURE(*status)) | |
| 1396 { | |
| 1397 res_close(result); | |
| 1398 return NULL; | |
| 1399 } | |
| 1400 | 1338 |
| 1401 /* eat optional comma if present */ | 1339 /* eat optional comma if present */ |
| 1402 token = peekToken(state, 0, NULL, NULL, NULL, status); | 1340 token = peekToken(state, 0, NULL, NULL, NULL, status); |
| 1403 | 1341 |
| 1404 if (token == TOK_COMMA) | 1342 if (token == TOK_COMMA) |
| 1405 { | 1343 { |
| 1406 getToken(state, NULL, NULL, NULL, status); | 1344 getToken(state, NULL, NULL, NULL, status); |
| 1407 } | 1345 } |
| 1408 | 1346 |
| 1409 if (U_FAILURE(*status)) | 1347 if (U_FAILURE(*status)) |
| 1410 { | 1348 { |
| 1411 res_close(result); | 1349 res_close(result); |
| 1412 return NULL; | 1350 return NULL; |
| 1413 } | 1351 } |
| 1414 readToken = TRUE; | 1352 readToken = TRUE; |
| 1415 } | 1353 } |
| 1416 | 1354 |
| 1417 ustr_deinit(&memberComments); | 1355 ustr_deinit(&memberComments); |
| 1418 return result; | 1356 return result; |
| 1419 } | 1357 } |
| 1420 | 1358 |
| 1421 static struct SResource * | 1359 static struct SResource * |
| 1422 parseIntVector(ParseState* state, char *tag, uint32_t startline, const struct US
tring *comment, UErrorCode *status) | 1360 parseIntVector(ParseState* state, char *tag, uint32_t startline, const struct US
tring *comment, UErrorCode *status) |
| 1423 { | 1361 { |
| 1424 struct SResource *result = NULL; | |
| 1425 enum ETokenType token; | 1362 enum ETokenType token; |
| 1426 char *string; | 1363 char *string; |
| 1427 int32_t value; | 1364 int32_t value; |
| 1428 UBool readToken = FALSE; | 1365 UBool readToken = FALSE; |
| 1429 char *stopstring; | 1366 char *stopstring; |
| 1430 uint32_t len; | 1367 uint32_t len; |
| 1431 struct UString memberComments; | 1368 struct UString memberComments; |
| 1432 | 1369 |
| 1433 result = intvector_open(state->bundle, tag, comment, status); | 1370 IntVectorResource *result = intvector_open(state->bundle, tag, comment, stat
us); |
| 1434 | 1371 |
| 1435 if (result == NULL || U_FAILURE(*status)) | 1372 if (result == NULL || U_FAILURE(*status)) |
| 1436 { | 1373 { |
| 1437 return NULL; | 1374 return NULL; |
| 1438 } | 1375 } |
| 1439 | 1376 |
| 1440 if(isVerbose()){ | 1377 if(isVerbose()){ |
| 1441 printf(" vector %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); | 1378 printf(" vector %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); |
| 1442 } | 1379 } |
| 1443 ustr_init(&memberComments); | 1380 ustr_init(&memberComments); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1467 res_close(result); | 1404 res_close(result); |
| 1468 return NULL; | 1405 return NULL; |
| 1469 } | 1406 } |
| 1470 | 1407 |
| 1471 /* For handling illegal char in the Intvector */ | 1408 /* For handling illegal char in the Intvector */ |
| 1472 value = uprv_strtoul(string, &stopstring, 0);/* make intvector support d
ecimal,hexdigit,octal digit ranging from -2^31-2^32-1*/ | 1409 value = uprv_strtoul(string, &stopstring, 0);/* make intvector support d
ecimal,hexdigit,octal digit ranging from -2^31-2^32-1*/ |
| 1473 len=(uint32_t)(stopstring-string); | 1410 len=(uint32_t)(stopstring-string); |
| 1474 | 1411 |
| 1475 if(len==uprv_strlen(string)) | 1412 if(len==uprv_strlen(string)) |
| 1476 { | 1413 { |
| 1477 intvector_add(result, value, status); | 1414 result->add(value, *status); |
| 1478 uprv_free(string); | 1415 uprv_free(string); |
| 1479 token = peekToken(state, 0, NULL, NULL, NULL, status); | 1416 token = peekToken(state, 0, NULL, NULL, NULL, status); |
| 1480 } | 1417 } |
| 1481 else | 1418 else |
| 1482 { | 1419 { |
| 1483 uprv_free(string); | 1420 uprv_free(string); |
| 1484 *status=U_INVALID_CHAR_FOUND; | 1421 *status=U_INVALID_CHAR_FOUND; |
| 1485 } | 1422 } |
| 1486 | 1423 |
| 1487 if (U_FAILURE(*status)) | 1424 if (U_FAILURE(*status)) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1502 /* not reached */ | 1439 /* not reached */ |
| 1503 /* A compiler warning will appear if all paths don't contain a return statem
ent. */ | 1440 /* A compiler warning will appear if all paths don't contain a return statem
ent. */ |
| 1504 /* intvector_close(result, status); | 1441 /* intvector_close(result, status); |
| 1505 *status = U_INTERNAL_PROGRAM_ERROR; | 1442 *status = U_INTERNAL_PROGRAM_ERROR; |
| 1506 return NULL;*/ | 1443 return NULL;*/ |
| 1507 } | 1444 } |
| 1508 | 1445 |
| 1509 static struct SResource * | 1446 static struct SResource * |
| 1510 parseBinary(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng *comment, UErrorCode *status) | 1447 parseBinary(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng *comment, UErrorCode *status) |
| 1511 { | 1448 { |
| 1512 struct SResource *result = NULL; | 1449 uint32_t line; |
| 1513 uint8_t *value; | 1450 LocalMemory<char> string(getInvariantString(state, &line, NULL, status)); |
| 1514 char *string; | 1451 if (string.isNull() || U_FAILURE(*status)) |
| 1515 char toConv[3] = {'\0', '\0', '\0'}; | |
| 1516 uint32_t count; | |
| 1517 uint32_t i; | |
| 1518 uint32_t line; | |
| 1519 char *stopstring; | |
| 1520 uint32_t len; | |
| 1521 | |
| 1522 string = getInvariantString(state, &line, NULL, status); | |
| 1523 | |
| 1524 if (string == NULL || U_FAILURE(*status)) | |
| 1525 { | 1452 { |
| 1526 return NULL; | 1453 return NULL; |
| 1527 } | 1454 } |
| 1528 | 1455 |
| 1529 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); | 1456 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); |
| 1530 | |
| 1531 if (U_FAILURE(*status)) | 1457 if (U_FAILURE(*status)) |
| 1532 { | 1458 { |
| 1533 uprv_free(string); | |
| 1534 return NULL; | 1459 return NULL; |
| 1535 } | 1460 } |
| 1536 | 1461 |
| 1537 if(isVerbose()){ | 1462 if(isVerbose()){ |
| 1538 printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); | 1463 printf(" binary %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); |
| 1539 } | 1464 } |
| 1540 | 1465 |
| 1541 count = (uint32_t)uprv_strlen(string); | 1466 uint32_t count = (uint32_t)uprv_strlen(string.getAlias()); |
| 1542 if (count > 0){ | 1467 if (count > 0){ |
| 1543 if((count % 2)==0){ | 1468 if((count % 2)==0){ |
| 1544 value = static_cast<uint8_t *>(uprv_malloc(sizeof(uint8_t) * count))
; | 1469 LocalMemory<uint8_t> value; |
| 1545 | 1470 if (value.allocateInsteadAndCopy(count) == NULL) |
| 1546 if (value == NULL) | |
| 1547 { | 1471 { |
| 1548 uprv_free(string); | |
| 1549 *status = U_MEMORY_ALLOCATION_ERROR; | 1472 *status = U_MEMORY_ALLOCATION_ERROR; |
| 1550 return NULL; | 1473 return NULL; |
| 1551 } | 1474 } |
| 1552 | 1475 |
| 1553 for (i = 0; i < count; i += 2) | 1476 char toConv[3] = {'\0', '\0', '\0'}; |
| 1477 for (uint32_t i = 0; i < count; i += 2) |
| 1554 { | 1478 { |
| 1555 toConv[0] = string[i]; | 1479 toConv[0] = string[i]; |
| 1556 toConv[1] = string[i + 1]; | 1480 toConv[1] = string[i + 1]; |
| 1557 | 1481 |
| 1482 char *stopstring; |
| 1558 value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16); | 1483 value[i >> 1] = (uint8_t) uprv_strtoul(toConv, &stopstring, 16); |
| 1559 len=(uint32_t)(stopstring-toConv); | 1484 uint32_t len=(uint32_t)(stopstring-toConv); |
| 1560 | 1485 |
| 1561 if(len!=uprv_strlen(toConv)) | 1486 if(len!=2) |
| 1562 { | 1487 { |
| 1563 uprv_free(string); | |
| 1564 *status=U_INVALID_CHAR_FOUND; | 1488 *status=U_INVALID_CHAR_FOUND; |
| 1565 return NULL; | 1489 return NULL; |
| 1566 } | 1490 } |
| 1567 } | 1491 } |
| 1568 | 1492 |
| 1569 result = bin_open(state->bundle, tag, (i >> 1), value,NULL, comment,
status); | 1493 return bin_open(state->bundle, tag, count >> 1, value.getAlias(), NU
LL, comment, status); |
| 1570 | |
| 1571 uprv_free(value); | |
| 1572 } | 1494 } |
| 1573 else | 1495 else |
| 1574 { | 1496 { |
| 1575 *status = U_INVALID_CHAR_FOUND; | 1497 *status = U_INVALID_CHAR_FOUND; |
| 1576 uprv_free(string); | 1498 error(line, "Encountered invalid binary value (length is odd)"); |
| 1577 error(line, "Encountered invalid binary string"); | |
| 1578 return NULL; | 1499 return NULL; |
| 1579 } | 1500 } |
| 1580 } | 1501 } |
| 1581 else | 1502 else |
| 1582 { | 1503 { |
| 1583 result = bin_open(state->bundle, tag, 0, NULL, "",comment,status); | 1504 warning(startline, "Encountered empty binary value"); |
| 1584 warning(startline, "Encountered empty binary tag"); | 1505 return bin_open(state->bundle, tag, 0, NULL, "", comment, status); |
| 1585 } | 1506 } |
| 1586 uprv_free(string); | |
| 1587 | |
| 1588 return result; | |
| 1589 } | 1507 } |
| 1590 | 1508 |
| 1591 static struct SResource * | 1509 static struct SResource * |
| 1592 parseInteger(ParseState* state, char *tag, uint32_t startline, const struct UStr
ing *comment, UErrorCode *status) | 1510 parseInteger(ParseState* state, char *tag, uint32_t startline, const struct UStr
ing *comment, UErrorCode *status) |
| 1593 { | 1511 { |
| 1594 struct SResource *result = NULL; | 1512 struct SResource *result = NULL; |
| 1595 int32_t value; | 1513 int32_t value; |
| 1596 char *string; | 1514 char *string; |
| 1597 char *stopstring; | 1515 char *stopstring; |
| 1598 uint32_t len; | 1516 uint32_t len; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 *status=U_INVALID_CHAR_FOUND; | 1552 *status=U_INVALID_CHAR_FOUND; |
| 1635 } | 1553 } |
| 1636 uprv_free(string); | 1554 uprv_free(string); |
| 1637 | 1555 |
| 1638 return result; | 1556 return result; |
| 1639 } | 1557 } |
| 1640 | 1558 |
| 1641 static struct SResource * | 1559 static struct SResource * |
| 1642 parseImport(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng* comment, UErrorCode *status) | 1560 parseImport(ParseState* state, char *tag, uint32_t startline, const struct UStri
ng* comment, UErrorCode *status) |
| 1643 { | 1561 { |
| 1644 struct SResource *result; | |
| 1645 FileStream *file; | |
| 1646 int32_t len; | |
| 1647 uint8_t *data; | |
| 1648 char *filename; | |
| 1649 uint32_t line; | 1562 uint32_t line; |
| 1650 char *fullname = NULL; | 1563 LocalMemory<char> filename(getInvariantString(state, &line, NULL, status)); |
| 1651 filename = getInvariantString(state, &line, NULL, status); | |
| 1652 | |
| 1653 if (U_FAILURE(*status)) | 1564 if (U_FAILURE(*status)) |
| 1654 { | 1565 { |
| 1655 return NULL; | 1566 return NULL; |
| 1656 } | 1567 } |
| 1657 | 1568 |
| 1658 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); | 1569 expect(state, TOK_CLOSE_BRACE, NULL, NULL, NULL, status); |
| 1659 | 1570 |
| 1660 if (U_FAILURE(*status)) | 1571 if (U_FAILURE(*status)) |
| 1661 { | 1572 { |
| 1662 uprv_free(filename); | |
| 1663 return NULL; | 1573 return NULL; |
| 1664 } | 1574 } |
| 1665 | 1575 |
| 1666 if(isVerbose()){ | 1576 if(isVerbose()){ |
| 1667 printf(" import %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); | 1577 printf(" import %s at line %i \n", (tag == NULL) ? "(null)" : tag, (int
)startline); |
| 1668 } | 1578 } |
| 1669 | 1579 |
| 1670 /* Open the input file for reading */ | 1580 /* Open the input file for reading */ |
| 1671 if (state->inputdir == NULL) | 1581 CharString fullname; |
| 1672 { | 1582 if (state->inputdir != NULL) { |
| 1673 #if 1 | 1583 fullname.append(state->inputdir, *status); |
| 1674 /* | |
| 1675 * Always save file file name, even if there's | |
| 1676 * no input directory specified. MIGHT BREAK SOMETHING | |
| 1677 */ | |
| 1678 int32_t filenameLength = uprv_strlen(filename); | |
| 1679 | |
| 1680 fullname = (char *) uprv_malloc(filenameLength + 1); | |
| 1681 uprv_strcpy(fullname, filename); | |
| 1682 #endif | |
| 1683 | |
| 1684 file = T_FileStream_open(filename, "rb"); | |
| 1685 } | 1584 } |
| 1686 else | 1585 fullname.appendPathPart(filename.getAlias(), *status); |
| 1687 { | 1586 if (U_FAILURE(*status)) { |
| 1688 | 1587 return NULL; |
| 1689 int32_t count = (int32_t)uprv_strlen(filename); | |
| 1690 | |
| 1691 if (state->inputdir[state->inputdirLength - 1] != U_FILE_SEP_CHAR) | |
| 1692 { | |
| 1693 fullname = (char *) uprv_malloc(state->inputdirLength + count + 2); | |
| 1694 | |
| 1695 /* test for NULL */ | |
| 1696 if(fullname == NULL) | |
| 1697 { | |
| 1698 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 1699 return NULL; | |
| 1700 } | |
| 1701 | |
| 1702 uprv_strcpy(fullname, state->inputdir); | |
| 1703 | |
| 1704 fullname[state->inputdirLength] = U_FILE_SEP_CHAR; | |
| 1705 fullname[state->inputdirLength + 1] = '\0'; | |
| 1706 | |
| 1707 uprv_strcat(fullname, filename); | |
| 1708 } | |
| 1709 else | |
| 1710 { | |
| 1711 fullname = (char *) uprv_malloc(state->inputdirLength + count + 1); | |
| 1712 | |
| 1713 /* test for NULL */ | |
| 1714 if(fullname == NULL) | |
| 1715 { | |
| 1716 *status = U_MEMORY_ALLOCATION_ERROR; | |
| 1717 return NULL; | |
| 1718 } | |
| 1719 | |
| 1720 uprv_strcpy(fullname, state->inputdir); | |
| 1721 uprv_strcat(fullname, filename); | |
| 1722 } | |
| 1723 | |
| 1724 file = T_FileStream_open(fullname, "rb"); | |
| 1725 | |
| 1726 } | 1588 } |
| 1727 | 1589 |
| 1590 FileStream *file = T_FileStream_open(fullname.data(), "rb"); |
| 1728 if (file == NULL) | 1591 if (file == NULL) |
| 1729 { | 1592 { |
| 1730 error(line, "couldn't open input file %s", filename); | 1593 error(line, "couldn't open input file %s", filename.getAlias()); |
| 1731 *status = U_FILE_ACCESS_ERROR; | 1594 *status = U_FILE_ACCESS_ERROR; |
| 1732 return NULL; | 1595 return NULL; |
| 1733 } | 1596 } |
| 1734 | 1597 |
| 1735 len = T_FileStream_size(file); | 1598 int32_t len = T_FileStream_size(file); |
| 1736 data = (uint8_t*)uprv_malloc(len * sizeof(uint8_t)); | 1599 LocalMemory<uint8_t> data; |
| 1737 /* test for NULL */ | 1600 if(data.allocateInsteadAndCopy(len) == NULL) |
| 1738 if(data == NULL) | |
| 1739 { | 1601 { |
| 1740 *status = U_MEMORY_ALLOCATION_ERROR; | 1602 *status = U_MEMORY_ALLOCATION_ERROR; |
| 1741 T_FileStream_close (file); | 1603 T_FileStream_close (file); |
| 1742 return NULL; | 1604 return NULL; |
| 1743 } | 1605 } |
| 1744 | 1606 |
| 1745 /* int32_t numRead = */ T_FileStream_read (file, data, len); | 1607 /* int32_t numRead = */ T_FileStream_read(file, data.getAlias(), len); |
| 1746 T_FileStream_close (file); | 1608 T_FileStream_close (file); |
| 1747 | 1609 |
| 1748 result = bin_open(state->bundle, tag, len, data, fullname, comment, status); | 1610 return bin_open(state->bundle, tag, len, data.getAlias(), fullname.data(), c
omment, status); |
| 1749 | |
| 1750 uprv_free(data); | |
| 1751 uprv_free(filename); | |
| 1752 uprv_free(fullname); | |
| 1753 | |
| 1754 return result; | |
| 1755 } | 1611 } |
| 1756 | 1612 |
| 1757 static struct SResource * | 1613 static struct SResource * |
| 1758 parseInclude(ParseState* state, char *tag, uint32_t startline, const struct UStr
ing* comment, UErrorCode *status) | 1614 parseInclude(ParseState* state, char *tag, uint32_t startline, const struct UStr
ing* comment, UErrorCode *status) |
| 1759 { | 1615 { |
| 1760 struct SResource *result; | 1616 struct SResource *result; |
| 1761 int32_t len=0; | 1617 int32_t len=0; |
| 1762 char *filename; | 1618 char *filename; |
| 1763 uint32_t line; | 1619 uint32_t line; |
| 1764 UChar *pTarget = NULL; | 1620 UChar *pTarget = NULL; |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 state.inputdirLength = (state.inputdir != NULL) ? (uint32_t)uprv_strlen(stat
e.inputdir) : 0; | 1982 state.inputdirLength = (state.inputdir != NULL) ? (uint32_t)uprv_strlen(stat
e.inputdir) : 0; |
| 2127 state.outputdir = outputDir; | 1983 state.outputdir = outputDir; |
| 2128 state.outputdirLength = (state.outputdir != NULL) ? (uint32_t)uprv_strlen(st
ate.outputdir) : 0; | 1984 state.outputdirLength = (state.outputdir != NULL) ? (uint32_t)uprv_strlen(st
ate.outputdir) : 0; |
| 2129 state.filename = filename; | 1985 state.filename = filename; |
| 2130 state.makeBinaryCollation = makeBinaryCollation; | 1986 state.makeBinaryCollation = makeBinaryCollation; |
| 2131 state.omitCollationRules = omitCollationRules; | 1987 state.omitCollationRules = omitCollationRules; |
| 2132 | 1988 |
| 2133 ustr_init(&comment); | 1989 ustr_init(&comment); |
| 2134 expect(&state, TOK_STRING, &tokenValue, &comment, NULL, status); | 1990 expect(&state, TOK_STRING, &tokenValue, &comment, NULL, status); |
| 2135 | 1991 |
| 2136 state.bundle = bundle_open(&comment, FALSE, status); | 1992 state.bundle = new SRBRoot(&comment, FALSE, *status); |
| 2137 | 1993 |
| 2138 if (state.bundle == NULL || U_FAILURE(*status)) | 1994 if (state.bundle == NULL || U_FAILURE(*status)) |
| 2139 { | 1995 { |
| 2140 return NULL; | 1996 return NULL; |
| 2141 } | 1997 } |
| 2142 | 1998 |
| 2143 | 1999 |
| 2144 bundle_setlocale(state.bundle, tokenValue->fChars, status); | 2000 state.bundle->setLocale(tokenValue->fChars, *status); |
| 2145 | 2001 |
| 2146 /* The following code is to make Empty bundle work no matter with :table spe
cifer or not */ | 2002 /* The following code is to make Empty bundle work no matter with :table spe
cifer or not */ |
| 2147 token = getToken(&state, NULL, NULL, &line, status); | 2003 token = getToken(&state, NULL, NULL, &line, status); |
| 2148 if(token==TOK_COLON) { | 2004 if(token==TOK_COLON) { |
| 2149 *status=U_ZERO_ERROR; | 2005 *status=U_ZERO_ERROR; |
| 2150 bundleType=parseResourceType(&state, status); | 2006 bundleType=parseResourceType(&state, status); |
| 2151 | 2007 |
| 2152 if(isTable(bundleType)) | 2008 if(isTable(bundleType)) |
| 2153 { | 2009 { |
| 2154 expect(&state, TOK_OPEN_BRACE, NULL, NULL, &line, status); | 2010 expect(&state, TOK_OPEN_BRACE, NULL, NULL, &line, status); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2171 { | 2027 { |
| 2172 /* neither colon nor open brace */ | 2028 /* neither colon nor open brace */ |
| 2173 *status=U_PARSE_ERROR; | 2029 *status=U_PARSE_ERROR; |
| 2174 bundleType=RESTYPE_UNKNOWN; | 2030 bundleType=RESTYPE_UNKNOWN; |
| 2175 error(line, "parse error, did not find open-brace '{' or colon ':',
stopped with %s", u_errorName(*status)); | 2031 error(line, "parse error, did not find open-brace '{' or colon ':',
stopped with %s", u_errorName(*status)); |
| 2176 } | 2032 } |
| 2177 } | 2033 } |
| 2178 | 2034 |
| 2179 if (U_FAILURE(*status)) | 2035 if (U_FAILURE(*status)) |
| 2180 { | 2036 { |
| 2181 bundle_close(state.bundle, status); | 2037 delete state.bundle; |
| 2182 return NULL; | 2038 return NULL; |
| 2183 } | 2039 } |
| 2184 | 2040 |
| 2185 if(bundleType==RESTYPE_TABLE_NO_FALLBACK) { | 2041 if(bundleType==RESTYPE_TABLE_NO_FALLBACK) { |
| 2186 /* | 2042 /* |
| 2187 * Parse a top-level table with the table(nofallback) declaration. | 2043 * Parse a top-level table with the table(nofallback) declaration. |
| 2188 * This is the same as a regular table, but also sets the | 2044 * This is the same as a regular table, but also sets the |
| 2189 * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] . | 2045 * URES_ATT_NO_FALLBACK flag in indexes[URES_INDEX_ATTRIBUTES] . |
| 2190 */ | 2046 */ |
| 2191 state.bundle->noFallback=TRUE; | 2047 state.bundle->fNoFallback=TRUE; |
| 2192 } | 2048 } |
| 2193 /* top-level tables need not handle special table names like "collations" */ | 2049 /* top-level tables need not handle special table names like "collations" */ |
| 2194 realParseTable(&state, state.bundle->fRoot, NULL, line, status); | 2050 assert(!state.bundle->fIsPoolBundle); |
| 2051 assert(state.bundle->fRoot->fType == URES_TABLE); |
| 2052 TableResource *rootTable = static_cast<TableResource *>(state.bundle->fRoot)
; |
| 2053 realParseTable(&state, rootTable, NULL, line, status); |
| 2195 if(dependencyArray!=NULL){ | 2054 if(dependencyArray!=NULL){ |
| 2196 table_add(state.bundle->fRoot, dependencyArray, 0, status); | 2055 rootTable->add(dependencyArray, 0, *status); |
| 2197 dependencyArray = NULL; | 2056 dependencyArray = NULL; |
| 2198 } | 2057 } |
| 2199 if (U_FAILURE(*status)) | 2058 if (U_FAILURE(*status)) |
| 2200 { | 2059 { |
| 2201 bundle_close(state.bundle, status); | 2060 delete state.bundle; |
| 2202 res_close(dependencyArray); | 2061 res_close(dependencyArray); |
| 2203 return NULL; | 2062 return NULL; |
| 2204 } | 2063 } |
| 2205 | 2064 |
| 2206 if (getToken(&state, NULL, NULL, &line, status) != TOK_EOF) | 2065 if (getToken(&state, NULL, NULL, &line, status) != TOK_EOF) |
| 2207 { | 2066 { |
| 2208 warning(line, "extraneous text after resource bundle (perhaps unmatched
braces)"); | 2067 warning(line, "extraneous text after resource bundle (perhaps unmatched
braces)"); |
| 2209 if(isStrict()){ | 2068 if(isStrict()){ |
| 2210 *status = U_INVALID_FORMAT_ERROR; | 2069 *status = U_INVALID_FORMAT_ERROR; |
| 2211 return NULL; | 2070 return NULL; |
| 2212 } | 2071 } |
| 2213 } | 2072 } |
| 2214 | 2073 |
| 2215 cleanupLookahead(&state); | 2074 cleanupLookahead(&state); |
| 2216 ustr_deinit(&comment); | 2075 ustr_deinit(&comment); |
| 2217 return state.bundle; | 2076 return state.bundle; |
| 2218 } | 2077 } |
| OLD | NEW |