/* * Search for an standard name of an alias (what is the default name * that this standard uses?) * return the listOffset for gTaggedAliasLists. If it's 0, * the it couldn't be found, but the parameters are valid. */ static uint32_t findTaggedAliasListsOffset(const char* alias, const char* standard, UErrorCode* pErrorCode) { uint32_t idx; uint32_t listOffset; uint32_t convNum; UErrorCode myErr = U_ZERO_ERROR; uint32_t tagNum = getTagNumber(standard); /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ convNum = findConverter(alias, NULL, &myErr); if (myErr != U_ZERO_ERROR) { *pErrorCode = myErr; } if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { listOffset = gMainTable.taggedAliasArray[tagNum * gMainTable.converterListSize + convNum]; if (listOffset && gMainTable.taggedAliasLists[listOffset + 1]) { return listOffset; } if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { /* Uh Oh! They used an ambiguous alias. We have to search the whole swiss cheese starting at the highest standard affinity. This may take a while. */ for (idx = 0; idx < gMainTable.taggedAliasArraySize; idx++) { listOffset = gMainTable.taggedAliasArray[idx]; if (listOffset && isAliasInList(alias, listOffset)) { uint32_t currTagNum = idx / gMainTable.converterListSize; uint32_t currConvNum = (idx - currTagNum * gMainTable.converterListSize); uint32_t tempListOffset = gMainTable.taggedAliasArray[tagNum * gMainTable.converterListSize + currConvNum]; if (tempListOffset && gMainTable.taggedAliasLists[tempListOffset + 1]) { return tempListOffset; } /* else keep on looking */ /* We could speed this up by starting on the next row because an alias is unique per row, right now. This would change if alias versioning appears. */ } } /* The standard doesn't know about the alias */ } /* else no default name */ return 0; } /* else converter or tag not found */ return UINT32_MAX; }
/* Return the canonical name */ static uint32_t findTaggedConverterNum(const char *alias, const char *standard, UErrorCode *pErrorCode) { uint32_t idx; uint32_t listOffset; uint32_t convNum; UErrorCode myErr = U_ZERO_ERROR; uint32_t tagNum = getTagNumber(standard); /* Make a quick guess. Hopefully they used a TR22 canonical alias. */ convNum = findConverter(alias, NULL, &myErr); if (myErr != U_ZERO_ERROR) { *pErrorCode = myErr; } if (tagNum < (gMainTable.tagListSize - UCNV_NUM_HIDDEN_TAGS) && convNum < gMainTable.converterListSize) { listOffset = gMainTable.taggedAliasArray[tagNum*gMainTable.converterListSize + convNum]; if (listOffset && isAliasInList(alias, listOffset)) { return convNum; } if (myErr == U_AMBIGUOUS_ALIAS_WARNING) { /* Uh Oh! They used an ambiguous alias. We have to search one slice of the swiss cheese. We search only in the requested tag, not the whole thing. This may take a while. */ uint32_t convStart = (tagNum)*gMainTable.converterListSize; uint32_t convLimit = (tagNum+1)*gMainTable.converterListSize; for (idx = convStart; idx < convLimit; idx++) { listOffset = gMainTable.taggedAliasArray[idx]; if (listOffset && isAliasInList(alias, listOffset)) { return idx-convStart; } } /* The standard doesn't know about the alias */ } /* else no canonical name */ } /* else converter or tag not found */ return UINT32_MAX; }
static void parseLine(const char *line) { uint16_t pos=0, start, limit, length, cnv; char *converter, *alias; /* skip leading white space */ /* There is no whitespace at the beginning anymore */ /* while(line[pos]!=0 && isspace(line[pos])) { ++pos; } */ /* is there nothing on this line? */ if(line[pos]==0) { return; } /* get the converter name */ start=pos; while(line[pos]!=0 && !isspace((int)line[pos])) { ++pos; } limit=pos; /* store the converter name */ length=(uint16_t)(limit-start); converter=allocString(&stringBlock, line+start, length); /* add the converter to the converter table */ cnv=addConverter(converter); /* The name itself may be tagged, so let's added it to the aliases list properly */ pos = start; /* get all the real aliases */ for(;;) { /* skip white space */ while(line[pos]!=0 && isspace((int)line[pos])) { ++pos; } /* is there no more alias name on this line? */ if(line[pos]==0) { break; } /* get an alias name */ start=pos; while(line[pos]!=0 && line[pos]!='{' && !isspace((int)line[pos])) { ++pos; } limit=pos; /* store the alias name */ length=(uint16_t)(limit-start); if (start == 0) { /* add the converter as its own alias to the alias table */ alias = converter; addAlias(alias, ALL_TAG_NUM, cnv, TRUE); } else { alias=allocString(&stringBlock, line+start, length); addAlias(alias, ALL_TAG_NUM, cnv, FALSE); } addToKnownAliases(alias); /* add the alias/converter pair to the alias table */ /* addAlias(alias, 0, cnv, FALSE);*/ /* skip whitespace */ while (line[pos] && isspace((int)line[pos])) { ++pos; } /* handle tags if they are present */ if (line[pos] == '{') { ++pos; do { start = pos; while (line[pos] && line[pos] != '}' && !isspace((int)line[pos])) { ++pos; } limit = pos; if (start != limit) { /* add the tag to the tag table */ uint16_t tag = getTagNumber(line + start, (uint16_t)(limit - start)); addAlias(alias, tag, cnv, (UBool)(line[limit-1] == '*')); } while (line[pos] && isspace((int)line[pos])) { ++pos; } } while (line[pos] && line[pos] != '}'); if (line[pos] == '}') { ++pos; } else { fprintf(stderr, "%s:%d: Unterminated tag list\n", path, lineNum); exit(U_UNMATCHED_BRACES); } } else { addAlias(alias, EMPTY_TAG_NUM, cnv, (UBool)(tags[0].aliasList[cnv].aliasCount == 0)); } } }
static void parseFile(FileStream *in) { char line[MAX_LINE_SIZE]; char lastLine[MAX_LINE_SIZE]; int32_t lineSize = 0; int32_t lastLineSize = 0; UBool validParse = TRUE; lineNum = 0; /* Add the empty tag, which is for untagged aliases */ getTagNumber("", 0); getTagNumber(ALL_TAG_STR, 3); allocString(&stringBlock, "", 0); /* read the list of aliases */ while (validParse) { validParse = FALSE; /* Read non-empty lines that don't start with a space character. */ while (T_FileStream_readLine(in, lastLine, MAX_LINE_SIZE) != NULL) { lastLineSize = chomp(lastLine); if (lineSize == 0 || (lastLineSize > 0 && isspace((int)*lastLine))) { uprv_strcpy(line + lineSize, lastLine); lineSize += lastLineSize; } else if (lineSize > 0) { validParse = TRUE; break; } lineNum++; } if (validParse || lineSize > 0) { if (isspace((int)*line)) { fprintf(stderr, "%s:%d: error: cannot start an alias with a space\n", path, lineNum-1); exit(U_PARSE_ERROR); } else if (line[0] == '{') { if (!standardTagsUsed && line[lineSize - 1] != '}') { fprintf(stderr, "%s:%d: error: alias needs to start with a converter name\n", path, lineNum); exit(U_PARSE_ERROR); } addOfficialTaggedStandards(line, lineSize); standardTagsUsed = TRUE; } else { if (standardTagsUsed) { parseLine(line); } else { fprintf(stderr, "%s:%d: error: alias table needs to start a list of standard tags\n", path, lineNum); exit(U_PARSE_ERROR); } } /* Was the last line consumed */ if (lastLineSize > 0) { uprv_strcpy(line, lastLine); lineSize = lastLineSize; } else { lineSize = 0; } } lineNum++; } }